15
15
import static com .tngtech .archunit .core .domain .JavaClass .Predicates .ANONYMOUS_CLASSES ;
16
16
import static com .tngtech .archunit .core .domain .JavaClass .Predicates .TOP_LEVEL_CLASSES ;
17
17
import static com .tngtech .archunit .core .domain .JavaClass .Predicates .resideInAPackage ;
18
- import static com .tngtech .archunit .core .domain .JavaClass .Predicates .resideInAnyPackage ;
19
18
import static com .tngtech .archunit .core .domain .JavaClass .Predicates .simpleName ;
20
19
import static com .tngtech .archunit .core .domain .JavaClass .Predicates .simpleNameEndingWith ;
21
20
import static com .tngtech .archunit .core .domain .JavaModifier .PUBLIC ;
27
26
import static com .tngtech .archunit .lang .conditions .ArchPredicates .have ;
28
27
import static com .tngtech .archunit .lang .syntax .ArchRuleDefinition .classes ;
29
28
import static com .tngtech .archunit .library .dependencies .SlicesRuleDefinition .slices ;
29
+ import static org .assertj .core .api .Assertions .assertThat ;
30
30
import static org .junit .jupiter .api .Assertions .assertTrue ;
31
31
32
32
import java .lang .annotation .Annotation ;
35
35
import java .lang .annotation .Target ;
36
36
import java .util .Arrays ;
37
37
import java .util .function .BiPredicate ;
38
+ import java .util .stream .Stream ;
38
39
39
40
import com .tngtech .archunit .base .DescribedPredicate ;
40
41
import com .tngtech .archunit .core .domain .JavaClass ;
41
42
import com .tngtech .archunit .core .domain .JavaClasses ;
43
+ import com .tngtech .archunit .core .domain .JavaPackage ;
44
+ import com .tngtech .archunit .core .domain .PackageMatcher ;
42
45
import com .tngtech .archunit .junit .AnalyzeClasses ;
43
46
import com .tngtech .archunit .junit .ArchTest ;
44
47
import com .tngtech .archunit .lang .ArchCondition ;
45
48
import com .tngtech .archunit .lang .ArchRule ;
46
49
import com .tngtech .archunit .library .GeneralCodingRules ;
47
50
48
51
import org .apiguardian .api .API ;
52
+ import org .jspecify .annotations .NullMarked ;
49
53
50
54
@ AnalyzeClasses (packages = { "org.junit.platform" , "org.junit.jupiter" , "org.junit.vintage" })
51
55
class ArchUnitTests {
@@ -64,7 +68,7 @@ class ArchUnitTests {
64
68
.and (not (describe ("are Kotlin SAM type implementations" , simpleName ("" )))) //
65
69
.and (not (describe ("are Kotlin-generated classes that contain only top-level functions" ,
66
70
simpleNameEndingWith ("Kt" )))) //
67
- .and (not (describe ("are shadowed" , resideInAnyPackage ("..shadow.." )))) //
71
+ .and (not (describe ("are shadowed" , resideInAPackage ("..shadow.." )))) //
68
72
.should ().beAnnotatedWith (API .class );
69
73
70
74
@ SuppressWarnings ("unused" )
@@ -76,6 +80,32 @@ class ArchUnitTests {
76
80
.should (haveContainerAnnotationWithSameRetentionPolicy ()) //
77
81
.andShould (haveContainerAnnotationWithSameTargetTypes ());
78
82
83
+ @ ArchTest
84
+ void packagesShouldBeNullMarked (JavaClasses classes ) {
85
+ var exclusions = Stream .of ( //
86
+ "..shadow.." , //
87
+ "org.junit.jupiter.api.." , //
88
+ "org.junit.jupiter.engine.." , //
89
+ "org.junit.jupiter.migrationsupport.." , //
90
+ "org.junit.jupiter.params.." , //
91
+ "org.junit.platform.launcher.." //
92
+ ).map (PackageMatcher ::of ).toList ();
93
+
94
+ var subpackages = Stream .of ("org.junit.platform" , "org.junit.jupiter" , "org.junit.vintage" ) //
95
+ .map (classes ::getPackage ) //
96
+ .flatMap (rootPackage -> rootPackage .getSubpackagesInTree ().stream ()) //
97
+ .filter (pkg -> exclusions .stream ().noneMatch (it -> it .matches (pkg .getName ()))) //
98
+ .filter (pkg -> !pkg .getClasses ().isEmpty ()) //
99
+ .toList ();
100
+ assertThat (subpackages ).isNotEmpty ();
101
+
102
+ var violations = subpackages .stream () //
103
+ .filter (pkg -> !pkg .isAnnotatedWith (NullMarked .class )) //
104
+ .map (JavaPackage ::getName ) //
105
+ .sorted ();
106
+ assertThat (violations ).describedAs ("The following packages are missing the @NullMarked annotation" ).isEmpty ();
107
+ }
108
+
79
109
@ ArchTest
80
110
void allAreIn (JavaClasses classes ) {
81
111
// about 928 classes found in all jars
0 commit comments