Skip to content

Commit c4f6e2c

Browse files
authored
Merge pull request #56 from rubensousa/test-groovy-support
Add integration test for groovy support
2 parents 8da0d28 + d15ad4b commit c4f6e2c

File tree

7 files changed

+237
-76
lines changed

7 files changed

+237
-76
lines changed

projectguard/api/projectguard.api

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@ public final class com/rubensousa/projectguard/plugin/GuardRule {
1414

1515
public abstract interface class com/rubensousa/projectguard/plugin/GuardScope {
1616
public abstract fun applyRule (Lcom/rubensousa/projectguard/plugin/GuardRule;)V
17+
public fun deny (Ljava/lang/String;)V
1718
public fun deny (Ljava/lang/String;Lgroovy/lang/Closure;)V
1819
public abstract fun deny (Ljava/lang/String;Lorg/gradle/api/Action;)V
20+
public fun deny (Lorg/gradle/api/internal/catalog/DelegatingProjectDependency;)V
21+
public fun deny (Lorg/gradle/api/internal/catalog/DelegatingProjectDependency;Lgroovy/lang/Closure;)V
1922
public fun deny (Lorg/gradle/api/internal/catalog/DelegatingProjectDependency;Lorg/gradle/api/Action;)V
23+
public fun deny (Lorg/gradle/api/provider/Provider;)V
2024
public fun deny (Lorg/gradle/api/provider/Provider;Lgroovy/lang/Closure;)V
2125
public abstract fun deny (Lorg/gradle/api/provider/Provider;Lorg/gradle/api/Action;)V
22-
public static synthetic fun deny$default (Lcom/rubensousa/projectguard/plugin/GuardScope;Ljava/lang/String;Lorg/gradle/api/Action;ILjava/lang/Object;)V
23-
public static synthetic fun deny$default (Lcom/rubensousa/projectguard/plugin/GuardScope;Lorg/gradle/api/internal/catalog/DelegatingProjectDependency;Lorg/gradle/api/Action;ILjava/lang/Object;)V
24-
public static synthetic fun deny$default (Lcom/rubensousa/projectguard/plugin/GuardScope;Lorg/gradle/api/provider/Provider;Lorg/gradle/api/Action;ILjava/lang/Object;)V
2526
}
2627

2728
public abstract interface class com/rubensousa/projectguard/plugin/ModuleRestrictionScope {

projectguard/src/main/kotlin/com/rubensousa/projectguard/plugin/GuardScope.kt

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,38 +23,63 @@ import org.gradle.api.internal.catalog.DelegatingProjectDependency
2323
import org.gradle.api.provider.Provider
2424
import org.gradle.util.internal.ConfigureUtil
2525

26+
private val emptyDenyScope = Action<DenyScope> { }
27+
2628
interface GuardScope {
2729

2830
fun deny(
2931
dependencyPath: String,
30-
action: Action<DenyScope> = Action<DenyScope> { },
32+
action: Action<DenyScope>,
3133
)
3234

35+
fun deny(
36+
provider: Provider<MinimalExternalModuleDependency>,
37+
action: Action<DenyScope>,
38+
)
39+
40+
fun applyRule(rule: GuardRule)
41+
3342
fun deny(
3443
dependencyDelegation: DelegatingProjectDependency,
35-
action: Action<DenyScope> = Action<DenyScope> { },
36-
) = deny(dependencyPath = dependencyDelegation.path, action = action)
44+
action: Action<DenyScope>,
45+
) {
46+
deny(dependencyPath = dependencyDelegation.path, action = action)
47+
}
48+
49+
// Required for groovy compatibility
50+
fun deny(dependencyPath: String) {
51+
deny(dependencyPath, emptyDenyScope)
52+
}
53+
54+
fun deny(dependencyDelegation: DelegatingProjectDependency) {
55+
deny(dependencyDelegation.path, emptyDenyScope)
56+
}
3757

3858
fun deny(
3959
provider: Provider<MinimalExternalModuleDependency>,
40-
action: Action<DenyScope> = Action<DenyScope> { },
41-
)
60+
) {
61+
deny(provider, emptyDenyScope)
62+
}
63+
64+
fun deny(
65+
dependencyDelegation: DelegatingProjectDependency,
66+
closure: Closure<DenyScope>,
67+
) {
68+
deny(dependencyDelegation.path, ConfigureUtil.configureUsing(closure))
69+
}
4270

43-
// Required for groovy compatibility
4471
fun deny(
4572
dependencyPath: String,
46-
closure: Closure<DenyScope>
73+
closure: Closure<DenyScope>,
4774
) {
4875
deny(dependencyPath, ConfigureUtil.configureUsing(closure))
4976
}
5077

51-
// Required for groovy compatibility
5278
fun deny(
5379
provider: Provider<MinimalExternalModuleDependency>,
54-
closure: Closure<DenyScope>
80+
closure: Closure<DenyScope>,
5581
) {
5682
deny(provider, ConfigureUtil.configureUsing(closure))
5783
}
5884

59-
fun applyRule(rule: GuardRule)
6085
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2026 Rúben Sousa
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+
17+
package com.rubensousa.projectguard.plugin
18+
19+
import org.junit.Before
20+
import org.junit.Rule
21+
import org.junit.Test
22+
import org.junit.rules.TemporaryFolder
23+
import java.io.File
24+
25+
class GroovyIntegrationTest {
26+
27+
@get:Rule
28+
val temporaryFolder = TemporaryFolder()
29+
30+
private val pluginRunner = PluginRunner(temporaryFolder)
31+
private lateinit var rootBuildFile: File
32+
33+
@Before
34+
fun setup() {
35+
rootBuildFile = temporaryFolder.newFile("build.gradle")
36+
rootBuildFile.writeText(
37+
"""
38+
plugins {
39+
id 'com.rubensousa.projectguard'
40+
}
41+
subprojects {
42+
apply plugin: 'java-library'
43+
apply plugin: 'com.rubensousa.projectguard'
44+
}
45+
46+
""".trimIndent()
47+
)
48+
}
49+
50+
@Test
51+
fun `check fails for guard restriction`() {
52+
// given
53+
val module = "consumer"
54+
val dependency = "libraryA"
55+
val reason = "Bla bla"
56+
pluginRunner.createModule(module)
57+
pluginRunner.createModule(dependency)
58+
rootBuildFile.appendText(
59+
"""
60+
projectGuard {
61+
guard(":$module") {
62+
deny(":$dependency") {
63+
reason("$reason")
64+
}
65+
}
66+
}
67+
""".trimIndent()
68+
)
69+
70+
// when
71+
pluginRunner.addDependency(from = module, to = dependency)
72+
73+
// then
74+
pluginRunner.assertCheckFails(module)
75+
pluginRunner.assertTaskOutputContains(reason)
76+
}
77+
78+
@Test
79+
fun `check succeeds for guard restriction that does not match`() {
80+
// given
81+
val module = "consumer"
82+
val dependency = "libraryA"
83+
pluginRunner.createModule(module)
84+
pluginRunner.createModule(dependency)
85+
rootBuildFile.appendText(
86+
"""
87+
projectGuard {
88+
guard(":$module") {
89+
deny(":another")
90+
}
91+
}
92+
""".trimIndent()
93+
)
94+
95+
// when
96+
pluginRunner.addDependency(from = module, to = dependency)
97+
98+
// then
99+
pluginRunner.assertCheckSucceeds(module)
100+
pluginRunner.assertTaskOutputContains("No fatal matches found")
101+
}
102+
103+
}

projectguard/src/test/kotlin/com/rubensousa/projectguard/plugin/PluginIntegrationTest.kt

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616

1717
package com.rubensousa.projectguard.plugin
1818

19-
import com.google.common.truth.Truth.assertThat
20-
import org.gradle.testkit.runner.BuildResult
21-
import org.gradle.testkit.runner.GradleRunner
22-
import org.gradle.testkit.runner.TaskOutcome
2319
import org.junit.Before
2420
import org.junit.Rule
2521
import org.junit.Test
@@ -31,19 +27,12 @@ class PluginIntegrationTest {
3127
@get:Rule
3228
val temporaryFolder = TemporaryFolder()
3329

30+
private val pluginRunner = PluginRunner(temporaryFolder)
3431
private lateinit var rootBuildFile: File
35-
private lateinit var settingsFile: File
36-
private lateinit var gradleRunner: GradleRunner
37-
private val checkTask = ":consumer:projectGuardCheck"
3832

3933
@Before
4034
fun setup() {
41-
settingsFile = temporaryFolder.newFile("settings.gradle.kts")
4235
rootBuildFile = temporaryFolder.newFile("build.gradle.kts")
43-
gradleRunner = GradleRunner.create()
44-
.withProjectDir(temporaryFolder.root)
45-
.withPluginClasspath()
46-
.withGradleVersion("8.13")
4736
rootBuildFile.writeText(
4837
"""
4938
plugins {
@@ -61,9 +50,9 @@ class PluginIntegrationTest {
6150
@Test
6251
fun `transitive dependencies are found and cause check to fail`() {
6352
// given
64-
createModule("consumer")
65-
createModule("libraryA")
66-
createModule("libraryB")
53+
pluginRunner.createModule("consumer")
54+
pluginRunner.createModule("libraryA")
55+
pluginRunner.createModule("libraryB")
6756

6857
rootBuildFile.appendText(
6958
"""
@@ -75,21 +64,19 @@ class PluginIntegrationTest {
7564
""".trimIndent()
7665
)
7766

78-
addDependency(from = "consumer", to = "libraryA")
79-
addDependency(from = "libraryA", to = "libraryB")
80-
8167
// when
82-
val result = runCheckTask(expectSuccess = false)
68+
pluginRunner.addDependency(from = "consumer", to = "libraryA")
69+
pluginRunner.addDependency(from = "libraryA", to = "libraryB")
8370

8471
// then
85-
assertThat(result.task(checkTask)?.outcome!!).isEqualTo(TaskOutcome.FAILED)
72+
pluginRunner.assertCheckFails("consumer")
8673
}
8774

8875
@Test
8976
fun `direct dependencies are found and cause check to fail`() {
9077
// given
91-
createModule("consumer")
92-
createModule("library")
78+
pluginRunner.createModule("consumer")
79+
pluginRunner.createModule("library")
9380

9481
rootBuildFile.appendText(
9582
"""
@@ -99,20 +86,18 @@ class PluginIntegrationTest {
9986
""".trimIndent()
10087
)
10188

102-
addDependency(from = "consumer", to = "library")
103-
10489
// when
105-
val result = runCheckTask(expectSuccess = false)
90+
pluginRunner.addDependency(from = "consumer", to = "library")
10691

10792
// then
108-
assertThat(result.task(checkTask)?.outcome!!).isEqualTo(TaskOutcome.FAILED)
93+
pluginRunner.assertCheckFails("consumer")
10994
}
11095

11196
@Test
11297
fun `check task succeeds when no matches are found`() {
11398
// given
114-
createModule("consumer")
115-
createModule("library")
99+
pluginRunner.createModule("consumer")
100+
pluginRunner.createModule("library")
116101

117102
rootBuildFile.appendText(
118103
"""
@@ -122,38 +107,10 @@ class PluginIntegrationTest {
122107
""".trimIndent()
123108
)
124109

125-
addDependency(from = "consumer", to = "library")
126-
127110
// when
128-
val result = runCheckTask(expectSuccess = true)
111+
pluginRunner.addDependency(from = "consumer", to = "library")
129112

130113
// then
131-
assertThat(result.task(checkTask)!!.outcome).isEqualTo(TaskOutcome.SUCCESS)
132-
}
133-
134-
private fun runCheckTask(expectSuccess: Boolean): BuildResult {
135-
val runner = gradleRunner.withArguments(checkTask)
136-
return if (expectSuccess) {
137-
runner.build()
138-
} else {
139-
runner.buildAndFail()
140-
}
141-
}
142-
143-
private fun createModule(name: String) {
144-
temporaryFolder.newFolder(name)
145-
temporaryFolder.newFile("$name/build.gradle.kts")
146-
settingsFile.appendText("\ninclude(\":$name\")")
114+
pluginRunner.assertCheckSucceeds("consumer")
147115
}
148-
149-
private fun addDependency(from: String, to: String, configuration: String = "implementation") {
150-
temporaryFolder.getRoot().resolve("$from/build.gradle.kts").appendText(
151-
"""
152-
dependencies {
153-
$configuration(project(":$to"))
154-
}
155-
""".trimIndent()
156-
)
157-
}
158-
159116
}

0 commit comments

Comments
 (0)