11package nebula.plugin.dependencylock
22
3+ import nebula.plugin.VerifierOutputAssertionsBase
34import nebula.plugin.dependencyverifier.DependencyResolutionVerifierKt
45import nebula.test.dependencies.DependencyGraphBuilder
56import nebula.test.dependencies.GradleDependencyGenerator
@@ -9,6 +10,14 @@ import spock.lang.IgnoreIf
910import spock.lang.Subject
1011import spock.lang.Unroll
1112
13+ import static nebula.plugin.VerifierOutputAssertionsBase.assertResolutionFailureForDependencyForProject
14+ import static nebula.plugin.dependencylock.DependencyLockPluginWithCoreVerifierSpec.OutputAssertions.assertExecutionFailedForTask
15+ import static nebula.plugin.dependencylock.DependencyLockPluginWithCoreVerifierSpec.OutputAssertions.assertLockStateFailure
16+ import static nebula.plugin.dependencylock.DependencyLockPluginWithCoreVerifierSpec.OutputAssertions.assertOutputMentionsProjects
17+ import static nebula.plugin.dependencylock.DependencyLockPluginWithCoreVerifierSpec.OutputAssertions.assertResolutionFailureForDependency
18+ import static nebula.plugin.dependencylock.DependencyLockPluginWithCoreVerifierSpec.OutputAssertions.assertResolutionFailureMessage
19+ import static nebula.plugin.dependencylock.DependencyLockPluginWithCoreVerifierSpec.OutputAssertions.assertUnresolvedDependenciesInOutput
20+
1221@Subject (DependencyResolutionVerifierKt )
1322class DependencyLockPluginWithCoreVerifierSpec extends AbstractDependencyLockPluginSpec {
1423 private static final String BASELINE_LOCKFILE_CONTENTS = """ # This is a Gradle generated file for dependency locking.
@@ -70,8 +79,8 @@ empty=annotationProcessor,testAnnotationProcessor
7079 def results = runTasks(* tasks(lockArg), ' -PdependencyResolutionVerifier.unresolvedDependenciesFailTheBuild=false' )
7180
7281 then :
73- results. output. contains(" Failed to resolve the following dependencies" )
74- results. output. contains(failedResolutionDependencies() )
82+ results. output. contains(' Failed to resolve the following dependencies' )
83+ assertUnresolvedDependenciesInOutput( results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
7584
7685 where :
7786 lockArg << [' write-locks' , ' update-locks' ]
@@ -92,9 +101,8 @@ empty=annotationProcessor,testAnnotationProcessor
92101 def results = runTasksAndFail(' dependencies' )
93102
94103 then :
95- results. output. contains(' FAILURE' )
96- results. output. contains(' Resolved dependencies were missing from the lock state' )
97- results. output. contains(' Resolved \' test.nebula:d:1.0.0\' which is not part of the dependency lock state' )
104+ assertExecutionFailedForTask(results. output)
105+ assertLockStateFailure(results. output, ' test.nebula:d:1.0.0' )
98106 }
99107
100108 @Unroll
@@ -140,9 +148,8 @@ empty=annotationProcessor,testAnnotationProcessor
140148 def results = runTasksAndFail(' dependenciesForAll' )
141149
142150 then :
143- results. output. contains(' FAILURE' )
144- results. output. contains(' Resolved dependencies were missing from the lock state' )
145- results. output. contains(' Resolved \' test.nebula:d:1.0.0\' which is not part of the dependency lock state' )
151+ assertExecutionFailedForTask(results. output)
152+ assertLockStateFailure(results. output, ' test.nebula:d:1.0.0' , ' sub1' )
146153 }
147154
148155 @Unroll
@@ -156,14 +163,9 @@ empty=annotationProcessor,testAnnotationProcessor
156163 def results = runTasksAndFail(* tasks(lockArg))
157164
158165 then :
159- results. output. contains(' test.nebula:c FAILED' )
160- results. output. contains(' test.nebula:e FAILED' )
161- results. output. contains(' not.available:a:1.0.0 FAILED' )
162- results. output. contains(' transitive.not.available:a:1.0.0 FAILED' )
163- results. output. contains(' FAILURE' )
164-
165- results. output. contains(" > Failed to resolve the following dependencies" )
166- results. output. contains(failedResolutionDependencies())
166+ assertExecutionFailedForTask(results. output)
167+ assertResolutionFailureMessage(results. output)
168+ assertUnresolvedDependenciesInOutput(results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
167169
168170 where :
169171 lockArg << [' write-locks' , ' update-locks' ]
@@ -181,14 +183,9 @@ empty=annotationProcessor,testAnnotationProcessor
181183 def results = runTasksAndFail(* tasks(lockArg, true ))
182184
183185 then :
184- results. output. contains(' test.nebula:c FAILED' )
185- results. output. contains(' test.nebula:e FAILED' )
186- results. output. contains(' not.available:a:1.0.0 FAILED' )
187- results. output. contains(' transitive.not.available:a:1.0.0 FAILED' )
188- results. output. contains(' FAILURE' )
189-
190- results. output. contains(" > Failed to resolve the following dependencies" )
191- results. output. contains(failedResolutionDependencies(' sub1' ))
186+ assertExecutionFailedForTask(results. output)
187+ assertResolutionFailureMessage(results. output)
188+ assertUnresolvedDependenciesInOutput(results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES , ' sub1' )
192189
193190 where :
194191 lockArg << [' write-locks' , ' update-locks' ]
@@ -253,13 +250,11 @@ empty=annotationProcessor,testAnnotationProcessor
253250 def results = runTasksAndFail(* tasks(lockArg, true ), ' --parallel' )
254251
255252 then :
256- results. output. contains(' FAILURE: Build completed with 2 failures.' )
253+ assertExecutionFailedForTask(results. output)
254+ assertResolutionFailureForDependencyForProject(results. output, ' not.available:a:1.0.0' , " sub1" )
255+ assertResolutionFailureForDependencyForProject(results. output, ' not.available:a:1.0.0' , " sub2" )
256+ assertOutputMentionsProjects(results. output, [' sub1' , ' sub2' ])
257257
258- results. output. findAll(" > Failed to resolve the following dependencies:\n " +
259- " 1. Failed to resolve 'not.available:a:1.0.0' for project 'sub1'" ). size() == 1
260-
261- results. output. findAll(" > Failed to resolve the following dependencies:\n " +
262- " 1. Failed to resolve 'not.available:a:1.0.0' for project 'sub2'" ). size() == 1
263258 where :
264259 lockArg << [' write-locks' , ' update-locks' ]
265260 }
@@ -279,13 +274,10 @@ empty=annotationProcessor,testAnnotationProcessor
279274 def results = runTasksAndFail(* tasks(lockArg, true ), ' --parallel' )
280275
281276 then :
282- results. output. contains(' FAILURE: Build completed with 2 failures.' )
283-
284- results. output. findAll(" > Failed to resolve the following dependencies:\n " +
285- " 1. Failed to resolve 'not.available:a:1.0.0' for project 'sub1'" ). size() == 1
286-
287- results. output. findAll(" > Failed to resolve the following dependencies:\n " +
288- " 1. Failed to resolve 'not.available:a:1.0.0' for project 'sub2'" ). size() == 1
277+ assertExecutionFailedForTask(results. output)
278+ assertResolutionFailureForDependencyForProject(results. output, ' not.available:a:1.0.0' , ' sub1' )
279+ assertResolutionFailureForDependencyForProject(results. output, ' not.available:a:1.0.0' , ' sub2' )
280+ assertOutputMentionsProjects(results. output, [' sub1' , ' sub2' ])
289281
290282 where :
291283 lockArg << [' write-locks' , ' update-locks' ]
@@ -304,14 +296,9 @@ empty=annotationProcessor,testAnnotationProcessor
304296 def results = runTasksAndFail(* tasks(lockArg))
305297
306298 then :
307- results. output. contains(' test.nebula:c FAILED' )
308- results. output. contains(' test.nebula:e FAILED' )
309- results. output. contains(' not.available:a:1.0.0 FAILED' )
310- results. output. contains(' transitive.not.available:a:1.0.0 FAILED' )
311- results. output. contains(' FAILURE' )
312-
313- results. output. contains(" > Failed to resolve the following dependencies" )
314- results. output. contains(failedResolutionDependencies())
299+ assertExecutionFailedForTask(results. output)
300+ assertResolutionFailureMessage(results. output)
301+ assertUnresolvedDependenciesInOutput(results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
315302
316303 where :
317304 conf | lockArg
@@ -330,8 +317,8 @@ empty=annotationProcessor,testAnnotationProcessor
330317 def results = runTasksAndFail(* tasks(lockArg))
331318
332319 then :
333- results. output. contains( ' FAILURE ' )
334- results. output. contains(failedResolutionDependencies() )
320+ assertExecutionFailedForTask( results. output)
321+ assertUnresolvedDependenciesInOutput( results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
335322
336323 where :
337324 lockArg << [' write-locks' , ' update-locks' ]
@@ -348,8 +335,8 @@ empty=annotationProcessor,testAnnotationProcessor
348335 def results = runTasksAndFail(* tasks(lockArg))
349336
350337 then :
351- results. output. contains( ' FAILURE ' )
352- results. output. contains(failedResolutionDependencies() )
338+ assertExecutionFailedForTask( results. output)
339+ assertUnresolvedDependenciesInOutput( results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
353340
354341 where :
355342 lockArg << [' write-locks' , ' update-locks' ]
@@ -366,8 +353,8 @@ empty=annotationProcessor,testAnnotationProcessor
366353 def results = runTasksAndFail(* tasks(lockArg))
367354
368355 then :
369- results. output. contains( ' FAILURE ' )
370- results. output. contains(failedResolutionDependencies() )
356+ assertExecutionFailedForTask( results. output)
357+ assertUnresolvedDependenciesInOutput( results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
371358
372359 where :
373360 lockArg << [' write-locks' , ' update-locks' ]
@@ -386,8 +373,8 @@ empty=annotationProcessor,testAnnotationProcessor
386373 def results = runTasksAndFail(* tasks(lockArg))
387374
388375 then :
389- results. output. contains( ' FAILURE ' )
390- results. output. contains(failedResolutionDependencies() )
376+ assertExecutionFailedForTask( results. output)
377+ assertUnresolvedDependenciesInOutput( results. output, MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES )
391378
392379 where :
393380 lockArg << [' write-locks' , ' update-locks' ]
@@ -696,12 +683,45 @@ empty=annotationProcessor,testAnnotationProcessor
696683 return tasks
697684 }
698685
699- private String failedResolutionDependencies (String subprojectName = ' ' ) {
700- def project = subprojectName != ' ' ? subprojectName : projectName
701- return """
702- 1. Failed to resolve 'not.available:a:1.0.0' for project '$project '
703- 2. Failed to resolve 'test.nebula:c' for project '$project '
704- 3. Failed to resolve 'test.nebula:e' for project '$project '
705- 4. Failed to resolve 'transitive.not.available:a:1.0.0' for project '$project '"""
686+ /**
687+ * Extends shared base; adds lock-plugin–specific assertions (lock state, batch unresolved, project mentions).
688+ */
689+ static class OutputAssertions extends VerifierOutputAssertionsBase {
690+
691+ private static final List<String > LOCK_STATE_MARKERS = [' lock' , ' Resolved' , ' Dependency lock state' ]
692+
693+ static void assertLockStateFailure (String resultsOutput , String dependencyCoordinate ) {
694+ assert resultsOutput. contains(' FAILURE' ), ' Expected build to fail'
695+ assert resultsOutput. contains(dependencyCoordinate) && LOCK_STATE_MARKERS . any { resultsOutput. contains(it) },
696+ " Expected lock-state failure mentioning '$dependencyCoordinate ' and a lock-related message"
697+ }
698+
699+ static void assertLockStateFailure (String resultsOutput , String dependencyCoordinate , String projectNameInOutput ) {
700+ assert resultsOutput. contains(' FAILURE' ), ' Expected build to fail'
701+ boolean lockFailure = resultsOutput. contains(dependencyCoordinate) && LOCK_STATE_MARKERS . any { resultsOutput. contains(it) }
702+ assert lockFailure || resultsOutput. contains(projectNameInOutput),
703+ " Expected lock-state failure for '$dependencyCoordinate ' or output mentioning '$projectNameInOutput '"
704+ }
705+
706+ static void assertUnresolvedDependenciesInOutput (String resultsOutput , List<String > dependencies ) {
707+ assertResolutionFailureMessage(resultsOutput)
708+ dependencies. each { dep ->
709+ assertResolutionFailureForDependency(resultsOutput, dep)
710+ }
711+ }
712+
713+ static void assertUnresolvedDependenciesInOutput (String resultsOutput , List<String > dependencies , String projectName ) {
714+ assertResolutionFailureMessage(resultsOutput)
715+ dependencies. each { dep ->
716+ assertResolutionFailureForDependencyForProject(resultsOutput, dep, projectName)
717+ }
718+ }
706719 }
720+
721+ private static final List<String > MIX_UNRESOLVABLE_DEPENDENCY_COORDINATES = [
722+ ' not.available:a:1.0.0' ,
723+ ' test.nebula:c' ,
724+ ' test.nebula:e' ,
725+ ' transitive.not.available:a:1.0.0'
726+ ]
707727}
0 commit comments