diff --git a/pom.xml b/pom.xml
index d864b2e4e6..fab78c65a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.1.0-SNAPSHOT
+ 4.1.0-archunit-dependency-tests-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index 1b2a1390e6..3f405e43be 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.1.0-SNAPSHOT
+ 4.1.0-archunit-dependency-tests-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 8db8d798fb..064351f06a 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -15,7 +15,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.1.0-SNAPSHOT
+ 4.1.0-archunit-dependency-tests-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 9a57f7eb52..6814d94000 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 4.1.0-SNAPSHOT
+ 4.1.0-archunit-dependency-tests-SNAPSHOT
../pom.xml
@@ -23,6 +23,7 @@
spring.data.mongodb
${basedir}/..
1.01
+ 1.0.1
@@ -250,9 +251,9 @@
- de.schauderhaft.degraph
- degraph-check
- 0.1.4
+ com.tngtech.archunit
+ archunit
+ ${archunit.version}
test
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/DependencyTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/DependencyTests.java
index 00d5b63551..e9b53b178b 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/DependencyTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/DependencyTests.java
@@ -15,12 +15,16 @@
*/
package org.springframework.data.mongodb;
-import static de.schauderhaft.degraph.check.JCheck.*;
-import static org.hamcrest.MatcherAssert.*;
-
-import de.schauderhaft.degraph.configuration.NamedPattern;
-
-import org.junit.jupiter.api.Disabled;
+import com.tngtech.archunit.base.DescribedPredicate;
+import com.tngtech.archunit.core.domain.JavaClass;
+import com.tngtech.archunit.core.domain.JavaClasses;
+import com.tngtech.archunit.core.importer.ClassFileImporter;
+import com.tngtech.archunit.core.importer.ImportOption;
+import com.tngtech.archunit.lang.ArchRule;
+import com.tngtech.archunit.library.dependencies.SliceAssignment;
+import com.tngtech.archunit.library.dependencies.SliceIdentifier;
+import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition;
+import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;
/**
@@ -29,49 +33,138 @@
* @author Jens Schauder
* @author Oliver Gierke
*/
-@Disabled("Needs to be tansitioned to ArchUnit")
class DependencyTests {
@Test
- void noInternalPackageCycles() {
-
- assertThat(classpath() //
- .noJars() //
- .including("org.springframework.data.mongodb.**") //
- .filterClasspath("*target/classes") //
- .printOnFailure("degraph.graphml"), //
- violationFree() //
- );
+ void cycleFree() {
+
+ JavaClasses importedClasses = new ClassFileImporter() //
+ .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) //
+ .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS) // we just analyze the code of this module.
+ .importPackages("org.springframework.data.mongodb").that( //
+ onlySpringData() //
+ );
+
+ ArchRule rule = SlicesRuleDefinition.slices() //
+ .matching("org.springframework.data.mongodb.(**)") //
+ .should() //
+ .beFreeOfCycles();
+
+ rule.check(importedClasses);
+ }
+
+ @Test
+ void acrossModules() {
+
+ JavaClasses importedClasses = new ClassFileImporter().withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
+ .importPackages( //
+ "org.springframework.data.mongodb", // Spring Data Relational
+ "org.springframework.data" // Spring Data Commons
+ ).that(onlySpringData());
+
+ ArchRule rule = SlicesRuleDefinition.slices() //
+ .assignedFrom(subModuleSlicing()) //
+ .should().beFreeOfCycles();
+
+ rule.check(importedClasses);
}
@Test
- void onlyConfigMayUseRepository() {
-
- assertThat(classpath() //
- .including("org.springframework.data.**") //
- .filterClasspath("*target/classes") //
- .printOnFailure("onlyConfigMayUseRepository.graphml") //
- .withSlicing("slices", //
- "**.(config).**", //
- new NamedPattern("**.cdi.**", "config"), //
- "**.(repository).**", //
- new NamedPattern("**", "other"))
- .allow("config", "repository", "other"), //
- violationFree() //
- );
+ // GH-1058
+ void testGetFirstPackagePart() {
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(getFirstPackagePart("a.b.c")).isEqualTo("a");
+ softly.assertThat(getFirstPackagePart("a")).isEqualTo("a");
+ });
}
@Test
- void commonsInternaly() {
-
- assertThat(classpath() //
- .noJars() //
- .including("org.springframework.data.**") //
- .excluding("org.springframework.data.mongodb.**") //
- .filterClasspath("*target/classes") //
- .printTo("commons.graphml"), //
- violationFree() //
- );
+ // GH-1058
+ void testSubModule() {
+
+ SoftAssertions.assertSoftly(softly -> {
+ softly.assertThat(subModule("a.b", "a.b.c.d")).isEqualTo("c");
+ softly.assertThat(subModule("a.b", "a.b.c")).isEqualTo("c");
+ softly.assertThat(subModule("a.b", "a.b")).isEqualTo("");
+ });
+ }
+
+ private DescribedPredicate onlySpringData() {
+
+ return new DescribedPredicate<>("Spring Data Classes") {
+ @Override
+ public boolean test(JavaClass input) {
+ return input.getPackageName().startsWith("org.springframework.data");
+ }
+ };
+ }
+
+ private DescribedPredicate ignore(Class> type) {
+
+ return new DescribedPredicate<>("ignored class " + type.getName()) {
+ @Override
+ public boolean test(JavaClass input) {
+ return !input.getFullName().startsWith(type.getName());
+ }
+ };
+ }
+
+ private DescribedPredicate ignorePackage(String type) {
+
+ return new DescribedPredicate<>("ignored class " + type) {
+ @Override
+ public boolean test(JavaClass input) {
+ return !input.getPackageName().equals(type);
+ }
+ };
+ }
+
+ private String getFirstPackagePart(String subpackage) {
+
+ int index = subpackage.indexOf(".");
+ if (index < 0) {
+ return subpackage;
+ }
+ return subpackage.substring(0, index);
+ }
+
+ private String subModule(String basePackage, String packageName) {
+
+ if (packageName.startsWith(basePackage) && packageName.length() > basePackage.length()) {
+
+ final int index = basePackage.length() + 1;
+ String subpackage = packageName.substring(index);
+ return getFirstPackagePart(subpackage);
+ }
+ return "";
}
+ private SliceAssignment subModuleSlicing() {
+ return new SliceAssignment() {
+
+ @Override
+ public SliceIdentifier getIdentifierOf(JavaClass javaClass) {
+
+ String packageName = javaClass.getPackageName();
+
+ String subModule = subModule("org.springframework.data.mongodb", packageName);
+ if (!subModule.isEmpty()) {
+ return SliceIdentifier.of(subModule);
+ }
+
+ subModule = subModule("org.springframework.data", packageName);
+ if (!subModule.isEmpty()) {
+ return SliceIdentifier.of(subModule);
+ }
+
+ return SliceIdentifier.ignore();
+ }
+
+ @Override
+ public String getDescription() {
+ return "Submodule";
+ }
+ };
+ }
}