]> source.dussan.org Git - sonarqube.git/blob
e2e75ae45c9f43f1831379be54ee0206c42f9e80
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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 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.server.computation.task.projectanalysis.component.Component;
28 import org.sonar.server.computation.task.projectanalysis.component.FileAttributes;
29 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
30 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
31 import org.sonar.server.computation.task.projectanalysis.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
32 import org.sonar.server.computation.task.projectanalysis.measure.Measure;
33 import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry;
34 import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule;
35 import org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations;
36 import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule;
37 import org.sonar.server.computation.task.projectanalysis.period.Period;
38 import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolderRule;
39 import org.sonar.server.computation.task.projectanalysis.scm.Changeset;
40 import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoRepositoryRule;
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.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY;
53 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE;
54 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.MODULE;
55 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
56 import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder;
57 import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder;
58 import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf;
59 import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries;
60 import static org.sonar.server.computation.task.projectanalysis.measure.MeasureVariations.newMeasureVariationsBuilder;
61
62 public class ReportNewCoverageMeasuresStepTest {
63
64   private static final int ROOT_REF = 1;
65   private static final int MODULE_REF = 11;
66   private static final int SUB_MODULE_REF = 111;
67   private static final int DIRECTORY_1_REF = 1111;
68   private static final int FILE_1_REF = 11111;
69   private static final int DIRECTORY_2_REF = 1112;
70   private static final int FILE_2_REF = 11121;
71   private static final int FILE_3_REF = 11122;
72
73   private static final ReportComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF)
74     .addChildren(
75       builder(MODULE, MODULE_REF)
76         .addChildren(
77           builder(MODULE, SUB_MODULE_REF)
78             .addChildren(
79               builder(DIRECTORY, DIRECTORY_1_REF)
80                 .addChildren(
81                   builder(FILE, FILE_1_REF).build())
82                 .build(),
83               builder(DIRECTORY, DIRECTORY_2_REF)
84                 .addChildren(
85                   builder(FILE, FILE_2_REF).build(),
86                   builder(FILE, FILE_3_REF).build())
87                 .build())
88             .build())
89         .build())
90     .build();
91
92   @Rule
93   public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
94   @Rule
95   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
96   @Rule
97   public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
98   @Rule
99   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
100     .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
101     .add(CoreMetrics.CONDITIONS_BY_LINE)
102     .add(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
103     .add(CoreMetrics.NEW_LINES_TO_COVER)
104     .add(CoreMetrics.NEW_UNCOVERED_LINES)
105     .add(CoreMetrics.NEW_CONDITIONS_TO_COVER)
106     .add(CoreMetrics.NEW_UNCOVERED_CONDITIONS)
107     .add(CoreMetrics.NEW_COVERAGE)
108     .add(CoreMetrics.NEW_BRANCH_COVERAGE)
109     .add(CoreMetrics.NEW_LINE_COVERAGE);
110
111   @Rule
112   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
113
114   private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, measureRepository, metricRepository, scmInfoRepository);
115   public static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_1_REF)
116     .setFileAttributes(new FileAttributes(false, null, 1)).build();
117
118   @Before
119   public void setUp() {
120     periodsHolder.setPeriods(
121       new Period(2, "mode_p_1", null, parseDate("2009-12-25").getTime(), "u1"),
122       new Period(5, "mode_p_5", null, parseDate("2011-02-18").getTime(), "u2"));
123   }
124
125   @Test
126   public void no_measure_for_PROJECT_component() {
127     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, ROOT_REF).build());
128
129     underTest.execute();
130
131     assertThat(measureRepository.isEmpty()).isTrue();
132   }
133
134   @Test
135   public void no_measure_for_MODULE_component() {
136     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.MODULE, MODULE_REF).build());
137
138     underTest.execute();
139
140     assertThat(measureRepository.isEmpty()).isTrue();
141   }
142
143   @Test
144   public void no_measure_for_DIRECTORY_component() {
145     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.DIRECTORY, DIRECTORY_1_REF).build());
146
147     underTest.execute();
148
149     assertThat(measureRepository.isEmpty()).isTrue();
150   }
151
152   @Test
153   public void no_measure_for_unit_test_FILE_component() {
154     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(true, null, 1)).build());
155
156     underTest.execute();
157
158     assertThat(measureRepository.isEmpty()).isTrue();
159   }
160
161   @Test
162   public void no_measures_for_FILE_component_without_code() {
163     treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null, 1)).build());
164
165     underTest.execute();
166
167     assertThat(measureRepository.isEmpty()).isTrue();
168   }
169
170   @Test
171   public void zero_measures_when_nothing_has_changed() {
172     treeRootHolder.setRoot(FILE_COMPONENT);
173     scmInfoRepository.setScmInfo(FILE_1_REF,
174       Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
175       Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
176       Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
177       Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build(),
178       Changeset.newChangesetBuilder().setDate(parseDate("2008-08-02").getTime()).setRevision("rev-1").build());
179
180     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERAGE_LINE_HITS_DATA_KEY, newMeasureBuilder().create("2=1;3=1"));
181     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
182     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERED_CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
183
184     underTest.execute();
185
186     verify_only_zero_measures_on_new_lines_and_conditions_measures(FILE_COMPONENT);
187   }
188
189   @Test
190   public void zero_measures_for_FILE_component_without_CoverageData() {
191     treeRootHolder.setRoot(FILE_COMPONENT);
192     scmInfoRepository.setScmInfo(FILE_1_REF,
193       Changeset.newChangesetBuilder().setDate(parseDate("2008-05-18").getTime()).setRevision("rev-1").build(),
194       Changeset.newChangesetBuilder().setDate(parseDate("2008-05-18").getTime()).setRevision("rev-1").build());
195
196     underTest.execute();
197
198     verify_only_zero_measures_on_new_lines_and_conditions_measures(FILE_COMPONENT);
199   }
200
201   @Test
202   public void verify_computation_of_measures_for_new_lines_for_FILE() {
203     String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
204     String newLinesToCover = NEW_LINES_TO_COVER_KEY;
205     String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
206     String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
207     String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
208
209     verify_computation_of_measures_for_new_lines(coverageLineHitsData,
210       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
211   }
212
213   private void verify_computation_of_measures_for_new_lines(String coverageLineHitsData,
214     String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
215     treeRootHolder.setRoot(FILE_COMPONENT);
216     scmInfoRepository.setScmInfo(FILE_1_REF,
217       Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
218       Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
219       Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(),
220       Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build());
221
222     measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=3"));
223
224     underTest.execute();
225
226     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
227       entryOf(newLinesToCover, createMeasure(2d, 0d)),
228       entryOf(newUncoveredLines, createMeasure(1d, 0d)),
229       entryOf(newConditionsToCover, createMeasure(0d, 0d)),
230       entryOf(newUncoveredConditions, createMeasure(0d, 0d)));
231   }
232
233   @Test
234   public void verify_computation_of_measures_for_new_conditions_for_FILE() {
235     String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
236     String conditionsByLine = CONDITIONS_BY_LINE_KEY;
237     String coveredConditionsByLine = COVERED_CONDITIONS_BY_LINE_KEY;
238     String newLinesToCover = NEW_LINES_TO_COVER_KEY;
239     String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
240     String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
241     String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
242
243     verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
244       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
245   }
246
247   @Test
248   public void verify_aggregation_of_measures_for_new_conditions() {
249     String coverageLineHitsData = CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
250     String conditionsByLine = CoreMetrics.CONDITIONS_BY_LINE_KEY;
251     String coveredConditionsByLine = CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
252     String newLinesToCover = NEW_LINES_TO_COVER_KEY;
253     String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
254     String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
255     String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
256
257     MetricKeys metricKeys = new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
258       newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
259
260     treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
261     defineChangeSetsAndMeasures(FILE_1_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
262     defineChangeSetsAndMeasures(FILE_2_REF, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7));
263     defineChangeSetsAndMeasures(FILE_3_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7));
264
265     underTest.execute();
266
267     // files
268     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(
269       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
270       entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
271       entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
272       entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d)));
273     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(
274       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
275       entryOf(metricKeys.newUncoveredLines, createMeasure(4d, 2d)),
276       entryOf(metricKeys.newConditionsToCover, createMeasure(27d, 13d)),
277       entryOf(metricKeys.newUncoveredConditions, createMeasure(14d, 6d)));
278     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_3_REF))).contains(
279       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
280       entryOf(metricKeys.newUncoveredLines, createMeasure(2d, 1d)),
281       entryOf(metricKeys.newConditionsToCover, createMeasure(17d, 13d)),
282       entryOf(metricKeys.newUncoveredConditions, createMeasure(9d, 6d)));
283     // directories
284     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).contains(
285       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
286       entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
287       entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
288       entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d)));
289     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).contains(
290       entryOf(metricKeys.newLinesToCover, createMeasure(10d, 6d)),
291       entryOf(metricKeys.newUncoveredLines, createMeasure(6d, 3d)),
292       entryOf(metricKeys.newConditionsToCover, createMeasure(44d, 26d)),
293       entryOf(metricKeys.newUncoveredConditions, createMeasure(23d, 12d)));
294     // submodule
295     MeasureRepoEntry[] repoEntriesFromSubModuleUp = {entryOf(metricKeys.newLinesToCover, createMeasure(15d, 9d)),
296       entryOf(metricKeys.newUncoveredLines, createMeasure(9d, 5d)),
297       entryOf(metricKeys.newConditionsToCover, createMeasure(51d, 29d)),
298       entryOf(metricKeys.newUncoveredConditions, createMeasure(27d, 13d))};
299     assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(repoEntriesFromSubModuleUp);
300     // module
301     assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(repoEntriesFromSubModuleUp);
302     // project
303     assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(repoEntriesFromSubModuleUp);
304   }
305
306   @Test
307   public void verify_aggregates_variations_for_new_code_line_and_branch_Coverage() {
308     LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
309       CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY,
310       CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY);
311     String codeCoverageKey = CoreMetrics.NEW_COVERAGE_KEY;
312     String lineCoverageKey = CoreMetrics.NEW_LINE_COVERAGE_KEY;
313     String branchCoverageKey = CoreMetrics.NEW_BRANCH_COVERAGE_KEY;
314
315     verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
316   }
317
318   private void verify_aggregates_variations(LinesAndConditionsWithUncoveredMetricKeys metricKeys, String codeCoverageKey, String lineCoverageKey, String branchCoverageKey) {
319     treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
320     measureRepository
321       .addRawMeasure(FILE_1_REF, metricKeys.getLines(), createMeasure(3000d, 2000d))
322       .addRawMeasure(FILE_1_REF, metricKeys.getConditions(), createMeasure(300d, 400d))
323       .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredLines(), createMeasure(30d, 200d))
324       .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredConditions(), createMeasure(9d, 16d))
325
326       .addRawMeasure(FILE_2_REF, metricKeys.getLines(), createMeasure(2000d, 3000d))
327       .addRawMeasure(FILE_2_REF, metricKeys.getConditions(), createMeasure(400d, 300d))
328       .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredLines(), createMeasure(200d, 30d))
329       .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredConditions(), createMeasure(16d, 9d));
330
331     underTest.execute();
332
333     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).containsOnly(
334       entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
335       entryOf(lineCoverageKey, createMeasure(99d, 90d)),
336       entryOf(branchCoverageKey, createMeasure(97d, 96d)));
337     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).containsOnly(
338       entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
339       entryOf(lineCoverageKey, createMeasure(90d, 99d)),
340       entryOf(branchCoverageKey, createMeasure(96d, 97d)));
341     assertThat(measureRepository.getAddedRawMeasures(FILE_3_REF)).isEmpty();
342
343     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).containsOnly(
344       entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
345       entryOf(lineCoverageKey, createMeasure(99d, 90d)),
346       entryOf(branchCoverageKey, createMeasure(97d, 96d)));
347
348     assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).containsOnly(
349       entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
350       entryOf(lineCoverageKey, createMeasure(90d, 99d)),
351       entryOf(branchCoverageKey, createMeasure(96d, 97d)));
352
353     MeasureRepoEntry[] modulesAndProjectEntries = {
354       entryOf(codeCoverageKey, createMeasure(95.5d, 95.5d)),
355       entryOf(lineCoverageKey, createMeasure(95.4d, 95.4d)),
356       entryOf(branchCoverageKey, createMeasure(96.4d, 96.4d))
357     };
358
359     assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).containsOnly(modulesAndProjectEntries);
360     assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).containsOnly(modulesAndProjectEntries);
361     assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).containsOnly(modulesAndProjectEntries);
362   }
363
364   private void verify_only_zero_measures_on_new_lines_and_conditions_measures(Component component) {
365     assertThat(toEntries(measureRepository.getAddedRawMeasures(component.getReportAttributes().getRef()))).containsOnly(
366       entryOf(NEW_LINES_TO_COVER_KEY, createMeasure(0d, 0d)),
367       entryOf(NEW_UNCOVERED_LINES_KEY, createMeasure(0d, 0d)),
368       entryOf(NEW_CONDITIONS_TO_COVER_KEY, createMeasure(0d, 0d)),
369       entryOf(NEW_UNCOVERED_CONDITIONS_KEY, createMeasure(0d, 0d)));
370   }
371
372   private void defineChangeSetsAndMeasures(int componentRef, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) {
373     scmInfoRepository.setScmInfo(componentRef,
374       Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
375       Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
376       Changeset.newChangesetBuilder().setDate(parseDate("2007-01-15").getTime()).setRevision("rev-2").build(),
377       Changeset.newChangesetBuilder().setDate(parseDate("2011-01-01").getTime()).setRevision("rev-1").build(),
378       Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build(),
379       Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build(),
380       Changeset.newChangesetBuilder().setDate(parseDate("2012-02-23").getTime()).setRevision("rev-3").build());
381
382     measureRepository.addRawMeasure(componentRef, metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0"));
383     measureRepository.addRawMeasure(componentRef, metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions));
384     measureRepository.addRawMeasure(componentRef, metricKeys.coveredConditionsByLine,
385       newMeasureBuilder().create("4=" + line4.uncoveredConditions + ";6=" + line6.uncoveredConditions));
386   }
387
388   private static final class MetricKeys {
389     private final String coverageLineHitsData;
390     private final String conditionsByLine;
391     private final String coveredConditionsByLine;
392     private final String newLinesToCover;
393     private final String newUncoveredLines;
394     private final String newConditionsToCover;
395     private final String newUncoveredConditions;
396
397     public MetricKeys(String coverageLineHitsData, String conditionsByLine, String coveredConditionsByLine,
398       String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
399       this.coverageLineHitsData = coverageLineHitsData;
400       this.conditionsByLine = conditionsByLine;
401       this.coveredConditionsByLine = coveredConditionsByLine;
402       this.newLinesToCover = newLinesToCover;
403       this.newUncoveredLines = newUncoveredLines;
404       this.newConditionsToCover = newConditionsToCover;
405       this.newUncoveredConditions = newUncoveredConditions;
406     }
407   }
408
409   private static final class MeasureValues {
410     private final int lineHits;
411     private final int coveredConditions;
412     private final int uncoveredConditions;
413
414     public MeasureValues(int lineHits, int coveredConditions, int uncoveredConditions) {
415       this.lineHits = lineHits;
416       this.coveredConditions = coveredConditions;
417       this.uncoveredConditions = uncoveredConditions;
418     }
419   }
420
421   private void verify_computation_of_measures_for_new_conditions(MetricKeys metricKeys) {
422     treeRootHolder.setRoot(FILE_COMPONENT);
423     defineChangeSetsAndMeasures(FILE_COMPONENT.getReportAttributes().getRef(), metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
424
425     underTest.execute();
426
427     assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
428       entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
429       entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
430       entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
431       entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d)));
432   }
433
434   private static Measure createMeasure(@Nullable Double variationPeriod2, @Nullable Double variationPeriod5) {
435     MeasureVariations.Builder variationBuilder = newMeasureVariationsBuilder();
436     if (variationPeriod2 != null) {
437       variationBuilder.setVariation(new Period(2, "", null, 1L, "u2"), variationPeriod2);
438     }
439     if (variationPeriod5 != null) {
440       variationBuilder.setVariation(new Period(5, "", null, 1L, "u2"), variationPeriod5);
441     }
442     return newMeasureBuilder()
443       .setVariations(variationBuilder.build())
444       .createNoValue();
445   }
446
447 }