Skip to content

Commit

Permalink
Merge branch 'master' into release-0.10.2
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
  • Loading branch information
codecholeric committed Mar 31, 2019
2 parents 4a6e738 + 92fef8a commit 1a49eb1
Show file tree
Hide file tree
Showing 34 changed files with 859 additions and 181 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tngtech.archunit.exampletest.junit4;

import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.junit.ArchUnitRunner;
Expand All @@ -9,6 +10,9 @@
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.util.logging.Logger;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import static com.tngtech.archunit.library.GeneralCodingRules.ACCESS_STANDARD_STREAMS;
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;
Expand All @@ -35,6 +39,14 @@ private void no_access_to_standard_streams_as_method(JavaClasses classes) {
@ArchTest
private final ArchRule no_java_util_logging = NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;

@ArchTest
private final ArchRule loggers_should_be_private_static_final =
fields().that().haveRawType(Logger.class)
.should().bePrivate()
.andShould().beStatic()
.andShould().beFinal()
.because("we agreed on this convention");

@ArchTest
private final ArchRule no_jodatime = NO_CLASSES_SHOULD_USE_JODATIME;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.tngtech.archunit.exampletest.junit5;

import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTag;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.CompositeArchRule;

import java.util.logging.Logger;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import static com.tngtech.archunit.library.GeneralCodingRules.ACCESS_STANDARD_STREAMS;
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;
Expand All @@ -32,6 +36,14 @@ private void no_access_to_standard_streams_as_method(JavaClasses classes) {
@ArchTest
private final ArchRule no_java_util_logging = NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING;

@ArchTest
private final ArchRule loggers_should_be_private_static_final =
fields().that().haveRawType(Logger.class)
.should().bePrivate()
.andShould().beStatic()
.andShould().beFinal()
.because("we agreed on this convention");

@ArchTest
private final ArchRule no_jodatime = NO_CLASSES_SHOULD_USE_JODATIME;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.logging.Logger;

public class ClassViolatingCodingRules {
private static final Logger log = Logger.getLogger("Wrong Logger"); // Violates rule not to use java.util.logging
static Logger log = Logger.getLogger("Wrong Logger"); // Violates rules not to use java.util.logging & that loggers should be private static final

public void printToStandardStream() throws FileNotFoundException {
System.out.println("I'm gonna print to the command line"); // Violates rule not to write to standard streams
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.tngtech.archunit.exampletest;

import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.example.ClassViolatingCodingRules;
import com.tngtech.archunit.lang.CompositeArchRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import java.util.logging.Logger;

import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.fields;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
import static com.tngtech.archunit.library.GeneralCodingRules.ACCESS_STANDARD_STREAMS;
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;
Expand Down Expand Up @@ -39,6 +43,16 @@ public void classes_should_not_use_java_util_logging() {
NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING.check(classes);
}

@Test
public void loggers_should_be_private_static_final() {
fields().that().haveRawType(Logger.class)
.should().bePrivate()
.andShould().beStatic()
.andShould().beFinal()
.because("we agreed on this convention")
.check(classes);
}

@Test
public void classes_should_not_use_jodatime() {
NO_CLASSES_SHOULD_USE_JODATIME.check(classes);
Expand All @@ -49,5 +63,4 @@ public void no_classes_should_access_standard_streams_or_throw_generic_exception
CompositeArchRule.of(NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS)
.and(NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS).check(classes);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.example.AbstractController;
import com.tngtech.archunit.example.ClassViolatingCodingRules;
import com.tngtech.archunit.example.ClassViolatingSessionBeanRules;
Expand Down Expand Up @@ -108,6 +109,7 @@
import com.tngtech.archunit.testutils.CyclicErrorMatcher;
import com.tngtech.archunit.testutils.ExpectedClass;
import com.tngtech.archunit.testutils.ExpectedConstructor;
import com.tngtech.archunit.testutils.ExpectedField;
import com.tngtech.archunit.testutils.ExpectedMethod;
import com.tngtech.archunit.testutils.ExpectedTestFailures;
import com.tngtech.archunit.testutils.MessageAssertionChain;
Expand Down Expand Up @@ -196,6 +198,11 @@ Stream<DynamicTest> CodingRulesTest() {
expectAccessToStandardStreams(expectFailures);
expectThrownGenericExceptions(expectFailures);

expectFailures.ofRule("fields that have raw type java.util.logging.Logger should be private " +
"and should be static and should be final, because we agreed on this convention")
.by(ExpectedField.of(ClassViolatingCodingRules.class, "log").doesNotHaveModifier(JavaModifier.PRIVATE))
.by(ExpectedField.of(ClassViolatingCodingRules.class, "log").doesNotHaveModifier(JavaModifier.FINAL));

return expectFailures.toDynamicTests();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.tngtech.archunit.testutils;

import com.tngtech.archunit.core.domain.JavaModifier;

import static java.lang.String.format;

public class ExpectedField {

public static ExpectedField.Creator of(Class<?> owner, String fieldName) {
return new ExpectedField.Creator(owner, fieldName);
}

public static class Creator {
private final Class<?> clazz;
private final String fieldName;

private Creator(Class<?> clazz, String fieldName) {
this.clazz = clazz;
this.fieldName = fieldName;
}

public ExpectedMessage doesNotHaveModifier(JavaModifier modifier) {
return field("does not have modifier " + modifier);
}

private ExpectedMessage field(String message) {
String fieldDescription = format("Field <%s.%s>", clazz.getName(), fieldName);
String sourceCodeLocation = format("(%s.java:0)", clazz.getSimpleName());
return new ExpectedMessage(format("%s %s in %s", fieldDescription, message, sourceCodeLocation));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.tngtech.archunit.core.domain.JavaClass;

import static java.lang.String.format;
import static com.tngtech.archunit.core.domain.Formatters.formatMethod;

public class ExpectedMethod {
Expand All @@ -23,24 +24,21 @@ private Creator(Class<?> clazz, String methodName, Class<?>[] params) {
}

public ExpectedMessage toNotHaveRawReturnType(Class<?> type) {
return new ExpectedMessage(String.format("Method <%s> does not have raw return type %s in (%s.java:0)",
formatMethod(clazz.getName(), methodName, JavaClass.namesOf(params)),
type.getName(),
clazz.getSimpleName()));
return method("does not have raw return type " + type.getName());
}

public ExpectedMessage throwsException(Class<?> type) {
return new ExpectedMessage(String.format("Method <%s> does declare throwable of type %s in (%s.java:0)",
formatMethod(clazz.getName(), methodName, JavaClass.namesOf(params)),
type.getName(),
clazz.getSimpleName()));
return method("does declare throwable of type " + type.getName());
}

public ExpectedMessage beingAnnotatedWith(Class<? extends Annotation> annotationType) {
return new ExpectedMessage(String.format("Method <%s> is annotated with @%s in (%s.java:0)",
formatMethod(clazz.getName(), methodName, JavaClass.namesOf(params)),
annotationType.getSimpleName(),
clazz.getSimpleName()));
return method("is annotated with @" + annotationType.getSimpleName());
}

private ExpectedMessage method(String message) {
String methodDescription = format("Method <%s>", formatMethod(clazz.getName(), methodName, JavaClass.namesOf(params)));
String sourceCodeLocation = format("(%s.java:0)", clazz.getSimpleName());
return new ExpectedMessage(format("%s %s in %s", methodDescription, message, sourceCodeLocation));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@
import com.tngtech.archunit.core.domain.properties.HasAnnotations;
import com.tngtech.archunit.core.domain.properties.HasModifiers;
import com.tngtech.archunit.core.domain.properties.HasName;
import com.tngtech.archunit.core.domain.properties.HasSourceCodeLocation;
import com.tngtech.archunit.core.domain.properties.HasOwner.Functions.Get;
import com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With;
import com.tngtech.archunit.core.domain.properties.HasSourceCodeLocation;
import com.tngtech.archunit.core.domain.properties.HasThrowsClause;
import com.tngtech.archunit.lang.ArchCondition;
import com.tngtech.archunit.lang.ConditionEvents;
Expand Down Expand Up @@ -90,6 +90,7 @@
import static com.tngtech.archunit.core.domain.JavaConstructor.CONSTRUCTOR_NAME;
import static com.tngtech.archunit.core.domain.JavaMember.Predicates.declaredIn;
import static com.tngtech.archunit.core.domain.JavaModifier.FINAL;
import static com.tngtech.archunit.core.domain.JavaModifier.STATIC;
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.annotatedWith;
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.metaAnnotatedWith;
import static com.tngtech.archunit.core.domain.properties.HasModifiers.Predicates.modifier;
Expand Down Expand Up @@ -522,22 +523,22 @@ public static <HAS_NAME extends HasName & HasDescription & HasSourceCodeLocation

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> resideInAPackage(final String packageIdentifier) {
return new DoesConditionByPredicate(JavaClass.Predicates.resideInAPackage(packageIdentifier));
return new DoesConditionByPredicate<>(JavaClass.Predicates.resideInAPackage(packageIdentifier));
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> resideInAnyPackage(String... packageIdentifiers) {
return new DoesConditionByPredicate(JavaClass.Predicates.resideInAnyPackage(packageIdentifiers));
return new DoesConditionByPredicate<>(JavaClass.Predicates.resideInAnyPackage(packageIdentifiers));
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> resideOutsideOfPackage(String packageIdentifier) {
return new DoesConditionByPredicate(JavaClass.Predicates.resideOutsideOfPackage(packageIdentifier));
return new DoesConditionByPredicate<>(JavaClass.Predicates.resideOutsideOfPackage(packageIdentifier));
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> resideOutsideOfPackages(String... packageIdentifiers) {
return new DoesConditionByPredicate(JavaClass.Predicates.resideOutsideOfPackages(packageIdentifiers));
return new DoesConditionByPredicate<>(JavaClass.Predicates.resideOutsideOfPackages(packageIdentifiers));
}

@PublicAPI(usage = ACCESS)
Expand Down Expand Up @@ -595,6 +596,26 @@ public static <HAS_MODIFIERS extends HasModifiers & HasDescription & HasSourceCo
return not(ArchConditions.<HAS_MODIFIERS>haveModifier(JavaModifier.PRIVATE)).as("not be private");
}

@PublicAPI(usage = ACCESS)
public static <HAS_MODIFIERS extends HasModifiers & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_MODIFIERS> beStatic() {
return ArchConditions.<HAS_MODIFIERS>haveModifier(STATIC).as("be static");
}

@PublicAPI(usage = ACCESS)
public static <HAS_MODIFIERS extends HasModifiers & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_MODIFIERS> notBeStatic() {
return not(ArchConditions.<HAS_MODIFIERS>haveModifier(STATIC).as("be static"));
}

@PublicAPI(usage = ACCESS)
public static <HAS_MODIFIERS extends HasModifiers & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_MODIFIERS> beFinal() {
return ArchConditions.<HAS_MODIFIERS>haveModifier(FINAL).as("be final");
}

@PublicAPI(usage = ACCESS)
public static <HAS_MODIFIERS extends HasModifiers & HasDescription & HasSourceCodeLocation> ArchCondition<HAS_MODIFIERS> notBeFinal() {
return not(ArchConditions.<HAS_MODIFIERS>haveModifier(FINAL).as("be final"));
}

@PublicAPI(usage = ACCESS)
public static ArchCondition<JavaClass> haveOnlyFinalFields() {
return new HaveOnlyFinalFieldsCondition();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,26 @@ public SELF notBePrivate() {
return addCondition(ArchConditions.notBePrivate());
}

// only applicable to fields and methods; therefore not exposed via MembersShould
public SELF beStatic() {
return addCondition(ArchConditions.beStatic());
}

// only applicable to fields and methods; therefore not exposed via MembersShould
public SELF notBeStatic() {
return addCondition(ArchConditions.notBeStatic());
}

// only applicable to fields and methods; therefore not exposed via MembersShould
public SELF beFinal() {
return addCondition(ArchConditions.beFinal());
}

// only applicable to fields and methods; therefore not exposed via MembersShould
public SELF notBeFinal() {
return addCondition(ArchConditions.notBeFinal());
}

@Override
public SELF haveModifier(JavaModifier modifier) {
return addCondition(ArchConditions.haveModifier(modifier));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.tngtech.archunit.lang.syntax.elements.FieldsShould;
import com.tngtech.archunit.lang.syntax.elements.FieldsShouldConjunction;

import static com.tngtech.archunit.lang.conditions.ArchConditions.not;

class FieldsShouldInternal
extends AbstractMembersShouldInternal<JavaField, FieldsShouldInternal>
implements FieldsShould<FieldsShouldInternal>, FieldsShouldConjunction {
Expand Down Expand Up @@ -66,13 +68,28 @@ public FieldsShouldInternal haveRawType(Class<?> type) {
return addCondition(ArchConditions.haveRawType(type));
}

@Override
public FieldsShouldInternal notHaveRawType(Class<?> type) {
return addCondition(not(ArchConditions.haveRawType(type)));
}

@Override
public FieldsShouldInternal haveRawType(String typeName) {
return addCondition(ArchConditions.haveRawType(typeName));
}

@Override
public FieldsShouldInternal notHaveRawType(String typeName) {
return addCondition(not(ArchConditions.haveRawType(typeName)));
}

@Override
public FieldsShouldInternal haveRawType(DescribedPredicate<? super JavaClass> predicate) {
return addCondition(ArchConditions.haveRawType(predicate));
}

@Override
public FieldsShouldInternal notHaveRawType(DescribedPredicate<? super JavaClass> predicate) {
return addCondition(not(ArchConditions.haveRawType(predicate)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ private GivenMethodsInternal(
super(factory, priority, classesTransformer, prepareCondition, relevantObjectsPredicates, overriddenDescription);
}

@Override
public MethodsThatInternal that() {
return new MethodsThatInternal(this, currentPredicate());
}

@Override
public MethodsThatInternal and() {
return new MethodsThatInternal(this, currentPredicate().thatANDs());
}

@Override
public MethodsThatInternal or() {
return new MethodsThatInternal(this, currentPredicate().thatORs());
}

@Override
public MethodsShouldInternal should() {
return new MethodsShouldInternal(finishedClassesTransformer(), priority, prepareCondition);
Expand Down
Loading

0 comments on commit 1a49eb1

Please sign in to comment.