]> source.dussan.org Git - sonarqube.git/blob
b1423876afd7666ad007694de301de34b1474745
[sonarqube.git] /
1 /*
2  * SonarQube, open source software quality management tool.
3  * Copyright (C) 2008-2014 SonarSource
4  * mailto:contact AT sonarsource DOT com
5  *
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.
10  *
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.
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.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.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;
38
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;
44
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;
51
52   @Rule
53   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(
54     builder(PROJECT, ROOT_REF)
55       .addChildren(
56         builder(FILE, FILE_1_REF).build(),
57         builder(FILE, FILE_2_REF).build()
58       )
59       .build()
60     );
61   @Rule
62   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
63   @Rule
64   public DuplicationRepositoryRule duplicationRepository = DuplicationRepositoryRule.create(treeRootHolder);
65   @Rule
66   public ExpectedException expectedException = ExpectedException.none();
67
68   private LoadDuplicationsFromReportStep underTest = new LoadDuplicationsFromReportStep(treeRootHolder, reportReader, duplicationRepository);
69
70   @Test
71   public void verify_description() {
72     assertThat(underTest.getDescription()).isEqualTo("Load inner file and in project duplications");
73   }
74
75   @Test
76   public void loads_no_duplications_if_reader_has_no_duplication() {
77     underTest.execute();
78
79     assertNoDuplication(FILE_1_REF);
80   }
81
82   @Test
83   public void loads_duplication_without_otherFileRef_as_inner_duplication() {
84     reportReader.putDuplications(FILE_2_REF, createDuplication(singleLineTextRange(LINE), createInnerDuplicate(LINE + 1)));
85
86     underTest.execute();
87
88     assertNoDuplication(FILE_1_REF);
89     assertDuplications(FILE_2_REF, singleLineDetailedTextBlock(1, LINE), new InnerDuplicate(singleLineTextBlock(LINE + 1)));
90   }
91
92   @Test
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)));
95
96     underTest.execute();
97
98     assertDuplications(FILE_1_REF, singleLineDetailedTextBlock(1, LINE), new InProjectDuplicate(treeRootHolder.getComponentByRef(FILE_2_REF), singleLineTextBlock(LINE + 1)));
99     assertNoDuplication(FILE_2_REF);
100   }
101
102   @Test
103   public void loads_multiple_duplications_with_multiple_duplicates() {
104     reportReader.putDuplications(
105       FILE_2_REF,
106       createDuplication(
107         singleLineTextRange(LINE),
108         createInnerDuplicate(LINE + 1), createInnerDuplicate(LINE + 2), createInProjectDuplicate(FILE_1_REF, LINE), createInProjectDuplicate(FILE_1_REF, LINE + 10)),
109       createDuplication(
110         singleLineTextRange(OTHER_LINE),
111         createInProjectDuplicate(FILE_1_REF, OTHER_LINE)),
112       createDuplication(
113         singleLineTextRange(OTHER_LINE + 80),
114         createInnerDuplicate(LINE), createInnerDuplicate(LINE + 10))
115       );
116
117     underTest.execute();
118
119     Component file1Component = treeRootHolder.getComponentByRef(FILE_1_REF);
120     assertThat(duplicationRepository.getDuplications(FILE_2_REF)).containsOnly(
121       duplication(
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))),
125       duplication(
126         singleLineDetailedTextBlock(2, OTHER_LINE),
127         new InProjectDuplicate(file1Component, singleLineTextBlock(OTHER_LINE))
128       ),
129       duplication(
130         singleLineDetailedTextBlock(3, OTHER_LINE + 80),
131         new InnerDuplicate(singleLineTextBlock(LINE)), new InnerDuplicate(singleLineTextBlock(LINE + 10))
132       )
133       );
134   }
135
136   @Test
137   public void loads_never_consider_originals_from_batch_on_same_lines_as_the_equals() {
138     reportReader.putDuplications(
139       FILE_2_REF,
140       createDuplication(
141         singleLineTextRange(LINE),
142         createInnerDuplicate(LINE + 1), createInnerDuplicate(LINE + 2), createInProjectDuplicate(FILE_1_REF, LINE + 2)),
143       createDuplication(
144         singleLineTextRange(LINE),
145         createInnerDuplicate(LINE + 2), createInnerDuplicate(LINE + 3), createInProjectDuplicate(FILE_1_REF, LINE + 2))
146       );
147
148     underTest.execute();
149
150     Component file1Component = treeRootHolder.getComponentByRef(FILE_1_REF);
151     assertThat(duplicationRepository.getDuplications(FILE_2_REF)).containsOnly(
152       duplication(
153         singleLineDetailedTextBlock(1, LINE),
154         new InnerDuplicate(singleLineTextBlock(LINE + 1)), new InnerDuplicate(singleLineTextBlock(LINE + 2)),
155         new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 2))
156       ),
157       duplication(
158         singleLineDetailedTextBlock(2, LINE),
159         new InnerDuplicate(singleLineTextBlock(LINE + 2)), new InnerDuplicate(singleLineTextBlock(LINE + 3)),
160         new InProjectDuplicate(file1Component, singleLineTextBlock(LINE + 2))
161       )
162       );
163   }
164
165   @Test
166   public void loads_duplication_with_otherFileRef_throws_IAE_if_component_does_not_exist() {
167     int line = 2;
168     reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(666, line + 1)));
169
170     expectedException.expect(VisitException.class);
171     expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("Component with ref '666' can't be found"));
172
173     underTest.execute();
174   }
175
176   @Test
177   public void loads_duplication_with_otherFileRef_throws_IAE_if_references_itself() {
178     int line = 2;
179     reportReader.putDuplications(FILE_1_REF, createDuplication(singleLineTextRange(line), createInProjectDuplicate(FILE_1_REF, line + 1)));
180
181     expectedException.expect(VisitException.class);
182     expectedException.expectCause(hasType(IllegalArgumentException.class).andMessage("file and otherFile Components can not be the same"));
183
184     underTest.execute();
185   }
186
187   private void assertDuplications(int fileRef, TextBlock original, Duplicate... duplicates) {
188     assertThat(duplicationRepository.getDuplications(fileRef)).containsExactly(duplication(original, duplicates));
189   }
190
191   private static Duplication duplication(TextBlock original, Duplicate... duplicates) {
192     return new Duplication(original, Arrays.asList(duplicates));
193   }
194
195   private TextBlock singleLineTextBlock(int line) {
196     return new TextBlock(line, line);
197   }
198
199   private DetailedTextBlock singleLineDetailedTextBlock(int id, int line) {
200     return new DetailedTextBlock(id, line, line);
201   }
202
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);
208     }
209     return builder.build();
210   }
211
212   private static BatchReport.Duplicate createInnerDuplicate(int line) {
213     return BatchReport.Duplicate.newBuilder()
214       .setRange(singleLineTextRange(line))
215       .build();
216   }
217
218   private static BatchReport.Duplicate createInProjectDuplicate(int componentRef, int line) {
219     return BatchReport.Duplicate.newBuilder()
220       .setOtherFileRef(componentRef)
221       .setRange(singleLineTextRange(line))
222       .build();
223   }
224
225   private static BatchReport.TextRange singleLineTextRange(int line) {
226     return BatchReport.TextRange.newBuilder()
227       .setStartLine(line)
228       .setEndLine(line)
229       .build();
230   }
231
232   private void assertNoDuplication(int fileRef) {
233     assertThat(duplicationRepository.getDuplications(fileRef)).isEmpty();
234   }
235
236 }