3 * Copyright (C) 2009-2019 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.ce.task.projectanalysis.component;
22 import java.util.Arrays;
23 import java.util.EnumSet;
24 import java.util.HashMap;
25 import java.util.List;
27 import java.util.Objects;
28 import java.util.Optional;
29 import java.util.Random;
30 import java.util.function.Function;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.junit.rules.ExpectedException;
34 import org.junit.rules.ExternalResource;
35 import org.sonar.ce.task.projectanalysis.analysis.Branch;
36 import org.sonar.core.component.ComponentKeys;
37 import org.sonar.scanner.protocol.output.ScannerReport;
38 import org.sonar.server.project.Project;
40 import static com.google.common.base.Preconditions.checkArgument;
41 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.junit.Assert.fail;
44 import static org.mockito.Mockito.mock;
45 import static org.mockito.Mockito.when;
46 import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
47 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
48 import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
49 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.DIRECTORY;
50 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.FILE;
51 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.MODULE;
52 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.PROJECT;
53 import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNRECOGNIZED;
54 import static org.sonar.scanner.protocol.output.ScannerReport.Component.newBuilder;
56 public class ComponentTreeBuilderTest {
58 private static final ComponentKeyGenerator KEY_GENERATOR = (projectKey, path) -> "generated_"
59 + ComponentKeys.createEffectiveKey(projectKey, path);
60 private static final ComponentKeyGenerator PUBLIC_KEY_GENERATOR = (projectKey, path) -> "public_"
61 + ComponentKeys.createEffectiveKey(projectKey, path);
62 private static final Function<String, String> UUID_SUPPLIER = (componentKey) -> componentKey + "_uuid";
63 private static final EnumSet<ScannerReport.Component.ComponentType> REPORT_TYPES = EnumSet.of(PROJECT, FILE);
64 private static final String NO_SCM_BASE_PATH = "";
65 // both no project as "" or null should be supported
66 private static final ProjectAttributes SOME_PROJECT_ATTRIBUTES = new ProjectAttributes(
67 randomAlphabetic(20), new Random().nextBoolean() ? null : randomAlphabetic(12));
70 public ExpectedException expectedException = ExpectedException.none();
73 public ScannerComponentProvider scannerComponentProvider = new ScannerComponentProvider();
75 private Project projectInDb = Project.from(newPrivateProjectDto(newOrganizationDto(), UUID_SUPPLIER.apply("K1")).setDbKey("K1").setDescription(null));
78 public void build_throws_IAE_for_all_types_except_PROJECT_and_FILE() {
79 Arrays.stream(ScannerReport.Component.ComponentType.values())
80 .filter((type) -> type != UNRECOGNIZED)
81 .filter((type) -> !REPORT_TYPES.contains(type))
84 scannerComponentProvider.clear();
85 ScannerReport.Component project = newBuilder()
87 .setKey(projectInDb.getKey())
90 .setProjectRelativePath("root")
92 scannerComponentProvider.add(newBuilder()
95 .setProjectRelativePath("src")
98 call(project, NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
99 fail("Should have thrown a IllegalArgumentException");
100 } catch (IllegalArgumentException e) {
101 assertThat(e).hasMessage("Unsupported component type '" + type + "'");
107 public void build_throws_IAE_if_root_is_not_PROJECT() {
108 Arrays.stream(ScannerReport.Component.ComponentType.values())
109 .filter((type) -> type != UNRECOGNIZED)
110 .filter((type) -> !REPORT_TYPES.contains(type))
113 ScannerReport.Component component = newBuilder().setType(type).build();
116 fail("Should have thrown a IllegalArgumentException");
117 } catch (IllegalArgumentException e) {
118 assertThat(e).hasMessage("Expected root component of type 'PROJECT'");
124 public void by_default_project_fields_are_loaded_from_report() {
125 String nameInReport = "the name";
126 String descriptionInReport = "the desc";
127 String buildString = randomAlphabetic(21);
128 Component root = call(newBuilder()
130 .setKey(projectInDb.getKey())
132 .setName(nameInReport)
133 .setDescription(descriptionInReport)
134 .build(), NO_SCM_BASE_PATH, new ProjectAttributes("6.5", buildString));
136 assertThat(root.getUuid()).isEqualTo("generated_K1_uuid");
137 assertThat(root.getDbKey()).isEqualTo("generated_K1");
138 assertThat(root.getKey()).isEqualTo("public_K1");
139 assertThat(root.getType()).isEqualTo(Component.Type.PROJECT);
140 assertThat(root.getName()).isEqualTo(nameInReport);
141 assertThat(root.getShortName()).isEqualTo(nameInReport);
142 assertThat(root.getDescription()).isEqualTo(descriptionInReport);
143 assertThat(root.getReportAttributes().getRef()).isEqualTo(42);
144 assertThat(root.getProjectAttributes().getProjectVersion()).contains("6.5");
145 assertThat(root.getProjectAttributes().getBuildString()).isEqualTo(Optional.of(buildString));
146 assertThatFileAttributesAreNotSet(root);
150 public void project_name_is_loaded_from_db_if_absent_from_report() {
151 Component root = call(newBuilder()
153 .build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
155 assertThat(root.getName()).isEqualTo(projectInDb.getName());
159 public void project_name_is_loaded_from_report_if_present_and_on_main_branch() {
160 String reportName = randomAlphabetic(5);
161 ScannerReport.Component reportProject = newBuilder()
166 Component root = newUnderTest(SOME_PROJECT_ATTRIBUTES, true).buildProject(reportProject, NO_SCM_BASE_PATH);
168 assertThat(root.getName()).isEqualTo(reportName);
172 public void project_name_is_loaded_from_db_if_not_on_main_branch() {
173 String reportName = randomAlphabetic(5);
174 ScannerReport.Component reportProject = newBuilder()
179 Component root = newUnderTest(SOME_PROJECT_ATTRIBUTES, false)
180 .buildProject(reportProject, NO_SCM_BASE_PATH);
182 assertThat(root.getName()).isEqualTo(projectInDb.getName());
186 public void project_description_is_loaded_from_db_if_absent_from_report() {
187 Component root = call(newBuilder()
189 .build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
191 assertThat(root.getDescription()).isEqualTo(projectInDb.getDescription());
195 public void project_description_is_loaded_from_report_if_present_and_on_main_branch() {
196 String reportDescription = randomAlphabetic(5);
197 ScannerReport.Component reportProject = newBuilder()
199 .setDescription(reportDescription)
202 Component root = newUnderTest(SOME_PROJECT_ATTRIBUTES, true).buildProject(reportProject, NO_SCM_BASE_PATH);
204 assertThat(root.getDescription()).isEqualTo(reportDescription);
208 public void project_description_is_loaded_from_db_if_not_on_main_branch() {
209 String reportDescription = randomAlphabetic(5);
210 ScannerReport.Component reportProject = newBuilder()
212 .setDescription(reportDescription)
215 Component root = newUnderTest(SOME_PROJECT_ATTRIBUTES, false).buildProject(reportProject, NO_SCM_BASE_PATH);
217 assertThat(root.getDescription()).isEqualTo(projectInDb.getDescription());
221 public void project_scmPath_is_empty_if_scmBasePath_is_empty() {
222 Component root = call(newBuilder()
224 .build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
226 assertThat(root.getReportAttributes().getScmPath()).isEmpty();
230 public void projectAttributes_is_constructor_argument() {
231 Component root = call(newBuilder()
233 .build(), NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
235 assertThat(root.getProjectAttributes()).isSameAs(SOME_PROJECT_ATTRIBUTES);
239 public void any_component_with_projectRelativePath_has_this_value_as_scmPath_if_scmBasePath_is_empty() {
240 ScannerReport.Component project = newBuilder()
242 .setKey(projectInDb.getKey())
245 .setProjectRelativePath("root")
247 scannerComponentProvider.add(newBuilder()
250 .setProjectRelativePath("src/js/Foo.js")
253 Component root = call(project, NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
255 assertThat(root.getReportAttributes().getScmPath())
257 Component directory = root.getChildren().iterator().next();
258 assertThat(directory.getReportAttributes().getScmPath())
260 Component file = directory.getChildren().iterator().next();
261 assertThat(file.getReportAttributes().getScmPath())
262 .contains("src/js/Foo.js");
266 public void any_component_with_projectRelativePath_has_this_value_appended_to_scmBasePath_and_a_slash_as_scmPath_if_scmBasePath_is_not_empty() {
267 ScannerReport.Component project = createProject();
268 String scmBasePath = randomAlphabetic(10);
270 Component root = call(project, scmBasePath, SOME_PROJECT_ATTRIBUTES);
271 assertThat(root.getReportAttributes().getScmPath())
272 .contains(scmBasePath);
273 Component directory = root.getChildren().iterator().next();
274 assertThat(directory.getReportAttributes().getScmPath())
275 .contains(scmBasePath + "/src/js");
276 Component file = directory.getChildren().iterator().next();
277 assertThat(file.getReportAttributes().getScmPath())
278 .contains(scmBasePath + "/src/js/Foo.js");
281 private ScannerReport.Component createProject() {
282 ScannerReport.Component project = newBuilder()
284 .setKey(projectInDb.getKey())
288 scannerComponentProvider.add(newBuilder()
291 .setProjectRelativePath("src/js/Foo.js")
297 public void keys_of_directory_and_file_are_generated() {
298 ScannerReport.Component project = createProject();
300 Component root = call(project);
301 assertThat(root.getDbKey()).isEqualTo("generated_" + projectInDb.getKey());
302 assertThat(root.getKey()).isEqualTo("public_" + projectInDb.getKey());
303 assertThat(root.getChildren()).hasSize(1);
305 Component directory = root.getChildren().iterator().next();
306 assertThat(directory.getDbKey()).isEqualTo("generated_" + projectInDb.getKey() + ":src/js");
307 assertThat(directory.getKey()).isEqualTo("public_" + projectInDb.getKey() + ":src/js");
308 assertThat(directory.getChildren()).hasSize(1);
310 Component file = directory.getChildren().iterator().next();
311 assertThat(file.getDbKey()).isEqualTo("generated_" + projectInDb.getKey() + ":src/js/Foo.js");
312 assertThat(file.getKey()).isEqualTo("public_" + projectInDb.getKey() + ":src/js/Foo.js");
313 assertThat(file.getChildren()).isEmpty();
317 public void modules_are_not_created() {
318 ScannerReport.Component project = newBuilder()
320 .setKey(projectInDb.getKey())
324 scannerComponentProvider.add(newBuilder()
327 .setProjectRelativePath("src/js/Foo.js")
330 Component root = call(project);
332 List<Component> components = root.getChildren();
333 assertThat(components).extracting("type").containsOnly(Component.Type.DIRECTORY);
337 public void folder_hierarchy_is_created() {
338 ScannerReport.Component project = newBuilder()
340 .setKey(projectInDb.getKey())
346 scannerComponentProvider.add(newBuilder()
349 .setProjectRelativePath("src/main/xoo/Foo1.js")
351 scannerComponentProvider.add(newBuilder()
354 .setProjectRelativePath("src/test/xoo/org/sonar/Foo2.js")
356 scannerComponentProvider.add(newBuilder()
359 .setProjectRelativePath("pom.xml")
362 Component root = call(project);
363 assertThat(root.getChildren()).hasSize(2);
365 Component pom = root.getChildren().get(1);
366 assertThat(pom.getKey()).isEqualTo("public_K1:pom.xml");
367 assertThat(pom.getName()).isEqualTo("pom.xml");
369 Component directory = root.getChildren().get(0);
370 assertThat(directory.getKey()).isEqualTo("public_K1:src");
371 assertThat(directory.getName()).isEqualTo("src");
373 // folders are collapsed and they only contain one directory
374 Component d1 = directory.getChildren().get(0);
375 assertThat(d1.getKey()).isEqualTo("public_K1:src/main/xoo");
376 assertThat(d1.getName()).isEqualTo("src/main/xoo");
377 assertThat(d1.getShortName()).isEqualTo("main/xoo");
379 Component d2 = directory.getChildren().get(1);
380 assertThat(d2.getKey()).isEqualTo("public_K1:src/test/xoo/org/sonar");
381 assertThat(d2.getName()).isEqualTo("src/test/xoo/org/sonar");
382 assertThat(d2.getShortName()).isEqualTo("test/xoo/org/sonar");
386 public void collapse_directories_from_root() {
387 ScannerReport.Component project = newBuilder()
389 .setKey(projectInDb.getKey())
393 scannerComponentProvider.add(newBuilder()
396 .setProjectRelativePath("src/test/xoo/org/sonar/Foo2.js")
399 Component root = call(project);
401 // folders are collapsed and they only contain one directory
402 Component dir = root.getChildren().get(0);
403 assertThat(dir.getKey()).isEqualTo("public_K1:src/test/xoo/org/sonar");
404 assertThat(dir.getName()).isEqualTo("src/test/xoo/org/sonar");
405 assertThat(dir.getShortName()).isEqualTo("src/test/xoo/org/sonar");
407 Component file = dir.getChildren().get(0);
408 assertThat(file.getKey()).isEqualTo("public_K1:src/test/xoo/org/sonar/Foo2.js");
409 assertThat(file.getName()).isEqualTo("src/test/xoo/org/sonar/Foo2.js");
410 assertThat(file.getShortName()).isEqualTo("Foo2.js");
414 public void directories_are_collapsed() {
415 ScannerReport.Component project = newBuilder()
417 .setKey(projectInDb.getKey())
421 scannerComponentProvider.add(newBuilder()
424 .setProjectRelativePath("src/js/Foo.js")
427 Component root = call(project);
429 Component directory = root.getChildren().iterator().next();
430 assertThat(directory.getKey()).isEqualTo("public_K1:src/js");
431 assertThat(directory.getName()).isEqualTo("src/js");
432 assertThat(directory.getShortName()).isEqualTo("src/js");
434 Component file = directory.getChildren().iterator().next();
435 assertThat(file.getKey()).isEqualTo("public_K1:src/js/Foo.js");
436 assertThat(file.getName()).isEqualTo("src/js/Foo.js");
437 assertThat(file.getShortName()).isEqualTo("Foo.js");
441 public void names_of_directory_and_file_are_based_on_the_path() {
442 ScannerReport.Component project = newBuilder()
444 .setKey(projectInDb.getKey())
448 scannerComponentProvider.add(newBuilder()
451 .setProjectRelativePath("src/js/Foo.js")
455 Component root = call(project);
457 Component directory = root.getChildren().iterator().next();
458 assertThat(directory.getName()).isEqualTo("src/js");
459 assertThat(directory.getShortName()).isEqualTo("src/js");
461 Component file = directory.getChildren().iterator().next();
462 assertThat(file.getName()).isEqualTo("src/js/Foo.js");
463 assertThat(file.getShortName()).isEqualTo("Foo.js");
467 public void create_full_hierarchy_of_directories() {
468 ScannerReport.Component project = newBuilder()
470 .setKey(projectInDb.getKey())
475 scannerComponentProvider.add(newBuilder()
478 .setProjectRelativePath("src/java/Bar.java")
481 scannerComponentProvider.add(newBuilder()
484 .setProjectRelativePath("src/js/Foo.js")
488 Component root = call(project);
490 Component directory = root.getChildren().iterator().next();
491 assertThat(directory.getKey()).isEqualTo("public_K1:src");
492 assertThat(directory.getName()).isEqualTo("src");
493 assertThat(directory.getShortName()).isEqualTo("src");
495 Component directoryJava = directory.getChildren().get(0);
496 assertThat(directoryJava.getKey()).isEqualTo("public_K1:src/java");
497 assertThat(directoryJava.getName()).isEqualTo("src/java");
498 assertThat(directoryJava.getShortName()).isEqualTo("java");
500 Component directoryJs = directory.getChildren().get(1);
501 assertThat(directoryJs.getKey()).isEqualTo("public_K1:src/js");
502 assertThat(directoryJs.getName()).isEqualTo("src/js");
503 assertThat(directoryJs.getShortName()).isEqualTo("js");
505 Component file = directoryJs.getChildren().iterator().next();
506 assertThat(file.getKey()).isEqualTo("public_K1:src/js/Foo.js");
507 assertThat(file.getName()).isEqualTo("src/js/Foo.js");
508 assertThat(file.getShortName()).isEqualTo("Foo.js");
511 private void assertThatFileAttributesAreNotSet(Component root) {
513 root.getFileAttributes();
515 } catch (IllegalStateException e) {
516 assertThat(e).hasMessage("Only component of type FILE have a FileAttributes object");
521 public void keys_of_directory_and_files_includes_always_root_project() {
522 ScannerReport.Component project = newBuilder()
526 .addChildRef(31).build();
527 scannerComponentProvider.add(newBuilder().setRef(31).setType(FILE).setProjectRelativePath("file in project").setLines(1));
528 Component root = call(project);
529 Map<String, Component> componentsByKey = indexComponentByKey(root);
531 assertThat(componentsByKey.values()).extracting("key").startsWith("public_project 1");
532 assertThat(componentsByKey.values()).extracting("dbKey").startsWith("generated_project 1");
536 public void uuids_are_provided_by_supplier() {
537 ScannerReport.Component project = newBuilder()
543 scannerComponentProvider.add(newBuilder()
546 .setProjectRelativePath("src/js/Foo.js")
549 Component root = call(project);
550 assertThat(root.getUuid()).isEqualTo("generated_c1_uuid");
552 Component directory = root.getChildren().iterator().next();
553 assertThat(directory.getUuid()).isEqualTo("generated_c1:src/js_uuid");
555 Component file = directory.getChildren().iterator().next();
556 assertThat(file.getUuid()).isEqualTo("generated_c1:src/js/Foo.js_uuid");
560 public void issues_are_relocated_from_directories_and_modules_to_root() {
561 ScannerReport.Component project = newBuilder()
567 ScannerReport.Component.Builder file = newBuilder()
570 .setProjectRelativePath("src/js/Foo.js")
572 scannerComponentProvider.add(file);
578 public void descriptions_of_module_directory_and_file_are_null_if_absent_from_report() {
579 ScannerReport.Component project = newBuilder()
584 scannerComponentProvider.add(newBuilder()
587 .setProjectRelativePath("src/js/Foo.js")
590 Component root = call(project);
592 Component directory = root.getChildren().iterator().next();
593 assertThat(directory.getDescription()).isNull();
595 Component file = directory.getChildren().iterator().next();
596 assertThat(file.getDescription()).isNull();
600 public void descriptions_of_module_directory_and_file_are_null_if_empty_in_report() {
601 ScannerReport.Component project = newBuilder()
607 scannerComponentProvider.add(newBuilder()
611 .setProjectRelativePath("src/js/Foo.js")
614 Component root = call(project);
616 Component directory = root.getChildren().iterator().next();
617 assertThat(directory.getDescription()).isNull();
619 Component file = directory.getChildren().iterator().next();
620 assertThat(file.getDescription()).isNull();
624 public void descriptions_of_module_directory_and_file_are_set_from_report_if_present() {
625 ScannerReport.Component project = newBuilder()
630 scannerComponentProvider.add(newBuilder()
634 .setProjectRelativePath("src/js/Foo.js")
637 Component root = call(project);
638 Component directory = root.getChildren().iterator().next();
639 assertThat(directory.getDescription()).isNull();
641 Component file = directory.getChildren().iterator().next();
642 assertThat(file.getDescription()).isEqualTo("d");
646 public void only_nb_of_lines_is_mandatory_on_file_attributes() {
647 ScannerReport.Component project = newBuilder()
652 scannerComponentProvider.add(newBuilder()
655 .setProjectRelativePath("src/js/Foo.js")
658 Component root = call(project);
659 Component dir = root.getChildren().iterator().next();
660 Component file = dir.getChildren().iterator().next();
661 assertThat(file.getFileAttributes().getLines()).isEqualTo(1);
662 assertThat(file.getFileAttributes().getLanguageKey()).isNull();
663 assertThat(file.getFileAttributes().isUnitTest()).isFalse();
667 public void language_file_attributes_is_null_if_empty_in_report() {
668 ScannerReport.Component project = newBuilder()
673 scannerComponentProvider.add(newBuilder()
676 .setProjectRelativePath("src/js/Foo.js")
680 Component root = call(project);
681 Component dir2 = root.getChildren().iterator().next();
683 Component file = dir2.getChildren().iterator().next();
684 assertThat(file.getFileAttributes().getLanguageKey()).isNull();
688 public void file_attributes_are_fully_loaded_from_report() {
689 ScannerReport.Component project = newBuilder()
694 scannerComponentProvider.add(newBuilder()
697 .setProjectRelativePath("src/js/Foo.js")
702 Component root = call(project);
703 Component dir = root.getChildren().iterator().next();
704 Component file = dir.getChildren().iterator().next();
705 assertThat(file.getFileAttributes().getLines()).isEqualTo(1);
706 assertThat(file.getFileAttributes().getLanguageKey()).isEqualTo("js");
707 assertThat(file.getFileAttributes().isUnitTest()).isTrue();
711 public void throw_IAE_if_lines_is_absent_from_report() {
712 ScannerReport.Component project = newBuilder()
717 scannerComponentProvider.add(newBuilder()
720 .setProjectRelativePath("src/js/Foo.js"));
722 expectedException.expect(IllegalArgumentException.class);
723 expectedException.expectMessage("File 'src/js/Foo.js' has no line");
729 public void throw_IAE_if_lines_is_zero_in_report() {
730 ScannerReport.Component project = newBuilder()
735 scannerComponentProvider.add(newBuilder()
738 .setProjectRelativePath("src/js/Foo.js")
741 expectedException.expect(IllegalArgumentException.class);
742 expectedException.expectMessage("File 'src/js/Foo.js' has no line");
748 public void throw_IAE_if_lines_is_negative_in_report() {
749 ScannerReport.Component project = newBuilder()
754 scannerComponentProvider.add(newBuilder()
757 .setProjectRelativePath("src/js/Foo.js")
760 expectedException.expect(IllegalArgumentException.class);
761 expectedException.expectMessage("File 'src/js/Foo.js' has no line");
766 private static class ScannerComponentProvider extends ExternalResource implements Function<Integer, ScannerReport.Component> {
767 private final Map<Integer, ScannerReport.Component> components = new HashMap<>();
770 protected void before() {
774 public void clear() {
779 public ScannerReport.Component apply(Integer componentRef) {
780 return Objects.requireNonNull(components.get(componentRef), "No Component for componentRef " + componentRef);
783 public ScannerReport.Component add(ScannerReport.Component.Builder builder) {
784 ScannerReport.Component component = builder.build();
785 ScannerReport.Component existing = components.put(component.getRef(), component);
786 checkArgument(existing == null, "Component %s already set for ref %s", existing, component.getRef());
791 private Component call(ScannerReport.Component project) {
792 return call(project, NO_SCM_BASE_PATH, SOME_PROJECT_ATTRIBUTES);
795 private Component call(ScannerReport.Component project, String scmBasePath, ProjectAttributes projectAttributes) {
796 return newUnderTest(projectAttributes, true).buildProject(project, scmBasePath);
799 private ComponentTreeBuilder newUnderTest(ProjectAttributes projectAttributes, boolean mainBranch) {
800 Branch branch = mock(Branch.class);
801 when(branch.isMain()).thenReturn(mainBranch);
802 return new ComponentTreeBuilder(KEY_GENERATOR, PUBLIC_KEY_GENERATOR, UUID_SUPPLIER, scannerComponentProvider,
803 projectInDb, branch, projectAttributes);
806 private static Map<String, Component> indexComponentByKey(Component root) {
807 Map<String, Component> componentsByKey = new HashMap<>();
808 new DepthTraversalTypeAwareCrawler(
809 new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, PRE_ORDER) {
811 public void visitAny(Component any) {
812 componentsByKey.put(any.getDbKey(), any);
815 return componentsByKey;