]> source.dussan.org Git - sonarqube.git/blob
98b4a8a0f034e7859a0d7f5dd6d5fe3f44ecff6f
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.computation.task.projectanalysis.step;
21
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.scanner.protocol.output.ScannerReport;
27 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
28 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
29 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
30 import org.sonar.server.computation.task.projectanalysis.component.Component;
31 import org.sonar.server.computation.task.projectanalysis.component.VisitException;
32 import org.sonar.server.computation.task.projectanalysis.duplication.DetailedTextBlock;
33 import org.sonar.server.computation.task.projectanalysis.duplication.Duplicate;
34 import org.sonar.server.computation.task.projectanalysis.duplication.Duplication;
35 import org.sonar.server.computation.task.projectanalysis.duplication.DuplicationRepositoryRule;
36 import org.sonar.server.computation.task.projectanalysis.duplication.InProjectDuplicate;
37 import org.sonar.server.computation.task.projectanalysis.duplication.InnerDuplicate;
38 import org.sonar.server.computation.task.projectanalysis.duplication.TextBlock;
39
40 import static org.assertj.core.api.Assertions.assertThat;
41 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE;
42 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
43 import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
44 import static org.sonar.test.ExceptionCauseMatcher.hasType;
45
46 public class LoadDuplicationsFromReportStepTest {
47   private static final int LINE = 2;
48   private static final int OTHER_LINE = 300;
49   private static final int ROOT_REF = 1;
50   private static final int FILE_1_REF = 11;
51   private static final int FILE_2_REF = 12;
52
53   @Rule
54   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(
55     builder(PROJECT, ROOT_REF)
56       .addChildren(
57         builder(FILE, FILE_1_REF).build(),
58         builder(FILE, FILE_2_REF).build()
59       )
60       .build()
61     );
62   @Rule
63   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
64   @Rule
65   public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
66   @Rule
67   public ExpectedException expectedException = ExpectedException.none();
68   @Rule
69   public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
70
71   private LoadDuplicationsFromReportStep underTest = new LoadDuplicationsFromReportStep(treeRootHolder, reportReader, duplicationRepository, analysisMetadataHolder);
72
73   @Test
74   public void verify_description() {
75     assertThat(underTest.getDescription()).isEqualTo("Load inner file and in project duplications");
76   }
77   
78   @Test
79   public void skip_if_incremental_analysis() {
80     analysisMetadataHolder.setIncrementalAnalysis(true);
81     reportReader.putDuplications(FILE_2_REF, createDuplication(singleLineTextRange(LINE), createInnerDuplicate(LINE + 1)));
82
83     underTest.execute();
84
85     assertNoDuplication(FILE_2_REF);
86   }
87
88   @Test
89   public void loads_no_duplications_if_reader_has_no_duplication() {
90     analysisMetadataHolder.setIncrementalAnalysis(false);
91     underTest.execute();
92
93     assertNoDuplication(FILE_1_REF);
94   }
95
96   @Test
97   public void loads_duplication_without_otherFileRef_as_inner_duplication() {
98     analysisMetadataHolder.setIncrementalAnalysis(false);
99     reportReader.putDuplications(FILE_2_REF, createDuplication(singleLineTextRange(LINE), createInnerDuplicate(LINE + 1)));
100
101     underTest.execute();
102
103     assertNoDuplication(FILE_1_REF);
104     assertDuplications(FILE_2_REF, singleLineDetailedTextBlock(1, LINE), new InnerDuplicate(singleLineTextBlock(LINE + 1)));
105   }
106
107   @Test
108   public void loads_duplication_with_otherFileRef_as_inProject_duplication() {
109     analysisMetadataHolder.setIncrementalAnalysis(false);
110     reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(LINE), createInProjectDuplicate(FILE_2_REF, LINE + 1)));
111
112     underTest.execute();
113
114     assertDuplications(FILE_1_REF, singleLineDetailedTextBlock(1, LINE), new InProjectDuplicate(treeRootHolder.getComponentByRef(FILE_2_REF), singleLineTextBlock(LINE + 1)));
115     assertNoDuplication(FILE_2_REF);
116   }
117
118   @Test
119   public void loads_multiple_duplications_with_multiple_duplicates() {
120     analysisMetadataHolder.setIncrementalAnalysis(false);
121     reportReader.putDuplications(
122       FILE_2_REF,
123       createDuplication(
124         singleLineTextRange(LINE),
125         createInnerDuplicate(LINE + 1), createInnerDuplicate(LINE + 2), createInProjectDuplicate(FILE_1_REF, LINE), createInProjectDuplicate(FILE_1_REF, LINE + 10)),
126       createDuplication(
127         singleLineTextRange(OTHER_LINE),
128         createInProjectDuplicate(FILE_1_REF, OTHER_LINE)),
129       createDuplication(
130         singleLineTextRange(OTHER_LINE + 80),
131         createInnerDuplicate(LINE), createInnerDuplicate(LINE + 10))
132       );
133
134     underTest.execute();
135
136     Component file1Component = treeRootHolder.getComponentByRef(FILE_1_REF);
137     assertThat(duplicationRepository.getDuplications(FILE_2_REF)).containsOnly(
138       duplication(
139         singleLineDetailedTextBlock(1, LINE),
140         new InnerDuplicate(singleLineTextBlock(LINE + 1)), new InnerDuplicate(singleLineTextBlock(LINE + 2)), new InProjectDuplicate(file1Component, singleLineTextBlock(LINE)),
141         new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 10))),
142       duplication(
143         singleLineDetailedTextBlock(2, OTHER_LINE),
144         new InProjectDuplicate(file1Component, singleLineTextBlock(OTHER_LINE))
145       ),
146       duplication(
147         singleLineDetailedTextBlock(3, OTHER_LINE + 80),
148         new InnerDuplicate(singleLineTextBlock(LINE)), new InnerDuplicate(singleLineTextBlock(LINE + 10))
149       )
150       );
151   }
152
153   @Test
154   public void loads_never_consider_originals_from_batch_on_same_lines_as_the_equals() {
155     analysisMetadataHolder.setIncrementalAnalysis(false);
156     reportReader.putDuplications(
157       FILE_2_REF,
158       createDuplication(
159         singleLineTextRange(LINE),
160         createInnerDuplicate(LINE + 1), createInnerDuplicate(LINE + 2), createInProjectDuplicate(FILE_1_REF, LINE + 2)),
161       createDuplication(
162         singleLineTextRange(LINE),
163         createInnerDuplicate(LINE + 2), createInnerDuplicate(LINE + 3), createInProjectDuplicate(FILE_1_REF, LINE + 2))
164       );
165
166     underTest.execute();
167
168     Component file1Component = treeRootHolder.getComponentByRef(FILE_1_REF);
169     assertThat(duplicationRepository.getDuplications(FILE_2_REF)).containsOnly(
170       duplication(
171         singleLineDetailedTextBlock(1, LINE),
172         new InnerDuplicate(singleLineTextBlock(LINE + 1)), new InnerDuplicate(singleLineTextBlock(LINE + 2)),
173         new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 2))
174       ),
175       duplication(
176         singleLineDetailedTextBlock(2, LINE),
177         new InnerDuplicate(singleLineTextBlock(LINE + 2)), new InnerDuplicate(singleLineTextBlock(LINE + 3)),
178         new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 2))
179       )
180       );
181   }
182
183   @Test
184   public void loads_duplication_with_otherFileRef_throws_IAE_if_component_does_not_exist() {
185     analysisMetadataHolder.setIncrementalAnalysis(false);
186     int line = 2;
187     reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(666, line + 1)));
188
189     expectedException.expect(VisitException.class);
190     expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("Component with ref '666' can't be found"));
191
192     underTest.execute();
193   }
194
195   @Test
196   public void loads_duplication_with_otherFileRef_throws_IAE_if_references_itself() {
197     analysisMetadataHolder.setIncrementalAnalysis(false);
198     int line = 2;
199     reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(FILE_1_REF, line + 1)));
200
201     expectedException.expect(VisitException.class);
202     expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("file and otherFile references can not be the same"));
203
204     underTest.execute();
205   }
206
207   private void assertDuplications(int fileRef, TextBlock original, Duplicate... duplicates) {
208     assertThat(duplicationRepository.getDuplications(fileRef)).containsExactly(duplication(original, duplicates));
209   }
210
211   private static Duplication duplication(TextBlock original, Duplicate... duplicates) {
212     return new Duplication(original, Arrays.asList(duplicates));
213   }
214
215   private TextBlock singleLineTextBlock(int line) {
216     return new TextBlock(line, line);
217   }
218
219   private DetailedTextBlock singleLineDetailedTextBlock(int id, int line) {
220     return new DetailedTextBlock(id, line, line);
221   }
222
223   private static ScannerReport.Duplication createDuplication(ScannerReport.TextRange original, ScannerReport.Duplicate... duplicates) {
224     ScannerReport.Duplication.Builder builder = ScannerReport.Duplication.newBuilder()
225       .setOriginPosition(original);
226     for (ScannerReport.Duplicate duplicate : duplicates) {
227       builder.addDuplicate(duplicate);
228     }
229     return builder.build();
230   }
231
232   private static ScannerReport.Duplicate createInnerDuplicate(int line) {
233     return ScannerReport.Duplicate.newBuilder()
234       .setRange(singleLineTextRange(line))
235       .build();
236   }
237
238   private static ScannerReport.Duplicate createInProjectDuplicate(int componentRef, int line) {
239     return ScannerReport.Duplicate.newBuilder()
240       .setOtherFileRef(componentRef)
241       .setRange(singleLineTextRange(line))
242       .build();
243   }
244
245   private static ScannerReport.TextRange singleLineTextRange(int line) {
246     return ScannerReport.TextRange.newBuilder()
247       .setStartLine(line)
248       .setEndLine(line)
249       .build();
250   }
251
252   private void assertNoDuplication(int fileRef) {
253     assertThat(duplicationRepository.getDuplications(fileRef)).isEmpty();
254   }
255
256 }