Skip to content

Commit 88cadb9

Browse files
committed
Extract Library plugin-specific integration test
this will allow more detailed assertions on the library test, while leaving the integration test to focus on how the plugins will integrate together
1 parent 523cd86 commit 88cadb9

File tree

5 files changed

+162
-58
lines changed

5 files changed

+162
-58
lines changed

nebula-archrules-gradle-plugin/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ description = "Plugins for authoring and running Nebula ArchRules"
66
repositories {
77
mavenCentral()
88
}
9+
dependencies {
10+
testImplementation("net.javacrumbs.json-unit:json-unit-assertj:5.0.0")
11+
testImplementation("org.json:json:20250517")
12+
}
913
gradlePlugin {
1014
plugins {
1115
create("library") {

nebula-archrules-gradle-plugin/gradle.lockfile

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,18 @@
22
# Manual edits can break the build and are not advised.
33
# This file is expected to be part of source control.
44
cglib:cglib-nodep:3.2.2=integTestRuntimeClasspath,testRuntimeClasspath
5+
com.jayway.jsonpath:json-path:2.9.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
56
com.netflix.nebula:nebula-test:11.7.1=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
6-
net.bytebuddy:byte-buddy:1.15.11=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
7+
net.bytebuddy:byte-buddy:1.17.7=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
8+
net.javacrumbs.json-unit:json-unit-assertj:5.0.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
9+
net.javacrumbs.json-unit:json-unit-core:5.0.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
10+
net.javacrumbs.json-unit:json-unit-json-path:5.0.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
11+
net.minidev:accessors-smart:2.5.0=integTestRuntimeClasspath,testRuntimeClasspath
12+
net.minidev:json-smart:2.5.0=integTestRuntimeClasspath,testRuntimeClasspath
713
org.apiguardian:apiguardian-api:1.1.2=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
8-
org.assertj:assertj-core:3.27.3=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
14+
org.assertj:assertj-core:3.27.6=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
15+
org.hamcrest:hamcrest-core:3.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
16+
org.hamcrest:hamcrest:3.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
917
org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable:2.2.0=kotlinCompilerPluginClasspathIntegTest,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
1018
org.jetbrains.kotlin:kotlin-build-tools-api:2.2.0=kotlinBuildToolsApiClasspath
1119
org.jetbrains.kotlin:kotlin-build-tools-impl:2.2.0=kotlinBuildToolsApiClasspath
@@ -24,6 +32,7 @@ org.jetbrains.kotlin:kotlin-scripting-jvm:2.2.0=kotlinBuildToolsApiClasspath,kot
2432
org.jetbrains.kotlin:kotlin-stdlib:2.2.0=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathIntegTest,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testCompileClasspath,testRuntimeClasspath
2533
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
2634
org.jetbrains:annotations:13.0=compileClasspath,integTestCompileClasspath,integTestRuntimeClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathIntegTest,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,testCompileClasspath,testRuntimeClasspath
35+
org.json:json:20250517=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
2736
org.jspecify:jspecify:1.0.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
2837
org.junit.jupiter:junit-jupiter-api:5.12.2=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
2938
org.junit.jupiter:junit-jupiter-engine:5.12.2=integTestRuntimeClasspath,testRuntimeClasspath
@@ -34,4 +43,6 @@ org.junit.platform:junit-platform-engine:1.14.0=integTestCompileClasspath,integT
3443
org.junit.platform:junit-platform-launcher:1.14.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
3544
org.objenesis:objenesis:2.4=integTestRuntimeClasspath,testRuntimeClasspath
3645
org.opentest4j:opentest4j:1.3.0=integTestCompileClasspath,integTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath
46+
org.ow2.asm:asm:9.3=integTestRuntimeClasspath,testRuntimeClasspath
47+
org.slf4j:slf4j-api:2.0.11=integTestRuntimeClasspath,testRuntimeClasspath
3748
empty=annotationProcessor,integTestAnnotationProcessor,integTestKotlinScriptDefExtensions,kotlinScriptDefExtensions,runtimeClasspath,testAnnotationProcessor,testKotlinScriptDefExtensions

nebula-archrules-gradle-plugin/src/test/kotlin/com/netflix/nebula/archrules/gradle/ArchrulesLibraryPluginTest.kt

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package com.netflix.nebula.archrules.gradle
22

3+
import nebula.test.dsl.*
34
import nebula.test.dsl.TestKitAssertions.assertThat
5+
import net.javacrumbs.jsonunit.assertj.assertThatJson
46
import org.gradle.testfixtures.ProjectBuilder
7+
import org.gradle.testkit.runner.TaskOutcome
58
import org.junit.jupiter.api.Test
9+
import org.junit.jupiter.api.io.TempDir
10+
import java.io.File
611

712
class ArchrulesLibraryPluginTest {
13+
@TempDir
14+
lateinit var projectDir: File
815

916
@Test
1017
fun `plugin registers library dependency`() {
@@ -18,4 +25,71 @@ class ArchrulesLibraryPluginTest {
1825
assertThat(coreLibrary).isNotNull
1926
assertThat(coreLibrary!!.version).isEqualTo("latest.release")
2027
}
28+
29+
@Test
30+
fun `plugin produces maven publication`() {
31+
val runner = testProject(projectDir) {
32+
settings {
33+
name("library-with-rules")
34+
}
35+
rootProject {
36+
group("com.example")
37+
// a library that contains production code and rules to go along with it
38+
plugins {
39+
id("java-library")
40+
id("com.netflix.nebula.archrules.library")
41+
id("maven-publish")
42+
}
43+
repositories {
44+
maven("https://netflixoss.jfrog.io/artifactory/gradle-plugins")
45+
mavenCentral()
46+
}
47+
declareMavenPublication()
48+
src {
49+
main {
50+
exampleLibraryClass()
51+
}
52+
sourceSet("archRules") {
53+
exampleDeprecatedArchRule()
54+
}
55+
}
56+
}
57+
}
58+
59+
val result = runner.run(
60+
"build",
61+
"archRulesJar",
62+
"generateMetadataFileForMavenPublication", // to test publication metadata without actually publishing,
63+
"-Pversion=0.0.1"
64+
)
65+
66+
assertThat(result.task(":compileArchRulesJava"))
67+
.`as`("compile task runs for the archRules source set")
68+
.hasOutcome(TaskOutcome.SUCCESS)
69+
assertThat(result.task(":archRulesJar"))
70+
.hasOutcome(TaskOutcome.SUCCESS)
71+
assertThat(result)
72+
.hasNoMutableStateWarnings()
73+
.hasNoDeprecationWarnings()
74+
75+
assertThat(projectDir.resolve("build/libs/library-with-rules-0.0.1.jar"))
76+
.`as`("Library Jar is created")
77+
.exists()
78+
assertThat(projectDir.resolve("build/libs/library-with-rules-0.0.1-archrules.jar"))
79+
.`as`("ArchRules Jar is created")
80+
.exists()
81+
82+
val moduleMetadata = projectDir.resolve("build/publications/maven/module.json")
83+
assertThat(moduleMetadata)
84+
.`as`("Gradle Module Metadata is created")
85+
.exists()
86+
val moduleMetadataJson = moduleMetadata.readText()
87+
println(moduleMetadataJson)
88+
assertThatJson(moduleMetadataJson)
89+
.inPath("$.variants[?(@.name=='runtimeElements')].files[0]")
90+
.isArray
91+
.first().isObject
92+
.containsEntry("name", "library-with-rules-0.0.1.jar")
93+
94+
}
2195
}

nebula-archrules-gradle-plugin/src/test/kotlin/com/netflix/nebula/archrules/gradle/IntegrationTest.kt

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,51 +28,10 @@ internal class IntegrationTest {
2828
}
2929
src {
3030
main {
31-
java(
32-
"com/example/library/LibraryClass.java",
33-
//language=java
34-
"""
35-
package com.example.library;
36-
37-
public class LibraryClass {
38-
39-
}
40-
"""
41-
)
31+
exampleLibraryClass()
4232
}
4333
sourceSet("archRules") {
44-
java(
45-
"com/example/library/LibraryArchRules.java",
46-
//language=java
47-
"""
48-
package com.example.library;
49-
50-
import com.netflix.nebula.archrules.core.ArchRulesService;
51-
import com.tngtech.archunit.lang.ArchRule;
52-
import com.tngtech.archunit.lang.Priority;
53-
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
54-
import java.util.Map;
55-
import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.target;
56-
import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.targetOwner;
57-
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.annotatedWith;
58-
59-
public class LibraryArchRules implements ArchRulesService {
60-
private final ArchRule noDeprecated = ArchRuleDefinition.priority(Priority.LOW)
61-
.noClasses()
62-
.should().accessTargetWhere(targetOwner(annotatedWith(Deprecated.class)))
63-
.orShould().accessTargetWhere(target(annotatedWith(Deprecated.class)))
64-
.orShould().dependOnClassesThat().areAnnotatedWith(Deprecated.class)
65-
.allowEmptyShould(true)
66-
.as("No code should reference deprecated APIs")
67-
.because("usage of deprecated APIs introduces risk that future upgrades and migrations will be blocked");
68-
69-
@Override
70-
public Map<String, ArchRule> getRules() {
71-
return Map.of("deprecated", noDeprecated);
72-
}
73-
}
74-
"""
75-
)
34+
exampleDeprecatedArchRule()
7635
}
7736
}
7837
}
@@ -88,28 +47,16 @@ public class LibraryArchRules implements ArchRulesService {
8847
}
8948
}
9049

91-
val result = runner.run("check", "archRulesJar") {
50+
val result = runner.run("check") {
9251
withGradleVersion(gradleVersion.version)
9352
}
9453

95-
assertThat(result.task(":library-with-rules:compileArchRulesJava"))
96-
.`as`("compile task runs for the archRules source set")
97-
.hasOutcome(TaskOutcome.SUCCESS)
98-
assertThat(result.task(":library-with-rules:archRulesJar"))
99-
.hasOutcome(TaskOutcome.SUCCESS)
10054
assertThat(result.task(":library-with-rules:check"))
10155
.hasOutcome(TaskOutcome.SUCCESS, TaskOutcome.UP_TO_DATE)
10256
assertThat(result.task(":code-to-check:check"))
10357
.hasOutcome(TaskOutcome.SUCCESS, TaskOutcome.UP_TO_DATE)
10458
assertThat(result)
10559
.hasNoMutableStateWarnings()
10660
.hasNoDeprecationWarnings()
107-
108-
assertThat(projectDir.resolve("library-with-rules/build/libs/library-with-rules.jar"))
109-
.`as`("Library Jar is created")
110-
.exists()
111-
assertThat(projectDir.resolve("library-with-rules/build/libs/library-with-rules-archrules.jar"))
112-
.`as`("ArchRules Jar is created")
113-
.exists()
11461
}
11562
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.netflix.nebula.archrules.gradle
2+
3+
import nebula.test.dsl.ProjectBuilder
4+
import nebula.test.dsl.SourceSetBuilder
5+
6+
fun ProjectBuilder.declareMavenPublication() {
7+
//language=kotlin
8+
rawBuildScript(
9+
"""
10+
publishing {
11+
publications {
12+
create<MavenPublication>("maven") {
13+
from(components["java"])
14+
}
15+
}
16+
}
17+
"""
18+
)
19+
}
20+
21+
fun SourceSetBuilder.exampleLibraryClass() {
22+
java(
23+
"com/example/library/LibraryClass.java",
24+
//language=java
25+
"""
26+
package com.example.library;
27+
28+
public class LibraryClass {
29+
30+
}
31+
"""
32+
)
33+
}
34+
35+
fun SourceSetBuilder.exampleDeprecatedArchRule() {
36+
java(
37+
"com/example/library/LibraryArchRules.java",
38+
//language=java
39+
"""
40+
package com.example.library;
41+
42+
import com.netflix.nebula.archrules.core.ArchRulesService;
43+
import com.tngtech.archunit.lang.ArchRule;
44+
import com.tngtech.archunit.lang.Priority;
45+
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
46+
import java.util.Map;
47+
import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.target;
48+
import static com.tngtech.archunit.core.domain.JavaAccess.Predicates.targetOwner;
49+
import static com.tngtech.archunit.core.domain.properties.CanBeAnnotated.Predicates.annotatedWith;
50+
51+
public class LibraryArchRules implements ArchRulesService {
52+
private final ArchRule noDeprecated = ArchRuleDefinition.priority(Priority.LOW)
53+
.noClasses()
54+
.should().accessTargetWhere(targetOwner(annotatedWith(Deprecated.class)))
55+
.orShould().accessTargetWhere(target(annotatedWith(Deprecated.class)))
56+
.orShould().dependOnClassesThat().areAnnotatedWith(Deprecated.class)
57+
.allowEmptyShould(true)
58+
.as("No code should reference deprecated APIs")
59+
.because("usage of deprecated APIs introduces risk that future upgrades and migrations will be blocked");
60+
61+
@Override
62+
public Map<String, ArchRule> getRules() {
63+
return Map.of("deprecated", noDeprecated);
64+
}
65+
}
66+
"""
67+
)
68+
}

0 commit comments

Comments
 (0)