From edd8aac1c6352e3857475390b7431f3c8baef010 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Fri, 21 Aug 2015 15:34:51 +0200 Subject: [PATCH] make SqaleMeasuresVisitor support Views Component tree --- .../sqale/SqaleMeasuresVisitor.java | 35 +++- ...va => ReportSqaleMeasuresVisitorTest.java} | 84 ++++---- .../sqale/ViewsSqaleMeasuresVisitorTest.java | 189 ++++++++++++++++++ 3 files changed, 263 insertions(+), 45 deletions(-) rename server/sonar-server/src/test/java/org/sonar/server/computation/sqale/{SqaleMeasuresVisitorTest.java => ReportSqaleMeasuresVisitorTest.java} (76%) create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java index e3bc862e30b..ab62abd3392 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitor.java @@ -22,8 +22,9 @@ package org.sonar.server.computation.sqale; import com.google.common.base.Optional; import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.sonar.server.computation.component.Component; -import org.sonar.server.computation.component.ComponentVisitor; import org.sonar.server.computation.component.CrawlerDepthLimit; import org.sonar.server.computation.component.PathAwareVisitorAdapter; import org.sonar.server.computation.measure.Measure; @@ -31,9 +32,11 @@ import org.sonar.server.computation.measure.MeasureRepository; import org.sonar.server.computation.metric.Metric; import org.sonar.server.computation.metric.MetricRepository; +import static org.sonar.server.computation.component.ComponentVisitor.Order.POST_ORDER; import static org.sonar.server.computation.measure.Measure.newMeasureBuilder; public class SqaleMeasuresVisitor extends PathAwareVisitorAdapter { + private static final Logger LOG = Loggers.get(SqaleMeasuresVisitor.class); private final MetricRepository metricRepository; private final MeasureRepository measureRepository; @@ -45,11 +48,17 @@ public class SqaleMeasuresVisitor extends PathAwareVisitorAdapter() { + super(CrawlerDepthLimit.LEAVES, POST_ORDER, new SimpleStackElementFactory() { @Override public DevelopmentCost createForAny(Component component) { return new DevelopmentCost(); } + + /** Counter is not used at ProjectView level, saves on instantiating useless objects */ + @Override + public DevelopmentCost createForProjectView(Component projectView) { + return null; + } }); this.metricRepository = metricRepository; this.measureRepository = measureRepository; @@ -85,6 +94,28 @@ public class SqaleMeasuresVisitor extends PathAwareVisitorAdapter path) { + computeAndSaveMeasures(view, path); + } + + @Override + public void visitSubView(Component subView, Path path) { + computeAndSaveMeasures(subView, path); + } + + @Override + public void visitProjectView(Component projectView, Path path) { + Optional developmentCostMeasure = measureRepository.getRawMeasure(projectView, developmentCostMetric); + if (developmentCostMeasure.isPresent()) { + try { + path.parent().add(Long.valueOf(developmentCostMeasure.get().getStringValue())); + } catch (NumberFormatException e) { + LOG.trace("Failed to parse value of metric {} for component {}", developmentCostMetric.getName(), projectView.getKey()); + } + } + } + private void computeAndSaveMeasures(Component component, Path path) { saveDevelopmentCostMeasure(component, path.current()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java similarity index 76% rename from server/sonar-server/src/test/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitorTest.java rename to server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java index 52a6cfa3d3e..cdda7a7075c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/SqaleMeasuresVisitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ReportSqaleMeasuresVisitorTest.java @@ -27,11 +27,10 @@ import org.junit.Test; import org.sonar.api.measures.CoreMetrics; import org.sonar.server.computation.batch.TreeRootHolderRule; import org.sonar.server.computation.component.ComponentVisitor; -import org.sonar.server.computation.component.ReportComponent; import org.sonar.server.computation.component.FileAttributes; +import org.sonar.server.computation.component.ReportComponent; import org.sonar.server.computation.component.VisitorsCrawler; import org.sonar.server.computation.measure.Measure; -import org.sonar.server.computation.measure.MeasureRepoEntry; import org.sonar.server.computation.measure.MeasureRepositoryRule; import org.sonar.server.computation.metric.Metric; import org.sonar.server.computation.metric.MetricImpl; @@ -49,11 +48,12 @@ import static org.sonar.server.computation.component.Component.Type.FILE; import static org.sonar.server.computation.component.Component.Type.MODULE; import static org.sonar.server.computation.component.Component.Type.PROJECT; import static org.sonar.server.computation.measure.Measure.newMeasureBuilder; +import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf; import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries; import static org.sonar.server.computation.sqale.SqaleRatingGrid.SqaleRating.A; import static org.sonar.server.computation.sqale.SqaleRatingGrid.SqaleRating.C; -public class SqaleMeasuresVisitorTest { +public class ReportSqaleMeasuresVisitorTest { private static final String METRIC_KEY_1 = "mKey1"; private static final String METRIC_KEY_2 = "mKey2"; @@ -67,7 +67,6 @@ public class SqaleMeasuresVisitorTest { @Rule public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); - @Rule public MetricRepositoryRule metricRepository = new MetricRepositoryRule() .add(METRIC_1) @@ -76,7 +75,6 @@ public class SqaleMeasuresVisitorTest { .add(CoreMetrics.TECHNICAL_DEBT) .add(CoreMetrics.SQALE_DEBT_RATIO) .add(CoreMetrics.SQALE_RATING); - @Rule public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); @@ -101,11 +99,11 @@ public class SqaleMeasuresVisitorTest { underTest.visit(root); - assertThat(toEntries(measureRepository.getRawMeasures(root))).containsOnly( - MeasureRepoEntry.entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")), - MeasureRepoEntry.entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d)), - MeasureRepoEntry.entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(A)) - ); + assertThat(toEntries(measureRepository.getRawMeasures(root))) + .containsOnly( + entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")), + entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d)), + entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(A))); } private Measure createSqaleRatingMeasure(SqaleRatingGrid.SqaleRating sqaleRating) { @@ -130,14 +128,15 @@ public class SqaleMeasuresVisitorTest { SqaleRatingGrid.SqaleRating expectedRating) { long measureValue = 10; - ReportComponent fileComponent = createFileComponent(languageKey, 1); + int componentRef = 1; + ReportComponent fileComponent = createFileComponent(languageKey, componentRef); treeRootHolder.setRoot(fileComponent); - measureRepository.addRawMeasure(fileComponent.getReportAttributes().getRef(), metricKey, newMeasureBuilder().create(measureValue)); - measureRepository.addRawMeasure(fileComponent.getReportAttributes().getRef(), TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt)); + addRawMeasure(metricKey, componentRef, measureValue); + addRawMeasure(TECHNICAL_DEBT_KEY, componentRef, debt); underTest.visit(fileComponent); - verifyFileMeasures(fileComponent.getReportAttributes().getRef(), measureValue, debt, languageCost, expectedRating); + verifyFileMeasures(componentRef, measureValue, debt, languageCost, expectedRating); } @Test @@ -149,57 +148,57 @@ public class SqaleMeasuresVisitorTest { ReportComponent.builder(DIRECTORY, 111) .addChildren( createFileComponent(LANGUAGE_KEY_1, 1111), - createFileComponent(LANGUAGE_KEY_2, 1112) - ).build(), + createFileComponent(LANGUAGE_KEY_2, 1112)) + .build(), ReportComponent.builder(DIRECTORY, 112) .addChildren( - createFileComponent(LANGUAGE_KEY_2, 1121) - ).build() - ).build(), + createFileComponent(LANGUAGE_KEY_2, 1121)) + .build()) + .build(), ReportComponent.builder(MODULE, 12) .addChildren( ReportComponent.builder(DIRECTORY, 121) .addChildren( - createFileComponent(LANGUAGE_KEY_1, 1211) - ).build(), - ReportComponent.builder(DIRECTORY, 122).build() - ).build(), - ReportComponent.builder(MODULE, 13).build() - ).build(); + createFileComponent(LANGUAGE_KEY_1, 1211)) + .build(), + ReportComponent.builder(DIRECTORY, 122).build()) + .build(), + ReportComponent.builder(MODULE, 13).build()) + .build(); treeRootHolder.setRoot(root); long measureValue1111 = 10; long debt1111 = 66000l; - measureRepository.addRawMeasure(1111, METRIC_KEY_1, newMeasureBuilder().create(measureValue1111)); - measureRepository.addRawMeasure(1111, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt1111)); + addRawMeasure(METRIC_KEY_1, 1111, measureValue1111); + addRawMeasure(TECHNICAL_DEBT_KEY, 1111, debt1111); long measureValue1112 = 10; long debt1112 = 4200l; - measureRepository.addRawMeasure(1112, METRIC_KEY_2, newMeasureBuilder().create(measureValue1112)); - measureRepository.addRawMeasure(1112, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt1112)); + addRawMeasure(METRIC_KEY_2, 1112, measureValue1112); + addRawMeasure(TECHNICAL_DEBT_KEY, 1112, debt1112); long debt111 = 96325l; - measureRepository.addRawMeasure(111, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt111)); + addRawMeasure(TECHNICAL_DEBT_KEY, 111, debt111); long measureValue1121 = 30; long debt1121 = 25200l; - measureRepository.addRawMeasure(1121, METRIC_KEY_2, newMeasureBuilder().create(measureValue1121)); - measureRepository.addRawMeasure(1121, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt1121)); + addRawMeasure(METRIC_KEY_2, 1121, measureValue1121); + addRawMeasure(TECHNICAL_DEBT_KEY, 1121, debt1121); long debt112 = 99633l; - measureRepository.addRawMeasure(112, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt112)); + addRawMeasure(TECHNICAL_DEBT_KEY, 112, debt112); long measureValue1211 = 20; long debt1211 = 33000l; - measureRepository.addRawMeasure(1211, METRIC_KEY_1, newMeasureBuilder().create(measureValue1211)); - measureRepository.addRawMeasure(1211, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt1211)); + addRawMeasure(METRIC_KEY_1, 1211, measureValue1211); + addRawMeasure(TECHNICAL_DEBT_KEY, 1211, debt1211); long debt121 = 7524l; - measureRepository.addRawMeasure(121, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt121)); + addRawMeasure(TECHNICAL_DEBT_KEY, 121, debt121); long debt1 = 9999l; - measureRepository.addRawMeasure(1, TECHNICAL_DEBT_KEY, newMeasureBuilder().create(debt1)); + addRawMeasure(TECHNICAL_DEBT_KEY, 1, debt1); underTest.visit(root); @@ -233,8 +232,8 @@ public class SqaleMeasuresVisitorTest { return ReportComponent.builder(FILE, fileRef).setFileAttributes(new FileAttributes(false, languageKey1)).build(); } - private void verifyNoMeasure(int componentRef) { - assertThat(measureRepository.getRawMeasures(componentRef).isEmpty()).isTrue(); + private void addRawMeasure(String metricKey, int componentRef, long value) { + measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); } private void verifyFileMeasures(int componentRef, long measureValue, long debt, long languageCost, SqaleRatingGrid.SqaleRating expectedRating) { @@ -244,10 +243,9 @@ public class SqaleMeasuresVisitorTest { private void verifyComponentMeasures(int componentRef, long expectedDevCost, double expectedDebtRatio, SqaleRatingGrid.SqaleRating expectedRating) { assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly( - MeasureRepoEntry.entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(Long.toString(expectedDevCost))), - MeasureRepoEntry.entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(expectedDebtRatio * 100.0)), - MeasureRepoEntry.entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(expectedRating)) - ); + entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(Long.toString(expectedDevCost))), + entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(expectedDebtRatio * 100.0)), + entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(expectedRating))); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java new file mode 100644 index 00000000000..bf865c4e4ea --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/sqale/ViewsSqaleMeasuresVisitorTest.java @@ -0,0 +1,189 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.computation.sqale; + +import java.util.Arrays; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.server.computation.batch.TreeRootHolderRule; +import org.sonar.server.computation.component.ComponentVisitor; +import org.sonar.server.computation.component.ViewsComponent; +import org.sonar.server.computation.component.VisitorsCrawler; +import org.sonar.server.computation.measure.Measure; +import org.sonar.server.computation.measure.MeasureRepositoryRule; +import org.sonar.server.computation.metric.MetricRepositoryRule; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST_KEY; +import static org.sonar.api.measures.CoreMetrics.SQALE_DEBT_RATIO_KEY; +import static org.sonar.api.measures.CoreMetrics.SQALE_RATING_KEY; +import static org.sonar.api.measures.CoreMetrics.TECHNICAL_DEBT_KEY; +import static org.sonar.server.computation.component.Component.Type.PROJECT_VIEW; +import static org.sonar.server.computation.component.Component.Type.SUBVIEW; +import static org.sonar.server.computation.component.Component.Type.VIEW; +import static org.sonar.server.computation.component.ViewsComponent.builder; +import static org.sonar.server.computation.measure.Measure.newMeasureBuilder; +import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf; +import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries; +import static org.sonar.server.computation.sqale.SqaleRatingGrid.SqaleRating.A; +import static org.sonar.server.computation.sqale.SqaleRatingGrid.SqaleRating.B; +import static org.sonar.server.computation.sqale.SqaleRatingGrid.SqaleRating.D; +import static org.sonar.server.computation.sqale.SqaleRatingGrid.SqaleRating.E; + +public class ViewsSqaleMeasuresVisitorTest { + + private static final double[] RATING_GRID = new double[] {34, 50, 362, 900, 36258}; + private static final int ROOT_REF = 1; + private static final int SUBVIEW_REF = 11; + private static final int SUB_SUBVIEW_1_REF = 111; + private static final int SUB_SUBVIEW_2_REF = 112; + private static final int PROJECT_VIEW_1_REF = 1111; + private static final int PROJECT_VIEW_2_REF = 1112; + private static final int PROJECT_VIEW_3_REF = 1121; + private static final int PROJECT_VIEW_4_REF = 12; + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule() + .setRoot(builder(VIEW, ROOT_REF) + .addChildren( + builder(SUBVIEW, SUBVIEW_REF) + .addChildren( + builder(SUBVIEW, SUB_SUBVIEW_1_REF) + .addChildren( + builder(PROJECT_VIEW, PROJECT_VIEW_1_REF).build(), + builder(PROJECT_VIEW, PROJECT_VIEW_2_REF).build()) + .build(), + builder(SUBVIEW, SUB_SUBVIEW_2_REF) + .addChildren( + builder(PROJECT_VIEW, PROJECT_VIEW_3_REF).build()) + .build()) + .build(), + builder(PROJECT_VIEW, PROJECT_VIEW_4_REF).build()) + .build()); + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule() + .add(CoreMetrics.DEVELOPMENT_COST) + .add(CoreMetrics.TECHNICAL_DEBT) + .add(CoreMetrics.SQALE_DEBT_RATIO) + .add(CoreMetrics.SQALE_RATING); + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + + private SqaleRatingSettings sqaleRatingSettings = mock(SqaleRatingSettings.class); + + private VisitorsCrawler underTest = new VisitorsCrawler(Arrays.asList(new SqaleMeasuresVisitor(metricRepository, measureRepository, sqaleRatingSettings))); + + @Before + public void setUp() { + when(sqaleRatingSettings.getRatingGrid()).thenReturn(RATING_GRID); + } + + @Test + public void measures_created_for_project_are_all_zero_when_they_have_no_FILE_child() { + ViewsComponent root = builder(VIEW, 1).build(); + treeRootHolder.setRoot(root); + + underTest.visit(root); + + assertThat(toEntries(measureRepository.getRawMeasures(root))) + .containsOnly( + entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create("0")), + entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(0d)), + entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(A))); + } + + private Measure createSqaleRatingMeasure(SqaleRatingGrid.SqaleRating sqaleRating) { + return newMeasureBuilder().create(sqaleRating.getIndex(), sqaleRating.name()); + } + + @Test + public void verify_aggregation_of_developmentCost_and_value_of_measures_computed_from_that() { + + long debtRoot = 9999l; + long debtSubView = 96325l; + long debtSubSubView1 = 96325l; + long debtSubSubView2 = 99633l; + addRawMeasure(TECHNICAL_DEBT_KEY, ROOT_REF, debtRoot); + addRawMeasure(TECHNICAL_DEBT_KEY, SUBVIEW_REF, debtSubView); + addRawMeasure(TECHNICAL_DEBT_KEY, SUB_SUBVIEW_1_REF, debtSubSubView1); + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_1_REF, 66000l); + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_2_REF, 4200l); + addRawMeasure(TECHNICAL_DEBT_KEY, SUB_SUBVIEW_2_REF, debtSubSubView2); + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_3_REF, 25200l); + addRawMeasure(TECHNICAL_DEBT_KEY, PROJECT_VIEW_4_REF, 33000l); + + addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_1_REF, "40"); + addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_2_REF, "70"); + addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_3_REF, "50"); + addRawMeasure(DEVELOPMENT_COST_KEY, PROJECT_VIEW_4_REF, "100"); + + underTest.visit(treeRootHolder.getRoot()); + + assertNoNewRawMeasureOnProjectViews(); + assertNewRawMeasures(SUB_SUBVIEW_1_REF, debtSubSubView1, 110, D); + assertNewRawMeasures(SUB_SUBVIEW_2_REF, debtSubSubView2, 50, E); + assertNewRawMeasures(SUBVIEW_REF, debtSubView, 160, D); + assertNewRawMeasures(ROOT_REF, debtRoot, 260, B); + } + + private void assertNewRawMeasures(int componentRef, long debt, long devCost, SqaleRatingGrid.SqaleRating sqaleRating) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly( + entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(String.valueOf(devCost))), + entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(debt / (double) devCost * 100.0)), + entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(sqaleRating))); + } + + private void assertNoNewRawMeasureOnProjectViews() { + assertNoNewRawMeasure(PROJECT_VIEW_1_REF); + assertNoNewRawMeasure(PROJECT_VIEW_2_REF); + assertNoNewRawMeasure(PROJECT_VIEW_3_REF); + assertNoNewRawMeasure(PROJECT_VIEW_4_REF); + } + + private void addRawMeasure(String metricKey, int componentRef, String value) { + measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); + } + + private void addRawMeasure(String metricKey, int componentRef, long value) { + measureRepository.addRawMeasure(componentRef, metricKey, newMeasureBuilder().create(value)); + } + + private void verifyFileMeasures(int componentRef, long measureValue, long debt, long languageCost, SqaleRatingGrid.SqaleRating expectedRating) { + long developmentCost = measureValue * languageCost; + verifyComponentMeasures(componentRef, developmentCost, debt / developmentCost, expectedRating); + } + + private void verifyComponentMeasures(int componentRef, long expectedDevCost, double expectedDebtRatio, SqaleRatingGrid.SqaleRating expectedRating) { + assertThat(toEntries(measureRepository.getAddedRawMeasures(componentRef))).containsOnly( + entryOf(DEVELOPMENT_COST_KEY, newMeasureBuilder().create(Long.toString(expectedDevCost))), + entryOf(SQALE_DEBT_RATIO_KEY, newMeasureBuilder().create(expectedDebtRatio * 100.0)), + entryOf(SQALE_RATING_KEY, createSqaleRatingMeasure(expectedRating))); + } + + private void assertNoNewRawMeasure(int componentRef) { + assertThat(measureRepository.getAddedRawMeasures(componentRef).isEmpty()).isTrue(); + } + +} -- 2.39.5