3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
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.
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.
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.qualitymodel;
22 import com.google.common.collect.ImmutableMap;
23 import com.google.common.collect.ImmutableSet;
24 import com.google.common.collect.Ordering;
25 import java.util.Arrays;
27 import org.assertj.core.data.Offset;
28 import org.junit.Rule;
29 import org.junit.Test;
30 import org.sonar.api.utils.KeyValueFormat;
31 import org.sonar.server.computation.batch.TreeRootHolderRule;
32 import org.sonar.server.computation.component.Component;
33 import org.sonar.server.computation.component.ComponentVisitor;
34 import org.sonar.server.computation.component.FileAttributes;
35 import org.sonar.server.computation.component.ReportComponent;
36 import org.sonar.server.computation.component.VisitorsCrawler;
37 import org.sonar.server.computation.measure.Measure;
38 import org.sonar.server.computation.measure.MeasureRepositoryRule;
39 import org.sonar.server.computation.measure.MeasureVariations;
40 import org.sonar.server.computation.metric.MetricRepositoryRule;
41 import org.sonar.server.computation.period.Period;
42 import org.sonar.server.computation.period.PeriodsHolderRule;
43 import org.sonar.server.computation.scm.Changeset;
44 import org.sonar.server.computation.scm.ScmInfoRepositoryRule;
46 import static com.google.common.base.Preconditions.checkArgument;
47 import static org.mockito.Mockito.mock;
48 import static org.mockito.Mockito.when;
49 import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA;
50 import static org.sonar.api.measures.CoreMetrics.NCLOC_DATA_KEY;
51 import static org.sonar.api.measures.CoreMetrics.NEW_SQALE_DEBT_RATIO;
52 import static org.sonar.api.measures.CoreMetrics.NEW_SQALE_DEBT_RATIO_KEY;
53 import static org.sonar.api.measures.CoreMetrics.NEW_TECHNICAL_DEBT;
54 import static org.sonar.api.measures.CoreMetrics.NEW_TECHNICAL_DEBT_KEY;
55 import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
56 import static org.sonar.server.computation.component.Component.Type.FILE;
57 import static org.sonar.server.computation.component.Component.Type.MODULE;
58 import static org.sonar.server.computation.component.Component.Type.PROJECT;
59 import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
60 import static org.sonar.server.computation.measure.MeasureAssert.assertThat;
62 public class NewQualityModelMeasuresVisitorTest {
63 private static final String LANGUAGE_1_KEY = "language 1 key";
64 private static final long LANGUAGE_1_DEV_COST = 30l;
65 private static final long PERIOD_2_SNAPSHOT_DATE = 12323l;
66 private static final long PERIOD_5_SNAPSHOT_DATE = 99999999l;
67 private static final String SOME_ANALYSIS_UUID = "9993l";
68 private static final String SOME_PERIOD_MODE = "some mode";
69 private static final int ROOT_REF = 1;
70 private static final int LANGUAGE_1_FILE_REF = 11111;
71 private static final Offset<Double> VARIATION_COMPARISON_OFFSET = Offset.offset(0.01);
74 public ScmInfoRepositoryRule scmInfoRepository = new ScmInfoRepositoryRule();
76 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
78 public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
79 .add(NEW_TECHNICAL_DEBT)
81 .add(NEW_SQALE_DEBT_RATIO);
83 public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
85 public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
87 private RatingSettings ratingSettings = mock(RatingSettings.class);
89 private VisitorsCrawler underTest = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new NewQualityModelMeasuresVisitor(metricRepository, measureRepository, scmInfoRepository,
90 periodsHolder, ratingSettings)));
93 public void project_has_new_debt_ratio_variation_for_each_defined_period() {
95 treeRootHolder.setRoot(builder(PROJECT, ROOT_REF).build());
97 underTest.visit(treeRootHolder.getRoot());
99 assertNewDebtRatioValues(ROOT_REF, 0, 0);
103 public void project_has_no_new_debt_ratio_variation_if_there_is_no_period() {
104 periodsHolder.setPeriods();
105 treeRootHolder.setRoot(builder(PROJECT, ROOT_REF).build());
107 underTest.visit(treeRootHolder.getRoot());
109 assertNoNewDebtRatioMeasure(ROOT_REF);
113 public void file_has_no_new_debt_ratio_variation_if_there_is_no_period() {
114 periodsHolder.setPeriods();
115 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
116 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
117 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
119 underTest.visit(treeRootHolder.getRoot());
121 assertNoNewDebtRatioMeasure(LANGUAGE_1_FILE_REF);
122 assertNoNewDebtRatioMeasure(ROOT_REF);
126 public void file_has_0_new_debt_ratio_if_all_scm_dates_are_before_snapshot_dates() {
128 treeRootHolder.setRoot(
129 builder(PROJECT, ROOT_REF)
131 builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY)).build()
135 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
136 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
137 scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_2_SNAPSHOT_DATE - 100, 4));
139 underTest.visit(treeRootHolder.getRoot());
141 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
142 assertNewDebtRatioValues(ROOT_REF, 0, 0);
146 public void file_has_new_debt_ratio_if_some_scm_dates_are_after_snapshot_dates() {
148 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
149 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
150 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
152 underTest.visit(treeRootHolder.getRoot());
154 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 83.33, 0);
155 assertNewDebtRatioValues(ROOT_REF, 83.33, 0);
159 public void new_debt_ratio_changes_with_language_cost() {
161 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST * 10);
162 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
163 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
165 underTest.visit(treeRootHolder.getRoot());
167 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 8.33, 0);
168 assertNewDebtRatioValues(ROOT_REF, 8.33, 0);
172 public void new_debt_ratio_changes_with_new_technical_debt() {
174 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
175 setupOneFileAloneInAProject(500, 120, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
176 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(500, 120));
178 underTest.visit(treeRootHolder.getRoot());
180 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 833.33, 0);
181 assertNewDebtRatioValues(ROOT_REF, 833.33, 0);
185 public void new_debt_ratio_on_non_file_level_is_based_on_new_technical_debt_of_that_level() {
187 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
188 setupOneFileAloneInAProject(500, 120, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
189 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(1200, 820));
191 underTest.visit(treeRootHolder.getRoot());
193 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 833.33, 0);
194 assertNewDebtRatioValues(ROOT_REF, 833.33, 0);
198 public void no_new_debt_ratio_when_file_is_unit_test() {
200 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
201 setupOneFileAloneInAProject(50, 12, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
202 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
204 underTest.visit(treeRootHolder.getRoot());
206 assertNoNewDebtRatioMeasure(LANGUAGE_1_FILE_REF);
207 assertNewDebtRatioValues(ROOT_REF, 0, 0);
211 public void new_debt_ratio_is_0_on_non_file_level_when_all_files_are_unit_test() {
213 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
214 setupOneFileAloneInAProject(50, 12, Flag.UT_FILE, Flag.WITH_NCLOC, Flag.WITH_CHANGESET);
215 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200, 162));
217 underTest.visit(treeRootHolder.getRoot());
219 assertNoNewDebtRatioMeasure(LANGUAGE_1_FILE_REF);
220 assertNewDebtRatioValues(ROOT_REF, 0, 0);
224 public void new_debt_ratio_is_0_when_file_has_no_changesets() {
226 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
227 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_CHANGESET);
228 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
230 underTest.visit(treeRootHolder.getRoot());
232 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
233 assertNewDebtRatioValues(ROOT_REF, 0, 0);
237 public void new_debt_ratio_is_0_on_non_file_level_when_no_file_has_changesets() {
239 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
240 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.WITH_NCLOC, Flag.NO_CHANGESET);
241 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200, 162));
243 underTest.visit(treeRootHolder.getRoot());
245 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
246 assertNewDebtRatioValues(ROOT_REF, 0, 0);
250 public void new_debt_ratio_is_0_when_there_is_no_ncloc_in_file() {
252 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
253 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_CHANGESET);
254 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
256 underTest.visit(treeRootHolder.getRoot());
258 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
259 assertNewDebtRatioValues(ROOT_REF, 0, 0);
263 public void new_debt_ratio_is_0_on_non_file_level_when_one_file_has_zero_new_debt_because_of_no_changeset() {
265 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
266 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.NO_NCLOC, Flag.WITH_CHANGESET);
267 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200, 162));
269 underTest.visit(treeRootHolder.getRoot());
271 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
272 assertNewDebtRatioValues(ROOT_REF, 0, 0);
276 public void new_debt_ratio_is_0_when_ncloc_measure_is_missing() {
278 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
279 setupOneFileAloneInAProject(50, 12, Flag.SRC_FILE, Flag.MISSING_MEASURE_NCLOC, Flag.WITH_CHANGESET);
280 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(50, 12));
282 underTest.visit(treeRootHolder.getRoot());
284 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 0, 0);
285 assertNewDebtRatioValues(ROOT_REF, 0, 0);
289 public void leaf_components_always_have_a_measure_when_at_least_one_period_exist_and_ratio_is_computed_from_current_level_new_debt() {
291 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
292 treeRootHolder.setRoot(
293 builder(PROJECT, ROOT_REF)
297 builder(DIRECTORY, 111)
299 builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY)).build()
305 Measure newDebtMeasure = createNewDebtMeasure(50, 12);
306 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, newDebtMeasure);
307 measureRepository.addRawMeasure(111, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(150, 112));
308 measureRepository.addRawMeasure(11, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(200, 112));
309 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY, createNewDebtMeasure(250, 212));
310 // 4 lines file, only first one is not ncloc
311 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
312 // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
313 scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_2_SNAPSHOT_DATE - 100, 2, PERIOD_2_SNAPSHOT_DATE + 100, 2));
315 underTest.visit(treeRootHolder.getRoot());
317 assertNewDebtRatioValues(LANGUAGE_1_FILE_REF, 83.33, 0);
318 assertNewDebtRatioValues(111, 83.33, 0);
319 assertNewDebtRatioValues(11, 83.33, 0);
320 assertNewDebtRatioValues(ROOT_REF, 83.33, 0);
324 public void new_debt_ratio_is_computed_for_five_periods() throws Exception {
325 long period1 = 10000L;
326 long period2 = 20000L;
327 long period3 = 30000L;
328 long period4 = 40000L;
329 long period5 = 50000L;
331 periodsHolder.setPeriods(
332 new Period(1, SOME_PERIOD_MODE, null, period1, SOME_ANALYSIS_UUID),
333 new Period(2, SOME_PERIOD_MODE, null, period2, SOME_ANALYSIS_UUID),
334 new Period(3, SOME_PERIOD_MODE, null, period3, SOME_ANALYSIS_UUID),
335 new Period(4, SOME_PERIOD_MODE, null, period4, SOME_ANALYSIS_UUID),
336 new Period(5, SOME_PERIOD_MODE, null, period5, SOME_ANALYSIS_UUID));
338 when(ratingSettings.getDevCost(LANGUAGE_1_KEY)).thenReturn(LANGUAGE_1_DEV_COST);
340 treeRootHolder.setRoot(
341 builder(PROJECT, ROOT_REF)
342 .addChildren(builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(false, LANGUAGE_1_KEY)).build())
346 Measure newDebtMeasure = newMeasureBuilder().setVariations(new MeasureVariations(500d, 500d, 500d, 120d, 120d)).createNoValue();
347 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, newDebtMeasure);
348 // 4 lines file, only first one is not ncloc
349 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
350 // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
351 scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(period2 - 100, 2, period2 + 100, 2));
353 measureRepository.addRawMeasure(ROOT_REF, NEW_TECHNICAL_DEBT_KEY,
354 newMeasureBuilder().setVariations(new MeasureVariations(1200d, 1200d, 1200d, 820d, 820d)).createNoValue());
356 underTest.visit(treeRootHolder.getRoot());
358 assertThat(measureRepository.getAddedRawMeasure(LANGUAGE_1_FILE_REF, NEW_SQALE_DEBT_RATIO_KEY))
359 .hasVariation1(833.333, VARIATION_COMPARISON_OFFSET)
360 .hasVariation2(833.333, VARIATION_COMPARISON_OFFSET)
361 .hasVariation3(0d, VARIATION_COMPARISON_OFFSET)
362 .hasVariation4(0d, VARIATION_COMPARISON_OFFSET)
363 .hasVariation5(0d, VARIATION_COMPARISON_OFFSET);
366 private void setupOneFileAloneInAProject(int newDebtPeriod2, int newDebtPeriod4, Flag isUnitTest, Flag withNclocLines, Flag withChangeSets) {
367 checkArgument(isUnitTest == Flag.UT_FILE || isUnitTest == Flag.SRC_FILE);
368 checkArgument(withNclocLines == Flag.WITH_NCLOC || withNclocLines == Flag.NO_NCLOC || withNclocLines == Flag.MISSING_MEASURE_NCLOC);
369 checkArgument(withChangeSets == Flag.WITH_CHANGESET || withChangeSets == Flag.NO_CHANGESET);
371 treeRootHolder.setRoot(
372 builder(PROJECT, ROOT_REF)
374 builder(FILE, LANGUAGE_1_FILE_REF).setFileAttributes(new FileAttributes(isUnitTest == Flag.UT_FILE, LANGUAGE_1_KEY)).build()
379 Measure newDebtMeasure = createNewDebtMeasure(newDebtPeriod2, newDebtPeriod4);
380 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NEW_TECHNICAL_DEBT_KEY, newDebtMeasure);
381 if (withNclocLines == Flag.WITH_NCLOC) {
382 // 4 lines file, only first one is not ncloc
383 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNclocDataMeasure(2, 3, 4));
384 } else if (withNclocLines == Flag.NO_NCLOC) {
385 // 4 lines file, none of which is ncloc
386 measureRepository.addRawMeasure(LANGUAGE_1_FILE_REF, NCLOC_DATA_KEY, createNoNclocDataMeasure(4));
388 if (withChangeSets == Flag.WITH_CHANGESET) {
389 // first 2 lines are before all snapshots, 2 last lines are after PERIOD 2's snapshot date
390 scmInfoRepository.setScmInfo(LANGUAGE_1_FILE_REF, createChangesets(PERIOD_2_SNAPSHOT_DATE - 100, 2, PERIOD_2_SNAPSHOT_DATE + 100, 2));
395 UT_FILE, SRC_FILE, NO_CHANGESET, WITH_CHANGESET, WITH_NCLOC, NO_NCLOC, MISSING_MEASURE_NCLOC
398 public static ReportComponent.Builder builder(Component.Type type, int ref) {
399 return ReportComponent.builder(type, ref).setKey(String.valueOf(ref));
402 private Measure createNewDebtMeasure(double period2Value, double period4Value) {
403 return newMeasureBuilder().setVariations(new MeasureVariations(null, period2Value, null, period4Value, null)).createNoValue();
406 private static Measure createNclocDataMeasure(Integer... nclocLines) {
407 Set<Integer> nclocLinesSet = ImmutableSet.copyOf(nclocLines);
408 int max = Ordering.<Integer>natural().max(nclocLinesSet);
409 ImmutableMap.Builder<Integer, Integer> builder = ImmutableMap.builder();
410 for (int i = 1; i <= max; i++) {
411 builder.put(i, nclocLinesSet.contains(i) ? 1 : 0);
413 return newMeasureBuilder().create(KeyValueFormat.format(builder.build(), KeyValueFormat.newIntegerConverter(), KeyValueFormat.newIntegerConverter()));
416 private static Measure createNoNclocDataMeasure(int lineCount) {
417 ImmutableMap.Builder<Integer, Integer> builder = ImmutableMap.builder();
418 for (int i = 1; i <= lineCount; i++) {
421 return newMeasureBuilder().create(KeyValueFormat.format(builder.build(), KeyValueFormat.newIntegerConverter(), KeyValueFormat.newIntegerConverter()));
425 * Creates changesets of {@code lines} lines which all have the same date {@code scmDate}.
427 private static Changeset[] createChangesets(long scmDate, int lines) {
428 Changeset changetset = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
429 Changeset[] changesets = new Changeset[lines];
430 for (int i = 0; i < lines; i++) {
431 changesets[i] = changetset;
437 * Creates a changeset of {@code lineCount} lines which have the date {@code scmDate} and {@code otherLineCount} lines which
438 * have the date {@code otherScmDate}.
440 private static Changeset[] createChangesets(long scmDate, int lineCount, long otherScmDate, int otherLineCount) {
441 Changeset[] changesets = new Changeset[lineCount + otherLineCount];
442 Changeset changetset1 = Changeset.newChangesetBuilder().setDate(scmDate).setRevision("rev-1").build();
443 for (int i = 0; i < lineCount; i++) {
444 changesets[i] = changetset1;
446 Changeset changetset2 = Changeset.newChangesetBuilder().setDate(otherScmDate).setRevision("rev-2").build();
447 for (int i = lineCount; i < lineCount + otherLineCount; i++) {
448 changesets[i] = changetset2;
453 private void assertNoNewDebtRatioMeasure(int componentRef) {
454 assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SQALE_DEBT_RATIO_KEY))
458 private void assertNewDebtRatioValues(int componentRef, double expectedPeriod2Value, double expectedPeriod4Value) {
459 assertThat(measureRepository.getAddedRawMeasure(componentRef, NEW_SQALE_DEBT_RATIO_KEY))
460 .hasVariation2(expectedPeriod2Value, VARIATION_COMPARISON_OFFSET)
461 .hasVariation4(expectedPeriod4Value, VARIATION_COMPARISON_OFFSET);
464 private void setTwoPeriods() {
465 periodsHolder.setPeriods(
466 new Period(2, SOME_PERIOD_MODE, null, PERIOD_2_SNAPSHOT_DATE, SOME_ANALYSIS_UUID),
467 new Period(4, SOME_PERIOD_MODE, null, PERIOD_5_SNAPSHOT_DATE, SOME_ANALYSIS_UUID));