Skip to content

Commit

Permalink
JUnit5-support for libraries with @ArchTests in abstract base classes
Browse files Browse the repository at this point in the history
This corresponds to 59f8c4d,
which added the same feature for JUnit4 (Issue: #104).

Signed-off-by: Manfred Hanke <[email protected]>
  • Loading branch information
hankem authored and codecholeric committed Jun 16, 2022
1 parent f3ea378 commit 89747bd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,19 @@ private static void resolveChildren(
if (ArchTests.class.isAssignableFrom(field.getType())) {
resolveArchRules(parent, resolver, field, classes);
} else {
Class<?> fieldOwner = parent instanceof ArchUnitTestDescriptor
? ((ArchUnitTestDescriptor) parent).testClass
: field.getDeclaringClass();
Class<?> fieldOwner = tryToFindOwner(parent).orElseGet(field::getDeclaringClass);
parent.addChild(new ArchUnitRuleDescriptor(resolver.getUniqueId(), getValue(field, fieldOwner), classes, field));
}
}

private static Optional<Class<?>> tryToFindOwner(TestDescriptor parent) {
return parent instanceof ArchUnitTestDescriptor
? Optional.of(((ArchUnitTestDescriptor) parent).testClass)
: parent instanceof ArchUnitArchTestsDescriptor
? Optional.of(((ArchUnitArchTestsDescriptor) parent).archTests.getDefinitionLocation())
: Optional.empty();
}

private static <T> T getValue(Field field, Class<?> fieldOwner) {
return getValueOrThrowException(field, fieldOwner, ArchTestInitializationException::new);
}
Expand Down Expand Up @@ -198,9 +204,7 @@ public Type getType() {

@Override
public ArchUnitEngineExecutionContext execute(ArchUnitEngineExecutionContext context, DynamicTestExecutor dynamicTestExecutor) {
Class<?> methodOwner = getParent().flatMap(parent ->
parent instanceof ArchUnitTestDescriptor ? Optional.of(((ArchUnitTestDescriptor) parent).testClass) : Optional.<Class<?>>empty()
).orElseGet(method::getDeclaringClass);
Class<?> methodOwner = getParent().flatMap(ArchUnitTestDescriptor::tryToFindOwner).orElseGet(method::getDeclaringClass);
invokeMethod(method, methodOwner, classes.get());
return context;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.tngtech.archunit.junit.internal.testexamples.UnwantedClass;
import com.tngtech.archunit.junit.internal.testexamples.abstractbase.ArchTestWithAbstractBaseClassWithFieldRule;
import com.tngtech.archunit.junit.internal.testexamples.abstractbase.ArchTestWithAbstractBaseClassWithMethodRule;
import com.tngtech.archunit.junit.internal.testexamples.abstractbase.ArchTestWithLibraryWithAbstractBaseClass;
import com.tngtech.archunit.junit.internal.testexamples.ignores.IgnoredClass;
import com.tngtech.archunit.junit.internal.testexamples.ignores.IgnoredField;
import com.tngtech.archunit.junit.internal.testexamples.ignores.IgnoredLibrary;
Expand Down Expand Up @@ -872,6 +873,26 @@ void private_instance_libraries() {
testListener.verifyViolation(testId, UnwantedClass.CLASS_VIOLATING_RULES.getSimpleName()));
}

@Test
public void library_with_rules_in_abstract_base_class() {
simulateCachedClassesForTest(ArchTestWithLibraryWithAbstractBaseClass.class, UnwantedClass.CLASS_SATISFYING_RULES);

EngineExecutionTestListener testListener = execute(engineId, ArchTestWithLibraryWithAbstractBaseClass.class);

testListener.verifySuccessful(engineId
.append(CLASS_SEGMENT_TYPE, ArchTestWithLibraryWithAbstractBaseClass.class.getName())
.append(FIELD_SEGMENT_TYPE, ArchTestWithLibraryWithAbstractBaseClass.FIELD_RULE_LIBRARY_NAME)
.append(CLASS_SEGMENT_TYPE, ArchTestWithAbstractBaseClassWithFieldRule.class.getName())
.append(FIELD_SEGMENT_TYPE, ArchTestWithAbstractBaseClassWithFieldRule.INSTANCE_FIELD_NAME)
);
testListener.verifySuccessful(engineId
.append(CLASS_SEGMENT_TYPE, ArchTestWithLibraryWithAbstractBaseClass.class.getName())
.append(FIELD_SEGMENT_TYPE, ArchTestWithLibraryWithAbstractBaseClass.METHOD_RULE_LIBRARY_NAME)
.append(CLASS_SEGMENT_TYPE, ArchTestWithAbstractBaseClassWithMethodRule.class.getName())
.append(METHOD_SEGMENT_TYPE, ArchTestWithAbstractBaseClassWithMethodRule.INSTANCE_METHOD_NAME)
);
}

@Test
void rule_by_unique_id_without_violation() {
UniqueId fieldRuleInLibrary = simpleRulesInLibraryId(engineId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.tngtech.archunit.junit.internal.testexamples.abstractbase;

import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.junit.ArchTests;

@AnalyzeClasses(packages = "some.dummy.package")
public class ArchTestWithLibraryWithAbstractBaseClass {
public static final String FIELD_RULE_LIBRARY_NAME = "fieldRules";
public static final String METHOD_RULE_LIBRARY_NAME = "methodRules";
@ArchTest
ArchTests fieldRules = ArchTests.in(ArchTestWithAbstractBaseClassWithFieldRule.class);
@ArchTest
ArchTests methodRules = ArchTests.in(ArchTestWithAbstractBaseClassWithMethodRule.class);
}

0 comments on commit 89747bd

Please sign in to comment.