1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.graph;
20
21 import java.io.File;
22 import java.nio.file.Paths;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collection;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.stream.Collectors;
29 import java.util.stream.Stream;
30
31 import org.apache.maven.MavenExecutionException;
32 import org.apache.maven.api.services.model.ModelProcessor;
33 import org.apache.maven.execution.BuildResumptionDataRepository;
34 import org.apache.maven.execution.MavenExecutionRequest;
35 import org.apache.maven.execution.MavenSession;
36 import org.apache.maven.execution.ProjectActivation;
37 import org.apache.maven.execution.ProjectDependencyGraph;
38 import org.apache.maven.impl.model.DefaultModelProcessor;
39 import org.apache.maven.model.Dependency;
40 import org.apache.maven.model.Parent;
41 import org.apache.maven.model.building.Result;
42 import org.apache.maven.project.MavenProject;
43 import org.apache.maven.project.ProjectBuilder;
44 import org.apache.maven.project.ProjectBuildingException;
45 import org.apache.maven.project.ProjectBuildingRequest;
46 import org.apache.maven.project.ProjectBuildingResult;
47 import org.apache.maven.project.collector.DefaultProjectsSelector;
48 import org.apache.maven.project.collector.MultiModuleCollectionStrategy;
49 import org.apache.maven.project.collector.PomlessCollectionStrategy;
50 import org.apache.maven.project.collector.ProjectsSelector;
51 import org.apache.maven.project.collector.RequestPomCollectionStrategy;
52 import org.junit.jupiter.api.BeforeEach;
53 import org.junit.jupiter.api.Test;
54 import org.junit.jupiter.params.ParameterizedTest;
55 import org.junit.jupiter.params.provider.Arguments;
56 import org.junit.jupiter.params.provider.MethodSource;
57
58 import static java.util.Arrays.asList;
59 import static java.util.Collections.emptyList;
60 import static java.util.Collections.singletonList;
61 import static java.util.function.Function.identity;
62 import static java.util.stream.Collectors.toList;
63 import static org.apache.maven.execution.MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM;
64 import static org.apache.maven.execution.MavenExecutionRequest.REACTOR_MAKE_UPSTREAM;
65 import static org.apache.maven.graph.DefaultGraphBuilderTest.ScenarioBuilder.scenario;
66 import static org.assertj.core.api.Assertions.assertThat;
67 import static org.junit.jupiter.api.Assertions.assertEquals;
68 import static org.mockito.ArgumentMatchers.any;
69 import static org.mockito.ArgumentMatchers.anyBoolean;
70 import static org.mockito.ArgumentMatchers.anyList;
71 import static org.mockito.Mockito.mock;
72 import static org.mockito.Mockito.when;
73
74 class DefaultGraphBuilderTest {
75
76
77
78
79
80
81
82
83
84
85
86
87 private static final String GROUP_ID = "unittest";
88 private static final String PARENT_MODULE = "module-parent";
89 private static final String INDEPENDENT_MODULE = "module-independent";
90 private static final String MODULE_A = "module-a";
91 private static final String MODULE_B = "module-b";
92 private static final String MODULE_C = "module-c";
93 private static final String MODULE_D = "module-d";
94 private static final String MODULE_C_1 = "module-c-1";
95 private static final String MODULE_C_2 = "module-c-2";
96
97 private DefaultGraphBuilder graphBuilder;
98
99 private final ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
100 private final MavenSession session = mock(MavenSession.class);
101 private final MavenExecutionRequest mavenExecutionRequest = mock(MavenExecutionRequest.class);
102
103 private final ProjectsSelector projectsSelector = new DefaultProjectsSelector(projectBuilder);
104
105
106
107 private final ModelProcessor modelProcessor = new DefaultModelProcessor(null, List.of());
108 private final PomlessCollectionStrategy pomlessCollectionStrategy = new PomlessCollectionStrategy(projectBuilder);
109 private final MultiModuleCollectionStrategy multiModuleCollectionStrategy =
110 new MultiModuleCollectionStrategy(modelProcessor, projectsSelector);
111 private final RequestPomCollectionStrategy requestPomCollectionStrategy =
112 new RequestPomCollectionStrategy(projectsSelector);
113
114 private Map<String, MavenProject> artifactIdProjectMap;
115
116 public static Stream<Arguments> parameters() {
117 return Stream.of(
118 scenario("Full reactor in order")
119 .expectResult(
120 PARENT_MODULE,
121 MODULE_C,
122 MODULE_C_1,
123 MODULE_A,
124 MODULE_B,
125 MODULE_C_2,
126 INDEPENDENT_MODULE),
127 scenario("Selected project").activeRequiredProjects(MODULE_B).expectResult(MODULE_B),
128 scenario("Selected aggregator project (including child modules)")
129 .activeRequiredProjects(MODULE_C)
130 .expectResult(MODULE_C, MODULE_C_1, MODULE_C_2),
131 scenario("Selected aggregator project with non-recursive")
132 .activeRequiredProjects(MODULE_C)
133 .nonRecursive()
134 .expectResult(MODULE_C),
135 scenario("Selected optional project")
136 .activeOptionalProjects(MODULE_B)
137 .expectResult(MODULE_B),
138 scenario("Selected missing optional project")
139 .activeOptionalProjects("non-existing-module")
140 .expectResult(
141 PARENT_MODULE,
142 MODULE_C,
143 MODULE_C_1,
144 MODULE_A,
145 MODULE_B,
146 MODULE_C_2,
147 INDEPENDENT_MODULE),
148 scenario("Selected missing optional and required project")
149 .activeOptionalProjects("non-existing-module")
150 .activeRequiredProjects(MODULE_B)
151 .expectResult(MODULE_B),
152 scenario("Excluded project")
153 .inactiveRequiredProjects(MODULE_B)
154 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
155 scenario("Excluded optional project")
156 .inactiveOptionalProjects(MODULE_B)
157 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
158 scenario("Excluded missing optional project")
159 .inactiveOptionalProjects("non-existing-module")
160 .expectResult(
161 PARENT_MODULE,
162 MODULE_C,
163 MODULE_C_1,
164 MODULE_A,
165 MODULE_B,
166 MODULE_C_2,
167 INDEPENDENT_MODULE),
168 scenario("Excluded missing optional and required project")
169 .inactiveOptionalProjects("non-existing-module")
170 .inactiveRequiredProjects(MODULE_B)
171 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
172 scenario("Excluded aggregator project with non-recursive")
173 .inactiveRequiredProjects(MODULE_C)
174 .nonRecursive()
175 .expectResult(PARENT_MODULE, MODULE_C_1, MODULE_A, MODULE_B, MODULE_C_2, INDEPENDENT_MODULE),
176 scenario("Selected and excluded same project")
177 .activeRequiredProjects(MODULE_A)
178 .inactiveRequiredProjects(MODULE_A)
179 .expectResult(MavenExecutionException.class, "empty reactor"),
180 scenario("Excluded aggregator, but selected child")
181 .activeRequiredProjects(MODULE_C_1)
182 .inactiveRequiredProjects(MODULE_C)
183 .expectResult(MavenExecutionException.class, "empty reactor"),
184 scenario("Project selected with different selector resolves to same project")
185 .activeRequiredProjects(GROUP_ID + ":" + MODULE_A)
186 .inactiveRequiredProjects(MODULE_A)
187 .expectResult(MavenExecutionException.class, "empty reactor"),
188 scenario("Selected and excluded same project, but also selected another project")
189 .activeRequiredProjects(MODULE_A, MODULE_B)
190 .inactiveRequiredProjects(MODULE_A)
191 .expectResult(MODULE_B),
192 scenario("Selected missing project as required and as optional")
193 .activeRequiredProjects("non-existing-module")
194 .activeOptionalProjects("non-existing-module")
195 .expectResult(MavenExecutionException.class, "do not exist"),
196 scenario("Resuming from project")
197 .resumeFrom(MODULE_B)
198 .expectResult(MODULE_B, MODULE_C_2, INDEPENDENT_MODULE),
199 scenario("Selected project with also make dependencies")
200 .activeRequiredProjects(MODULE_C_2)
201 .makeBehavior(REACTOR_MAKE_UPSTREAM)
202 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_B, MODULE_C_2),
203 scenario("Selected project with also make dependents")
204 .activeRequiredProjects(MODULE_B)
205 .makeBehavior(REACTOR_MAKE_DOWNSTREAM)
206 .expectResult(MODULE_B, MODULE_C_2),
207 scenario("Resuming from project with also make dependencies")
208 .makeBehavior(REACTOR_MAKE_UPSTREAM)
209 .resumeFrom(MODULE_C_2)
210 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_B, MODULE_C_2, INDEPENDENT_MODULE),
211 scenario("Selected project with resume from and also make dependency (MNG-4960 IT#1)")
212 .activeRequiredProjects(MODULE_C_2)
213 .resumeFrom(MODULE_B)
214 .makeBehavior(REACTOR_MAKE_UPSTREAM)
215 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_B, MODULE_C_2),
216 scenario("Selected project with resume from and also make dependent (MNG-4960 IT#2)")
217 .activeRequiredProjects(MODULE_B)
218 .resumeFrom(MODULE_C_2)
219 .makeBehavior(REACTOR_MAKE_DOWNSTREAM)
220 .expectResult(MODULE_C_2),
221 scenario("Excluding an also make dependency from selectedProject does take its transitive dependency")
222 .activeRequiredProjects(MODULE_C_2)
223 .inactiveRequiredProjects(MODULE_B)
224 .makeBehavior(REACTOR_MAKE_UPSTREAM)
225 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_C_2),
226 scenario("Excluding a project also excludes its children")
227 .inactiveRequiredProjects(MODULE_C)
228 .expectResult(PARENT_MODULE, MODULE_A, MODULE_B, INDEPENDENT_MODULE),
229 scenario("Excluding an also make dependency from resumeFrom does take its transitive dependency")
230 .resumeFrom(MODULE_C_2)
231 .inactiveRequiredProjects(MODULE_B)
232 .makeBehavior(REACTOR_MAKE_UPSTREAM)
233 .expectResult(PARENT_MODULE, MODULE_C, MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
234 scenario("Resume from exclude project downstream")
235 .resumeFrom(MODULE_A)
236 .inactiveRequiredProjects(MODULE_B)
237 .expectResult(MODULE_A, MODULE_C_2, INDEPENDENT_MODULE),
238 scenario("Exclude the project we are resuming from (as proposed in MNG-6676)")
239 .resumeFrom(MODULE_B)
240 .inactiveRequiredProjects(MODULE_B)
241 .expectResult(MODULE_C_2, INDEPENDENT_MODULE),
242 scenario("Selected projects in wrong order are resumed correctly in order")
243 .activeRequiredProjects(MODULE_C_2, MODULE_B, MODULE_A)
244 .resumeFrom(MODULE_B)
245 .expectResult(MODULE_B, MODULE_C_2),
246 scenario("Duplicate projects are filtered out")
247 .activeRequiredProjects(MODULE_A, MODULE_A)
248 .expectResult(MODULE_A),
249 scenario("Select reactor by specific pom")
250 .requestedPom(MODULE_C)
251 .expectResult(MODULE_C, MODULE_C_1, MODULE_C_2),
252 scenario("Select reactor by specific pom with also make dependencies")
253 .requestedPom(MODULE_C)
254 .makeBehavior(REACTOR_MAKE_UPSTREAM)
255 .expectResult(PARENT_MODULE, MODULE_C, MODULE_C_1, MODULE_A, MODULE_B, MODULE_C_2),
256 scenario("Select reactor by specific pom with also make dependents")
257 .requestedPom(MODULE_B)
258 .makeBehavior(REACTOR_MAKE_DOWNSTREAM)
259 .expectResult(MODULE_B, MODULE_C_2));
260 }
261
262 interface ExpectedResult {}
263
264 static class SelectedProjectsResult implements ExpectedResult {
265 final List<String> projectNames;
266
267 SelectedProjectsResult(List<String> projectSelectors) {
268 this.projectNames = projectSelectors;
269 }
270 }
271
272 static class ExceptionThrown implements ExpectedResult {
273 final Class<? extends Throwable> expected;
274 final String partOfMessage;
275
276 ExceptionThrown(final Class<? extends Throwable> expected, final String partOfMessage) {
277 this.expected = expected;
278 this.partOfMessage = partOfMessage;
279 }
280 }
281
282 @ParameterizedTest
283 @MethodSource("parameters")
284 @SuppressWarnings("checkstyle:ParameterNumber")
285 void testGetReactorProjects(
286 String parameterDescription,
287 List<String> parameterActiveRequiredProjects,
288 List<String> parameterActiveOptionalProjects,
289 List<String> parameterInactiveRequiredProjects,
290 List<String> parameterInactiveOptionalProjects,
291 String parameterResumeFrom,
292 String parameterMakeBehavior,
293 ExpectedResult parameterExpectedResult,
294 File parameterRequestedPom,
295 boolean parameterRecursive) {
296
297 ProjectActivation projectActivation = new ProjectActivation();
298 parameterActiveRequiredProjects.forEach(projectActivation::activateRequiredProject);
299 parameterActiveOptionalProjects.forEach(projectActivation::activateOptionalProject);
300 parameterInactiveRequiredProjects.forEach(projectActivation::deactivateRequiredProject);
301 parameterInactiveOptionalProjects.forEach(projectActivation::deactivateOptionalProject);
302
303 when(mavenExecutionRequest.getRootDirectory()).thenReturn(Paths.get("."));
304 when(mavenExecutionRequest.getProjectActivation()).thenReturn(projectActivation);
305 when(mavenExecutionRequest.getMakeBehavior()).thenReturn(parameterMakeBehavior);
306 when(mavenExecutionRequest.getPom()).thenReturn(parameterRequestedPom);
307 when(mavenExecutionRequest.isRecursive()).thenReturn(parameterRecursive);
308 if (parameterResumeFrom != null && !parameterResumeFrom.isEmpty()) {
309 when(mavenExecutionRequest.getResumeFrom()).thenReturn(":" + parameterResumeFrom);
310 }
311
312
313 Result<ProjectDependencyGraph> result = graphBuilder.build(session);
314
315
316 if (parameterExpectedResult instanceof SelectedProjectsResult selectedProjectsResult) {
317 assertThat(result.hasErrors())
318 .withFailMessage("Expected result not to have errors")
319 .isFalse();
320 List<String> expectedProjectNames = selectedProjectsResult.projectNames;
321 List<MavenProject> actualReactorProjects = result.get().getSortedProjects();
322 List<MavenProject> expectedReactorProjects =
323 expectedProjectNames.stream().map(artifactIdProjectMap::get).collect(toList());
324 assertEquals(expectedReactorProjects, actualReactorProjects, parameterDescription);
325 } else {
326 assertThat(result.hasErrors())
327 .withFailMessage("Expected result to have errors")
328 .isTrue();
329 Class<? extends Throwable> expectedException = ((ExceptionThrown) parameterExpectedResult).expected;
330 String partOfMessage = ((ExceptionThrown) parameterExpectedResult).partOfMessage;
331
332 assertThat(result.getProblems()).hasSize(1);
333 result.getProblems().forEach(p -> assertThat(p.getException())
334 .isInstanceOf(expectedException)
335 .hasMessageContaining(partOfMessage));
336 }
337 }
338
339 @Test
340 void testProcessPackagingAttribute() throws ProjectBuildingException {
341 graphBuilder = new DefaultGraphBuilder(
342 mock(BuildResumptionDataRepository.class),
343 pomlessCollectionStrategy,
344 multiModuleCollectionStrategy,
345 requestPomCollectionStrategy);
346
347
348 MavenProject projectParent = getMavenProject(PARENT_MODULE);
349 MavenProject projectModuleD = getMavenProject(MODULE_D, projectParent, "bom");
350
351 projectParent.setCollectedProjects(singletonList(projectModuleD));
352
353
354 when(session.getRequest()).thenReturn(mavenExecutionRequest);
355 when(session.getProjects()).thenReturn(null);
356 when(mavenExecutionRequest.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
357 List<ProjectBuildingResult> projectBuildingResults =
358 createProjectBuildingResultMocks(Stream.of(projectParent, projectModuleD)
359 .collect(Collectors.toMap(MavenProject::getArtifactId, identity()))
360 .values());
361 when(projectBuilder.build(anyList(), anyBoolean(), any(ProjectBuildingRequest.class)))
362 .thenReturn(projectBuildingResults);
363
364 ProjectActivation projectActivation = new ProjectActivation();
365
366 when(mavenExecutionRequest.getProjectActivation()).thenReturn(projectActivation);
367 when(mavenExecutionRequest.getPom()).thenReturn(new File(PARENT_MODULE, "pom.xml"));
368
369 Result<ProjectDependencyGraph> result = graphBuilder.build(session);
370
371 assertThat(result.hasErrors())
372 .withFailMessage("Expected result not to have errors")
373 .isFalse();
374 List<MavenProject> actualReactorProjects = result.get().getSortedProjects();
375 assertEquals(2, actualReactorProjects.size());
376 assertEquals("pom", actualReactorProjects.get(1).getPackaging());
377 }
378
379 @BeforeEach
380 void before() throws Exception {
381 graphBuilder = new DefaultGraphBuilder(
382 mock(BuildResumptionDataRepository.class),
383 pomlessCollectionStrategy,
384 multiModuleCollectionStrategy,
385 requestPomCollectionStrategy);
386
387
388 MavenProject projectParent = getMavenProject(PARENT_MODULE);
389 MavenProject projectIndependentModule = getMavenProject(INDEPENDENT_MODULE);
390 MavenProject projectModuleA = getMavenProject(MODULE_A, projectParent);
391 MavenProject projectModuleB = getMavenProject(MODULE_B, projectParent);
392 MavenProject projectModuleC = getMavenProject(MODULE_C, projectParent);
393 MavenProject projectModuleC1 = getMavenProject(MODULE_C_1, projectModuleC);
394 MavenProject projectModuleC2 = getMavenProject(MODULE_C_2, projectModuleC);
395
396 artifactIdProjectMap = Stream.of(
397 projectParent,
398 projectIndependentModule,
399 projectModuleA,
400 projectModuleB,
401 projectModuleC,
402 projectModuleC1,
403 projectModuleC2)
404 .collect(Collectors.toMap(MavenProject::getArtifactId, identity()));
405
406
407 projectModuleB.setDependencies(singletonList(toDependency(projectModuleA)));
408 projectModuleC2.setDependencies(singletonList(toDependency(projectModuleB)));
409 projectParent.setCollectedProjects(asList(
410 projectIndependentModule,
411 projectModuleA,
412 projectModuleB,
413 projectModuleC,
414 projectModuleC1,
415 projectModuleC2));
416 projectModuleC.setCollectedProjects(asList(projectModuleC1, projectModuleC2));
417
418
419 when(session.getRequest()).thenReturn(mavenExecutionRequest);
420 when(session.getProjects()).thenReturn(null);
421 when(mavenExecutionRequest.getProjectBuildingRequest()).thenReturn(mock(ProjectBuildingRequest.class));
422 List<ProjectBuildingResult> projectBuildingResults =
423 createProjectBuildingResultMocks(artifactIdProjectMap.values());
424 when(projectBuilder.build(anyList(), anyBoolean(), any(ProjectBuildingRequest.class)))
425 .thenReturn(projectBuildingResults);
426 when(mavenExecutionRequest.getRootDirectory()).thenReturn(null);
427 }
428
429 private MavenProject getMavenProject(String artifactId, MavenProject parentProject) {
430 MavenProject project = getMavenProject(artifactId);
431 Parent parent = new Parent();
432 parent.setGroupId(parentProject.getGroupId());
433 parent.setArtifactId(parentProject.getArtifactId());
434 project.getModel().setParent(parent);
435 return project;
436 }
437
438 private MavenProject getMavenProject(String artifactId) {
439 MavenProject mavenProject = new MavenProject();
440 mavenProject.setGroupId(GROUP_ID);
441 mavenProject.setArtifactId(artifactId);
442 mavenProject.setVersion("1.0");
443 mavenProject.setPomFile(new File(artifactId, "pom.xml"));
444 mavenProject.setCollectedProjects(new ArrayList<>());
445 return mavenProject;
446 }
447
448 private MavenProject getMavenProject(String artifactId, MavenProject parentProject, String packaging) {
449 MavenProject project = getMavenProject(artifactId);
450 Parent parent = new Parent();
451 parent.setGroupId(parentProject.getGroupId());
452 parent.setArtifactId(parentProject.getArtifactId());
453 project.getModel().setParent(parent);
454 project.setPackaging(packaging);
455 return project;
456 }
457
458 private Dependency toDependency(MavenProject mavenProject) {
459 Dependency dependency = new Dependency();
460 dependency.setGroupId(mavenProject.getGroupId());
461 dependency.setArtifactId(mavenProject.getArtifactId());
462 dependency.setVersion(mavenProject.getVersion());
463 return dependency;
464 }
465
466 private List<ProjectBuildingResult> createProjectBuildingResultMocks(Collection<MavenProject> projects) {
467 return projects.stream()
468 .map(project -> {
469 ProjectBuildingResult result = mock(ProjectBuildingResult.class);
470 when(result.getProject()).thenReturn(project);
471 return result;
472 })
473 .collect(toList());
474 }
475
476 static class ScenarioBuilder {
477 private String description;
478 private List<String> activeRequiredProjects = emptyList();
479 private List<String> activeOptionalProjects = emptyList();
480 private List<String> inactiveRequiredProjects = emptyList();
481 private List<String> inactiveOptionalProjects = emptyList();
482 private String resumeFrom = "";
483 private String makeBehavior = "";
484 private File requestedPom = new File(PARENT_MODULE, "pom.xml");
485 private boolean recursive = true;
486
487 private ScenarioBuilder() {}
488
489 public static ScenarioBuilder scenario(String description) {
490 ScenarioBuilder scenarioBuilder = new ScenarioBuilder();
491 scenarioBuilder.description = description;
492 return scenarioBuilder;
493 }
494
495 public ScenarioBuilder activeRequiredProjects(String... activeRequiredProjects) {
496 this.activeRequiredProjects = prependWithColonIfNeeded(activeRequiredProjects);
497 return this;
498 }
499
500 public ScenarioBuilder activeOptionalProjects(String... activeOptionalProjects) {
501 this.activeOptionalProjects = prependWithColonIfNeeded(activeOptionalProjects);
502 return this;
503 }
504
505 public ScenarioBuilder inactiveRequiredProjects(String... inactiveRequiredProjects) {
506 this.inactiveRequiredProjects = prependWithColonIfNeeded(inactiveRequiredProjects);
507 return this;
508 }
509
510 public ScenarioBuilder inactiveOptionalProjects(String... inactiveOptionalProjects) {
511 this.inactiveOptionalProjects = prependWithColonIfNeeded(inactiveOptionalProjects);
512 return this;
513 }
514
515 public ScenarioBuilder resumeFrom(String resumeFrom) {
516 this.resumeFrom = resumeFrom;
517 return this;
518 }
519
520 public ScenarioBuilder makeBehavior(String makeBehavior) {
521 this.makeBehavior = makeBehavior;
522 return this;
523 }
524
525 public ScenarioBuilder requestedPom(String requestedPom) {
526 this.requestedPom = new File(requestedPom, "pom.xml");
527 return this;
528 }
529
530 public ScenarioBuilder nonRecursive() {
531 this.recursive = false;
532 return this;
533 }
534
535 public Arguments expectResult(String... expectedReactorProjects) {
536 ExpectedResult expectedResult = new SelectedProjectsResult(asList(expectedReactorProjects));
537 return createTestArguments(expectedResult);
538 }
539
540 public Arguments expectResult(Class<? extends Exception> expected, final String partOfMessage) {
541 ExpectedResult expectedResult = new ExceptionThrown(expected, partOfMessage);
542 return createTestArguments(expectedResult);
543 }
544
545 private Arguments createTestArguments(ExpectedResult expectedResult) {
546 return Arguments.arguments(
547 description,
548 activeRequiredProjects,
549 activeOptionalProjects,
550 inactiveRequiredProjects,
551 inactiveOptionalProjects,
552 resumeFrom,
553 makeBehavior,
554 expectedResult,
555 requestedPom,
556 recursive);
557 }
558
559 private List<String> prependWithColonIfNeeded(String[] selectors) {
560 return Arrays.stream(selectors).map(this::prependWithColonIfNeeded).collect(toList());
561 }
562
563 private String prependWithColonIfNeeded(String selector) {
564 return selector.indexOf(':') == -1 ? ":" + selector : selector;
565 }
566 }
567 }