diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-02-28 18:05:03 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-02-28 18:05:03 +0100 |
commit | 1ec6704480f79ab80b0c43c2a663d810df93f1b7 (patch) | |
tree | 90d4e15ae9dba55d6b0451cd2d0e58efc74b39d5 | |
parent | 8c1d9bf46953dfde3ab5b4ade5a80e4dcaa9d10d (diff) | |
download | sonarqube-1ec6704480f79ab80b0c43c2a663d810df93f1b7.tar.gz sonarqube-1ec6704480f79ab80b0c43c2a663d810df93f1b7.zip |
SONAR-2218 compute coverage on new/changed code
8 files changed, 387 insertions, 102 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java index b548de52143..d5a6e95c047 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/AbstractCoverageDecorator.java @@ -22,11 +22,15 @@ package org.sonar.plugins.core.sensors; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependedUpon; +import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; +import java.util.Arrays; +import java.util.Collection; + public abstract class AbstractCoverageDecorator implements Decorator { public boolean shouldExecuteOnProject(Project project) { @@ -34,36 +38,60 @@ public abstract class AbstractCoverageDecorator implements Decorator { } @DependedUpon - public Metric generatesCoverage() { - return getTargetMetric(); + public Collection<Metric> generatedMetrics() { + return Arrays.asList(getGeneratedMetric(), getGeneratedMetricForNewCode()); } public void decorate(final Resource resource, final DecoratorContext context) { if (shouldDecorate(resource, context)) { - saveLineCoverage(context); + computeMeasure(context); + computeMeasureForNewCode(context); } } protected boolean shouldDecorate(final Resource resource, final DecoratorContext context) { - return context.getMeasure(getTargetMetric()) == null && !ResourceUtils.isUnitTestClass(resource); + return context.getMeasure(getGeneratedMetric()) == null && !ResourceUtils.isUnitTestClass(resource); + } + + private void computeMeasure(DecoratorContext context) { + Long elements = countElements(context); + if (elements != null && elements > 0L) { + Long coveredElements = countCoveredElements(context); + context.saveMeasure(getGeneratedMetric(), calculateCoverage(coveredElements, elements)); + } } - private void saveLineCoverage(DecoratorContext context) { - Double elements = countElements(context); - Double coveredElements = countCoveredElements(context); + private void computeMeasureForNewCode(DecoratorContext context) { + Measure measure = new Measure(getGeneratedMetricForNewCode()); + boolean hasValue = false; + /* TODO remove this magic number */ + for (int periodIndex = 1; periodIndex <= 5; periodIndex++) { + Long elements = countElementsForNewCode(context, periodIndex); - if (elements != null && elements > 0.0 && coveredElements != null) { - context.saveMeasure(getTargetMetric(), calculateCoverage(coveredElements, elements)); + if (elements != null && elements > 0L) { + long coveredElements = countCoveredElementsForNewCode(context, periodIndex); + measure.setVariation(periodIndex, calculateCoverage(coveredElements, elements)); + hasValue = true; + } + } + if (hasValue) { + context.saveMeasure(measure); } } - private double calculateCoverage(final Double coveredLines, final Double lines) { + private double calculateCoverage(final long coveredLines, final long lines) { return (100.0 * coveredLines) / lines; } - protected abstract Metric getTargetMetric(); + protected abstract Metric getGeneratedMetric(); + + protected abstract Long countElements(DecoratorContext context); + + protected abstract long countCoveredElements(DecoratorContext context); + + protected abstract Metric getGeneratedMetricForNewCode(); - protected abstract Double countCoveredElements(DecoratorContext context); + protected abstract Long countElementsForNewCode(DecoratorContext context, int periodIndex); - protected abstract Double countElements(DecoratorContext context); + protected abstract long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex); } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java index ce4c61bd11a..d9f3cc76ef0 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java @@ -28,27 +28,45 @@ import org.sonar.api.measures.Metric; import java.util.Arrays; import java.util.List; -public class BranchCoverageDecorator extends AbstractCoverageDecorator { +public final class BranchCoverageDecorator extends AbstractCoverageDecorator { + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_TO_COVER, + CoreMetrics.NEW_UNCOVERED_CONDITIONS, CoreMetrics.NEW_CONDITIONS_TO_COVER); + } @Override - protected Metric getTargetMetric() { + protected Metric getGeneratedMetric() { return CoreMetrics.BRANCH_COVERAGE; } - @DependsUpon - public List<Metric> dependsUponMetrics() { - return Arrays.asList(CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_TO_COVER); + @Override + protected Long countElements(DecoratorContext context) { + return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L); } @Override - protected Double countCoveredElements(DecoratorContext context) { - double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0.0); - double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + protected long countCoveredElements(DecoratorContext context) { + long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0L); + long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L); return conditions - uncoveredConditions; } @Override - protected Double countElements(DecoratorContext context) { - return MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + protected Metric getGeneratedMetricForNewCode() { + return CoreMetrics.NEW_BRANCH_COVERAGE; + } + + @Override + protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) { + return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex); + } + + @Override + protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) { + long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS), periodIndex, 0L); + long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L); + return conditions - uncoveredConditions; } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java index 4342742a87e..0944f8dabcd 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java @@ -20,39 +20,69 @@ package org.sonar.plugins.core.sensors; import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.DependedUpon; import org.sonar.api.batch.DependsUpon; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.MeasureUtils; import org.sonar.api.measures.Metric; import java.util.Arrays; +import java.util.Collection; import java.util.List; -public class CoverageDecorator extends AbstractCoverageDecorator { +public final class CoverageDecorator extends AbstractCoverageDecorator { + + @DependsUpon + public Collection<Metric> usedMetrics() { + return Arrays.asList(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER, + CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS, + CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS); + } @Override - protected Metric getTargetMetric() { + protected Metric getGeneratedMetric() { return CoreMetrics.COVERAGE; } - @DependsUpon - public List<Metric> dependsUponMetrics() { - return Arrays.asList(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS); + @Override + protected Long countElements(DecoratorContext context) { + long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L); + long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L); + return lines + conditions; } @Override - protected Double countCoveredElements(DecoratorContext context) { - double uncoveredLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0.0); - double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); - double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0.0); - double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); + protected long countCoveredElements(DecoratorContext context) { + long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0L); + long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L); + long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_CONDITIONS), 0L); + long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0L); return lines + conditions - uncoveredConditions - uncoveredLines; } + + @Override - protected Double countElements(DecoratorContext context) { - double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); - double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.CONDITIONS_TO_COVER), 0.0); - return lines + conditions; + protected Metric getGeneratedMetricForNewCode() { + return CoreMetrics.NEW_COVERAGE; + } + + @Override + protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) { + Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex); + if (newLinesToCover!=null) { + long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L); + return newLinesToCover + newConditionsToCover; + } + return null; + } + + @Override + protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) { + long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex, 0L); + long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES), periodIndex, 0L); + long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_CONDITIONS), periodIndex, 0L); + long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_CONDITIONS_TO_COVER), periodIndex, 0L); + return newLines + newConditions - newUncoveredConditions - newUncoveredLines; } }
\ No newline at end of file diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java index 5d8ed7bd57a..d702f6b3c12 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java @@ -28,27 +28,46 @@ import org.sonar.api.measures.Metric; import java.util.Arrays; import java.util.List; -public class LineCoverageDecorator extends AbstractCoverageDecorator { +public final class LineCoverageDecorator extends AbstractCoverageDecorator { + + @DependsUpon + public List<Metric> dependsUponMetrics() { + return Arrays.asList(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, + CoreMetrics.NEW_LINES_TO_COVER); + } @Override - protected Metric getTargetMetric() { + protected Metric getGeneratedMetric() { return CoreMetrics.LINE_COVERAGE; } - @DependsUpon - public List<Metric> dependsUponMetrics() { - return Arrays.asList(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER); + @Override + protected Long countElements(DecoratorContext context) { + return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L); } @Override - protected Double countCoveredElements(DecoratorContext context) { - double uncoveredLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0.0); - double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); + protected long countCoveredElements(DecoratorContext context) { + long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.UNCOVERED_LINES), 0L); + long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0L); return lines - uncoveredLines; } + @Override - protected Double countElements(DecoratorContext context) { - return MeasureUtils.getValue(context.getMeasure(CoreMetrics.LINES_TO_COVER), 0.0); + protected Metric getGeneratedMetricForNewCode() { + return CoreMetrics.NEW_LINE_COVERAGE; + } + + @Override + protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) { + return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex); + } + + @Override + protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) { + long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_UNCOVERED_LINES), periodIndex, 0L); + long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_LINES_TO_COVER), periodIndex, 0L); + return lines - uncoveredLines; } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java index f4d56097161..0104f20faa5 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java @@ -56,7 +56,7 @@ public final class NewCoverageAggregator implements Decorator { } } - private void aggregate(DecoratorContext context, Metric metric, int maxPeriods) { + void aggregate(DecoratorContext context, Metric metric, int maxPeriods) { int[] variations = {0,0,0,0,0}; boolean[] hasValues = {false,false,false,false,false}; for (Measure child : context.getChildrenMeasures(metric)) { @@ -80,7 +80,7 @@ public final class NewCoverageAggregator implements Decorator { } } - private boolean shouldDecorate(Resource resource) { + boolean shouldDecorate(Resource resource) { return Scopes.isHigherThan(resource, Scopes.FILE); } } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java index e98980ba776..2c529e87a96 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/BranchCoverageDecoratorTest.java @@ -31,7 +31,7 @@ import org.sonar.api.resources.Project; public class BranchCoverageDecoratorTest { @Test - public void noBranchCoverageIfMissingConditions() { + public void shouldNotSaveBranchCoverageIfMissingConditions() { Project resource = mock(Project.class); when(resource.getScope()).thenReturn(Project.SCOPE_SET); when(resource.getQualifier()).thenReturn(Project.QUALIFIER_SUBVIEW); @@ -43,7 +43,7 @@ public class BranchCoverageDecoratorTest { } @Test - public void branchCoverage() { + public void shouldSaveBranchCoverage() { Project resource = mock(Project.class); when(resource.getScope()).thenReturn(Project.SCOPE_SET); when(resource.getQualifier()).thenReturn(Project.QUALIFIER_PROJECT); diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageAggregatorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageAggregatorTest.java new file mode 100644 index 00000000000..e5d7ea44a5c --- /dev/null +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageAggregatorTest.java @@ -0,0 +1,96 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.plugins.core.timemachine; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Test; +import org.mockito.Matchers; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; + +import java.util.Arrays; +import java.util.Collections; + +import static org.mockito.Mockito.*; + +public class NewCoverageAggregatorTest { + + @Test + public void shouldNotSaveDataWhenNoMeasures() { + NewCoverageAggregator aggregator = new NewCoverageAggregator(); + DecoratorContext context = mock(DecoratorContext.class); + when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Collections.<Measure>emptyList()); + + aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3); + + verify(context, never()).saveMeasure(Matchers.<Measure>anyObject()); + } + + @Test + public void shouldNotsetZeroWhenNoValueOnPeriod() { + NewCoverageAggregator aggregator = new NewCoverageAggregator(); + DecoratorContext context = mock(DecoratorContext.class); + when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Arrays.asList(newMeasure(null, 3.0, 2.0), newMeasure(null, 13.0, null))); + + aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3); + + verify(context).saveMeasure(argThat(new BaseMatcher<Measure>() { + public boolean matches(Object o) { + Measure m = (Measure)o; + return m.getVariation1()==null; + } + + public void describeTo(Description description) { + + } + })); + } + + + @Test + public void shouldSumValues() { + NewCoverageAggregator aggregator = new NewCoverageAggregator(); + DecoratorContext context = mock(DecoratorContext.class); + when(context.getChildrenMeasures(CoreMetrics.NEW_LINES_TO_COVER)).thenReturn(Arrays.asList(newMeasure(null, 3.0, 2.0), newMeasure(null, 13.0, null))); + + aggregator.aggregate(context, CoreMetrics.NEW_LINES_TO_COVER, 3); + + verify(context).saveMeasure(argThat(new BaseMatcher<Measure>() { + public boolean matches(Object o) { + Measure m = (Measure)o; + return m.getVariation2()==16.0 && m.getVariation3()==2.0; + } + + public void describeTo(Description description) { + + } + })); + } + + + private Measure newMeasure(Double variation1, Double variation2, Double variation3) { + return new Measure(CoreMetrics.NEW_LINES_TO_COVER) + .setVariation1(variation1) + .setVariation2(variation2) + .setVariation3(variation3); + } +} 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 b33487af40f..80f9451ec42 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 @@ -107,6 +107,57 @@ public final class CoreMetrics { public static final Metric PUBLIC_API = new Metric(PUBLIC_API_KEY, "Public API", "Public API", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_SIZE).setFormula(new SumChildValuesFormula(false)); + + + + + + //-------------------------------------------------------------------------------------------------------------------- + // + // DOCUMENTATION + // + //-------------------------------------------------------------------------------------------------------------------- + + public static final String COMMENT_LINES_KEY = "comment_lines"; + public static final Metric COMMENT_LINES = new Metric(COMMENT_LINES_KEY, "Comment lines", "Number of comment lines", + Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DOCUMENTATION).setFormula(new SumChildValuesFormula(false)); + + public static final String COMMENT_LINES_DENSITY_KEY = "comment_lines_density"; + public static final Metric COMMENT_LINES_DENSITY = new Metric(COMMENT_LINES_DENSITY_KEY, "Comments (%)", + "Comments balanced by ncloc + comment lines", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_DOCUMENTATION); + + public static final String COMMENT_BLANK_LINES_KEY = "comment_blank_lines"; + public static final Metric COMMENT_BLANK_LINES = new Metric(COMMENT_BLANK_LINES_KEY, "Blank comments", + "Comments that do not contain comments", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, CoreMetrics.DOMAIN_DOCUMENTATION) + .setFormula(new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true); + + public static final String PUBLIC_DOCUMENTED_API_DENSITY_KEY = "public_documented_api_density"; + public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric(PUBLIC_DOCUMENTED_API_DENSITY_KEY, "Public documented API (%)", + "Public documented classes and methods balanced by ncloc", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, + DOMAIN_DOCUMENTATION).setWorstValue(0.0).setBestValue(100.0).setOptimizedBestValue(true); + + public static final String PUBLIC_UNDOCUMENTED_API_KEY = "public_undocumented_api"; + public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric(PUBLIC_UNDOCUMENTED_API_KEY, "Public undocumented API", + "Public undocumented classes, methods and variables", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION) + .setBestValue(0.0).setDirection(Metric.DIRECTION_WORST).setOptimizedBestValue(true).setFormula( + new SumChildValuesFormula(false)); + + public static final String COMMENTED_OUT_CODE_LINES_KEY = "commented_out_code_lines"; + public static final Metric COMMENTED_OUT_CODE_LINES = new Metric(COMMENTED_OUT_CODE_LINES_KEY, "Commented LOCs", + "Commented lines of code", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION).setFormula( + new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true); + + + + + + + //-------------------------------------------------------------------------------------------------------------------- + // + // COMPLEXITY + // + //-------------------------------------------------------------------------------------------------------------------- + public static final String COMPLEXITY_KEY = "complexity"; public static final Metric COMPLEXITY = new Metric(COMPLEXITY_KEY, "Complexity", "Cyclomatic complexity", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_COMPLEXITY).setFormula(new SumChildValuesFormula(false)); @@ -150,37 +201,12 @@ public final class CoreMetrics { "Paragraph distribution /complexity", "Paragraph distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); - public static final String COMMENT_LINES_KEY = "comment_lines"; - public static final Metric COMMENT_LINES = new Metric(COMMENT_LINES_KEY, "Comment lines", "Number of comment lines", - Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DOCUMENTATION).setFormula(new SumChildValuesFormula(false)); - - public static final String COMMENT_LINES_DENSITY_KEY = "comment_lines_density"; - public static final Metric COMMENT_LINES_DENSITY = new Metric(COMMENT_LINES_DENSITY_KEY, "Comments (%)", - "Comments balanced by ncloc + comment lines", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_DOCUMENTATION); - - public static final String COMMENT_BLANK_LINES_KEY = "comment_blank_lines"; - public static final Metric COMMENT_BLANK_LINES = new Metric(COMMENT_BLANK_LINES_KEY, "Blank comments", - "Comments that do not contain comments", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, CoreMetrics.DOMAIN_DOCUMENTATION) - .setFormula(new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true); - - public static final String PUBLIC_DOCUMENTED_API_DENSITY_KEY = "public_documented_api_density"; - public static final Metric PUBLIC_DOCUMENTED_API_DENSITY = new Metric(PUBLIC_DOCUMENTED_API_DENSITY_KEY, "Public documented API (%)", - "Public documented classes and methods balanced by ncloc", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, - DOMAIN_DOCUMENTATION).setWorstValue(0.0).setBestValue(100.0).setOptimizedBestValue(true); - - public static final String PUBLIC_UNDOCUMENTED_API_KEY = "public_undocumented_api"; - public static final Metric PUBLIC_UNDOCUMENTED_API = new Metric(PUBLIC_UNDOCUMENTED_API_KEY, "Public undocumented API", - "Public undocumented classes, methods and variables", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION) - .setBestValue(0.0).setDirection(Metric.DIRECTION_WORST).setOptimizedBestValue(true).setFormula( - new SumChildValuesFormula(false)); - - public static final String COMMENTED_OUT_CODE_LINES_KEY = "commented_out_code_lines"; - public static final Metric COMMENTED_OUT_CODE_LINES = new Metric(COMMENTED_OUT_CODE_LINES_KEY, "Commented LOCs", - "Commented lines of code", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION).setFormula( - new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true); - + //-------------------------------------------------------------------------------------------------------------------- + // // UNIT TESTS + // + //-------------------------------------------------------------------------------------------------------------------- public static final String TESTS_KEY = "tests"; public static final Metric TESTS = new Metric(TESTS_KEY, "Unit tests", "Number of unit tests", Metric.ValueType.INT, @@ -217,8 +243,26 @@ public final class CoreMetrics { Metric.DIRECTION_WORST, false, DOMAIN_TESTS); public static final String COVERAGE_KEY = "coverage"; - public static final Metric COVERAGE = new Metric(COVERAGE_KEY, "Coverage", "Coverage by unit tests", Metric.ValueType.PERCENT, - Metric.DIRECTION_BETTER, true, DOMAIN_TESTS).setWorstValue(0.0).setBestValue(100.0); + public static final Metric COVERAGE = new Metric.Builder(COVERAGE_KEY, Metric.ValueType.PERCENT) + .setName("Coverage") + .setDescription("Coverage by unit tests") + .setDirection(Metric.DIRECTION_BETTER) + .setQualitative(true) + .setDomain(DOMAIN_TESTS) + .setWorstValue(0.0) + .setBestValue(100.0) + .create(); + + public static final String NEW_COVERAGE_KEY = "new_coverage"; + public static final Metric NEW_COVERAGE = new Metric.Builder(NEW_COVERAGE_KEY, Metric.ValueType.PERCENT) + .setName("New coverage") + .setDescription("Coverage of new/changed code") + .setDirection(Metric.DIRECTION_BETTER) + .setQualitative(true) + .setDomain(DOMAIN_TESTS) + .setWorstValue(0.0) + .setBestValue(100.0) + .create(); public static final String LINES_TO_COVER_KEY = "lines_to_cover"; public static final Metric LINES_TO_COVER = new Metric(LINES_TO_COVER_KEY, "Lines to cover", "Lines to cover", Metric.ValueType.INT, @@ -253,8 +297,24 @@ public final class CoreMetrics { .create(); public static final String LINE_COVERAGE_KEY = "line_coverage"; - public static final Metric LINE_COVERAGE = new Metric(LINE_COVERAGE_KEY, "Line coverage", "Line coverage", Metric.ValueType.PERCENT, - Metric.DIRECTION_BETTER, true, DOMAIN_TESTS); + public static final Metric LINE_COVERAGE = new Metric.Builder(LINE_COVERAGE_KEY, Metric.ValueType.PERCENT) + .setName("Line coverage") + .setDescription("Line coverage") + .setDirection(Metric.DIRECTION_BETTER) + .setQualitative(true) + .setDomain(DOMAIN_TESTS) + .create(); + + public static final String NEW_LINE_COVERAGE_KEY = "new_line_coverage"; + public static final Metric NEW_LINE_COVERAGE = new Metric.Builder(NEW_LINE_COVERAGE_KEY, Metric.ValueType.PERCENT) + .setName("New line coverage") + .setDescription("Line coverage of added/changed code") + .setDirection(Metric.DIRECTION_BETTER) + .setQualitative(true) + .setWorstValue(0.0) + .setBestValue(100.0) + .setDomain(DOMAIN_TESTS) + .create(); public static final String COVERAGE_LINE_HITS_DATA_KEY = "coverage_line_hits_data"; public static final Metric COVERAGE_LINE_HITS_DATA = new Metric.Builder(COVERAGE_LINE_HITS_DATA_KEY, Metric.ValueType.DATA) @@ -308,6 +368,17 @@ public final class CoreMetrics { .setBestValue(100.0) .create(); + public static final String NEW_BRANCH_COVERAGE_KEY = "new_branch_coverage"; + public static final Metric NEW_BRANCH_COVERAGE = new Metric.Builder(NEW_BRANCH_COVERAGE_KEY, Metric.ValueType.PERCENT) + .setName("NEw branch coverage") + .setDescription("Branch coverage of new/changed code") + .setDirection(Metric.DIRECTION_BETTER) + .setQualitative(true) + .setDomain(DOMAIN_TESTS) + .setWorstValue(0.0) + .setBestValue(100.0) + .create(); + @Deprecated public static final String BRANCH_COVERAGE_HITS_DATA_KEY = "branch_coverage_hits_data"; @@ -339,6 +410,12 @@ public final class CoreMetrics { .create(); + //-------------------------------------------------------------------------------------------------------------------- + // + // DUPLICATIONS + // + //-------------------------------------------------------------------------------------------------------------------- + public static final String DUPLICATED_LINES_KEY = "duplicated_lines"; public static final Metric DUPLICATED_LINES = new Metric(DUPLICATED_LINES_KEY, "Duplicated lines", "Duplicated lines", Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_DUPLICATION).setBestValue(0.0).setOptimizedBestValue(true); @@ -360,7 +437,12 @@ public final class CoreMetrics { public static final Metric DUPLICATIONS_DATA = new Metric(DUPLICATIONS_DATA_KEY, "Duplications details", "Duplications details", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_DUPLICATION); - /* coding rules */ + + //-------------------------------------------------------------------------------------------------------------------- + // + // CODING RULES + // + //-------------------------------------------------------------------------------------------------------------------- /** * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007 */ @@ -483,7 +565,11 @@ public final class CoreMetrics { Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true); + //-------------------------------------------------------------------------------------------------------------------- + // // DESIGN + // + //-------------------------------------------------------------------------------------------------------------------- public static final String ABSTRACTNESS_KEY = "abstractness"; public static final Metric ABSTRACTNESS = new Metric(ABSTRACTNESS_KEY, "Abstractness", "Abstractness", Metric.ValueType.PERCENT, @@ -582,25 +668,12 @@ public final class CoreMetrics { Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_DESIGN).setHidden(true); - // Alerts - public static final String ALERT_STATUS_KEY = "alert_status"; - public static final Metric ALERT_STATUS = new Metric.Builder(ALERT_STATUS_KEY, Metric.ValueType.LEVEL) - .setName("Alert") - .setDescription("Alert") - .setDirection(Metric.DIRECTION_BETTER) - .setQualitative(true) - .setDomain(DOMAIN_GENERAL) - .create(); - - - /* quality profile */ - public static final String PROFILE_KEY = "profile"; - public static final Metric PROFILE = new Metric(PROFILE_KEY, "Profile", "Selected quality profile", Metric.ValueType.DATA, - Metric.DIRECTION_NONE, false, DOMAIN_GENERAL); - - + //-------------------------------------------------------------------------------------------------------------------- + // // SCM // These metrics are computed by the SCM Activity plugin, since version 1.2. + // + //-------------------------------------------------------------------------------------------------------------------- public static final String SCM_COMMITS_KEY = "commits"; public static final Metric SCM_COMMITS = new Metric.Builder(SCM_COMMITS_KEY, Metric.ValueType.INT) @@ -635,6 +708,27 @@ public final class CoreMetrics { .setDomain(DOMAIN_SCM) .create(); + + //-------------------------------------------------------------------------------------------------------------------- + // + // OTHERS + // + //-------------------------------------------------------------------------------------------------------------------- + public static final String ALERT_STATUS_KEY = "alert_status"; + public static final Metric ALERT_STATUS = new Metric.Builder(ALERT_STATUS_KEY, Metric.ValueType.LEVEL) + .setName("Alert") + .setDescription("Alert") + .setDirection(Metric.DIRECTION_BETTER) + .setQualitative(true) + .setDomain(DOMAIN_GENERAL) + .create(); + + + public static final String PROFILE_KEY = "profile"; + public static final Metric PROFILE = new Metric(PROFILE_KEY, "Profile", "Selected quality profile", Metric.ValueType.DATA, + Metric.DIRECTION_NONE, false, DOMAIN_GENERAL); + + public static List<Metric> metrics = Lists.newLinkedList(); public static List<Metric> getMetrics() { |