TSK-991: Add more architecture tests
(cherry picked from commit 760adb24b54d588e8a977853d092d5744781f496)
This commit is contained in:
parent
68c016f5c8
commit
957feac270
|
|
@ -1,16 +1,25 @@
|
||||||
package pro.taskana;
|
package pro.taskana;
|
||||||
|
|
||||||
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
|
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes;
|
||||||
|
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
|
||||||
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;
|
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS;
|
||||||
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;
|
import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;
|
||||||
import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices;
|
import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices;
|
||||||
|
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||||
|
|
||||||
import com.tngtech.archunit.core.domain.JavaClasses;
|
import com.tngtech.archunit.core.domain.JavaClasses;
|
||||||
import com.tngtech.archunit.core.importer.ClassFileImporter;
|
import com.tngtech.archunit.core.importer.ClassFileImporter;
|
||||||
|
import com.tngtech.archunit.core.importer.ImportOption.DoNotIncludeTests;
|
||||||
import com.tngtech.archunit.lang.ArchRule;
|
import com.tngtech.archunit.lang.ArchRule;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
|
import org.junit.jupiter.api.DynamicTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test architecture of classes in taskana. For more info and examples see
|
* Test architecture of classes in taskana. For more info and examples see
|
||||||
|
|
@ -22,22 +31,13 @@ class ArchitectureTest {
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
static void init() throws ClassNotFoundException {
|
static void init() throws ClassNotFoundException {
|
||||||
// time intensive operation should only be done once
|
// time intensive operation should only be done once
|
||||||
importedClasses = new ClassFileImporter().importPackages("pro.taskana");
|
importedClasses =
|
||||||
|
new ClassFileImporter()
|
||||||
|
.withImportOption(new DoNotIncludeTests())
|
||||||
|
.importPackages("pro.taskana");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled
|
@Disabled
|
||||||
void mapperShouldBePlacedInMappingsPackage() {
|
|
||||||
ArchRule myRule =
|
|
||||||
classes()
|
|
||||||
.that()
|
|
||||||
.haveSimpleNameEndingWith("Mapper")
|
|
||||||
.should()
|
|
||||||
.resideInAPackage("..mappings..");
|
|
||||||
|
|
||||||
myRule.check(importedClasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void apiClassesShouldNotDependOnInternalClasses() {
|
void apiClassesShouldNotDependOnInternalClasses() {
|
||||||
ArchRule myRule =
|
ArchRule myRule =
|
||||||
|
|
@ -47,7 +47,7 @@ class ArchitectureTest {
|
||||||
.and()
|
.and()
|
||||||
.haveSimpleNameNotEndingWith("BulkOperationResults")
|
.haveSimpleNameNotEndingWith("BulkOperationResults")
|
||||||
.and()
|
.and()
|
||||||
.resideInAPackage("..api")
|
.resideInAPackage("..api..")
|
||||||
.should()
|
.should()
|
||||||
.onlyDependOnClassesThat()
|
.onlyDependOnClassesThat()
|
||||||
.resideOutsideOfPackage("..internal..");
|
.resideOutsideOfPackage("..internal..");
|
||||||
|
|
@ -69,8 +69,7 @@ class ArchitectureTest {
|
||||||
@Test
|
@Test
|
||||||
void onlyExceptionsShouldResideInExceptionPackage() {
|
void onlyExceptionsShouldResideInExceptionPackage() {
|
||||||
ArchRule myRule =
|
ArchRule myRule =
|
||||||
classes().that().resideInAPackage("..exceptions").should()
|
classes().that().resideInAPackage("..exceptions").should().beAssignableTo(Throwable.class);
|
||||||
.beAssignableTo(Throwable.class);
|
|
||||||
myRule.check(importedClasses);
|
myRule.check(importedClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,20 +83,94 @@ class ArchitectureTest {
|
||||||
NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS.check(importedClasses);
|
NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS.check(importedClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
/**
|
||||||
|
* Solution would be nice, but is not achievable without big changes
|
||||||
|
* https://www.archunit.org/userguide/html/000_Index.html#_cycle_checks
|
||||||
|
*/
|
||||||
@Disabled
|
@Disabled
|
||||||
|
@Test
|
||||||
void freeOfCycles() {
|
void freeOfCycles() {
|
||||||
ArchRule myRule = slices().matching("pro.taskana.(*)..")
|
ArchRule myRule = slices().matching("pro.taskana.(*)..").should().beFreeOfCycles();
|
||||||
.should().beFreeOfCycles();
|
|
||||||
myRule.check(importedClasses);
|
myRule.check(importedClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for cycles with subpackages
|
||||||
|
* https://www.archunit.org/userguide/html/000_Index.html#_cycle_checks
|
||||||
|
*/
|
||||||
|
@TestFactory
|
||||||
|
Collection<DynamicTest> freeOfCycles_subpackages() {
|
||||||
|
|
||||||
|
Stream<String> packagesToTest =
|
||||||
|
Stream.of(
|
||||||
|
"pro.taskana.common.internal.(*)..",
|
||||||
|
"pro.taskana.common.api.(*)..",
|
||||||
|
"pro.taskana.classification.api.(*)..",
|
||||||
|
"pro.taskana.classification.internal.(*)..",
|
||||||
|
"pro.taskana.history.api.(*)..",
|
||||||
|
"pro.taskana.history.internal.(*)..",
|
||||||
|
// to be fixed soon
|
||||||
|
// "pro.taskana.report.api.(*)..",
|
||||||
|
"pro.taskana.report.internal.(*)..",
|
||||||
|
"pro.taskana.task.api.(*)..",
|
||||||
|
"pro.taskana.task.internal.(*)..",
|
||||||
|
"pro.taskana.workbasket.api.(*)..",
|
||||||
|
"pro.taskana.workbasket.internal.(*)..");
|
||||||
|
return packagesToTest
|
||||||
|
.map(
|
||||||
|
p ->
|
||||||
|
dynamicTest(
|
||||||
|
p.replaceAll(Pattern.quote("pro.taskana."), "") + " is free of cycles",
|
||||||
|
() -> slices().matching(p).should().beFreeOfCycles().check(importedClasses)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled("TBD")
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
void commonClassesShouldNotDependOnOtherDomainClasses() {
|
||||||
void freeOfCyclicDependencies() {
|
ArchRule myRule =
|
||||||
ArchRule myRule = slices().matching("pro.taskana.(*)..").should()
|
noClasses()
|
||||||
.notDependOnEachOther();
|
.that()
|
||||||
|
.resideInAPackage("..common..")
|
||||||
|
.should()
|
||||||
|
.dependOnClassesThat()
|
||||||
|
.resideInAnyPackage(
|
||||||
|
"..classification..", "..history..", "..report..", "..task..", "..workbasket..");
|
||||||
myRule.check(importedClasses);
|
myRule.check(importedClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestFactory
|
||||||
|
Collection<DynamicTest> classesShouldNotDependOnReportDomainClasses() {
|
||||||
|
|
||||||
|
Stream<String> packagesToTest =
|
||||||
|
Stream.of(
|
||||||
|
"..workbasket..",
|
||||||
|
"..history..",
|
||||||
|
// tasks are to be fixed ...
|
||||||
|
// "..task..",
|
||||||
|
"..classification..");
|
||||||
|
return packagesToTest
|
||||||
|
.map(
|
||||||
|
p ->
|
||||||
|
dynamicTest(
|
||||||
|
"Domain "
|
||||||
|
+ p.replaceAll(Pattern.quote("."), "")
|
||||||
|
+ " should not depend on reports",
|
||||||
|
() ->
|
||||||
|
noClasses()
|
||||||
|
.that()
|
||||||
|
.resideInAPackage(p)
|
||||||
|
.should()
|
||||||
|
.dependOnClassesThat()
|
||||||
|
.resideInAnyPackage("..report..")
|
||||||
|
.check(importedClasses)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Disabled
|
||||||
|
@Test
|
||||||
|
void freeOfCyclicDependencies() {
|
||||||
|
ArchRule myRule = slices().matching("pro.taskana.(*)..").should().notDependOnEachOther();
|
||||||
|
myRule.check(importedClasses);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue