diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-02-25 00:16:09 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-02-25 07:44:16 +0100 |
commit | d4beaec49895945d23d509d1502790794b008d56 (patch) | |
tree | e10aef01542a6de8a4b00b985870dfdcdbc3a700 /sonar-plugin-api | |
parent | 2dc09dd0800e0fca575133775e4b97dc5f711104 (diff) | |
download | sonarqube-d4beaec49895945d23d509d1502790794b008d56.tar.gz sonarqube-d4beaec49895945d23d509d1502790794b008d56.zip |
SONAR-2218 Add CoverageMeasuresBuilder to API + add Metric.Builder, first step to get an immutable Metric class
Diffstat (limited to 'sonar-plugin-api')
6 files changed, 573 insertions, 51 deletions
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 0b5c68efb46..d7c94b4853b 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 @@ -19,15 +19,13 @@ */ package org.sonar.api.measures; +import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Scopes; import org.sonar.api.utils.SonarException; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * @since 1.10 @@ -43,6 +41,7 @@ public final class CoreMetrics { public static final String DOMAIN_COMPLEXITY = "Complexity"; public static final String DOMAIN_DOCUMENTATION = "Documentation"; public static final String DOMAIN_RULES = "Rules"; + public static final String DOMAIN_SCM = "SCM"; /** * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007 @@ -180,7 +179,12 @@ public final class CoreMetrics { "Commented lines of code", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_DOCUMENTATION).setFormula( new SumChildValuesFormula(false)).setBestValue(0.0).setOptimizedBestValue(true); - /* unit tests */ + + + + + // 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, Metric.DIRECTION_WORST, false, DOMAIN_TESTS); @@ -214,33 +218,83 @@ public final class CoreMetrics { public static final Metric LINES_TO_COVER = new Metric(LINES_TO_COVER_KEY, "Lines to cover", "Lines to cover", Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)).setHidden(true); + public static final String UNCOVERED_LINES_KEY = "uncovered_lines"; - public static final Metric UNCOVERED_LINES = new Metric(UNCOVERED_LINES_KEY, "Uncovered lines", "Uncovered lines", Metric.ValueType.INT, - Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)); + public static final Metric UNCOVERED_LINES = new Metric.Builder(UNCOVERED_LINES_KEY, Metric.ValueType.INT) + .setName("Uncovered lines") + .setDescription("Uncovered lines") + .setDirection(Metric.DIRECTION_WORST) + .setDomain(DOMAIN_TESTS) + .setFormula(new SumChildValuesFormula(false)) + .create(); + + public static final String NEW_UNCOVERED_LINES_KEY = "new_uncovered_lines"; + public static final Metric NEW_UNCOVERED_LINES = new Metric.Builder(NEW_UNCOVERED_LINES_KEY, Metric.ValueType.INT) + .setName("New uncovered lines") + .setDescription("New uncovered lines") + .setDirection(Metric.DIRECTION_WORST) + .setDomain(DOMAIN_TESTS) + .setFormula(new SumChildValuesFormula(false)) + .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 String COVERAGE_LINE_HITS_DATA_KEY = "coverage_line_hits_data"; - public static final Metric COVERAGE_LINE_HITS_DATA = new Metric(COVERAGE_LINE_HITS_DATA_KEY, "Coverage hits data", - "Code coverage line hits data", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_TESTS); + public static final Metric COVERAGE_LINE_HITS_DATA = new Metric.Builder(COVERAGE_LINE_HITS_DATA_KEY, Metric.ValueType.DATA) + .setDomain(DOMAIN_TESTS) + .create(); public static final String CONDITIONS_TO_COVER_KEY = "conditions_to_cover"; public static final Metric CONDITIONS_TO_COVER = new Metric(CONDITIONS_TO_COVER_KEY, "Conditions to cover", "Conditions to cover", Metric.ValueType.INT, Metric.DIRECTION_BETTER, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)).setHidden(true); public static final String UNCOVERED_CONDITIONS_KEY = "uncovered_conditions"; - public static final Metric UNCOVERED_CONDITIONS = new Metric(UNCOVERED_CONDITIONS_KEY, "Uncovered conditions", "Uncovered conditions", - Metric.ValueType.INT, Metric.DIRECTION_WORST, false, DOMAIN_TESTS).setFormula(new SumChildValuesFormula(false)); + public static final Metric UNCOVERED_CONDITIONS = new Metric.Builder(UNCOVERED_CONDITIONS_KEY, Metric.ValueType.INT) + .setName("Uncovered conditions") + .setDescription("Uncovered conditions") + .setDirection(Metric.DIRECTION_WORST) + .setDomain(DOMAIN_TESTS) + .setFormula(new SumChildValuesFormula(false)) + .create(); + + public static final String NEW_UNCOVERED_CONDITIONS_KEY = "new_uncovered_conditions"; + public static final Metric NEW_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_UNCOVERED_CONDITIONS_KEY, Metric.ValueType.INT) + .setName("New uncovered conditions") + .setDescription("New uncovered conditions") + .setDirection(Metric.DIRECTION_WORST) + .setDomain(DOMAIN_TESTS) + .setFormula(new SumChildValuesFormula(false)) + .create(); public static final String BRANCH_COVERAGE_KEY = "branch_coverage"; public static final Metric BRANCH_COVERAGE = new Metric(BRANCH_COVERAGE_KEY, "Branch coverage", "Branch coverage", Metric.ValueType.PERCENT, Metric.DIRECTION_BETTER, true, DOMAIN_TESTS).setWorstValue(0.0).setBestValue(100.0); public static final String BRANCH_COVERAGE_HITS_DATA_KEY = "branch_coverage_hits_data"; - public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric(BRANCH_COVERAGE_HITS_DATA_KEY, "Branch coverage hits", - "Branch coverage hits", Metric.ValueType.DATA, Metric.DIRECTION_NONE, false, DOMAIN_TESTS); + public static final Metric BRANCH_COVERAGE_HITS_DATA = new Metric.Builder(BRANCH_COVERAGE_HITS_DATA_KEY, Metric.ValueType.DATA) + .setName("Branch coverage hits") + .setDomain(DOMAIN_TESTS) + .create(); + + public static final String CONDITIONS_BY_LINE_DATA_KEY = "conditions_by_line_data"; + + /** + * @since 2.7 + */ + public static final Metric CONDITIONS_BY_LINE_DATA = new Metric.Builder(CONDITIONS_BY_LINE_DATA_KEY, Metric.ValueType.DATA) + .setDomain(DOMAIN_TESTS) + .create(); + + public static final String COVERED_CONDITIONS_BY_LINE_DATA_KEY = "covered_conditions_by_line_data"; + + /** + * @since 2.7 + */ + public static final Metric COVERED_CONDITIONS_BY_LINE_DATA = new Metric.Builder(COVERED_CONDITIONS_BY_LINE_DATA_KEY, Metric.ValueType.DATA) + .setDomain(DOMAIN_TESTS) + .create(); /** * @deprecated replaced since 1.11 by UNCOVERED_LINES and UNCOVERED_CONDITIONS @@ -398,7 +452,11 @@ public final class CoreMetrics { public static final Metric NEW_INFO_VIOLATIONS = new Metric(NEW_INFO_VIOLATIONS_KEY, "New Info violations", "New Info violations", Metric.ValueType.INT, Metric.DIRECTION_WORST, true, DOMAIN_RULES).setHidden(true).setBestValue(0.0).setOptimizedBestValue(true); - /* Design */ + + + + + // DESIGN public static final String ABSTRACTNESS_KEY = "abstractness"; public static final Metric ABSTRACTNESS = new Metric(ABSTRACTNESS_KEY, "Abstractness", "Abstractness", Metric.ValueType.PERCENT, @@ -506,9 +564,28 @@ public final class CoreMetrics { 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 = new ArrayList<Metric>(); - public static Set<String> metricKeys = new HashSet<String>(); + + + + // SCM + + public static final String SCM_AUTHORS_BY_LINE_KEY = "blame_authors_data";//"scm_authors_by_line"; + public static final Metric SCM_AUTHORS_BY_LINE = new Metric.Builder(SCM_AUTHORS_BY_LINE_KEY, Metric.ValueType.DATA) + .setDomain(DOMAIN_SCM) + .create(); + + public static final String SCM_REVISIONS_BY_LINE_KEY = "blame_revision_data";//"scm_revisions_by_line"; + public static final Metric SCM_REVISIONS_BY_LINE = new Metric.Builder(SCM_REVISIONS_BY_LINE_KEY, Metric.ValueType.DATA) + .setDomain(DOMAIN_SCM) + .create(); + + public static final String SCM_LAST_UPDATE_DATETIME_BY_LINE_KEY = "blame_date_data";//"scm_last_update_datetime_by_line"; + public static final Metric SCM_LAST_UPDATE_DATETIME_BY_LINE = new Metric.Builder(SCM_LAST_UPDATE_DATETIME_BY_LINE_KEY, Metric.ValueType.DATA) + .setDomain(DOMAIN_SCM) + .create(); + + public static List<Metric> metrics = Lists.newLinkedList(); public static List<Metric> getMetrics() { if (metrics.isEmpty()) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoverageMeasuresBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoverageMeasuresBuilder.java new file mode 100644 index 00000000000..dfc37496a54 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoverageMeasuresBuilder.java @@ -0,0 +1,161 @@ +/* + * 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.api.measures; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.sonar.api.utils.KeyValueFormat; + +import java.util.*; + +/** + * @since 2.7 + */ +public final class CoverageMeasuresBuilder { + + /** + * Metrics of generated measures + */ + public static final List<Metric> METRICS = Arrays.asList( + CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.COVERAGE_LINE_HITS_DATA, + CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_BY_LINE_DATA, + CoreMetrics.COVERED_CONDITIONS_BY_LINE_DATA, CoreMetrics.BRANCH_COVERAGE_HITS_DATA); + + + private int totalCoveredLines = 0, totalConditions = 0, totalCoveredConditions = 0; + private SortedMap<Integer, Integer> hitsByLine = Maps.newTreeMap(); + private SortedMap<Integer, Integer> conditionsByLine = Maps.newTreeMap(); + private SortedMap<Integer, Integer> coveredConditionsByLine = Maps.newTreeMap(); + + private CoverageMeasuresBuilder() { + // use the factory + } + + public CoverageMeasuresBuilder reset() { + totalCoveredLines = 0; + totalConditions = 0; + totalCoveredConditions = 0; + hitsByLine.clear(); + conditionsByLine.clear(); + coveredConditionsByLine.clear(); + return this; + } + + public CoverageMeasuresBuilder setHits(int lineId, int hits) { + if (hitsByLine.containsKey(lineId)) { + throw new IllegalArgumentException("Line " + lineId + " is count twice (hits=" + hits + ")"); + } + hitsByLine.put(lineId, hits); + if (hits > 0) { + totalCoveredLines += 1; + } + return this; + } + + public CoverageMeasuresBuilder setConditions(int lineId, int conditions, int coveredConditions) { + if (conditionsByLine.containsKey(lineId)) { + throw new IllegalArgumentException("Line " + lineId + " is count twice (conditions=" + conditions + ")"); + } + if (conditions > 0) { + totalConditions += conditions; + totalCoveredConditions += coveredConditions; + conditionsByLine.put(lineId, conditions); + coveredConditionsByLine.put(lineId, coveredConditions); + } + return this; + } + + public int getCoveredLines() { + return totalCoveredLines; + } + + public int getLinesToCover() { + return hitsByLine.size(); + } + + public int getConditions() { + return totalConditions; + } + + public int getCoveredConditions() { + return totalCoveredConditions; + } + + public SortedMap<Integer, Integer> getHitsByLine() { + return Collections.unmodifiableSortedMap(hitsByLine); + } + + public SortedMap<Integer, Integer> getConditionsByLine() { + return Collections.unmodifiableSortedMap(conditionsByLine); + } + + public SortedMap<Integer, Integer> getCoveredConditionsByLine() { + return Collections.unmodifiableSortedMap(coveredConditionsByLine); + } + + public Collection<Measure> createMeasures() { + Collection<Measure> measures = Lists.newArrayList(); + if (getLinesToCover() > 0) { + measures.add(new Measure(CoreMetrics.LINES_TO_COVER, (double) getLinesToCover())); + measures.add(new Measure(CoreMetrics.UNCOVERED_LINES, (double) (getLinesToCover() - getCoveredLines()))); + measures.add(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA).setData(KeyValueFormat.format(hitsByLine)).setPersistenceMode(PersistenceMode.DATABASE)); + } + if (getConditions() > 0) { + measures.add(new Measure(CoreMetrics.CONDITIONS_TO_COVER, (double) getConditions())); + measures.add(new Measure(CoreMetrics.UNCOVERED_CONDITIONS, (double) (getConditions() - getCoveredConditions()))); + measures.add(createConditionsByLineData()); + measures.add(createCoveredConditionsByLineData()); + measures.add(createBranchCoverageByLine()); + } + return measures; + } + + private Measure createCoveredConditionsByLineData() { + return new Measure(CoreMetrics.COVERED_CONDITIONS_BY_LINE_DATA) + .setData(KeyValueFormat.format(coveredConditionsByLine)) + .setPersistenceMode(PersistenceMode.DATABASE); + } + + private Measure createConditionsByLineData() { + return new Measure(CoreMetrics.CONDITIONS_BY_LINE_DATA) + .setData(KeyValueFormat.format(conditionsByLine)) + .setPersistenceMode(PersistenceMode.DATABASE); + } + + private Measure createBranchCoverageByLine() { + PropertiesBuilder<Integer, String> builder = new PropertiesBuilder<Integer, String>(CoreMetrics.BRANCH_COVERAGE_HITS_DATA); + for (Map.Entry<Integer, Integer> entry : conditionsByLine.entrySet()) { + Integer lineId = entry.getKey(); + int conditions = entry.getValue(); + int coveredConditions = coveredConditionsByLine.get(lineId); + builder.add(lineId, formatBranchCoverage(conditions, coveredConditions)); + } + return builder.build().setPersistenceMode(PersistenceMode.DATABASE); + } + + static String formatBranchCoverage(int conditions, int coveredConditions) { + long branchCoverage = Math.round(100.0 * coveredConditions / conditions); + return branchCoverage + "%"; + } + + public static CoverageMeasuresBuilder create() { + return new CoverageMeasuresBuilder(); + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java index e27d13cf69e..3b64b89da3f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Measure.java @@ -28,7 +28,7 @@ import java.util.Date; /** * A class to handle measures. - * + * * @since 1.10 */ public class Measure { @@ -60,7 +60,7 @@ public class Measure { /** * Creates a measure with a metric - * + * * @param metric the metric */ public Measure(Metric metric) { @@ -70,9 +70,9 @@ public class Measure { /** * Creates a measure with a metric and a value - * + * * @param metric the metric - * @param value its value + * @param value its value */ public Measure(Metric metric, Double value) { this.metric = metric; @@ -82,9 +82,9 @@ public class Measure { /** * Creates a measure with a metric, a value and a precision for the value - * - * @param metric the metric - * @param value its value + * + * @param metric the metric + * @param value its value * @param precision the value precision */ public Measure(Metric metric, Double value, int precision) { @@ -95,10 +95,10 @@ public class Measure { /** * Creates a measure with a metric, a value and a data field - * + * * @param metric the metric - * @param value the value - * @param data the data field + * @param value the value + * @param data the data field */ public Measure(Metric metric, Double value, String data) { this.metric = metric; @@ -109,9 +109,9 @@ public class Measure { /** * * Creates a measure with a metric and a data field - * + * * @param metric the metric - * @param data the data field + * @param data the data field */ public Measure(Metric metric, String data) { this.metric = metric; @@ -121,9 +121,9 @@ public class Measure { /** * Creates a measure with a metric and an alert level - * + * * @param metric the metric - * @param level the alert level + * @param level the alert level */ public Measure(Metric metric, Metric.Level level) { this.metric = metric; @@ -156,7 +156,7 @@ public class Measure { * example, a measure save in memory at the module level will not be accessible by the root project. In that case, database should be * used. * </p> - * + * * @param mode the mode * @return the measure object instance */ @@ -178,7 +178,7 @@ public class Measure { /** * Set the underlying metric - * + * * @param metric the metric * @return the measure object instance */ @@ -198,6 +198,10 @@ public class Measure { return null; } + public boolean hasData() { + return data != null; + } + /** * @return the date of the measure, i.e. the date the measure was taken. Used only in TimeMachine queries */ @@ -207,7 +211,7 @@ public class Measure { /** * Sets the date of the measure - Used only in TimeMachine queries - * + * * @param date the date * @return the measure object instance */ @@ -235,7 +239,7 @@ public class Measure { /** * Sets the measure value with the default precision of 1 - * + * * @param v the measure value * @return the measure object instance */ @@ -245,7 +249,7 @@ public class Measure { /** * Sets the measure value as an int - * + * * @param i the value * @return the measure object instance */ @@ -260,8 +264,8 @@ public class Measure { /** * Sets the measure value with a given precision - * - * @param v the measure value + * + * @param v the measure value * @param precision the measure value precision * @return the measure object instance */ @@ -291,7 +295,7 @@ public class Measure { /** * Sets the data field of the measure. - * + * * @param s the data * @return the measure object instance */ @@ -305,7 +309,7 @@ public class Measure { /** * Sets an alert level as the data field - * + * * @param level the alert level * @return the measure object instance */ @@ -327,7 +331,7 @@ public class Measure { /** * Sets the measure description - * + * * @param description the description * @return the measure object instance */ @@ -345,7 +349,7 @@ public class Measure { /** * Set the alert status of the measure - * + * * @param status the status * @return the measure object instance */ @@ -363,7 +367,7 @@ public class Measure { /** * Sets the text associated to the alert on the measure - * + * * @param alertText the text * @return the measure object instance */ @@ -374,7 +378,7 @@ public class Measure { /** * Gets the measure tendency - * + * * @return the tendency */ public Integer getTendency() { @@ -383,7 +387,7 @@ public class Measure { /** * Sets the tendency for the measure - Internal use only - * + * * @param tendency the tendency * @return the measure object instance */ @@ -401,7 +405,7 @@ public class Measure { /** * Sets the measure id - Internal use only - * + * * @param id the id * @return the measure object instance */ @@ -420,7 +424,7 @@ public class Measure { /** * Internal use only - * + * * @since 2.5 */ public Measure setVariation1(Double d) { @@ -438,7 +442,7 @@ public class Measure { /** * Internal use only - * + * * @since 2.5 */ public Measure setVariation2(Double d) { @@ -456,7 +460,7 @@ public class Measure { /** * Internal use only - * + * * @since 2.5 */ public Measure setVariation3(Double d) { @@ -522,7 +526,7 @@ public class Measure { /** * Internal use only - * + * * @since 2.5 */ public Measure setVariation(int index, Double d) { @@ -557,7 +561,7 @@ public class Measure { /** * Sets the URL of the measure - * + * * @param url the url * @return the measure object instance */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java index 781b63eef13..92050c92d81 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/Metric.java @@ -105,7 +105,7 @@ public class Metric implements ServerExtension, BatchExtension { @Column(name = "origin", updatable = true, nullable = true, length = 3) @Enumerated(EnumType.STRING) - private Origin origin; + private Origin origin = Origin.JAV; @Column(name = "worst_value", updatable = true, nullable = true, precision = 30, scale = 20) private Double worstValue; @@ -119,7 +119,6 @@ public class Metric implements ServerExtension, BatchExtension { @Column(name = "hidden", updatable = true, nullable = true) private Boolean hidden = Boolean.FALSE; - /** * Creates an empty metric */ @@ -216,6 +215,23 @@ public class Metric implements ServerExtension, BatchExtension { } } + private Metric(String key, String name, ValueType type, String description, Integer direction, String domain, Boolean qualitative, Double worstValue, Double bestValue, Boolean optimizedBestValue, Boolean hidden, Formula formula) { + this.key = key; + this.name = name; + this.description = description; + this.type = type; + this.direction = direction; + this.domain = domain; + this.qualitative = qualitative; + this.userManaged = Boolean.FALSE; + this.enabled = Boolean.TRUE; + this.worstValue = worstValue; + this.optimizedBestValue = optimizedBestValue; + this.bestValue = bestValue; + this.hidden = hidden; + this.formula = formula; + } + /** * For internal use only */ @@ -554,4 +570,81 @@ public class Metric implements ServerExtension, BatchExtension { this.hidden = with.hidden; return this; } + + public static final class Builder { + private String key; + private Metric.ValueType type; + private String name; + private String description; + private Integer direction = DIRECTION_NONE; + private Boolean qualitative = Boolean.FALSE; + private String domain = null; + private Formula formula; + private Double worstValue; + private Double bestValue; + private boolean optimizedBestValue = false; + private boolean hidden = false; + + public Builder(String key, ValueType type) { + this.key = key; + this.type = type; + } + + public Builder setName(String s) { + this.name = s; + return this; + } + + public Builder setDescription(String s) { + this.description = s; + return this; + } + + /** + * Used for numeric values only + */ + public Builder setDirection(Integer i) { + this.direction = i; + return this; + } + + public Builder setQualitative(Boolean b) { + this.qualitative = b; + return this; + } + + public Builder setDomain(String s) { + this.domain = s; + return this; + } + + public Builder setFormula(Formula f) { + this.formula = f; + return this; + } + + public Builder setWorstValue(Double d) { + this.worstValue = d; + return this; + } + + public Builder setBestValue(Double d) { + this.bestValue = d; + return this; + } + + public Builder setOptimizedBestValue(boolean b) { + this.optimizedBestValue = b; + return this; + } + + public Builder setHidden(boolean b) { + this.hidden = b; + return this; + } + + public Metric create() { + return new Metric(key, name, type, description, direction, domain, qualitative, worstValue, bestValue, optimizedBestValue, hidden, formula); + } + } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/CoverageMeasuresBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/CoverageMeasuresBuilderTest.java new file mode 100644 index 00000000000..12c43709c37 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/CoverageMeasuresBuilderTest.java @@ -0,0 +1,128 @@ +/* + * 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.api.measures; + +import org.junit.Test; + +import java.util.Collection; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class CoverageMeasuresBuilderTest { + + @Test + public void shouldNotCreateIfNoValues() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + assertThat(builder.createMeasures().size(), is(0)); + } + + @Test + public void shouldCreateHitsByLineData() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setHits(1, 0); + builder.setHits(2, 3); + builder.setHits(4, 2); + assertThat(find(builder.createMeasures(), CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY).getData(), is("1=0;2=3;4=2")); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldFailIfDuplicatedLineHits() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setHits(1, 0); + builder.setHits(1, 3); + } + + @Test + public void shouldCreateUncoveredLines() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setHits(1, 0); + builder.setHits(2, 3); + builder.setHits(3, 0); + assertThat(find(builder.createMeasures(), CoreMetrics.UNCOVERED_LINES_KEY).getIntValue(), is(2)); + } + + @Test + public void shouldCreateConditionsByLineData() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setConditions(1, 2, 2); + builder.setConditions(2, 1, 0); + assertThat(find(builder.createMeasures(), CoreMetrics.CONDITIONS_BY_LINE_DATA_KEY).getData(), is("1=2;2=1")); + assertThat(find(builder.createMeasures(), CoreMetrics.COVERED_CONDITIONS_BY_LINE_DATA_KEY).getData(), is("1=2;2=0")); + assertThat(find(builder.createMeasures(), CoreMetrics.BRANCH_COVERAGE_HITS_DATA_KEY).getData(), is("1=100%;2=0%")); + } + + @Test + public void shouldCreateNumberOfConditionsToCover() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setConditions(1, 2, 2); + builder.setConditions(2, 1, 0); + assertThat(find(builder.createMeasures(), CoreMetrics.CONDITIONS_TO_COVER_KEY).getIntValue(), is(3)); + } + + @Test + public void shouldCreateNumberOfUncoveredConditions() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setConditions(1, 2, 2); + builder.setConditions(2, 1, 0); + builder.setConditions(3, 3, 1); + assertThat(find(builder.createMeasures(), CoreMetrics.UNCOVERED_CONDITIONS_KEY).getIntValue(), is(3)); + } + + @Test + public void shouldSetOnlyPositiveConditions() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setConditions(1, 0, 0); + builder.setConditions(2, 1, 0); + assertThat(find(builder.createMeasures(), CoreMetrics.CONDITIONS_BY_LINE_DATA_KEY).getData(), is("2=1")); + assertThat(find(builder.createMeasures(), CoreMetrics.COVERED_CONDITIONS_BY_LINE_DATA_KEY).getData(), is("2=0")); + assertThat(find(builder.createMeasures(), CoreMetrics.BRANCH_COVERAGE_HITS_DATA_KEY).getData(), is("2=0%")); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldFailIfDuplicatedLineConditions() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setConditions(1, 3, 0); + builder.setConditions(1, 3, 1); + } + + @Test + public void shouldResetFields() { + CoverageMeasuresBuilder builder = CoverageMeasuresBuilder.create(); + builder.setHits(1, 4); + builder.setConditions(1, 3, 1); + builder.reset(); + assertThat(builder.getConditions(), is(0)); + assertThat(builder.getCoveredConditions(), is(0)); + assertThat(builder.getCoveredLines(), is(0)); + assertThat(builder.getHitsByLine().size(), is(0)); + assertThat(builder.getConditionsByLine().size(), is(0)); + assertThat(builder.getCoveredConditionsByLine().size(), is(0)); + } + + private Measure find(Collection<Measure> measures, String metricKey) { + for (Measure measure : measures) { + if (metricKey.equals(measure.getMetricKey())) { + return measure; + } + } + return null; + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java new file mode 100644 index 00000000000..84706bcc658 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/MetricTest.java @@ -0,0 +1,59 @@ +/* + * 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.api.measures; + +import org.junit.Test; + +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.nullValue; +import static org.junit.Assert.assertThat; + +public class MetricTest { + + @Test + public void shouldCreateMetric() { + Metric metric = new Metric.Builder("foo", Metric.ValueType.INT) + .setDomain("my domain") + .setName("Foo") + .create(); + + assertThat(metric.getKey(), is("foo")); + assertThat(metric.getName(), is("Foo")); + assertThat(metric.getDomain(), is("my domain")); + } + + @Test + public void shouldCreateMetricWithDefaultValues() { + Metric metric = new Metric.Builder("foo", Metric.ValueType.INT) + .create(); + + assertThat(metric.getBestValue(), nullValue()); + assertThat(metric.getDescription(), nullValue()); + assertThat(metric.getWorstValue(), nullValue()); + assertThat(metric.getDirection(), is(Metric.DIRECTION_NONE)); + assertThat(metric.getEnabled(), is(true)); + assertThat(metric.getOrigin(), is(Metric.Origin.JAV)); + assertThat(metric.getFormula(), nullValue()); + assertThat(metric.getId(), nullValue()); + assertThat(metric.getUserManaged(), is(false)); + assertThat(metric.isHidden(), is(false)); + assertThat(metric.isOptimizedBestValue(), is(false)); + } +} |