]> source.dussan.org Git - sonarqube.git/blob
35c66c745eac1a7d5fc13f520559e64a92da0e68
[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 javax.annotation.Nullable;
23 import org.junit.Before;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.sonar.api.measures.CoreMetrics;
27 import org.sonar.batch.protocol.output.BatchReport;
28 import org.sonar.server.computation.batch.BatchReportReaderRule;
29 import org.sonar.server.computation.batch.TreeRootHolderRule;
30 import org.sonar.server.computation.component.Component;
31 import org.sonar.server.computation.component.ReportComponent;
32 import org.sonar.server.computation.component.FileAttributes;
33 import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
34 import org.sonar.server.computation.measure.Measure;
35 import org.sonar.server.computation.measure.MeasureRepoEntry;
36 import org.sonar.server.computation.measure.MeasureRepositoryRule;
37 import org.sonar.server.computation.measure.MeasureVariations;
38 import org.sonar.server.computation.metric.MetricRepositoryRule;
39 import org.sonar.server.computation.period.Period;
40 import org.sonar.server.computation.period.PeriodsHolderRule;
41
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.assertj.guava.api.Assertions.assertThat;
44 import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE_KEY;
45 import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
46 import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
47 import static org.sonar.api.measures.CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY;
48 import static org.sonar.api.measures.CoreMetrics.NEW_LINES_TO_COVER_KEY;
49 import static org.sonar.api.measures.CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY;
50 import static org.sonar.api.measures.CoreMetrics.NEW_UNCOVERED_LINES_KEY;
51 import static org.sonar.api.utils.DateUtils.parseDate;
52 import static org.sonar.batch.protocol.output.BatchReport.Changesets;
53 import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
54 import static org.sonar.server.computation.component.Component.Type.FILE;
55 import static org.sonar.server.computation.component.Component.Type.MODULE;
56 import static org.sonar.server.computation.component.Component.Type.PROJECT;
57 import static org.sonar.server.computation.component.ReportComponent.builder;
58 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
59 import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf;
60 import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries;
61 import static org.sonar.server.computation.measure.MeasureVariations.newMeasureVariationsBuilder;
62
63 public class ReportNewCoverageMeasuresStepTest {
64
65   private static final int ROOT_REF = 1;
66   private static final int MODULE_REF = 11;
67   private static final int SUB_MODULE_REF = 111;
68   private static final int DIRECTORY_1_REF = 1111;
69   private static final int FILE_1_REF = 11111;
70   private static final int DIRECTORY_2_REF = 1112;
71   private static final int FILE_2_REF = 11121;
72   private static final int FILE_3_REF = 11122;
73
74   private static final ReportComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF)
75     .addChildren(
76       builder(MODULE, MODULE_REF)
77         .addChildren(
78           builder(MODULE, SUB_MODULE_REF)
79             .addChildren(
80               builder(DIRECTORY, DIRECTORY_1_REF)
81                 .addChildren(
82                   builder(FILE, FILE_1_REF).build()
83                 ).build(),
84               builder(DIRECTORY, DIRECTORY_2_REF)
85                 .addChildren(
86                   builder(FILE, FILE_2_REF).build(),
87                   builder(FILE, FILE_3_REF).build()
88                 ).build()
89             )
90             .build()
91         ).build()
92     ).build();
93
94   @Rule
95   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
96   @Rule
97   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
98   @Rule
99   public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
100   @Rule
101   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
102     .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
103     .add(CoreMetrics.CONDITIONS_BY_LINE)
104     .add(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
105     .add(CoreMetrics.NEW_LINES_TO_COVER)
106     .add(CoreMetrics.NEW_UNCOVERED_LINES)
107     .add(CoreMetrics.NEW_CONDITIONS_TO_COVER)
108     .add(CoreMetrics.NEW_UNCOVERED_CONDITIONS)
109     .add(CoreMetrics.NEW_COVERAGE)
110     .add(CoreMetrics.NEW_BRANCH_COVERAGE)
111     .add(CoreMetrics.NEW_LINE_COVERAGE)
112
113     .add(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA)
114     .add(CoreMetrics.IT_CONDITIONS_BY_LINE)
115     .add(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE)
116     .add(CoreMetrics.NEW_IT_LINES_TO_COVER)
117     .add(CoreMetrics.NEW_IT_UNCOVERED_LINES)
118     .add(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER)
119     .add(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS)
120     .add(CoreMetrics.NEW_IT_COVERAGE)
121     .add(CoreMetrics.NEW_IT_BRANCH_COVERAGE)
122     .add(CoreMetrics.NEW_IT_LINE_COVERAGE)
123
124     .add(CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA)
125     .add(CoreMetrics.OVERALL_CONDITIONS_BY_LINE)
126     .add(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE)
127     .add(CoreMetrics.NEW_OVERALL_LINES_TO_COVER)
128     .add(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES)
129     .add(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER)
130     .add(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS)
131     .add(CoreMetrics.NEW_OVERALL_COVERAGE)
132     .add(CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE)
133     .add(CoreMetrics.NEW_OVERALL_LINE_COVERAGE)
134     ;
135   @Rule
136   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
137
138   private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, reportReader,
139     measureRepository, metricRepository);
140   public static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_1_REF)
141     .setFileAttributes(new FileAttributes(false, null)).build();
142
143   @Before
144   public void setUp() {
145     periodsHolder.setPeriods(
146       new Period(2, "mode_p_1", null, parseDate("2009-12-25").getTime(), 1),
147       new Period(5, "mode_p_5", null, parseDate("2011-02-18").getTime(), 2));
148   }
149
150   @Test
151   public void no_measure_for_PROJECT_component() {
152     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, ROOT_REF).build());
153
154     underTest.execute();
155
156     assertThat(measureRepository.isEmpty()).isTrue();
157   }
158
159   @Test
160   public void no_measure_for_MODULE_component() {
161     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.MODULE, MODULE_REF).build());
162
163     underTest.execute();
164
165     assertThat(measureRepository.isEmpty()).isTrue();
166   }
167
168   @Test
169   public void no_measure_for_DIRECTORY_component() {
170     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.DIRECTORY, DIRECTORY_1_REF).build());
171
172     underTest.execute();
173
174     assertThat(measureRepository.isEmpty()).isTrue();
175   }
176
177   @Test
178   public void no_measure_for_unit_test_FILE_component() {
179     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(true, null)).build());
180
181     underTest.execute();
182
183     assertThat(measureRepository.isEmpty()).isTrue();
184   }
185
186   @Test
187   public void no_measures_for_FILE_component_without_code() {
188     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null)).build());
189
190     underTest.execute();
191
192     assertThat(measureRepository.isEmpty()).isTrue();
193   }
194
195   @Test
196   public void verify_measure_of_condition_not_computed_if_there_is_none() {
197     treeRootHolder.setRoot(FILE_COMPONENT);
198     reportReader.putChangesets(Changesets.newBuilder()
199         .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
200         .addChangeset(Changesets.Changeset.newBuilder().build())
201         .addChangeset(Changesets.Changeset.newBuilder()
202           .setDate(parseDate("2007-01-15").getTime())
203           .build())
204         .addChangeset(Changesets.Changeset.newBuilder()
205           .setDate(parseDate("2011-01-01").getTime())
206           .build())
207         .addChangesetIndexByLine(0)
208         .addChangesetIndexByLine(1)
209         .addChangesetIndexByLine(2)
210         .build()
211     );
212
213     underTest.execute();
214
215     assertThat(measureRepository.isEmpty()).isTrue();
216   }
217
218   @Test
219   public void verify_no_measure_when_nothing_has_changed() {
220     treeRootHolder.setRoot(FILE_COMPONENT);
221     reportReader.putChangesets(BatchReport.Changesets.newBuilder()
222       .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
223       .addChangeset(Changesets.Changeset.newBuilder()
224         .setDate(parseDate("2008-08-02").getTime())
225         .build())
226       .addChangesetIndexByLine(0)
227       .addChangesetIndexByLine(0)
228       .addChangesetIndexByLine(0)
229       .addChangesetIndexByLine(0)
230       .build());
231     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERAGE_LINE_HITS_DATA_KEY, newMeasureBuilder().create("2=1;3=1"));
232     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
233     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERED_CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
234
235     underTest.execute();
236
237     assertThat(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef())).isEmpty();
238   }
239
240   @Test
241   public void no_measures_for_FILE_component_without_CoverageData() {
242     ReportComponent fileComponent = ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null)).build();
243
244     treeRootHolder.setRoot(fileComponent);
245     reportReader.putChangesets(Changesets.newBuilder()
246       .setComponentRef(fileComponent.getReportAttributes().getRef())
247       .addChangeset(Changesets.Changeset.newBuilder()
248         .setDate(parseDate("2008-05-18").getTime())
249         .build())
250       .addChangesetIndexByLine(0)
251       .build());
252
253     underTest.execute();
254
255     assertThat(measureRepository.isEmpty()).isTrue();
256   }
257
258   @Test
259   public void verify_computation_of_measures_for_new_lines_for_FILE() {
260     String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
261     String newLinesToCover = NEW_LINES_TO_COVER_KEY;
262     String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
263     String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
264     String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
265
266     verify_computation_of_measures_for_new_lines(coverageLineHitsData,
267       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
268   }
269
270   @Test
271   public void verify_computation_of_measures_for_new_lines_for_IT_FILE() {
272     String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
273     String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
274     String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
275     String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
276     String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
277
278     verify_computation_of_measures_for_new_lines(coverageLineHitsData,
279       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
280   }
281
282   @Test
283   public void verify_computation_of_measures_for_new_lines_for_Overall() {
284     String coverageLineHitsData = CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
285     String newLinesToCover = CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY;
286     String newUncoveredLines = CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY;
287     String newConditionsToCover = CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY;
288     String newUncoveredConditions = CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY;
289
290     verify_computation_of_measures_for_new_lines(coverageLineHitsData,
291       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
292   }
293
294   private void verify_computation_of_measures_for_new_lines(String coverageLineHitsData,
295                                                             String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
296     treeRootHolder.setRoot(FILE_COMPONENT);
297     reportReader.putChangesets(Changesets.newBuilder()
298       .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
299       .addChangeset(Changesets.Changeset.newBuilder().build())
300       .addChangeset(Changesets.Changeset.newBuilder()
301         .setDate(parseDate("2007-01-15").getTime())
302         .build())
303       .addChangeset(Changesets.Changeset.newBuilder()
304         .setDate(parseDate("2011-01-01").getTime())
305         .build())
306       .addChangesetIndexByLine(0)
307       .addChangesetIndexByLine(2) // line 2
308       .addChangesetIndexByLine(1) // line 3
309       .addChangesetIndexByLine(2) // line 4
310       .build());
311     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=3"));
312
313     underTest.execute();
314
315     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
316       entryOf(newLinesToCover, createMeasure(2d, null)),
317       entryOf(newUncoveredLines, createMeasure(1d, null)),
318       entryOf(newConditionsToCover, createMeasure(0d, null)),
319       entryOf(newUncoveredConditions, createMeasure(0d, null))
320     );
321   }
322
323   @Test
324   public void verify_computation_of_measures_for_new_conditions_for_FILE() {
325     String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
326     String conditionsByLine = CONDITIONS_BY_LINE_KEY;
327     String coveredConditionsByLine = COVERED_CONDITIONS_BY_LINE_KEY;
328     String newLinesToCover = NEW_LINES_TO_COVER_KEY;
329     String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
330     String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
331     String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
332
333     verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
334       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
335   }
336
337   @Test
338   public void verify_computation_of_measures_for_new_conditions_for_IT_FILE() {
339     String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
340     String conditionsByLine = CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
341     String coveredConditionsByLine = CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
342     String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
343     String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
344     String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
345     String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
346
347     verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
348       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
349   }
350
351   @Test
352   public void verify_computation_of_measures_for_new_conditions_Overall() {
353     String coverageLineHitsData = CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
354     String conditionsByLine = CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY;
355     String coveredConditionsByLine = CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY;
356     String newLinesToCover = CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY;
357     String newUncoveredLines = CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY;
358     String newConditionsToCover = CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY;
359     String newUncoveredConditions = CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY;
360
361     verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
362       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
363   }
364
365   @Test
366   public void verify_aggregation_of_measures_for_new_conditions() {
367     String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
368     String conditionsByLine = CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
369     String coveredConditionsByLine = CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
370     String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
371     String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
372     String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
373     String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
374
375     MetricKeys metricKeys = new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
376       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
377
378     treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
379     defineChangeSetsAndMeasures(FILE_1_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
380     defineChangeSetsAndMeasures(FILE_2_REF, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7));
381     defineChangeSetsAndMeasures(FILE_3_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7));
382
383     underTest.execute();
384
385     // files
386     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(
387       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
388       entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
389       entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
390       entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
391     );
392     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(
393       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
394       entryOf(metricKeys.newUncoveredLines, createMeasure(4d, 2d)),
395       entryOf(metricKeys.newConditionsToCover, createMeasure(27d, 13d)),
396       entryOf(metricKeys.newUncoveredConditions, createMeasure(14d, 6d))
397     );
398     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_3_REF))).contains(
399       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
400       entryOf(metricKeys.newUncoveredLines, createMeasure(2d, 1d)),
401       entryOf(metricKeys.newConditionsToCover, createMeasure(17d, 13d)),
402       entryOf(metricKeys.newUncoveredConditions, createMeasure(9d, 6d))
403     );
404     // directories
405     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).contains(
406       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
407       entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
408       entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
409       entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
410     );
411     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).contains(
412       entryOf(metricKeys.newLinesToCover, createMeasure(10d, 6d)),
413       entryOf(metricKeys.newUncoveredLines, createMeasure(6d, 3d)),
414       entryOf(metricKeys.newConditionsToCover, createMeasure(44d, 26d)),
415       entryOf(metricKeys.newUncoveredConditions, createMeasure(23d, 12d))
416     );
417     // submodule
418     MeasureRepoEntry[] repoEntriesFromSubModuleUp = {entryOf(metricKeys.newLinesToCover, createMeasure(15d, 9d)),
419       entryOf(metricKeys.newUncoveredLines, createMeasure(9d, 5d)),
420       entryOf(metricKeys.newConditionsToCover, createMeasure(51d, 29d)),
421       entryOf(metricKeys.newUncoveredConditions, createMeasure(27d, 13d))};
422     assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(repoEntriesFromSubModuleUp);
423     // module
424     assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(repoEntriesFromSubModuleUp);
425     // project
426     assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(repoEntriesFromSubModuleUp);
427   }
428
429   @Test
430   public void verify_aggregates_variations_for_new_code_line_and_branch_Coverage() {
431     LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
432       CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY,
433       CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY
434     );
435     String codeCoverageKey = CoreMetrics.NEW_COVERAGE_KEY;
436     String lineCoverageKey = CoreMetrics.NEW_LINE_COVERAGE_KEY;
437     String branchCoverageKey = CoreMetrics.NEW_BRANCH_COVERAGE_KEY;
438
439     verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
440   }
441
442   @Test
443   public void verify_aggregates_variations_for_new_IT_code_line_and_branch_Coverage() {
444     LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
445       CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY,
446       CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY
447     );
448     String codeCoverageKey = CoreMetrics.NEW_IT_COVERAGE_KEY;
449     String lineCoverageKey = CoreMetrics.NEW_IT_LINE_COVERAGE_KEY;
450     String branchCoverageKey = CoreMetrics.NEW_IT_BRANCH_COVERAGE_KEY;
451
452     verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
453   }
454
455   @Test
456   public void verify_aggregates_variations_for_new_Overall_code_line_and_branch_Coverage() {
457     LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
458       CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY,
459       CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY
460     );
461     String codeCoverageKey = CoreMetrics.NEW_OVERALL_COVERAGE_KEY;
462     String lineCoverageKey = CoreMetrics.NEW_OVERALL_LINE_COVERAGE_KEY;
463     String branchCoverageKey = CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE_KEY;
464
465     verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
466   }
467
468   private void verify_aggregates_variations(LinesAndConditionsWithUncoveredMetricKeys metricKeys, String codeCoverageKey, String lineCoverageKey, String branchCoverageKey) {
469     treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
470     measureRepository
471       .addRawMeasure(FILE_1_REF, metricKeys.getLines(), createMeasure(3000d, 2000d))
472       .addRawMeasure(FILE_1_REF, metricKeys.getConditions(), createMeasure(300d, 400d))
473       .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredLines(), createMeasure(30d, 200d))
474       .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredConditions(), createMeasure(9d, 16d))
475
476       .addRawMeasure(FILE_2_REF, metricKeys.getLines(), createMeasure(2000d, 3000d))
477       .addRawMeasure(FILE_2_REF, metricKeys.getConditions(), createMeasure(400d, 300d))
478       .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredLines(), createMeasure(200d, 30d))
479       .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredConditions(), createMeasure(16d, 9d));
480
481     underTest.execute();
482
483     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).containsOnly(
484       entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
485       entryOf(lineCoverageKey, createMeasure(99d, 90d)),
486       entryOf(branchCoverageKey, createMeasure(97d, 96d))
487     );
488     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).containsOnly(
489       entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
490       entryOf(lineCoverageKey, createMeasure(90d, 99d)),
491       entryOf(branchCoverageKey, createMeasure(96d, 97d))
492     );
493     assertThat(measureRepository.getAddedRawMeasures(FILE_3_REF)).isEmpty();
494
495     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).containsOnly(
496       entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
497       entryOf(lineCoverageKey, createMeasure(99d, 90d)),
498       entryOf(branchCoverageKey, createMeasure(97d, 96d))
499     );
500
501     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).containsOnly(
502       entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
503       entryOf(lineCoverageKey, createMeasure(90d, 99d)),
504       entryOf(branchCoverageKey, createMeasure(96d, 97d))
505     );
506
507     MeasureRepoEntry[] modulesAndProjectEntries = {
508       entryOf(codeCoverageKey, createMeasure(95.5d, 95.5d)),
509       entryOf(lineCoverageKey, createMeasure(95.4d, 95.4d)),
510       entryOf(branchCoverageKey, createMeasure(96.4d, 96.4d))
511     };
512
513     assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).containsOnly(modulesAndProjectEntries);
514     assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).containsOnly(modulesAndProjectEntries);
515     assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).containsOnly(modulesAndProjectEntries);
516   }
517
518   private void defineChangeSetsAndMeasures(int componentRef, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) {
519     reportReader.putChangesets(Changesets.newBuilder()
520       .setComponentRef(componentRef)
521       .addChangeset(Changesets.Changeset.newBuilder().build())
522       .addChangeset(Changesets.Changeset.newBuilder()
523         .setDate(parseDate("2007-01-15").getTime())
524         .build())
525       .addChangeset(Changesets.Changeset.newBuilder()
526         .setDate(parseDate("2011-01-01").getTime())
527         .build())
528       .addChangeset(Changesets.Changeset.newBuilder()
529         .setDate(parseDate("2012-02-23").getTime())
530         .build())
531       .addChangesetIndexByLine(0)
532       .addChangesetIndexByLine(2) // line 2
533       .addChangesetIndexByLine(1) // line 3
534       .addChangesetIndexByLine(2) // line 4
535       .addChangesetIndexByLine(3) // line 5
536       .addChangesetIndexByLine(3) // line 6
537       .addChangesetIndexByLine(3) // line 7
538       .build());
539     measureRepository.addRawMeasure(componentRef, metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0"));
540     measureRepository.addRawMeasure(componentRef, metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions));
541     measureRepository.addRawMeasure(componentRef, metricKeys.coveredConditionsByLine,
542       newMeasureBuilder().create("4=" + line4.uncoveredConditions + ";6=" + line6.uncoveredConditions));
543   }
544
545   private static final class MetricKeys {
546     private final String coverageLineHitsData;
547     private final String conditionsByLine;
548     private final String coveredConditionsByLine;
549     private final String newLinesToCover;
550     private final String newUncoveredLines;
551     private final String newConditionsToCover;
552     private final String newUncoveredConditions;
553
554     public MetricKeys(String coverageLineHitsData, String conditionsByLine, String coveredConditionsByLine,
555                       String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
556       this.coverageLineHitsData = coverageLineHitsData;
557       this.conditionsByLine = conditionsByLine;
558       this.coveredConditionsByLine = coveredConditionsByLine;
559       this.newLinesToCover = newLinesToCover;
560       this.newUncoveredLines = newUncoveredLines;
561       this.newConditionsToCover = newConditionsToCover;
562       this.newUncoveredConditions = newUncoveredConditions;
563     }
564   }
565
566   private static final class MeasureValues {
567     private final int lineHits;
568     private final int coveredConditions;
569     private final int uncoveredConditions;
570
571     public MeasureValues(int lineHits, int coveredConditions, int uncoveredConditions) {
572       this.lineHits = lineHits;
573       this.coveredConditions = coveredConditions;
574       this.uncoveredConditions = uncoveredConditions;
575     }
576   }
577
578   private void verify_computation_of_measures_for_new_conditions(MetricKeys metricKeys) {
579     treeRootHolder.setRoot(FILE_COMPONENT);
580     defineChangeSetsAndMeasures(FILE_COMPONENT.getReportAttributes().getRef(), metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
581
582     underTest.execute();
583
584     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
585       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
586       entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
587       entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
588       entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
589     );
590   }
591
592   private static Measure createMeasure(@Nullable Double variationPeriod2, @Nullable Double variationPeriod5) {
593     MeasureVariations.Builder variationBuilder = newMeasureVariationsBuilder();
594     if (variationPeriod2 != null) {
595       variationBuilder.setVariation(new Period(2, "", null, 1L, 2L), variationPeriod2);
596     }
597     if (variationPeriod5 != null) {
598       variationBuilder.setVariation(new Period(5, "", null, 1L, 2L), variationPeriod5);
599     }
600     return newMeasureBuilder()
601       .setVariations(variationBuilder.build())
602       .createNoValue();
603   }
604
605 }