Skip to content

Commit a5c75ba

Browse files
committed
Reimplemented dependency tests using ArchUnit.
Moved RelationalAuditingCallback and JdbcArrayColumns to remove dependency cycle. Closes #1058 Original pull request #1107
1 parent c913413 commit a5c75ba

File tree

15 files changed

+349
-164
lines changed

15 files changed

+349
-164
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
<!-- test utilities-->
4343
<awaitility.version>4.0.3</awaitility.version>
44-
<degraph-check.version>0.1.4</degraph-check.version>
44+
<archunit.version>0.22.0</archunit.version>
4545
</properties>
4646

4747
<inceptionYear>2017</inceptionYear>

spring-data-jdbc/pom.xml

+7-8
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,6 @@
207207
<scope>test</scope>
208208
</dependency>
209209

210-
211-
<dependency>
212-
<groupId>de.schauderhaft.degraph</groupId>
213-
<artifactId>degraph-check</artifactId>
214-
<version>${degraph-check.version}</version>
215-
<scope>test</scope>
216-
</dependency>
217-
218210
<dependency>
219211
<groupId>org.testcontainers</groupId>
220212
<artifactId>mysql</artifactId>
@@ -264,6 +256,13 @@
264256
<scope>test</scope>
265257
</dependency>
266258

259+
<dependency>
260+
<groupId>com.tngtech.archunit</groupId>
261+
<artifactId>archunit</artifactId>
262+
<version>${archunit.version}</version>
263+
<scope>test</scope>
264+
</dependency>
265+
267266
</dependencies>
268267

269268
</project>

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/DefaultJdbcTypeFactory.java

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.sql.Array;
1919
import java.sql.JDBCType;
2020

21-
import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns;
2221
import org.springframework.data.jdbc.support.JdbcUtil;
2322
import org.springframework.jdbc.core.ConnectionCallback;
2423
import org.springframework.jdbc.core.JdbcOperations;

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcArrayColumns.java renamed to spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcArrayColumns.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.springframework.data.jdbc.core.dialect;
16+
package org.springframework.data.jdbc.core.convert;
1717

1818
import java.sql.SQLType;
1919

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.jdbc.core.dialect;
1717

18+
import org.springframework.data.jdbc.core.convert.JdbcArrayColumns;
1819
import org.springframework.data.relational.core.dialect.Dialect;
1920

2021
/**

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcPostgresDialect.java

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.sql.JDBCType;
1919
import java.sql.SQLType;
2020

21+
import org.springframework.data.jdbc.core.convert.JdbcArrayColumns;
2122
import org.springframework.data.relational.core.dialect.PostgresDialect;
2223

2324
/**

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
4343
import org.springframework.data.jdbc.core.convert.RelationResolver;
4444
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
45-
import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns;
45+
import org.springframework.data.jdbc.core.convert.JdbcArrayColumns;
4646
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
4747
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
4848
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/JdbcAuditingRegistrar.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
2525
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
2626
import org.springframework.data.auditing.config.AuditingConfiguration;
27-
import org.springframework.data.relational.core.mapping.event.RelationalAuditingCallback;
27+
import org.springframework.data.relational.auditing.RelationalAuditingCallback;
2828
import org.springframework.data.repository.config.PersistentEntitiesFactoryBean;
2929
import org.springframework.util.Assert;
3030

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright 2017-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.jdbc;
17+
18+
import org.assertj.core.api.SoftAssertions;
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.data.auditing.config.AuditingHandlerBeanDefinitionParser;
21+
22+
import com.tngtech.archunit.base.DescribedPredicate;
23+
import com.tngtech.archunit.core.domain.JavaClass;
24+
import com.tngtech.archunit.core.domain.JavaClasses;
25+
import com.tngtech.archunit.core.importer.ClassFileImporter;
26+
import com.tngtech.archunit.core.importer.ImportOption;
27+
import com.tngtech.archunit.lang.ArchRule;
28+
import com.tngtech.archunit.library.dependencies.SliceAssignment;
29+
import com.tngtech.archunit.library.dependencies.SliceIdentifier;
30+
import com.tngtech.archunit.library.dependencies.SlicesRuleDefinition;
31+
32+
/**
33+
* Test package dependencies for violations.
34+
*
35+
* @author Jens Schauder
36+
*/
37+
public class DependencyTests {
38+
39+
@Test
40+
void cycleFree() {
41+
42+
JavaClasses importedClasses = new ClassFileImporter() //
43+
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) //
44+
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_JARS) // we just analyze the code of this module.
45+
.importPackages("org.springframework.data.jdbc")
46+
.that( //
47+
onlySpringData() //
48+
);
49+
50+
ArchRule rule = SlicesRuleDefinition.slices() //
51+
.matching("org.springframework.data.jdbc.(**)") //
52+
.should() //
53+
.beFreeOfCycles();
54+
55+
rule.check(importedClasses);
56+
}
57+
58+
@Test
59+
void acrossModules() {
60+
61+
JavaClasses importedClasses = new ClassFileImporter()
62+
.withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS)
63+
.importPackages( //
64+
"org.springframework.data.jdbc", // Spring Data Relational
65+
"org.springframework.data.relational", // Spring Data Relational
66+
"org.springframework.data" // Spring Data Commons
67+
).that(onlySpringData()) //
68+
.that(ignore(AuditingHandlerBeanDefinitionParser.class));
69+
70+
ArchRule rule = SlicesRuleDefinition.slices() //
71+
.assignedFrom(subModuleSlicing()) //
72+
.should().beFreeOfCycles();
73+
74+
rule.check(importedClasses);
75+
}
76+
77+
@Test // GH-1058
78+
void testGetFirstPackagePart() {
79+
80+
SoftAssertions.assertSoftly(softly -> {
81+
softly.assertThat(getFirstPackagePart("a.b.c")).isEqualTo("a");
82+
softly.assertThat(getFirstPackagePart("a")).isEqualTo("a");
83+
});
84+
}
85+
86+
@Test // GH-1058
87+
void testSubModule() {
88+
89+
SoftAssertions.assertSoftly(softly -> {
90+
softly.assertThat(subModule("a.b", "a.b.c.d")).isEqualTo("c");
91+
softly.assertThat(subModule("a.b", "a.b.c")).isEqualTo("c");
92+
softly.assertThat(subModule("a.b", "a.b")).isEqualTo("");
93+
});
94+
}
95+
96+
private DescribedPredicate<JavaClass> onlySpringData() {
97+
98+
return new DescribedPredicate<>("Spring Data Classes") {
99+
@Override
100+
public boolean apply(JavaClass input) {
101+
return input.getPackageName().startsWith("org.springframework.data");
102+
}
103+
};
104+
}
105+
106+
private DescribedPredicate<JavaClass> ignore(Class<?> type) {
107+
108+
return new DescribedPredicate<>("ignored class " + type.getName()) {
109+
@Override
110+
public boolean apply(JavaClass input) {
111+
return !input.getFullName().startsWith(type.getName());
112+
}
113+
};
114+
}
115+
116+
private String getFirstPackagePart(String subpackage) {
117+
118+
int index = subpackage.indexOf(".");
119+
if (index < 0) {
120+
return subpackage;
121+
}
122+
return subpackage.substring(0, index);
123+
}
124+
125+
private String subModule(String basePackage, String packageName) {
126+
127+
if (packageName.startsWith(basePackage) && packageName.length() > basePackage.length()) {
128+
129+
final int index = basePackage.length() + 1;
130+
String subpackage = packageName.substring(index);
131+
return getFirstPackagePart(subpackage);
132+
}
133+
return "";
134+
}
135+
136+
private SliceAssignment subModuleSlicing() {
137+
return new SliceAssignment() {
138+
139+
@Override
140+
public SliceIdentifier getIdentifierOf(JavaClass javaClass) {
141+
142+
String packageName = javaClass.getPackageName();
143+
144+
String subModule = subModule("org.springframework.data.jdbc", packageName);
145+
if (!subModule.isEmpty()) {
146+
return SliceIdentifier.of(subModule);
147+
}
148+
149+
subModule = subModule("org.springframework.data.relational", packageName);
150+
if (!subModule.isEmpty()) {
151+
return SliceIdentifier.of(subModule);
152+
}
153+
154+
subModule = subModule("org.springframework.data", packageName);
155+
if (!subModule.isEmpty()) {
156+
return SliceIdentifier.of(subModule);
157+
}
158+
159+
return SliceIdentifier.ignore();
160+
}
161+
162+
@Override
163+
public String getDescription() {
164+
return "Submodule";
165+
}
166+
};
167+
}
168+
169+
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/degraph/DependencyTests.java

-70
This file was deleted.

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
4242
import org.springframework.data.jdbc.core.convert.RelationResolver;
4343
import org.springframework.data.jdbc.core.convert.SqlGeneratorSource;
44-
import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns;
44+
import org.springframework.data.jdbc.core.convert.JdbcArrayColumns;
4545
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
4646
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
4747
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;

spring-data-relational/pom.xml

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
</dependency>
6666

6767
<dependency>
68-
<groupId>de.schauderhaft.degraph</groupId>
69-
<artifactId>degraph-check</artifactId>
70-
<version>${degraph-check.version}</version>
68+
<groupId>com.tngtech.archunit</groupId>
69+
<artifactId>archunit</artifactId>
70+
<version>${archunit.version}</version>
7171
<scope>test</scope>
7272
</dependency>
7373

Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.springframework.data.relational.core.mapping.event;
16+
package org.springframework.data.relational.auditing;
1717

1818
import org.springframework.context.ApplicationListener;
1919
import org.springframework.core.Ordered;
2020
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
21+
import org.springframework.data.relational.core.mapping.event.BeforeConvertCallback;
2122
import org.springframework.util.Assert;
2223

2324
/**

0 commit comments

Comments
 (0)