2 * SonarQube, open source software quality management tool.
3 * Copyright (C) 2008-2014 SonarSource
4 * mailto:contact AT sonarsource DOT com
6 * SonarQube 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 * SonarQube 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.server.computation.step;
22 import java.util.Arrays;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.rules.ExpectedException;
26 import org.sonar.batch.protocol.output.BatchReport;
27 import org.sonar.server.computation.batch.BatchReportReaderRule;
28 import org.sonar.server.computation.batch.TreeRootHolderRule;
29 import org.sonar.server.computation.component.Component;
30 import org.sonar.server.computation.component.VisitException;
31 import org.sonar.server.computation.duplication.DetailedTextBlock;
32 import org.sonar.server.computation.duplication.Duplicate;
33 import org.sonar.server.computation.duplication.Duplication;
34 import org.sonar.server.computation.duplication.DuplicationRepositoryRule;
35 import org.sonar.server.computation.duplication.InProjectDuplicate;
36 import org.sonar.server.computation.duplication.InnerDuplicate;
37 import org.sonar.server.computation.duplication.TextBlock;
39 import static org.assertj.core.api.Assertions.assertThat;
40 import static org.sonar.server.computation.component.Component.Type.FILE;
41 import static org.sonar.server.computation.component.Component.Type.PROJECT;
42 import static org.sonar.server.computation.component.ReportComponent.builder;
43 import static org.sonar.test.ExceptionCauseMatcher.hasType;
45 public class LoadDuplicationsFromReportStepTest {
46 private static final int LINE = 2;
47 private static final int OTHER_LINE = 300;
48 private static final int ROOT_REF = 1;
49 private static final int FILE_1_REF = 11;
50 private static final int FILE_2_REF = 12;
53 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(
54 builder(PROJECT, ROOT_REF)
56 builder(FILE, FILE_1_REF).build(),
57 builder(FILE, FILE_2_REF).build()
62 public BatchReportReaderRule reportReader = new BatchReportReaderRule();
64 public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
66 public ExpectedException expectedException = ExpectedException.none();
68 private LoadDuplicationsFromReportStep underTest = new LoadDuplicationsFromReportStep(treeRootHolder, reportReader, duplicationRepository);
71 public void verify_description() {
72 assertThat(underTest.getDescription()).isEqualTo("Load inner file and in project duplications");
76 public void loads_no_duplications_if_reader_has_no_duplication() {
79 assertNoDuplication(FILE_1_REF);
83 public void loads_duplication_without_otherFileRef_as_inner_duplication() {
84 reportReader.putDuplications(FILE_2_REF, createDuplication(singleLineTextRange(LINE), createInnerDuplicate(LINE + 1)));
88 assertNoDuplication(FILE_1_REF);
89 assertDuplications(FILE_2_REF, singleLineDetailedTextBlock(1, LINE), new InnerDuplicate(singleLineTextBlock(LINE + 1)));
93 public void loads_duplication_with_otherFileRef_as_inProject_duplication() {
94 reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(LINE), createInProjectDuplicate(FILE_2_REF, LINE + 1)));
98 assertDuplications(FILE_1_REF, singleLineDetailedTextBlock(1, LINE), new InProjectDuplicate(treeRootHolder.getComponentByRef(FILE_2_REF), singleLineTextBlock(LINE + 1)));
99 assertNoDuplication(FILE_2_REF);
103 public void loads_multiple_duplications_with_multiple_duplicates() {
104 reportReader.putDuplications(
107 singleLineTextRange(LINE),
108 createInnerDuplicate(LINE + 1), createInnerDuplicate(LINE + 2), createInProjectDuplicate(FILE_1_REF, LINE), createInProjectDuplicate(FILE_1_REF, LINE + 10)),
110 singleLineTextRange(OTHER_LINE),
111 createInProjectDuplicate(FILE_1_REF, OTHER_LINE)),
113 singleLineTextRange(OTHER_LINE + 80),
114 createInnerDuplicate(LINE), createInnerDuplicate(LINE + 10))
119 Component file1Component = treeRootHolder.getComponentByRef(FILE_1_REF);
120 assertThat(duplicationRepository.getDuplications(FILE_2_REF)).containsOnly(
122 singleLineDetailedTextBlock(1, LINE),
123 new InnerDuplicate(singleLineTextBlock(LINE + 1)), new InnerDuplicate(singleLineTextBlock(LINE + 2)), new InProjectDuplicate(file1Component, singleLineTextBlock(LINE)),
124 new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 10))),
126 singleLineDetailedTextBlock(2, OTHER_LINE),
127 new InProjectDuplicate(file1Component, singleLineTextBlock(OTHER_LINE))
130 singleLineDetailedTextBlock(3, OTHER_LINE + 80),
131 new InnerDuplicate(singleLineTextBlock(LINE)), new InnerDuplicate(singleLineTextBlock(LINE + 10))
137 public void loads_never_consider_originals_from_batch_on_same_lines_as_the_equals() {
138 reportReader.putDuplications(
141 singleLineTextRange(LINE),
142 createInnerDuplicate(LINE + 1), createInnerDuplicate(LINE + 2), createInProjectDuplicate(FILE_1_REF, LINE + 2)),
144 singleLineTextRange(LINE),
145 createInnerDuplicate(LINE + 2), createInnerDuplicate(LINE + 3), createInProjectDuplicate(FILE_1_REF, LINE + 2))
150 Component file1Component = treeRootHolder.getComponentByRef(FILE_1_REF);
151 assertThat(duplicationRepository.getDuplications(FILE_2_REF)).containsOnly(
153 singleLineDetailedTextBlock(1, LINE),
154 new InnerDuplicate(singleLineTextBlock(LINE + 1)), new InnerDuplicate(singleLineTextBlock(LINE + 2)),
155 new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 2))
158 singleLineDetailedTextBlock(2, LINE),
159 new InnerDuplicate(singleLineTextBlock(LINE + 2)), new InnerDuplicate(singleLineTextBlock(LINE + 3)),
160 new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 2))
166 public void loads_duplication_with_otherFileRef_throws_IAE_if_component_does_not_exist() {
168 reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(666, line + 1)));
170 expectedException.expect(VisitException.class);
171 expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("Component with ref '666' can't be found"));
177 public void loads_duplication_with_otherFileRef_throws_IAE_if_references_itself() {
179 reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(FILE_1_REF, line + 1)));
181 expectedException.expect(VisitException.class);
182 expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("file and otherFile Components can not be the same"));
187 private void assertDuplications(int fileRef, TextBlock original, Duplicate... duplicates) {
188 assertThat(duplicationRepository.getDuplications(fileRef)).containsExactly(duplication(original, duplicates));
191 private static Duplication duplication(TextBlock original, Duplicate... duplicates) {
192 return new Duplication(original, Arrays.asList(duplicates));
195 private TextBlock singleLineTextBlock(int line) {
196 return new TextBlock(line, line);
199 private DetailedTextBlock singleLineDetailedTextBlock(int id, int line) {
200 return new DetailedTextBlock(id, line, line);
203 private static BatchReport.Duplication createDuplication(BatchReport.TextRange original, BatchReport.Duplicate... duplicates) {
204 BatchReport.Duplication.Builder builder = BatchReport.Duplication.newBuilder()
205 .setOriginPosition(original);
206 for (BatchReport.Duplicate duplicate : duplicates) {
207 builder.addDuplicate(duplicate);
209 return builder.build();
212 private static BatchReport.Duplicate createInnerDuplicate(int line) {
213 return BatchReport.Duplicate.newBuilder()
214 .setRange(singleLineTextRange(line))
218 private static BatchReport.Duplicate createInProjectDuplicate(int componentRef, int line) {
219 return BatchReport.Duplicate.newBuilder()
220 .setOtherFileRef(componentRef)
221 .setRange(singleLineTextRange(line))
225 private static BatchReport.TextRange singleLineTextRange(int line) {
226 return BatchReport.TextRange.newBuilder()
232 private void assertNoDuplication(int fileRef) {
233 assertThat(duplicationRepository.getDuplications(fileRef)).isEmpty();