diff --git a/archunit-junit/junit5/engine/src/main/java/com/tngtech/archunit/junit/AbstractArchUnitTestDescriptor.java b/archunit-junit/junit5/engine/src/main/java/com/tngtech/archunit/junit/AbstractArchUnitTestDescriptor.java index a4bf663092..128581ff18 100644 --- a/archunit-junit/junit5/engine/src/main/java/com/tngtech/archunit/junit/AbstractArchUnitTestDescriptor.java +++ b/archunit-junit/junit5/engine/src/main/java/com/tngtech/archunit/junit/AbstractArchUnitTestDescriptor.java @@ -19,8 +19,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.Optional; import java.util.Set; +import org.junit.platform.commons.support.AnnotationSupport; import org.junit.platform.engine.TestDescriptor; import org.junit.platform.engine.TestSource; import org.junit.platform.engine.TestTag; @@ -39,15 +41,17 @@ abstract class AbstractArchUnitTestDescriptor extends AbstractTestDescriptor imp super(uniqueId, displayName, source); tags = Arrays.stream(elements).map(this::findTagsOn).flatMap(Collection::stream).collect(toSet()); skipResult = Arrays.stream(elements) - .filter(e -> e.isAnnotationPresent(ArchIgnore.class)) - .map(e -> e.getAnnotation(ArchIgnore.class)) + .map(e -> AnnotationSupport.findAnnotation(e, ArchIgnore.class)) + .filter(Optional::isPresent) + .map(Optional::get) .findFirst() .map(ignore -> SkipResult.skip(ignore.reason())) .orElse(SkipResult.doNotSkip()); } private Set findTagsOn(AnnotatedElement annotatedElement) { - return Arrays.stream(annotatedElement.getAnnotationsByType(ArchTag.class)) + return AnnotationSupport.findRepeatableAnnotations(annotatedElement, ArchTag.class) + .stream() .map(annotation -> TestTag.create(annotation.value())) .collect(toSet()); } diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/ArchUnitTestEngineTest.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/ArchUnitTestEngineTest.java index ce6850ccfd..e658944a01 100644 --- a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/ArchUnitTestEngineTest.java +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/ArchUnitTestEngineTest.java @@ -15,19 +15,30 @@ import com.tngtech.archunit.core.domain.JavaClasses; import com.tngtech.archunit.junit.ArchUnitTestEngine.SharedCache; import com.tngtech.archunit.junit.testexamples.ClassWithPrivateTests; +import com.tngtech.archunit.junit.testexamples.ComplexMetaTags; import com.tngtech.archunit.junit.testexamples.ComplexRuleLibrary; import com.tngtech.archunit.junit.testexamples.ComplexTags; import com.tngtech.archunit.junit.testexamples.FullAnalyzeClassesSpec; import com.tngtech.archunit.junit.testexamples.LibraryWithPrivateTests; import com.tngtech.archunit.junit.testexamples.SimpleRuleLibrary; +import com.tngtech.archunit.junit.testexamples.TestClassWithMetaTag; +import com.tngtech.archunit.junit.testexamples.TestClassWithMetaTags; import com.tngtech.archunit.junit.testexamples.TestClassWithTags; +import com.tngtech.archunit.junit.testexamples.TestFieldWithMetaTag; +import com.tngtech.archunit.junit.testexamples.TestFieldWithMetaTags; import com.tngtech.archunit.junit.testexamples.TestFieldWithTags; +import com.tngtech.archunit.junit.testexamples.TestMethodWithMetaTag; +import com.tngtech.archunit.junit.testexamples.TestMethodWithMetaTags; import com.tngtech.archunit.junit.testexamples.TestMethodWithTags; import com.tngtech.archunit.junit.testexamples.UnwantedClass; import com.tngtech.archunit.junit.testexamples.ignores.IgnoredClass; import com.tngtech.archunit.junit.testexamples.ignores.IgnoredField; import com.tngtech.archunit.junit.testexamples.ignores.IgnoredLibrary; import com.tngtech.archunit.junit.testexamples.ignores.IgnoredMethod; +import com.tngtech.archunit.junit.testexamples.ignores.MetaIgnoredClass; +import com.tngtech.archunit.junit.testexamples.ignores.MetaIgnoredField; +import com.tngtech.archunit.junit.testexamples.ignores.MetaIgnoredLibrary; +import com.tngtech.archunit.junit.testexamples.ignores.MetaIgnoredMethod; import com.tngtech.archunit.junit.testexamples.subone.SimpleRuleField; import com.tngtech.archunit.junit.testexamples.subone.SimpleRuleMethod; import com.tngtech.archunit.junit.testexamples.subtwo.SimpleRules; @@ -59,7 +70,11 @@ import static com.tngtech.archunit.junit.ArchUnitTestDescriptor.FIELD_SEGMENT_TYPE; import static com.tngtech.archunit.junit.ArchUnitTestDescriptor.METHOD_SEGMENT_TYPE; import static com.tngtech.archunit.junit.EngineExecutionTestListener.onlyElement; +import static com.tngtech.archunit.junit.testexamples.TestFieldWithMetaTag.FIELD_WITH_META_TAG_NAME; +import static com.tngtech.archunit.junit.testexamples.TestFieldWithMetaTags.FIELD_WITH_META_TAGS_NAME; import static com.tngtech.archunit.junit.testexamples.TestFieldWithTags.FIELD_WITH_TAG_NAME; +import static com.tngtech.archunit.junit.testexamples.TestMethodWithMetaTag.METHOD_WITH_META_TAG_NAME; +import static com.tngtech.archunit.junit.testexamples.TestMethodWithMetaTags.METHOD_WITH_META_TAGS_NAME; import static com.tngtech.archunit.junit.testexamples.TestMethodWithTags.METHOD_WITH_TAG_NAME; import static com.tngtech.archunit.junit.testexamples.subone.SimpleRuleField.SIMPLE_RULE_FIELD_NAME; import static com.tngtech.archunit.junit.testexamples.subone.SimpleRuleMethod.SIMPLE_RULE_METHOD_NAME; @@ -463,6 +478,38 @@ void tags_of_test_classes() { ); } + @Test + void meta_tag_of_test_classes() { + EngineDiscoveryTestRequest discoveryRequest = new EngineDiscoveryTestRequest().withClass(TestClassWithMetaTag.class); + + TestDescriptor descriptor = testEngine.discover(discoveryRequest, engineId); + + TestDescriptor testClass = getOnlyElement(descriptor.getChildren()); + assertThat(testClass.getTags()).containsOnly(TestTag.create("meta-tag-one"), TestTag.create("meta-tag-two")); + + Set concreteRules = getAllLeafs(testClass); + assertThat(concreteRules).as("concrete rules").hasSize(3); + concreteRules.forEach(concreteRule -> + assertThat(concreteRule.getTags()).containsOnly(TestTag.create("meta-tag-one"), TestTag.create("meta-tag-two")) + ); + } + + @Test + void meta_tags_of_test_classes() { + EngineDiscoveryTestRequest discoveryRequest = new EngineDiscoveryTestRequest().withClass(TestClassWithMetaTags.class); + + TestDescriptor descriptor = testEngine.discover(discoveryRequest, engineId); + + TestDescriptor testClass = getOnlyElement(descriptor.getChildren()); + assertThat(testClass.getTags()).containsOnly(TestTag.create("meta-tags-one"), TestTag.create("meta-tags-two")); + + Set concreteRules = getAllLeafs(testClass); + assertThat(concreteRules).as("concrete rules").hasSize(3); + concreteRules.forEach(concreteRule -> + assertThat(concreteRule.getTags()).containsOnly(TestTag.create("meta-tags-one"), TestTag.create("meta-tags-two")) + ); + } + @Test void tags_of_rule_fields() { TestDescriptor testField = getOnlyChildWithDescriptorContaining(FIELD_WITH_TAG_NAME, TestFieldWithTags.class); @@ -470,6 +517,20 @@ void tags_of_rule_fields() { assertThat(testField.getTags()).containsOnly(TestTag.create("field-tag-one"), TestTag.create("field-tag-two")); } + @Test + void meta_tag_of_rule_fields() { + TestDescriptor testField = getOnlyChildWithDescriptorContaining(FIELD_WITH_META_TAG_NAME, TestFieldWithMetaTag.class); + + assertThat(testField.getTags()).containsOnly(TestTag.create("field-meta-tag-one"), TestTag.create("field-meta-tag-two")); + } + + @Test + void meta_tags_of_rule_fields() { + TestDescriptor testField = getOnlyChildWithDescriptorContaining(FIELD_WITH_META_TAGS_NAME, TestFieldWithMetaTags.class); + + assertThat(testField.getTags()).containsOnly(TestTag.create("field-meta-tags-one"), TestTag.create("field-meta-tags-two")); + } + @Test void tags_of_rule_methods() { TestDescriptor testMethod = getOnlyChildWithDescriptorContaining(METHOD_WITH_TAG_NAME, TestMethodWithTags.class); @@ -477,6 +538,20 @@ void tags_of_rule_methods() { assertThat(testMethod.getTags()).containsOnly(TestTag.create("method-tag-one"), TestTag.create("method-tag-two")); } + @Test + void meta_tag_of_rule_methods() { + TestDescriptor testMethod = getOnlyChildWithDescriptorContaining(METHOD_WITH_META_TAG_NAME, TestMethodWithMetaTag.class); + + assertThat(testMethod.getTags()).containsOnly(TestTag.create("method-meta-tag-one"), TestTag.create("method-meta-tag-two")); + } + + @Test + void meta_tags_of_rule_methods() { + TestDescriptor testMethod = getOnlyChildWithDescriptorContaining(METHOD_WITH_META_TAGS_NAME, TestMethodWithMetaTags.class); + + assertThat(testMethod.getTags()).containsOnly(TestTag.create("method-meta-tags-one"), TestTag.create("method-meta-tags-two")); + } + @Test void complex_tags() { EngineDiscoveryTestRequest discoveryRequest = new EngineDiscoveryTestRequest().withClass(ComplexTags.class); @@ -514,6 +589,57 @@ void complex_tags() { TestTag.create("method-tag")); } + @Test + void complex_meta_tags() { + EngineDiscoveryTestRequest discoveryRequest = new EngineDiscoveryTestRequest().withClass(ComplexMetaTags.class); + + TestDescriptor descriptor = testEngine.discover(discoveryRequest, engineId); + + Map> tagsById = new HashMap<>(); + descriptor.accept(d -> tagsById.put(d.getUniqueId(), d.getTags())); + + assertThat(getTagsForIdEndingIn(ComplexMetaTags.class.getSimpleName(), tagsById)) + .containsOnly(TestTag.create("library-meta-tag")); + + assertThat(getTagsForIdEndingIn(TestClassWithMetaTag.class.getSimpleName(), tagsById)) + .containsOnly( + TestTag.create("library-meta-tag"), + TestTag.create("rules-meta-tag"), + TestTag.create("meta-tag-one"), + TestTag.create("meta-tag-two")); + + assertThat(getTagsForIdEndingIn(TestClassWithMetaTags.class.getSimpleName(), tagsById)) + .containsOnly( + TestTag.create("library-meta-tag"), + TestTag.create("rules-meta-tag"), + TestTag.create("meta-tags-one"), + TestTag.create("meta-tags-two")); + + assertThat(getTagsForIdEndingIn(TestClassWithMetaTag.FIELD_RULE_NAME, tagsById)) + .containsOnly( + TestTag.create("library-meta-tag"), + TestTag.create("rules-meta-tag"), + TestTag.create("meta-tag-one"), + TestTag.create("meta-tag-two")); + + assertThat(getTagsForIdEndingIn(TestClassWithMetaTags.FIELD_RULE_NAME, tagsById)) + .containsOnly( + TestTag.create("library-meta-tag"), + TestTag.create("rules-meta-tag"), + TestTag.create("meta-tags-one"), + TestTag.create("meta-tags-two")); + + assertThat(getTagsForIdEndingIn(ComplexMetaTags.FIELD_RULE_NAME, tagsById)) + .containsOnly( + TestTag.create("library-meta-tag"), + TestTag.create("field-meta-tag")); + + assertThat(getTagsForIdEndingIn(ComplexMetaTags.METHOD_RULE_NAME, tagsById)) + .containsOnly( + TestTag.create("library-meta-tag"), + TestTag.create("method-meta-tag")); + } + @Test void filtering_excluded_class_names() { EngineDiscoveryTestRequest discoveryRequest = new EngineDiscoveryTestRequest() @@ -885,6 +1011,105 @@ void with_reason() { } } + @Nested + class MetaIgnores { + @Test + void fields() { + simulateCachedClassesForTest(MetaIgnoredField.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredField.class); + + testListener.verifySkipped(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredField.class.getName()) + .append(FIELD_SEGMENT_TYPE, MetaIgnoredField.IGNORED_RULE_FIELD)); + + testListener.verifyViolation(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredField.class.getName()) + .append(FIELD_SEGMENT_TYPE, MetaIgnoredField.UNIGNORED_RULE_FIELD)); + } + + @Test + void methods() { + simulateCachedClassesForTest(MetaIgnoredMethod.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredMethod.class); + + testListener.verifySkipped(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredMethod.class.getName()) + .append(METHOD_SEGMENT_TYPE, MetaIgnoredMethod.IGNORED_RULE_METHOD)); + + testListener.verifyViolation(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredMethod.class.getName()) + .append(METHOD_SEGMENT_TYPE, MetaIgnoredMethod.UNIGNORED_RULE_METHOD)); + } + + @Test + void classes() { + simulateCachedClassesForTest(MetaIgnoredClass.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredClass.class); + + testListener.verifySkipped(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredClass.class.getName())); + + testListener.verifyNoOtherStartExceptHierarchyOf(engineId); + } + + @Test + void libraries() { + simulateCachedClassesForTest(MetaIgnoredLibrary.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredLibrary.class); + + testListener.verifySkipped(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredLibrary.class.getName()) + .append(FIELD_SEGMENT_TYPE, MetaIgnoredLibrary.IGNORED_LIB_FIELD) + .append(CLASS_SEGMENT_TYPE, SimpleRules.class.getName())); + } + + @Test + void library_referenced_classes() { + simulateCachedClassesForTest(MetaIgnoredLibrary.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredLibrary.class); + + testListener.verifySkipped(engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredLibrary.class.getName()) + .append(FIELD_SEGMENT_TYPE, MetaIgnoredLibrary.UNIGNORED_LIB_ONE_FIELD) + .append(CLASS_SEGMENT_TYPE, MetaIgnoredClass.class.getName())); + } + + @Test + void library_sub_rules() { + simulateCachedClassesForTest(MetaIgnoredLibrary.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredLibrary.class); + + UniqueId classWithIgnoredMethod = engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredLibrary.class.getName()) + .append(FIELD_SEGMENT_TYPE, MetaIgnoredLibrary.UNIGNORED_LIB_TWO_FIELD) + .append(CLASS_SEGMENT_TYPE, MetaIgnoredMethod.class.getName()); + + testListener.verifySkipped(classWithIgnoredMethod + .append(METHOD_SEGMENT_TYPE, MetaIgnoredMethod.IGNORED_RULE_METHOD)); + + testListener.verifyViolation(classWithIgnoredMethod + .append(METHOD_SEGMENT_TYPE, MetaIgnoredMethod.UNIGNORED_RULE_METHOD)); + } + + @Test + void with_reason() { + simulateCachedClassesForTest(MetaIgnoredField.class, UnwantedClass.CLASS_VIOLATING_RULES); + + EngineExecutionTestListener testListener = execute(engineId, MetaIgnoredField.class); + + UniqueId ignoredId = engineId + .append(CLASS_SEGMENT_TYPE, MetaIgnoredField.class.getName()) + .append(FIELD_SEGMENT_TYPE, MetaIgnoredField.IGNORED_RULE_FIELD); + testListener.verifySkipped(ignoredId, "some example description"); + } + } + private UniqueId createEngineId() { return UniqueId.forEngine(ArchUnitTestEngine.UNIQUE_ID); } diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ComplexMetaTags.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ComplexMetaTags.java new file mode 100644 index 0000000000..bfb9791444 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ComplexMetaTags.java @@ -0,0 +1,67 @@ +package com.tngtech.archunit.junit.testexamples; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchRules; +import com.tngtech.archunit.junit.ArchTag; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.lang.ArchRule; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@ComplexMetaTags.LibraryTag +@AnalyzeClasses +public class ComplexMetaTags { + public static final String FIELD_RULE_NAME = "field_rule"; + public static final String METHOD_RULE_NAME = "method_rule"; + + @RulesTag + @ArchTest + static final ArchRules classWithMetaTag = ArchRules.in(TestClassWithMetaTag.class); + + @RulesTag + @ArchTest + static final ArchRules classWithMetaTags = ArchRules.in(TestClassWithMetaTags.class); + + @FieldTag + @ArchTest + static final ArchRule field_rule = RuleThatFails.on(UnwantedClass.class); + + @MethodTag + @ArchTest + static void method_rule(JavaClasses classes) { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("library-meta-tag") + @interface LibraryTag { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("rules-meta-tag") + @interface RulesTag { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("field-meta-tag") + @interface FieldTag { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("method-meta-tag") + @interface MethodTag { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestClassWithMetaTag.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestClassWithMetaTag.java new file mode 100644 index 0000000000..6b918cfe90 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestClassWithMetaTag.java @@ -0,0 +1,40 @@ +package com.tngtech.archunit.junit.testexamples; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchRules; +import com.tngtech.archunit.junit.ArchTag; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.junit.testexamples.subone.SimpleRuleField; +import com.tngtech.archunit.lang.ArchRule; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@TestClassWithMetaTag.MetaTag +@AnalyzeClasses +public class TestClassWithMetaTag { + public static final String FIELD_RULE_NAME = "rule_in_class_with_meta_tag"; + + @ArchTest + public static final ArchRule rule_in_class_with_meta_tag = RuleThatFails.on(UnwantedClass.class); + + @ArchTest + public static final ArchRules rules_in_class_with_meta_tag = ArchRules.in(SimpleRuleField.class); + + @ArchTest + static void method_in_class_with_meta_tag(JavaClasses classes) { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("meta-tag-one") + @ArchTag("meta-tag-two") + @interface MetaTag { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestClassWithMetaTags.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestClassWithMetaTags.java new file mode 100644 index 0000000000..aa50554000 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestClassWithMetaTags.java @@ -0,0 +1,39 @@ +package com.tngtech.archunit.junit.testexamples; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.*; +import com.tngtech.archunit.junit.testexamples.subone.SimpleRuleField; +import com.tngtech.archunit.lang.ArchRule; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@TestClassWithMetaTags.MetaTags +@AnalyzeClasses +public class TestClassWithMetaTags { + public static final String FIELD_RULE_NAME = "rule_in_class_with_meta_tags"; + + @ArchTest + public static final ArchRule rule_in_class_with_meta_tags = RuleThatFails.on(UnwantedClass.class); + + @ArchTest + public static final ArchRules rules_in_class_with_meta_tags = ArchRules.in(SimpleRuleField.class); + + @ArchTest + static void method_in_class_with_meta_tags(JavaClasses classes) { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTags({ + @ArchTag("meta-tags-one"), + @ArchTag("meta-tags-two"), + }) + @interface MetaTags { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestFieldWithMetaTag.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestFieldWithMetaTag.java new file mode 100644 index 0000000000..6ef490f930 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestFieldWithMetaTag.java @@ -0,0 +1,30 @@ +package com.tngtech.archunit.junit.testexamples; + +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 java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@AnalyzeClasses +public class TestFieldWithMetaTag { + public static final String FIELD_WITH_META_TAG_NAME = "field_with_meta_tag"; + + @MetaTag + @ArchTest + static ArchRule field_with_meta_tag = RuleThatFails.on(UnwantedClass.CLASS_VIOLATING_RULES); + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("field-meta-tag-one") + @ArchTag("field-meta-tag-two") + private @interface MetaTag { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestFieldWithMetaTags.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestFieldWithMetaTags.java new file mode 100644 index 0000000000..a4e626d674 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestFieldWithMetaTags.java @@ -0,0 +1,34 @@ +package com.tngtech.archunit.junit.testexamples; + +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTag; +import com.tngtech.archunit.junit.ArchTags; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.lang.ArchRule; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@AnalyzeClasses +public class TestFieldWithMetaTags { + public static final String FIELD_WITH_META_TAGS_NAME = "field_with_meta_tags"; + + @MetaTags + @ArchTest + static ArchRule field_with_meta_tags = RuleThatFails.on(UnwantedClass.CLASS_VIOLATING_RULES); + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTags({ + @ArchTag("field-meta-tags-one"), + @ArchTag("field-meta-tags-two"), + }) + private @interface MetaTags { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestMethodWithMetaTag.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestMethodWithMetaTag.java new file mode 100644 index 0000000000..4f3f68dd57 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestMethodWithMetaTag.java @@ -0,0 +1,31 @@ +package com.tngtech.archunit.junit.testexamples; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTag; +import com.tngtech.archunit.junit.ArchTest; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@AnalyzeClasses +public class TestMethodWithMetaTag { + public static final String METHOD_WITH_META_TAG_NAME = "method_with_meta_tag"; + + @MetaTag + @ArchTest + static void method_with_meta_tag(JavaClasses classes) { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTag("method-meta-tag-one") + @ArchTag("method-meta-tag-two") + private @interface MetaTag { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestMethodWithMetaTags.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestMethodWithMetaTags.java new file mode 100644 index 0000000000..507fb89b56 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/TestMethodWithMetaTags.java @@ -0,0 +1,34 @@ +package com.tngtech.archunit.junit.testexamples; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTag; +import com.tngtech.archunit.junit.ArchTags; +import com.tngtech.archunit.junit.ArchTest; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@AnalyzeClasses +public class TestMethodWithMetaTags { + public static final String METHOD_WITH_META_TAGS_NAME = "method_with_meta_tags"; + + @MetaTags + @ArchTest + static void method_with_meta_tags(JavaClasses classes) { + } + + @Inherited + @Retention(RUNTIME) + @Target({TYPE, METHOD, FIELD}) + @ArchTags({ + @ArchTag("method-meta-tags-one"), + @ArchTag("method-meta-tags-two"), + }) + private @interface MetaTags { + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/ArchIgnoreMetaAnnotation.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/ArchIgnoreMetaAnnotation.java new file mode 100644 index 0000000000..a50bfaa4bf --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/ArchIgnoreMetaAnnotation.java @@ -0,0 +1,17 @@ +package com.tngtech.archunit.junit.testexamples.ignores; + +import com.tngtech.archunit.junit.ArchIgnore; + +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Inherited +@Retention(RUNTIME) +@Target({TYPE, METHOD, FIELD}) +@ArchIgnore(reason = "some example description") +public @interface ArchIgnoreMetaAnnotation { +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredClass.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredClass.java new file mode 100644 index 0000000000..3470a7c7d2 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredClass.java @@ -0,0 +1,22 @@ +package com.tngtech.archunit.junit.testexamples.ignores; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.junit.testexamples.RuleThatFails; +import com.tngtech.archunit.lang.ArchRule; + +import static com.tngtech.archunit.junit.testexamples.UnwantedClass.CLASS_VIOLATING_RULES; + +@ArchIgnoreMetaAnnotation +@AnalyzeClasses(packages = "some.dummy.package") +public class MetaIgnoredClass { + + @ArchTest + static final ArchRule rule_one = RuleThatFails.on(CLASS_VIOLATING_RULES); + + @ArchTest + static void rule_two(JavaClasses classes) { + RuleThatFails.on(CLASS_VIOLATING_RULES).check(classes); + } +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredField.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredField.java new file mode 100644 index 0000000000..641dfd8a4c --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredField.java @@ -0,0 +1,22 @@ +package com.tngtech.archunit.junit.testexamples.ignores; + +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.junit.testexamples.RuleThatFails; +import com.tngtech.archunit.lang.ArchRule; + +import static com.tngtech.archunit.junit.testexamples.UnwantedClass.CLASS_VIOLATING_RULES; + +@AnalyzeClasses(packages = "some.dummy.package") +public class MetaIgnoredField { + + @ArchTest + static final ArchRule unignored_rule = RuleThatFails.on(CLASS_VIOLATING_RULES); + + @ArchTest + @ArchIgnoreMetaAnnotation + static final ArchRule ignored_rule = RuleThatFails.on(CLASS_VIOLATING_RULES); + + public static final String UNIGNORED_RULE_FIELD = "unignored_rule"; + public static final String IGNORED_RULE_FIELD = "ignored_rule"; +} diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredLibrary.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredLibrary.java new file mode 100644 index 0000000000..d21a96c9b2 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredLibrary.java @@ -0,0 +1,24 @@ +package com.tngtech.archunit.junit.testexamples.ignores; + +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchRules; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.junit.testexamples.subtwo.SimpleRules; + +@AnalyzeClasses(packages = "some.dummy.package") +public class MetaIgnoredLibrary { + + @ArchTest + static final ArchRules unignored_lib_one = ArchRules.in(MetaIgnoredClass.class); + + @ArchTest + static final ArchRules unignored_lib_two = ArchRules.in(MetaIgnoredMethod.class); + + @ArchTest + @ArchIgnoreMetaAnnotation + static final ArchRules ignored_lib = ArchRules.in(SimpleRules.class); + + public static final String UNIGNORED_LIB_ONE_FIELD = "unignored_lib_one"; + public static final String UNIGNORED_LIB_TWO_FIELD = "unignored_lib_two"; + public static final String IGNORED_LIB_FIELD = "ignored_lib"; +} \ No newline at end of file diff --git a/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredMethod.java b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredMethod.java new file mode 100644 index 0000000000..1d35756019 --- /dev/null +++ b/archunit-junit/junit5/engine/src/test/java/com/tngtech/archunit/junit/testexamples/ignores/MetaIgnoredMethod.java @@ -0,0 +1,26 @@ +package com.tngtech.archunit.junit.testexamples.ignores; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.junit.AnalyzeClasses; +import com.tngtech.archunit.junit.ArchTest; +import com.tngtech.archunit.junit.testexamples.RuleThatFails; + +import static com.tngtech.archunit.junit.testexamples.UnwantedClass.CLASS_VIOLATING_RULES; + +@AnalyzeClasses(packages = "some.dummy.package") +public class MetaIgnoredMethod { + + @ArchTest + static void unignored_rule(JavaClasses classes) { + RuleThatFails.on(CLASS_VIOLATING_RULES).check(classes); + } + + @ArchTest + @ArchIgnoreMetaAnnotation + static void ignored_rule(JavaClasses classes) { + RuleThatFails.on(CLASS_VIOLATING_RULES).check(classes); + } + + public static final String UNIGNORED_RULE_METHOD = "unignored_rule"; + public static final String IGNORED_RULE_METHOD = "ignored_rule"; +}