Skip to content

Commit 1f3704d

Browse files
committed
add support JUnit 6.x testing framework initial commit.
Issue: #1556 Signed-off-by: junya koyama <arukiidou@yahoo.co.jp>
1 parent c87e5e1 commit 1f3704d

File tree

74 files changed

+4793
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+4793
-2
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
plugins {
2+
id 'archunit.java-release-conventions'
3+
}
4+
5+
ext.moduleName = 'com.tngtech.archunit.junit6'
6+
7+
ext.minimumJavaVersion = JavaVersion.VERSION_17
8+
9+
dependencies {
10+
api(project(":archunit-junit6-api"))
11+
implementation(project(":archunit-junit6-engine"))
12+
}
13+
14+
shadowJar {
15+
exclude '**'
16+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
plugins {
2+
id 'archunit.java-release-conventions'
3+
}
4+
5+
ext.moduleName = 'com.tngtech.archunit.junit6.api'
6+
7+
ext.minimumJavaVersion = JavaVersion.VERSION_17
8+
9+
dependencies {
10+
api project(path: ':archunit')
11+
api project(path: ':archunit-junit', configuration: 'archJunitApi')
12+
api libs.junit6PlatformCommons
13+
}
14+
15+
javadoc {
16+
source(project(':archunit-junit').sourceSets.archJunitApi.allJava)
17+
}
18+
sourcesJar {
19+
from project(':archunit-junit').sourceSets.archJunitApi.allSource
20+
}
21+
22+
shadowJar {
23+
exclude 'META-INF/maven/**'
24+
25+
dependencies {
26+
exclude(dependency { !it.name.contains('archunit-junit') })
27+
}
28+
}
29+
30+
def configureDependencies = { deps ->
31+
deps.children().removeIf { dep ->
32+
dep.scope.text() != 'compile' || !(dep.artifactId.text() in ['archunit'])
33+
}
34+
}
35+
this.with project(':archunit-junit').configureJUnitArchive(configureDependencies)
36+
37+
singlePackageExport {
38+
exportedPackage = 'com.tngtech.archunit.junit'
39+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright 2014-2026 TNG Technology Consulting GmbH
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+
* http://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 com.tngtech.archunit.junit;
17+
18+
import java.lang.annotation.Retention;
19+
import java.lang.annotation.Target;
20+
21+
import com.tngtech.archunit.PublicAPI;
22+
import com.tngtech.archunit.core.domain.JavaClasses;
23+
import com.tngtech.archunit.core.importer.ClassFileImporter;
24+
import com.tngtech.archunit.core.importer.ImportOption;
25+
import com.tngtech.archunit.core.importer.ImportOption.DoNotIncludeJars;
26+
import com.tngtech.archunit.core.importer.ImportOption.DoNotIncludeTests;
27+
import org.junit.platform.commons.annotation.Testable;
28+
29+
import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
30+
import static java.lang.annotation.ElementType.TYPE;
31+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
32+
33+
/**
34+
* Specifies which packages/locations should be scanned and tested when running a JUnit 5 test.
35+
* <br><br>
36+
* To ignore certain classes (e.g. classes in test scope) see {@link #importOptions()}, in particular {@link DoNotIncludeTests} and
37+
* {@link DoNotIncludeJars}.
38+
* <br><br>
39+
* When checking rules, it is important to remember that all relevant information/classes need to be imported for the rules
40+
* to work. For example, if class A accesses class B and class B extends class C, but class B is not imported, then
41+
* a rule checking for no accesses to classes assignable to C will not fail, since ArchUnit does not know about the details
42+
* of class B, but only simple information like the fully qualified name. For information how to configure the import and
43+
* resolution behavior of missing classes, compare {@link ClassFileImporter}.
44+
*
45+
* @see ClassFileImporter
46+
*/
47+
@Testable
48+
@Target(TYPE)
49+
@Retention(RUNTIME)
50+
@PublicAPI(usage = ACCESS)
51+
public @interface AnalyzeClasses {
52+
/**
53+
* @return Packages to look for within the classpath / modulepath
54+
*/
55+
String[] packages() default {};
56+
57+
/**
58+
* @return Classes that specify packages to look for within the classpath / modulepath
59+
*/
60+
Class<?>[] packagesOf() default {};
61+
62+
/**
63+
* @return Implementations of {@link LocationProvider}. Allows to completely customize the sources,
64+
* where classes are imported from.
65+
*/
66+
Class<? extends LocationProvider>[] locations() default {};
67+
68+
/**
69+
* @return Whether to look for classes on the whole classpath.
70+
* Warning: Without any further {@link #importOptions() filtering} this can require a lot of resources.
71+
*/
72+
boolean wholeClasspath() default false;
73+
74+
/**
75+
* Allows to filter the class import. The supplied types will be instantiated and used to create the
76+
* {@link ImportOption ImportOptions} passed to the {@link ClassFileImporter}. Considering caching, compare the notes on
77+
* {@link ImportOption}.
78+
*
79+
* @return The types of {@link ImportOption} to use for the import
80+
*/
81+
Class<? extends ImportOption>[] importOptions() default {};
82+
83+
/**
84+
* Controls, if {@link JavaClasses} should be cached by location,
85+
* to be reused between several test classes, or just within the same class.
86+
*
87+
* @return The {@link CacheMode} to use for this test class.
88+
*/
89+
CacheMode cacheMode() default CacheMode.FOREVER;
90+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2014-2026 TNG Technology Consulting GmbH
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+
* http://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 com.tngtech.archunit.junit;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.Inherited;
20+
import java.lang.annotation.Repeatable;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.Target;
23+
24+
import com.tngtech.archunit.PublicAPI;
25+
26+
import static com.tngtech.archunit.PublicAPI.Usage.ACCESS;
27+
import static java.lang.annotation.ElementType.FIELD;
28+
import static java.lang.annotation.ElementType.METHOD;
29+
import static java.lang.annotation.ElementType.TYPE;
30+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
31+
32+
/**
33+
* {@link ArchTag @ArchTag} is a {@linkplain Repeatable repeatable} annotation that allows
34+
* tagging any {@link ArchTest @ArchTest} field/method/class. Sets of rules can be classified to run together this way.
35+
*
36+
* Rules could be tagged like
37+
* <br><br>
38+
* <pre><code>
39+
*{@literal @}ArchTag("dependencies")
40+
* static ArchRule no_accesses_from_server_to_client = classes()...
41+
* </code></pre>
42+
*
43+
* Users of {@link ArchTag} must follow the syntax conventions that the JUnit Platform Engine defines:
44+
*
45+
* <ul>
46+
* <li>A tag must not be blank.</li>
47+
* <li>A <em>trimmed</em> tag must not contain whitespace.</li>
48+
* <li>A <em>trimmed</em> tag must not contain ISO control characters.</li>
49+
* <li>A <em>trimmed</em> tag must not contain any of the following
50+
* <em>reserved characters</em>.
51+
* <ul>
52+
* <li>{@code ,}: <em>comma</em></li>
53+
* <li>{@code (}: <em>left parenthesis</em></li>
54+
* <li>{@code )}: <em>right parenthesis</em></li>
55+
* <li>{@code &}: <em>ampersand</em></li>
56+
* <li>{@code |}: <em>vertical bar</em></li>
57+
* <li>{@code !}: <em>exclamation point</em></li>
58+
* </ul>
59+
* </li>
60+
* </ul>
61+
*/
62+
@Inherited
63+
@Documented
64+
@Retention(RUNTIME)
65+
@PublicAPI(usage = ACCESS)
66+
@Repeatable(ArchTags.class)
67+
@Target({TYPE, METHOD, FIELD})
68+
public @interface ArchTag {
69+
/**
70+
* The actual <em>tag</em>. It will first be {@linkplain String#trim() trimmed} and must then adhere to the
71+
* {@linkplain ArchTag Syntax Rules for Tags}. Otherwise the tag will be ignored.
72+
*/
73+
String value();
74+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2014-2026 TNG Technology Consulting GmbH
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+
* http://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 com.tngtech.archunit.junit;
17+
18+
import java.lang.annotation.Documented;
19+
import java.lang.annotation.Inherited;
20+
import java.lang.annotation.Repeatable;
21+
import java.lang.annotation.Retention;
22+
import java.lang.annotation.Target;
23+
24+
import com.tngtech.archunit.Internal;
25+
26+
import static java.lang.annotation.ElementType.FIELD;
27+
import static java.lang.annotation.ElementType.METHOD;
28+
import static java.lang.annotation.ElementType.TYPE;
29+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
30+
31+
/**
32+
* Simply a container for {@link ArchTag}. Should never be used directly, but instead
33+
* {@link ArchTag} should be used in a {@linkplain Repeatable repeatable} manner, e.g.
34+
* <br><br>
35+
* <pre><code>
36+
*{@literal @}ArchTag("foo")
37+
*{@literal @}ArchTag("bar")
38+
* static ArchRule example = classes()...
39+
* </code></pre>
40+
*/
41+
@Internal
42+
@Inherited
43+
@Documented
44+
@Retention(RUNTIME)
45+
@Target({TYPE, METHOD, FIELD})
46+
public @interface ArchTags {
47+
ArchTag[] value();
48+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2014-2026 TNG Technology Consulting GmbH
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+
* http://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 com.tngtech.archunit.junit;
17+
18+
import java.lang.annotation.Retention;
19+
import java.lang.annotation.Target;
20+
21+
import com.tngtech.archunit.core.domain.JavaClasses;
22+
import com.tngtech.archunit.lang.ArchRule;
23+
import org.junit.platform.commons.annotation.Testable;
24+
25+
import static java.lang.annotation.ElementType.FIELD;
26+
import static java.lang.annotation.ElementType.METHOD;
27+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
28+
29+
/**
30+
* Marks ArchUnit tests to be executed by the test infrastructure. These tests can have the following form:
31+
* <ul>
32+
* <li>
33+
* A static field of type {@link ArchRule} -&gt; this rule will automatically be checked against the imported classes
34+
* </li>
35+
* <li>
36+
* A static method with one parameter {@link JavaClasses} -&gt; this method will be called with the imported classes
37+
* </li>
38+
* </ul>
39+
* <br>Example:
40+
* <pre><code>
41+
*{@literal @}ArchTest
42+
* public static final ArchRule someRule = classes()... ;
43+
*
44+
*{@literal @}ArchTest
45+
* public static void someMethod(JavaClasses classes) {
46+
* // do something with classes
47+
* }
48+
* </code></pre>
49+
*/
50+
@Testable
51+
@Target({FIELD, METHOD})
52+
@Retention(RUNTIME)
53+
public @interface ArchTest {
54+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
plugins {
2+
id 'archunit.java-release-conventions'
3+
}
4+
5+
ext.moduleName = 'com.tngtech.archunit.junit6.engineapi'
6+
7+
ext.minimumJavaVersion = JavaVersion.VERSION_17
8+
9+
dependencies {
10+
api libs.junit6PlatformEngine
11+
implementation project(path: ':archunit')
12+
13+
testImplementation project(path: ':archunit-junit6-api')
14+
testImplementation libs.assertj
15+
}
16+
17+
compileJava.dependsOn project(':archunit-junit6-api').finishArchive
18+
19+
test {
20+
useJUnitPlatform() {
21+
excludeEngines 'archunit'
22+
}
23+
}
24+
25+
shadowJar {
26+
exclude 'META-INF/maven/**'
27+
28+
dependencies {
29+
exclude(dependency { true })
30+
}
31+
}
32+
33+
// dependencies to archunit only cover annotations; we can skip those without breaking consumers to keep the dependency slim
34+
def configureDependencies = { deps ->
35+
deps.children().removeIf{ dep ->
36+
dep.artifactId.text() != 'junit-platform-engine'
37+
}
38+
}
39+
this.with project(':archunit-junit').configureJUnitArchive(configureDependencies)
40+
41+
singlePackageExport {
42+
exportedPackage = 'com.tngtech.archunit.junit.engine_api'
43+
}

0 commit comments

Comments
 (0)