From 64acfbfb05a09ea3ecc62e7cb107ca24986fe8d9 Mon Sep 17 00:00:00 2001 From: Per Lundberg Date: Wed, 9 Sep 2020 14:15:50 +0300 Subject: [PATCH] add doNotBelongToAnyOf() to syntax Signed-off-by: Per Lundberg --- .../lang/syntax/ClassesThatInternal.java | 5 +++++ .../syntax/MembersDeclaredInClassesThat.java | 5 +++++ .../lang/syntax/elements/ClassesThat.java | 8 ++++++++ .../syntax/elements/GivenClassesThatTest.java | 10 ++++++++++ .../GivenMembersDeclaredInClassesThatTest.java | 13 +++++++++++++ .../syntax/elements/ShouldClassesThatTest.java | 11 +++++++++++ .../elements/ShouldOnlyByClassesThatTest.java | 18 ++++++++++++++++-- 7 files changed, 68 insertions(+), 2 deletions(-) diff --git a/archunit/src/main/java/com/tngtech/archunit/lang/syntax/ClassesThatInternal.java b/archunit/src/main/java/com/tngtech/archunit/lang/syntax/ClassesThatInternal.java index 35ca0470ef..e4449ae0b5 100644 --- a/archunit/src/main/java/com/tngtech/archunit/lang/syntax/ClassesThatInternal.java +++ b/archunit/src/main/java/com/tngtech/archunit/lang/syntax/ClassesThatInternal.java @@ -358,6 +358,11 @@ public CONJUNCTION belongToAnyOf(Class... classes) { return givenWith(JavaClass.Predicates.belongToAnyOf(classes)); } + @Override + public CONJUNCTION doNotBelongToAnyOf(Class... classes) { + return givenWith(doNot(JavaClass.Predicates.belongToAnyOf(classes))); + } + @Override public CONJUNCTION arePublic() { return givenWith(SyntaxPredicates.arePublic()); diff --git a/archunit/src/main/java/com/tngtech/archunit/lang/syntax/MembersDeclaredInClassesThat.java b/archunit/src/main/java/com/tngtech/archunit/lang/syntax/MembersDeclaredInClassesThat.java index ff39c6c426..132a4fedd6 100644 --- a/archunit/src/main/java/com/tngtech/archunit/lang/syntax/MembersDeclaredInClassesThat.java +++ b/archunit/src/main/java/com/tngtech/archunit/lang/syntax/MembersDeclaredInClassesThat.java @@ -431,6 +431,11 @@ public CONJUNCTION belongToAnyOf(final Class... classes) { return givenWith(JavaClass.Predicates.belongToAnyOf(classes)); } + @Override + public CONJUNCTION doNotBelongToAnyOf(Class... classes) { + return givenWith(doNot(JavaClass.Predicates.belongToAnyOf(classes))); + } + private CONJUNCTION givenWith(DescribedPredicate predicate) { return predicateAggregator.apply(predicate); } diff --git a/archunit/src/main/java/com/tngtech/archunit/lang/syntax/elements/ClassesThat.java b/archunit/src/main/java/com/tngtech/archunit/lang/syntax/elements/ClassesThat.java index a584c1b5bd..6579a9dcb8 100644 --- a/archunit/src/main/java/com/tngtech/archunit/lang/syntax/elements/ClassesThat.java +++ b/archunit/src/main/java/com/tngtech/archunit/lang/syntax/elements/ClassesThat.java @@ -675,4 +675,12 @@ public interface ClassesThat { @PublicAPI(usage = ACCESS) CONJUNCTION belongToAnyOf(Class... classes); + /** + * Inverted form of {@link #belongToAnyOf belongToAnyOf(Outer.class)} + * + * @param classes List of {@link Class} objects. + * @return A syntax conjunction element, which can be completed to form a full rule + */ + @PublicAPI(usage = ACCESS) + CONJUNCTION doNotBelongToAnyOf(Class... classes); } diff --git a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenClassesThatTest.java b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenClassesThatTest.java index 1124331b4f..2467638585 100644 --- a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenClassesThatTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenClassesThatTest.java @@ -758,6 +758,16 @@ public void belongToAnyOf() { String.class); } + @Test + public void doNotBelongToAnyOf() { + List classes = filterResultOf(classes().that().doNotBelongToAnyOf(ClassWithInnerClasses.class, String.class)) + .on(ClassWithInnerClasses.class, ClassWithInnerClasses.InnerClass.class, ClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class, + List.class, String.class, Iterable.class, StringBuilder.class); + + assertThatTypes(classes).matchInAnyOrder( + List.class, Iterable.class, StringBuilder.class); + } + @Test public void and_conjunction() { List classes = filterResultOf( diff --git a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMembersDeclaredInClassesThatTest.java b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMembersDeclaredInClassesThatTest.java index 215e159a90..f47a76f8bb 100644 --- a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMembersDeclaredInClassesThatTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMembersDeclaredInClassesThatTest.java @@ -762,6 +762,19 @@ public void belongToAnyOf() { ); } + @Test + public void doNotBelongToAnyOf() { + List members = + filterResultOf(members().that().areDeclaredInClassesThat().doNotBelongToAnyOf(ClassWithInnerClasses.class, String.class)) + .on(ClassWithInnerClasses.class, ClassWithInnerClasses.InnerClass.class, + ClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class, + List.class, String.class, Iterable.class, StringBuilder.class); + + assertThatMembers(members).matchInAnyOrderMembersOf( + List.class, Iterable.class, StringBuilder.class + ); + } + @Test public void and_conjunction() { List members = filterResultOf( diff --git a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldClassesThatTest.java b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldClassesThatTest.java index 705f0bb1ac..72d80b69c8 100644 --- a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldClassesThatTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldClassesThatTest.java @@ -865,6 +865,17 @@ public void belongToAnyOf(ClassesThat noClassesShouldT ClassAccessingString.class); } + @Test + @UseDataProvider("no_classes_should_that_rule_starts") + public void doNotBelongToAnyOf(ClassesThat noClassesShouldThatRuleStart) { + Set classes = filterClassesAppearingInFailureReport( + noClassesShouldThatRuleStart.doNotBelongToAnyOf(ClassWithInnerClasses.class, String.class)) + .on(ClassAccessingNestedInnerClass.class, ClassWithInnerClasses.class, ClassWithInnerClasses.InnerClass.class, + ClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class, ClassAccessingString.class, ClassAccessingIterable.class); + + assertThatTypes(classes).matchInAnyOrder(ClassAccessingIterable.class); + } + @Test @UseDataProvider("classes_should_only_that_rule_starts") public void only_haveFullyQualifiedName(ClassesThat classesShouldOnlyThatRuleStart) { diff --git a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldOnlyByClassesThatTest.java b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldOnlyByClassesThatTest.java index 54a11cfe51..40d9c6d476 100644 --- a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldOnlyByClassesThatTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/ShouldOnlyByClassesThatTest.java @@ -987,6 +987,20 @@ public void belongToAnyOf(ClassesThat classesShouldOnl assertThatTypes(classes).matchInAnyOrder(AnotherClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class); } + @Test + @UseDataProvider("should_only_be_by_rule_starts") + public void doNotBelongToAnyOf(ClassesThat classesShouldOnlyBeBy) { + Set classes = filterViolationCausesInFailureReport( + classesShouldOnlyBeBy.doNotBelongToAnyOf(ClassWithInnerClasses.class)) + .on(ClassWithInnerClasses.class, ClassWithInnerClasses.InnerClass.class, + ClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class, + AnotherClassWithInnerClasses.class, AnotherClassWithInnerClasses.InnerClass.class, + AnotherClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class, + ClassBeingAccessedByInnerClass.class); + + assertThatTypes(classes).matchInAnyOrder(ClassWithInnerClasses.InnerClass.EvenMoreInnerClass.class); + } + @DataProvider public static Object[][] byClassesThat_predicate_rules() { return testForEach( @@ -1183,7 +1197,7 @@ private static class ClassBeingAccessedByClassImplementingSomeInterface { @SuppressWarnings("unused") private static class ClassAccessingItself { - private String field; + private final String field; ClassAccessingItself(String field) { this.field = field; @@ -1299,7 +1313,7 @@ void access() { } } - private static Runnable anonymousClassBeingAccessed = new Runnable() { + private static final Runnable anonymousClassBeingAccessed = new Runnable() { @Override public void run() { new ClassAccessingAnonymousClass();