diff --git a/pom.xml b/pom.xml
index 7ec86c87a..17e9520f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -335,9 +335,9 @@
- de.schauderhaft.degraph
- degraph-check
- 0.1.4
+ com.tngtech.archunit
+ archunit
+ ${archunit}
test
diff --git a/src/main/java/org/springframework/data/repository/config/AotRepositoryInformation.java b/src/main/java/org/springframework/data/repository/config/AotRepositoryInformation.java
index e9ba3ad70..b2faf62e4 100644
--- a/src/main/java/org/springframework/data/repository/config/AotRepositoryInformation.java
+++ b/src/main/java/org/springframework/data/repository/config/AotRepositoryInformation.java
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/main/java/org/springframework/data/repository/config/DefaultAotRepositoryContext.java b/src/main/java/org/springframework/data/repository/config/DefaultAotRepositoryContext.java
index f9769fd09..74e8ad1c1 100644
--- a/src/main/java/org/springframework/data/repository/config/DefaultAotRepositoryContext.java
+++ b/src/main/java/org/springframework/data/repository/config/DefaultAotRepositoryContext.java
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionReader.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionReader.java
index 89d52970e..ff4c6a001 100644
--- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionReader.java
+++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionReader.java
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/java/org/springframework/data/DependencyTests.java b/src/test/java/org/springframework/data/DependencyTests.java
index 8a3e7a511..fd1eaf0bf 100644
--- a/src/test/java/org/springframework/data/DependencyTests.java
+++ b/src/test/java/org/springframework/data/DependencyTests.java
@@ -15,29 +15,122 @@
*/
package org.springframework.data;
-import static de.schauderhaft.degraph.check.JCheck.*;
-import static org.junit.Assert.*;
+import static org.assertj.core.api.Assertions.*;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+import org.springframework.data.repository.core.RepositoryMetadata;
+
+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.SlicesRuleDefinition;
/**
+ * Tests for package and slice cycles. All packages that have the same start including the part after {@literal data}
+ * are considered one slice. For example {@literal org.springframework.data.repository} and
+ * {@literal org.springframework.data.repository.support} are part of the same slice {@literal repository}.
+ *
* @author Jens Schauder
*/
-@Disabled("Requires newer version of ASM 5.1")
public class DependencyTests {
- @Test
- public void noInternalPackageCycles() {
+ 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") //
+ .that(onlySpringData()) //
- assertThat(
- classpath() //
- .noJars() //
- .including("org.springframework.data.**") //
- .filterClasspath("*target/classes") //
- .printOnFailure("degraph.graphml"), //
- violationFree() //
- );
+ // new cycle
+ .that(ignore(RepositoryMetadata.class));
+
+ @Test
+ void cycleFreeSlices() {
+
+ ArchRule rule = SlicesRuleDefinition.slices() //
+ .matching("org.springframework.data.(*)..") //
+ .should() //
+ .beFreeOfCycles();
+
+ rule.check(importedClasses);
+ }
+
+ @Test
+ void cycleFreePackages() {
+
+ ArchRule rule = SlicesRuleDefinition.slices() //
+ .matching("org.springframework.data.(**)") //
+ .should() //
+ .beFreeOfCycles();
+
+ rule.check(importedClasses);
+ }
+
+ @Test
+ void testGetFirstPackagePart() {
+
+ assertThat(getFirstPackagePart("a.b.c")).isEqualTo("a");
+ assertThat(getFirstPackagePart("a")).isEqualTo("a");
+ }
+
+ @Test
+ void testSubModule() {
+
+ assertThat(subModule("a.b", "a.b.c.d")).isEqualTo("c");
+ assertThat(subModule("a.b", "a.b.c")).isEqualTo("c");
+ 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 "";
}
}