From 239c1c798c2c7685ab71c1b063072dab0be06aae Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Thu, 10 Jul 2014 17:20:58 +0200 Subject: [PATCH] SONAR-5445 Introduce new metric "SQALE Debt Ratio" --- .../sonar/batch/debt/SqaleRatingDecorator.java | 4 +++- .../batch/debt/SqaleRatingDecoratorTest.java | 10 +++++++--- .../resources/org/sonar/l10n/core.properties | 3 +++ .../org/sonar/api/measures/CoreMetrics.java | 17 +++++++++++++++++ .../sonar/api/resources/CoreMetricsTest.java | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/sonar-batch/src/main/java/org/sonar/batch/debt/SqaleRatingDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/debt/SqaleRatingDecorator.java index d94fc38f5c5..458b1d27eb0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/debt/SqaleRatingDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/debt/SqaleRatingDecorator.java @@ -76,7 +76,7 @@ public final class SqaleRatingDecorator implements Decorator { @DependedUpon public List generatesMetrics() { - return Lists.newArrayList(CoreMetrics.RATING, CoreMetrics.DEVELOPMENT_COST); + return Lists.newArrayList(CoreMetrics.RATING, CoreMetrics.DEVELOPMENT_COST, CoreMetrics.SQALE_DEBT_RATIO); } public void decorate(Resource resource, DecoratorContext context) { @@ -86,6 +86,8 @@ public final class SqaleRatingDecorator implements Decorator { long debt = getMeasureValue(context, CoreMetrics.TECHNICAL_DEBT); double density = computeDensity(debt, developmentCost); + context.saveMeasure(CoreMetrics.SQALE_DEBT_RATIO, 100.0 * density); + SqaleRatingGrid ratingGrid = new SqaleRatingGrid(sqaleRatingSettings.getRatingGrid()); context.saveMeasure(createRatingMeasure(ratingGrid.getRatingForDensity(density))); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java index cd3029f6e51..48a58f4a050 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/debt/SqaleRatingDecoratorTest.java @@ -55,7 +55,7 @@ public class SqaleRatingDecoratorTest { static final Long ONE_DAY_IN_MINUTES = 8L * 60; Settings settings; - Metric[] metrics = {CoreMetrics.NCLOC, CoreMetrics.ABSTRACTNESS, CoreMetrics.COMPLEXITY}; + Metric[] metrics = {CoreMetrics.NCLOC, CoreMetrics.COMPLEXITY}; @Mock DecoratorContext context; @@ -81,7 +81,7 @@ public class SqaleRatingDecoratorTest { @Test public void generates_metrics() throws Exception { SqaleRatingDecorator decorator = new SqaleRatingDecorator(); - assertThat(decorator.generatesMetrics()).hasSize(2); + assertThat(decorator.generatesMetrics()).hasSize(3); } @Test @@ -121,6 +121,7 @@ public class SqaleRatingDecoratorTest { decorator.decorate(file, context); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 3.0))); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600"))); + verify(context).saveMeasure(CoreMetrics.SQALE_DEBT_RATIO, 1500d); verify(context).getMeasure(CoreMetrics.NCLOC); } @@ -138,6 +139,7 @@ public class SqaleRatingDecoratorTest { decorator.decorate(file, context); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 1.0))); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600"))); + verify(context).saveMeasure(CoreMetrics.SQALE_DEBT_RATIO, 0d); verify(context).getMeasure(CoreMetrics.NCLOC); } @@ -150,11 +152,12 @@ public class SqaleRatingDecoratorTest { when(context.getResource()).thenReturn(file); when(context.getMeasure(CoreMetrics.NCLOC)).thenReturn(new Measure(CoreMetrics.NCLOC, 10.0)); - when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure(CoreMetrics.TECHNICAL_DEBT, 100000000000.0)); + when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure(CoreMetrics.TECHNICAL_DEBT, 960000.0)); decorator.decorate(file, context); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 5.0))); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600"))); + verify(context).saveMeasure(CoreMetrics.SQALE_DEBT_RATIO, 10000d); verify(context).getMeasure(CoreMetrics.NCLOC); } @@ -170,6 +173,7 @@ public class SqaleRatingDecoratorTest { decorator.decorate(mock(File.class), context); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.RATING, 3.0))); verify(context).saveMeasure(argThat(new IsMeasure(CoreMetrics.DEVELOPMENT_COST, "9600"))); + verify(context).saveMeasure(CoreMetrics.SQALE_DEBT_RATIO, 1500d); verify(context, never()).getMeasure(CoreMetrics.NCLOC); } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 356976050a2..c4d35c11947 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2516,6 +2516,9 @@ metric.new_technical_debt.description=Technical Debt on new code metric.sqale_rating.name=SQALE Rating metric.sqale_rating.description=Density of technical debt computed by dividing the technical debt by the estimated effort to develop from scratch an application. +metric.sqale_debt_ratio.name=SQALE Technical Debt Ratio +metric.sqale_debt_ratio.description=Ratio of the technical debt compared to what it would cost to develop the whole source code from scratch. + #------------------------------------------------------------------------------ # diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java index c0d57a89728..2545bd0699a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java @@ -2155,6 +2155,23 @@ public final class CoreMetrics { .setHidden(true) .create(); + /** + * @since 4.5 + */ + public static final String SQALE_DEBT_RATIO_KEY = "sqale_debt_ratio"; + + /** + * @since 4.5 + */ + public static final Metric SQALE_DEBT_RATIO = new Metric.Builder(SQALE_DEBT_RATIO_KEY, "SQALE Technical Debt Ratio", Metric.ValueType.PERCENT) + .setDescription("Ratio of the technical debt compared to what it would cost to develop the whole source code from scratch.") + .setDomain(DOMAIN_TECHNICAL_DEBT) + .setDirection(Metric.DIRECTION_WORST) + .setOptimizedBestValue(true) + .setBestValue(0.0) + .setQualitative(true) + .create(); + // -------------------------------------------------------------------------------------------------------------------- // // FILE DATA diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java index 086005be0f8..6d4156dc668 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/CoreMetricsTest.java @@ -32,7 +32,7 @@ public class CoreMetricsTest { @Test public void read_metrics_from_class_reflection() { List metrics = CoreMetrics.getMetrics(); - assertThat(metrics).hasSize(152); + assertThat(metrics).hasSize(153); assertThat(metrics).contains(CoreMetrics.NCLOC, CoreMetrics.DIRECTORIES); } -- 2.39.5