*/ | */ | ||||
package org.sonar.plugins.jacoco; | package org.sonar.plugins.jacoco; | ||||
import java.util.Arrays; | |||||
import java.util.List; | |||||
import org.sonar.api.Plugin; | |||||
import org.sonar.api.Properties; | import org.sonar.api.Properties; | ||||
import org.sonar.api.Property; | import org.sonar.api.Property; | ||||
import org.sonar.api.SonarPlugin; | |||||
import org.sonar.plugins.jacoco.itcoverage.*; | import org.sonar.plugins.jacoco.itcoverage.*; | ||||
import org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewerDefinition; | |||||
import java.util.Arrays; | |||||
import java.util.List; | |||||
@Properties({ | @Properties({ | ||||
@Property( | @Property( | ||||
module = true, | module = true, | ||||
project = true | project = true | ||||
) }) | ) }) | ||||
public class JaCoCoPlugin implements Plugin { | |||||
public String getKey() { | |||||
return "jacoco"; | |||||
} | |||||
public String getName() { | |||||
return "JaCoCo"; | |||||
} | |||||
public String getDescription() { | |||||
return "<a href='http://www.eclemma.org/jacoco/'>JaCoCo</a> calculates coverage of unit tests." + | |||||
" Set the parameter 'Code coverage plugin' to <code>jacoco</code> in the General plugin."; | |||||
} | |||||
public class JaCoCoPlugin extends SonarPlugin { | |||||
public List getExtensions() { | public List getExtensions() { | ||||
return Arrays.asList( | return Arrays.asList( | ||||
JaCoCoSensor.class, | JaCoCoSensor.class, | ||||
// Integration tests | // Integration tests | ||||
JaCoCoItMetrics.class, | |||||
JaCoCoItSensor.class, | JaCoCoItSensor.class, | ||||
ItCoverageWidget.class, | ItCoverageWidget.class, | ||||
ItCoverageDecorator.class, | ItCoverageDecorator.class, | ||||
ItLineCoverageDecorator.class, | ItLineCoverageDecorator.class, | ||||
ItBranchCoverageDecorator.class, | |||||
CoverageViewerDefinition.class); | |||||
ItBranchCoverageDecorator.class); | |||||
} | } | ||||
@Override | |||||
public String toString() { | |||||
return getKey(); | |||||
} | |||||
} | } |
import org.sonar.api.batch.DecoratorContext; | import org.sonar.api.batch.DecoratorContext; | ||||
import org.sonar.api.batch.DependsUpon; | import org.sonar.api.batch.DependsUpon; | ||||
import org.sonar.api.measures.CoreMetrics; | |||||
import org.sonar.api.measures.MeasureUtils; | import org.sonar.api.measures.MeasureUtils; | ||||
import org.sonar.api.measures.Metric; | import org.sonar.api.measures.Metric; | ||||
public final class ItBranchCoverageDecorator extends AbstractCoverageDecorator { | public final class ItBranchCoverageDecorator extends AbstractCoverageDecorator { | ||||
@Override | @Override | ||||
protected Metric getTargetMetric() { | protected Metric getTargetMetric() { | ||||
return JaCoCoItMetrics.IT_BRANCH_COVERAGE; | |||||
return CoreMetrics.IT_BRANCH_COVERAGE; | |||||
} | } | ||||
@DependsUpon | @DependsUpon | ||||
public List<Metric> dependsUponMetrics() { | public List<Metric> dependsUponMetrics() { | ||||
return Arrays.asList(JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS, JaCoCoItMetrics.IT_CONDITIONS_TO_COVER); | |||||
return Arrays.asList(CoreMetrics.IT_UNCOVERED_CONDITIONS, CoreMetrics.IT_CONDITIONS_TO_COVER); | |||||
} | } | ||||
@Override | @Override | ||||
protected Double countCoveredElements(DecoratorContext context) { | protected Double countCoveredElements(DecoratorContext context) { | ||||
double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS), 0.0); | |||||
double conditions = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0.0); | |||||
double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
return conditions - uncoveredConditions; | return conditions - uncoveredConditions; | ||||
} | } | ||||
@Override | @Override | ||||
protected Double countElements(DecoratorContext context) { | protected Double countElements(DecoratorContext context) { | ||||
return MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
return MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
} | } | ||||
} | } |
import org.sonar.api.batch.DecoratorContext; | import org.sonar.api.batch.DecoratorContext; | ||||
import org.sonar.api.batch.DependsUpon; | import org.sonar.api.batch.DependsUpon; | ||||
import org.sonar.api.measures.CoreMetrics; | |||||
import org.sonar.api.measures.MeasureUtils; | import org.sonar.api.measures.MeasureUtils; | ||||
import org.sonar.api.measures.Metric; | import org.sonar.api.measures.Metric; | ||||
@Override | @Override | ||||
protected Metric getTargetMetric() { | protected Metric getTargetMetric() { | ||||
return JaCoCoItMetrics.IT_COVERAGE; | |||||
return CoreMetrics.IT_COVERAGE; | |||||
} | } | ||||
@DependsUpon | @DependsUpon | ||||
public List<Metric> dependsUponMetrics() { | public List<Metric> dependsUponMetrics() { | ||||
return Arrays.asList(JaCoCoItMetrics.IT_LINES_TO_COVER, JaCoCoItMetrics.IT_UNCOVERED_LINES, JaCoCoItMetrics.IT_CONDITIONS_TO_COVER, JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS); | |||||
return Arrays.asList(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_CONDITIONS_TO_COVER, CoreMetrics.IT_UNCOVERED_CONDITIONS); | |||||
} | } | ||||
@Override | @Override | ||||
protected Double countCoveredElements(DecoratorContext context) { | protected Double countCoveredElements(DecoratorContext context) { | ||||
double uncoveredLines = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_UNCOVERED_LINES), 0.0); | |||||
double lines = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_LINES_TO_COVER), 0.0); | |||||
double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS), 0.0); | |||||
double conditions = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
double uncoveredLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0.0); | |||||
double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0.0); | |||||
double uncoveredConditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0.0); | |||||
double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
return lines + conditions - uncoveredConditions - uncoveredLines; | return lines + conditions - uncoveredConditions - uncoveredLines; | ||||
} | } | ||||
@Override | @Override | ||||
protected Double countElements(DecoratorContext context) { | protected Double countElements(DecoratorContext context) { | ||||
double lines = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_LINES_TO_COVER), 0.0); | |||||
double conditions = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0.0); | |||||
double conditions = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0.0); | |||||
return lines + conditions; | return lines + conditions; | ||||
} | } | ||||
import org.sonar.api.batch.DecoratorContext; | import org.sonar.api.batch.DecoratorContext; | ||||
import org.sonar.api.batch.DependsUpon; | import org.sonar.api.batch.DependsUpon; | ||||
import org.sonar.api.measures.CoreMetrics; | |||||
import org.sonar.api.measures.MeasureUtils; | import org.sonar.api.measures.MeasureUtils; | ||||
import org.sonar.api.measures.Metric; | import org.sonar.api.measures.Metric; | ||||
public class ItLineCoverageDecorator extends AbstractCoverageDecorator { | public class ItLineCoverageDecorator extends AbstractCoverageDecorator { | ||||
@Override | @Override | ||||
protected Metric getTargetMetric() { | protected Metric getTargetMetric() { | ||||
return JaCoCoItMetrics.IT_LINE_COVERAGE; | |||||
return CoreMetrics.IT_LINE_COVERAGE; | |||||
} | } | ||||
@DependsUpon | @DependsUpon | ||||
public List<Metric> dependsUponMetrics() { | public List<Metric> dependsUponMetrics() { | ||||
return Arrays.asList(JaCoCoItMetrics.IT_UNCOVERED_LINES, JaCoCoItMetrics.IT_LINES_TO_COVER); | |||||
return Arrays.asList(CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_LINES_TO_COVER); | |||||
} | } | ||||
@Override | @Override | ||||
protected Double countCoveredElements(DecoratorContext context) { | protected Double countCoveredElements(DecoratorContext context) { | ||||
double uncoveredLines = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_UNCOVERED_LINES), 0.0); | |||||
double lines = MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_LINES_TO_COVER), 0.0); | |||||
double uncoveredLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0.0); | |||||
double lines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0.0); | |||||
return lines - uncoveredLines; | return lines - uncoveredLines; | ||||
} | } | ||||
@Override | @Override | ||||
protected Double countElements(DecoratorContext context) { | protected Double countElements(DecoratorContext context) { | ||||
return MeasureUtils.getValue(context.getMeasure(JaCoCoItMetrics.IT_LINES_TO_COVER), 0.0); | |||||
return MeasureUtils.getValue(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0.0); | |||||
} | } | ||||
} | } |
/* | |||||
* 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.jacoco.itcoverage; | |||||
import org.sonar.api.measures.Metric; | |||||
import org.sonar.api.measures.Metrics; | |||||
import org.sonar.api.measures.SumChildValuesFormula; | |||||
import java.util.Arrays; | |||||
import java.util.List; | |||||
/** | |||||
* Should be in {@link org.sonar.api.measures.CoreMetrics} | |||||
* | |||||
* @author Evgeny Mandrikov | |||||
*/ | |||||
public final class JaCoCoItMetrics implements Metrics { | |||||
public static final String DOMAIN_IT_TESTS = "Integration Tests"; | |||||
public static final String IT_COVERAGE_KEY = "it_coverage"; | |||||
public static final Metric IT_COVERAGE = new Metric.Builder(IT_COVERAGE_KEY, "IT Coverage", Metric.ValueType.PERCENT) | |||||
.setDescription("Coverage by integration tests") | |||||
.setDirection(Metric.DIRECTION_BETTER) | |||||
.setQualitative(true) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.setWorstValue(0.0) | |||||
.setBestValue(100.0) | |||||
.create(); | |||||
public static final String IT_LINES_TO_COVER_KEY = "it_lines_to_cover"; | |||||
public static final Metric IT_LINES_TO_COVER = new Metric.Builder(IT_LINES_TO_COVER_KEY, "IT lines to cover", Metric.ValueType.INT) | |||||
.setDescription("IT lines to cover") | |||||
.setDirection(Metric.DIRECTION_BETTER) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.setQualitative(false) | |||||
.setFormula(new SumChildValuesFormula(false)) | |||||
.setHidden(true) | |||||
.create(); | |||||
public static final String IT_UNCOVERED_LINES_KEY = "it_uncovered_lines"; | |||||
public static final Metric IT_UNCOVERED_LINES = new Metric.Builder(IT_UNCOVERED_LINES_KEY, "IT uncovered lines", Metric.ValueType.INT) | |||||
.setDescription("IT uncovered lines") | |||||
.setDirection(Metric.DIRECTION_WORST) | |||||
.setQualitative(false) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.setFormula(new SumChildValuesFormula(false)) | |||||
.create(); | |||||
public static final String IT_LINE_COVERAGE_KEY = "it_line_coverage"; | |||||
public static final Metric IT_LINE_COVERAGE = new Metric.Builder(IT_LINE_COVERAGE_KEY, "IT line coverage", Metric.ValueType.PERCENT) | |||||
.setDescription("IT line coverage") | |||||
.setDirection(Metric.DIRECTION_BETTER) | |||||
.setQualitative(true) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.create(); | |||||
public static final String IT_COVERAGE_LINE_HITS_DATA_KEY = "it_coverage_line_hits_data"; | |||||
public static final Metric IT_COVERAGE_LINE_HITS_DATA = new Metric.Builder(IT_COVERAGE_LINE_HITS_DATA_KEY, "IT Coverage hits data", Metric.ValueType.DATA) | |||||
.setDescription("IT Code coverage line hits data") | |||||
.setDirection(Metric.DIRECTION_NONE) | |||||
.setQualitative(false) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.create(); | |||||
public static final String IT_CONDITIONS_TO_COVER_KEY = "it_conditions_to_cover"; | |||||
public static final Metric IT_CONDITIONS_TO_COVER = new Metric.Builder(IT_CONDITIONS_TO_COVER_KEY, "IT Conditions to cover", Metric.ValueType.INT) | |||||
.setDescription("IT Conditions to cover") | |||||
.setDirection(Metric.DIRECTION_BETTER) | |||||
.setQualitative(false) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.setFormula(new SumChildValuesFormula(false)) | |||||
.setHidden(true) | |||||
.create(); | |||||
public static final String IT_UNCOVERED_CONDITIONS_KEY = "it_uncovered_conditions"; | |||||
public static final Metric IT_UNCOVERED_CONDITIONS = new Metric.Builder(IT_UNCOVERED_CONDITIONS_KEY, "IT Uncovered conditions", Metric.ValueType.INT) | |||||
.setDescription("IT Uncovered conditions") | |||||
.setDirection(Metric.DIRECTION_WORST) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.setFormula(new SumChildValuesFormula(false)) | |||||
.create(); | |||||
public static final String IT_BRANCH_COVERAGE_KEY = "it_branch_coverage"; | |||||
public static final Metric IT_BRANCH_COVERAGE = new Metric.Builder(IT_BRANCH_COVERAGE_KEY, "IT Branch coverage", Metric.ValueType.PERCENT) | |||||
.setDescription("IT Branch coverage") | |||||
.setDirection(Metric.DIRECTION_BETTER) | |||||
.setQualitative(true) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.setWorstValue(0.0) | |||||
.setBestValue(100.0) | |||||
.create(); | |||||
public static final String IT_CONDITIONS_BY_LINE_KEY = "it_conditions_by_line"; | |||||
public static final Metric IT_CONDITIONS_BY_LINE = new Metric.Builder(IT_CONDITIONS_BY_LINE_KEY, "IT Conditions by line", Metric.ValueType.DATA) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.create(); | |||||
public static final String IT_COVERED_CONDITIONS_BY_LINE_KEY = "it_covered_conditions_by_line"; | |||||
public static final Metric IT_COVERED_CONDITIONS_BY_LINE = new Metric.Builder(IT_COVERED_CONDITIONS_BY_LINE_KEY, "IT Covered conditions by line", Metric.ValueType.DATA) | |||||
.setDomain(DOMAIN_IT_TESTS) | |||||
.create(); | |||||
public List<Metric> getMetrics() { | |||||
return Arrays.asList(IT_COVERAGE, IT_LINES_TO_COVER, IT_UNCOVERED_LINES, IT_LINE_COVERAGE, IT_COVERAGE_LINE_HITS_DATA, | |||||
IT_CONDITIONS_TO_COVER, IT_UNCOVERED_CONDITIONS, IT_BRANCH_COVERAGE, | |||||
IT_CONDITIONS_BY_LINE, IT_COVERED_CONDITIONS_BY_LINE); | |||||
} | |||||
} |
private Measure convertForIT(Measure measure) { | private Measure convertForIT(Measure measure) { | ||||
Measure itMeasure = null; | Measure itMeasure = null; | ||||
if (CoreMetrics.LINES_TO_COVER.equals(measure.getMetric())) { | if (CoreMetrics.LINES_TO_COVER.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_LINES_TO_COVER, measure.getValue()); | |||||
itMeasure = new Measure(CoreMetrics.IT_LINES_TO_COVER, measure.getValue()); | |||||
} else if (CoreMetrics.UNCOVERED_LINES.equals(measure.getMetric())) { | } else if (CoreMetrics.UNCOVERED_LINES.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_UNCOVERED_LINES, measure.getValue()); | |||||
itMeasure = new Measure(CoreMetrics.IT_UNCOVERED_LINES, measure.getValue()); | |||||
} else if (CoreMetrics.COVERAGE_LINE_HITS_DATA.equals(measure.getMetric())) { | } else if (CoreMetrics.COVERAGE_LINE_HITS_DATA.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_COVERAGE_LINE_HITS_DATA, measure.getData()); | |||||
itMeasure = new Measure(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA, measure.getData()); | |||||
} else if (CoreMetrics.CONDITIONS_TO_COVER.equals(measure.getMetric())) { | } else if (CoreMetrics.CONDITIONS_TO_COVER.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_CONDITIONS_TO_COVER, measure.getValue()); | |||||
itMeasure = new Measure(CoreMetrics.IT_CONDITIONS_TO_COVER, measure.getValue()); | |||||
} else if (CoreMetrics.UNCOVERED_CONDITIONS.equals(measure.getMetric())) { | } else if (CoreMetrics.UNCOVERED_CONDITIONS.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS, measure.getValue()); | |||||
itMeasure = new Measure(CoreMetrics.IT_UNCOVERED_CONDITIONS, measure.getValue()); | |||||
} else if (CoreMetrics.COVERED_CONDITIONS_BY_LINE.equals(measure.getMetric())) { | } else if (CoreMetrics.COVERED_CONDITIONS_BY_LINE.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_COVERED_CONDITIONS_BY_LINE, measure.getData()); | |||||
itMeasure = new Measure(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE, measure.getData()); | |||||
} else if (CoreMetrics.CONDITIONS_BY_LINE.equals(measure.getMetric())) { | } else if (CoreMetrics.CONDITIONS_BY_LINE.equals(measure.getMetric())) { | ||||
itMeasure = new Measure(JaCoCoItMetrics.IT_CONDITIONS_BY_LINE, measure.getData()); | |||||
itMeasure = new Measure(CoreMetrics.IT_CONDITIONS_BY_LINE, measure.getData()); | |||||
} | } | ||||
return itMeasure; | return itMeasure; | ||||
} | } |
/* | |||||
* 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.jacoco.itcoverage.viewer; | |||||
import org.sonar.api.resources.Resource; | |||||
import org.sonar.api.web.*; | |||||
import org.sonar.plugins.jacoco.itcoverage.JaCoCoItMetrics; | |||||
@ResourceQualifier(Resource.QUALIFIER_CLASS) | |||||
@NavigationSection(NavigationSection.RESOURCE_TAB) | |||||
@DefaultTab(metrics = { JaCoCoItMetrics.IT_COVERAGE_KEY, JaCoCoItMetrics.IT_LINES_TO_COVER_KEY, JaCoCoItMetrics.IT_UNCOVERED_LINES_KEY, JaCoCoItMetrics.IT_LINE_COVERAGE_KEY, JaCoCoItMetrics.IT_CONDITIONS_TO_COVER_KEY, JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS_KEY, JaCoCoItMetrics.IT_BRANCH_COVERAGE_KEY }) | |||||
@UserRole(UserRole.CODEVIEWER) | |||||
public class CoverageViewerDefinition extends GwtPage { | |||||
public String getTitle() { | |||||
return "IT Coverage"; | |||||
} | |||||
public String getGwtId() { | |||||
return "org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewer"; | |||||
} | |||||
} |
/* | |||||
* 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.jacoco.itcoverage.viewer.client; | |||||
import org.sonar.gwt.ui.SourcePanel; | |||||
import org.sonar.wsclient.gwt.AbstractCallback; | |||||
import org.sonar.wsclient.gwt.Sonar; | |||||
import org.sonar.wsclient.services.Resource; | |||||
import org.sonar.wsclient.services.ResourceQuery; | |||||
import java.util.Arrays; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* Copied from org.sonar.plugins.core.coverageviewer.client.CoveragePanel | |||||
*/ | |||||
public class CoveragePanel extends SourcePanel { | |||||
private Map<Integer, Integer> hitsByLine = new HashMap<Integer, Integer>(); | |||||
private Map<Integer, Integer> conditionsByLine = new HashMap<Integer, Integer>(); | |||||
private Map<Integer, Integer> coveredConditionsByLine = new HashMap<Integer, Integer>(); | |||||
private Map<Integer, String> branchCoverageByLine = new HashMap<Integer, String>(); | |||||
public CoveragePanel(Resource resource) { | |||||
super(resource); | |||||
loadCoverageHits(resource); | |||||
} | |||||
private void loadCoverageHits(Resource resource) { | |||||
ResourceQuery query = ResourceQuery.createForResource(resource, Metrics.IT_COVERAGE_LINE_HITS_DATA, Metrics.IT_BRANCH_COVERAGE_HITS_DATA, Metrics.IT_CONDITIONS_BY_LINE, Metrics.IT_COVERED_CONDITIONS_BY_LINE); | |||||
Sonar.getInstance().find(query, new AbstractCallback<Resource>() { | |||||
@Override | |||||
protected void doOnResponse(Resource resource) { | |||||
handleLineHits(resource); | |||||
handleLineConditions(resource); | |||||
handleDeprecatedBranchCoverage(resource); | |||||
setStarted(); | |||||
} | |||||
}); | |||||
} | |||||
private void handleLineHits(Resource resource) { | |||||
parseDataMap(resource, Metrics.IT_COVERAGE_LINE_HITS_DATA, hitsByLine); | |||||
} | |||||
private void handleLineConditions(Resource resource) { | |||||
parseDataMap(resource, Metrics.IT_CONDITIONS_BY_LINE, conditionsByLine); | |||||
parseDataMap(resource, Metrics.IT_COVERED_CONDITIONS_BY_LINE, coveredConditionsByLine); | |||||
} | |||||
private void parseDataMap(Resource resource, String metric, Map<Integer, Integer> map) { | |||||
if (resource == null || resource.getMeasure(metric) == null) { | |||||
return; | |||||
} | |||||
map.clear(); | |||||
String data = resource.getMeasure(metric).getData(); | |||||
for (String lineWithValue : data.split(";")) { | |||||
String[] elt = lineWithValue.split("="); | |||||
if (elt != null && elt.length == 2) { | |||||
map.put(Integer.parseInt(elt[0]), Integer.parseInt(elt[1])); | |||||
} | |||||
} | |||||
} | |||||
private void handleDeprecatedBranchCoverage(Resource resource) { | |||||
if (resource == null || resource.getMeasure(Metrics.IT_BRANCH_COVERAGE_HITS_DATA) == null) { | |||||
return; | |||||
} | |||||
branchCoverageByLine.clear(); | |||||
String data = resource.getMeasure(Metrics.IT_BRANCH_COVERAGE_HITS_DATA).getData(); | |||||
for (String lineWithValue : data.split(";")) { | |||||
String[] elt = lineWithValue.split("="); | |||||
if (elt != null && elt.length == 2) { | |||||
branchCoverageByLine.put(Integer.parseInt(elt[0]), elt[1]); | |||||
} | |||||
} | |||||
} | |||||
@Override | |||||
protected boolean shouldDecorateLine(int index) { | |||||
return index > 0; | |||||
} | |||||
@Override | |||||
protected List<Row> decorateLine(int index, String source) { | |||||
Row row = new Row().setLineIndex(index, ""); | |||||
Integer hits = hitsByLine.get(index); | |||||
Integer conditions = conditionsByLine.get(index); | |||||
Integer coveredConditions = coveredConditionsByLine.get(index); | |||||
String branchCoverage = branchCoverageByLine.get(index); | |||||
if (branchCoverage == null && conditions != null && coveredConditions != null) { | |||||
branchCoverage = String.valueOf(conditions - coveredConditions) + "/" + String.valueOf(conditions); | |||||
} | |||||
boolean hasLineCoverage = (hits != null); | |||||
boolean hasBranchCoverage = (branchCoverage != null); | |||||
boolean lineIsCovered = (hasLineCoverage && hits > 0); | |||||
boolean branchIsCovered = ("100%".equals(branchCoverage) || (conditions != null && coveredConditions != null && coveredConditions == conditions)); | |||||
row.setSource(source, ""); | |||||
row.setValue(" ", ""); | |||||
row.setValue2(" ", ""); | |||||
if (lineIsCovered) { | |||||
if (branchIsCovered) { | |||||
row.setValue(String.valueOf(hits), "green"); | |||||
row.setValue2(branchCoverage, "green"); | |||||
} else if (hasBranchCoverage) { | |||||
row.setValue(String.valueOf(hits), "orange"); | |||||
row.setValue2(branchCoverage, "orange"); | |||||
row.setSource(source, "orange"); | |||||
} else { | |||||
row.setValue(String.valueOf(hits), "green"); | |||||
} | |||||
} else if (hasLineCoverage) { | |||||
row.setValue(String.valueOf(hits), "red"); | |||||
row.setSource(source, "red"); | |||||
if (hasBranchCoverage) { | |||||
row.setValue2(branchCoverage, "red"); | |||||
} else { | |||||
row.setValue2(" ", "red"); | |||||
} | |||||
} | |||||
return Arrays.asList(row); | |||||
} | |||||
} |
/* | |||||
* 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.jacoco.itcoverage.viewer.client; | |||||
import org.sonar.gwt.ui.Page; | |||||
import org.sonar.gwt.ui.ViewerHeader; | |||||
import org.sonar.wsclient.services.Measure; | |||||
import org.sonar.wsclient.services.Resource; | |||||
import com.google.gwt.user.client.ui.FlowPanel; | |||||
import com.google.gwt.user.client.ui.HorizontalPanel; | |||||
import com.google.gwt.user.client.ui.Widget; | |||||
/** | |||||
* Copied from org.sonar.plugins.core.coverageviewer.client.CoverageViewer | |||||
*/ | |||||
public class CoverageViewer extends Page { | |||||
@Override | |||||
protected Widget doOnResourceLoad(Resource resource) { | |||||
FlowPanel panel = new FlowPanel(); | |||||
panel.setWidth("100%"); | |||||
panel.add(new CoverageHeader(resource)); | |||||
panel.add(new CoveragePanel(resource)); | |||||
return panel; | |||||
} | |||||
private static class CoverageHeader extends ViewerHeader { | |||||
public CoverageHeader(Resource resource) { | |||||
super(resource, new String[] { Metrics.IT_COVERAGE, Metrics.IT_LINE_COVERAGE, Metrics.IT_UNCOVERED_LINES, Metrics.IT_BRANCH_COVERAGE, Metrics.IT_UNCOVERED_CONDITIONS }); | |||||
} | |||||
@Override | |||||
protected void display(FlowPanel header, Resource resource) { | |||||
HorizontalPanel panel = new HorizontalPanel(); | |||||
header.add(panel); | |||||
Measure measure = resource.getMeasure(Metrics.IT_COVERAGE); | |||||
if (measure == null) { | |||||
addBigCell(panel, "-"); | |||||
} else { | |||||
addBigCell(panel, measure.getFormattedValue()); | |||||
} | |||||
addCell(panel, resource.getMeasure(Metrics.IT_LINE_COVERAGE)); | |||||
addCell(panel, resource.getMeasure(Metrics.IT_UNCOVERED_LINES)); | |||||
addCell(panel, resource.getMeasure(Metrics.IT_LINES_TO_COVER)); | |||||
addCell(panel, resource.getMeasure(Metrics.IT_BRANCH_COVERAGE)); | |||||
addCell(panel, resource.getMeasure(Metrics.IT_UNCOVERED_CONDITIONS)); | |||||
addCell(panel, resource.getMeasure(Metrics.IT_CONDITIONS_TO_COVER)); | |||||
} | |||||
} | |||||
} |
/* | |||||
* 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.jacoco.itcoverage.viewer.client; | |||||
/** | |||||
* Should be in {@link org.sonar.gwt.Metrics} | |||||
*/ | |||||
public interface Metrics { | |||||
String IT_COVERAGE = "it_coverage"; | |||||
String IT_LINES_TO_COVER = "it_lines_to_cover"; | |||||
String IT_UNCOVERED_LINES = "it_uncovered_lines"; | |||||
String IT_LINE_COVERAGE = "it_line_coverage"; | |||||
String IT_COVERAGE_LINE_HITS_DATA = "it_coverage_line_hits_data"; | |||||
String IT_CONDITIONS_TO_COVER = "it_conditions_to_cover"; | |||||
String IT_UNCOVERED_CONDITIONS = "it_uncovered_conditions"; | |||||
String IT_BRANCH_COVERAGE = "it_branch_coverage"; | |||||
String IT_CONDITIONS_BY_LINE = "it_conditions_by_line"; | |||||
String IT_COVERED_CONDITIONS_BY_LINE = "it_covered_conditions_by_line"; | |||||
/** | |||||
* @deprecated use IT_CONDITIONS_BY_LINE and IT_COVERED_CONDITIONS_BY_LINE | |||||
*/ | |||||
@Deprecated | |||||
String IT_BRANCH_COVERAGE_HITS_DATA = "it_branch_coverage_hits_data"; | |||||
} |
<module> | |||||
<inherits name="com.google.gwt.user.User"/> | |||||
<inherits name="com.google.gwt.json.JSON"/> | |||||
<inherits name="com.google.gwt.http.HTTP"/> | |||||
<inherits name="org.sonar.Sonar"/> | |||||
<inherits name="com.google.gwt.gen2.table.Table"/> | |||||
<entry-point class="org.sonar.plugins.jacoco.itcoverage.viewer.client.CoverageViewer"/> | |||||
</module> |
<module rename-to="org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewer"> | |||||
<inherits name="org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewer"/> | |||||
<inherits name="org.sonar.SonarDev"/> | |||||
<entry-point class="org.sonar.plugins.jacoco.itcoverage.viewer.client.CoverageViewer"/> | |||||
</module> |
*/ | */ | ||||
package org.sonar.plugins.jacoco; | package org.sonar.plugins.jacoco; | ||||
import org.junit.Test; | |||||
import static org.hamcrest.Matchers.greaterThan; | import static org.hamcrest.Matchers.greaterThan; | ||||
import static org.hamcrest.Matchers.is; | |||||
import static org.hamcrest.Matchers.notNullValue; | |||||
import static org.junit.Assert.assertThat; | import static org.junit.Assert.assertThat; | ||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
/** | |||||
* @author Evgeny Mandrikov | |||||
*/ | |||||
public class JaCoCoPluginTest { | public class JaCoCoPluginTest { | ||||
private JaCoCoPlugin plugin = new JaCoCoPlugin(); | |||||
@Before | |||||
public void setUp() { | |||||
plugin = new JaCoCoPlugin(); | |||||
} | |||||
@Test | |||||
public void testPluginDefition() { | |||||
assertThat(plugin.getKey(), is("jacoco")); | |||||
assertThat(plugin.getName(), notNullValue()); | |||||
assertThat(plugin.getDescription(), notNullValue()); | |||||
assertThat(plugin.toString(), is("jacoco")); | |||||
} | |||||
@Test | @Test | ||||
public void testExtensions() { | public void testExtensions() { | ||||
assertThat(plugin.getExtensions().size(), greaterThan(0)); | |||||
assertThat(new JaCoCoPlugin().getExtensions().size(), greaterThan(0)); | |||||
} | } | ||||
} | } |
/* | |||||
* 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.jacoco.itcoverage; | |||||
import static org.hamcrest.Matchers.is; | |||||
import static org.junit.Assert.assertThat; | |||||
import org.junit.Test; | |||||
public class JaCoCoItMetricsTest { | |||||
@Test | |||||
public void metricsDefinition() { | |||||
assertThat(new JaCoCoItMetrics().getMetrics().size(), is(10)); | |||||
} | |||||
} |
*/ | */ | ||||
package org.sonar.plugins.jacoco.itcoverage; | package org.sonar.plugins.jacoco.itcoverage; | ||||
import static org.hamcrest.Matchers.is; | |||||
import static org.junit.Assert.assertThat; | |||||
import static org.mockito.Matchers.any; | |||||
import static org.mockito.Matchers.anyString; | |||||
import static org.mockito.Matchers.argThat; | |||||
import static org.mockito.Matchers.eq; | |||||
import static org.mockito.Mockito.*; | |||||
import org.junit.Before; | import org.junit.Before; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.sonar.api.batch.SensorContext; | import org.sonar.api.batch.SensorContext; | ||||
import org.sonar.api.measures.CoreMetrics; | |||||
import org.sonar.api.measures.Measure; | import org.sonar.api.measures.Measure; | ||||
import org.sonar.api.resources.*; | |||||
import org.sonar.api.resources.JavaFile; | |||||
import org.sonar.api.resources.Project; | |||||
import org.sonar.api.resources.Project.AnalysisType; | import org.sonar.api.resources.Project.AnalysisType; | ||||
import org.sonar.api.resources.ProjectFileSystem; | |||||
import org.sonar.api.resources.Resource; | |||||
import org.sonar.api.test.IsMeasure; | import org.sonar.api.test.IsMeasure; | ||||
import org.sonar.plugins.jacoco.JacocoConfiguration; | import org.sonar.plugins.jacoco.JacocoConfiguration; | ||||
import java.io.File; | import java.io.File; | ||||
import static org.hamcrest.Matchers.is; | |||||
import static org.junit.Assert.assertThat; | |||||
import static org.mockito.Matchers.any; | |||||
import static org.mockito.Matchers.anyString; | |||||
import static org.mockito.Matchers.argThat; | |||||
import static org.mockito.Matchers.eq; | |||||
import static org.mockito.Mockito.*; | |||||
public class JaCoCoItSensorTest { | public class JaCoCoItSensorTest { | ||||
private JacocoConfiguration configuration; | private JacocoConfiguration configuration; | ||||
private JaCoCoItSensor sensor; | private JaCoCoItSensor sensor; | ||||
sensor.analyse(project, context); | sensor.analyse(project, context); | ||||
verify(context).getResource(eq(resource)); | verify(context).getResource(eq(resource)); | ||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(JaCoCoItMetrics.IT_LINES_TO_COVER, 7.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(JaCoCoItMetrics.IT_UNCOVERED_LINES, 3.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(CoreMetrics.IT_LINES_TO_COVER, 7.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(CoreMetrics.IT_UNCOVERED_LINES, 3.0))); | |||||
verify(context).saveMeasure(eq(resource), | verify(context).saveMeasure(eq(resource), | ||||
argThat(new IsMeasure(JaCoCoItMetrics.IT_COVERAGE_LINE_HITS_DATA, "6=1;7=1;8=1;11=1;15=0;16=0;18=0"))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(JaCoCoItMetrics.IT_CONDITIONS_TO_COVER, 2.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(JaCoCoItMetrics.IT_UNCOVERED_CONDITIONS, 2.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(JaCoCoItMetrics.IT_CONDITIONS_BY_LINE, "15=2"))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(JaCoCoItMetrics.IT_COVERED_CONDITIONS_BY_LINE, "15=0"))); | |||||
argThat(new IsMeasure(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA, "6=1;7=1;8=1;11=1;15=0;16=0;18=0"))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER, 2.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS, 2.0))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(CoreMetrics.IT_CONDITIONS_BY_LINE, "15=2"))); | |||||
verify(context).saveMeasure(eq(resource), argThat(new IsMeasure(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE, "15=0"))); | |||||
verifyNoMoreInteractions(context); | verifyNoMoreInteractions(context); | ||||
} | } | ||||
duplications.collapse=Collapse | duplications.collapse=Collapse | ||||
#------------------------------------------------------------------------------ | |||||
# | |||||
# COVERAGE TAB | |||||
# | |||||
#------------------------------------------------------------------------------ | |||||
coverage_tab.unit_tests=Unit Tests | |||||
coverage_tab.integration_tests=Integration Tests | |||||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | ||||
# | # | ||||
# MANUAL MEASURES | # MANUAL MEASURES | ||||
metric_domain.Size=Size | metric_domain.Size=Size | ||||
metric_domain.Tests=Tests | metric_domain.Tests=Tests | ||||
metric_domain.Integration Tests=L10n Integration Tests | |||||
metric_domain.Complexity=Complexity | metric_domain.Complexity=Complexity | ||||
metric_domain.Documentation=Documentation | metric_domain.Documentation=Documentation | ||||
metric_domain.Rules=Rules | metric_domain.Rules=Rules | ||||
metric.covered_conditions_by_line.name=Covered branches by line | metric.covered_conditions_by_line.name=Covered branches by line | ||||
metric.covered_conditions_by_line.description=Covered branches by line | metric.covered_conditions_by_line.description=Covered branches by line | ||||
#-------------------------------------------------------------------------------------------------------------------- | |||||
# | |||||
# INTEGRATION TESTS | |||||
# | |||||
#-------------------------------------------------------------------------------------------------------------------- | |||||
metric.it_coverage.name=Coverage | |||||
metric.it_coverage.description=Coverage by unit tests | |||||
metric.it_lines_to_cover.name=Lines to cover | |||||
metric.it_lines_to_cover.description=Lines to cover | |||||
metric.it_uncovered_lines.name=Uncovered lines | |||||
metric.it_uncovered_lines.description=Uncovered lines | |||||
metric.it_line_coverage.name=Line coverage | |||||
metric.it_line_coverage.description=Line coverage | |||||
metric.it_coverage_line_hits_data.name=Coverage hits by line | |||||
metric.it_coverage_line_hits_data.description=Coverage hits by line | |||||
metric.it_conditions_to_cover.name=Branches to cover | |||||
metric.it_conditions_to_cover.description=Branches to cover | |||||
metric.it_uncovered_conditions.name=Uncovered branches | |||||
metric.it_uncovered_conditions.description=Uncovered branches | |||||
metric.it_branch_coverage.name=Branch coverage | |||||
metric.it_branch_coverage.description=Branch coverage | |||||
metric.it_conditions_by_line.name=Branches by line | |||||
metric.it_conditions_by_line.description=Branches by line | |||||
metric.it_covered_conditions_by_line.name=Covered branches by line | |||||
metric.it_covered_conditions_by_line.description=Covered branches by line | |||||
#-------------------------------------------------------------------------------------------------------------------- | #-------------------------------------------------------------------------------------------------------------------- | ||||
# | # | ||||
# DUPLICATIONS | # DUPLICATIONS |
*/ | */ | ||||
public final class DefaultPages { | public final class DefaultPages { | ||||
private static final View[] PAGES = { new SourceTab(), new CoverageTab(), new ViolationsTab(), new DuplicationsTab() }; | |||||
private static final View[] PAGES = {new SourceTab(), new CoverageTab(), new ViolationsTab(), new DuplicationsTab()}; | |||||
private DefaultPages() { | private DefaultPages() { | ||||
} | } | ||||
@NavigationSection(NavigationSection.RESOURCE_TAB) | @NavigationSection(NavigationSection.RESOURCE_TAB) | ||||
@ResourceQualifier({Qualifiers.FILE, Qualifiers.CLASS}) | @ResourceQualifier({Qualifiers.FILE, Qualifiers.CLASS}) | ||||
@DefaultTab(metrics = {CoreMetrics.COVERAGE_KEY, CoreMetrics.LINES_TO_COVER_KEY, CoreMetrics.UNCOVERED_LINES_KEY, CoreMetrics.LINE_COVERAGE_KEY, | |||||
CoreMetrics.CONDITIONS_TO_COVER_KEY, CoreMetrics.UNCOVERED_CONDITIONS_KEY, CoreMetrics.BRANCH_COVERAGE_KEY, | |||||
CoreMetrics.NEW_COVERAGE_KEY, CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_LINE_COVERAGE_KEY, | |||||
CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_BRANCH_COVERAGE_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY | |||||
@DefaultTab(metrics = { | |||||
/* unit tests */ | |||||
CoreMetrics.COVERAGE_KEY, CoreMetrics.LINES_TO_COVER_KEY, CoreMetrics.UNCOVERED_LINES_KEY, CoreMetrics.LINE_COVERAGE_KEY, | |||||
CoreMetrics.CONDITIONS_TO_COVER_KEY, CoreMetrics.UNCOVERED_CONDITIONS_KEY, CoreMetrics.BRANCH_COVERAGE_KEY, | |||||
CoreMetrics.NEW_COVERAGE_KEY, CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_LINE_COVERAGE_KEY, | |||||
CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_BRANCH_COVERAGE_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY, | |||||
/* integration tests */ | |||||
CoreMetrics.IT_COVERAGE_KEY, CoreMetrics.IT_LINES_TO_COVER_KEY, CoreMetrics.IT_UNCOVERED_LINES_KEY, CoreMetrics.IT_LINE_COVERAGE_KEY, | |||||
CoreMetrics.IT_CONDITIONS_TO_COVER_KEY, CoreMetrics.IT_UNCOVERED_CONDITIONS_KEY, CoreMetrics.IT_BRANCH_COVERAGE_KEY | |||||
}) | }) | ||||
@UserRole(UserRole.CODEVIEWER) | @UserRole(UserRole.CODEVIEWER) | ||||
private static final class CoverageTab implements RubyRailsPage { | private static final class CoverageTab implements RubyRailsPage { | ||||
@NavigationSection(NavigationSection.RESOURCE_TAB) | @NavigationSection(NavigationSection.RESOURCE_TAB) | ||||
@DefaultTab(metrics = {CoreMetrics.VIOLATIONS_DENSITY_KEY, CoreMetrics.WEIGHTED_VIOLATIONS_KEY, CoreMetrics.VIOLATIONS_KEY, CoreMetrics.BLOCKER_VIOLATIONS_KEY, | @DefaultTab(metrics = {CoreMetrics.VIOLATIONS_DENSITY_KEY, CoreMetrics.WEIGHTED_VIOLATIONS_KEY, CoreMetrics.VIOLATIONS_KEY, CoreMetrics.BLOCKER_VIOLATIONS_KEY, | ||||
CoreMetrics.CRITICAL_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, CoreMetrics.INFO_VIOLATIONS_KEY, | |||||
CoreMetrics.NEW_VIOLATIONS_KEY, CoreMetrics.NEW_BLOCKER_VIOLATIONS_KEY, CoreMetrics.NEW_CRITICAL_VIOLATIONS_KEY, CoreMetrics.NEW_MAJOR_VIOLATIONS_KEY, | |||||
CoreMetrics.NEW_MINOR_VIOLATIONS_KEY, CoreMetrics.NEW_INFO_VIOLATIONS_KEY}) | |||||
CoreMetrics.CRITICAL_VIOLATIONS_KEY, CoreMetrics.MAJOR_VIOLATIONS_KEY, CoreMetrics.MINOR_VIOLATIONS_KEY, CoreMetrics.INFO_VIOLATIONS_KEY, | |||||
CoreMetrics.NEW_VIOLATIONS_KEY, CoreMetrics.NEW_BLOCKER_VIOLATIONS_KEY, CoreMetrics.NEW_CRITICAL_VIOLATIONS_KEY, CoreMetrics.NEW_MAJOR_VIOLATIONS_KEY, | |||||
CoreMetrics.NEW_MINOR_VIOLATIONS_KEY, CoreMetrics.NEW_INFO_VIOLATIONS_KEY}) | |||||
@ResourceQualifier({Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.PACKAGE, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.CLASS}) | @ResourceQualifier({Qualifiers.VIEW, Qualifiers.SUBVIEW, Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.PACKAGE, Qualifiers.DIRECTORY, Qualifiers.FILE, Qualifiers.CLASS}) | ||||
/* all exept unit tests...*/ | /* all exept unit tests...*/ | ||||
@UserRole(UserRole.CODEVIEWER) | @UserRole(UserRole.CODEVIEWER) |
def render_coverage | def render_coverage | ||||
load_sources() | load_sources() | ||||
@display_coverage=true | |||||
@expandable=(@lines!=nil) | |||||
@display_coverage = true | |||||
@display_it_coverage = (! @snapshot.measure('it_coverage').nil?) | |||||
@expandable = (@lines!=nil) | |||||
if @lines | if @lines | ||||
@hits_by_line=load_distribution('coverage_line_hits_data') | |||||
@conditions_by_line=load_distribution('conditions_by_line') | |||||
@covered_conditions_by_line=load_distribution('covered_conditions_by_line') | |||||
metric = Metric.by_key(params[:coverage_filter]||params[:metric]) | |||||
@coverage_filter = (metric ? metric.key : 'coverage') | |||||
it_prefix = (@coverage_filter.start_with?('it_') ? 'it_' : '') | |||||
@hits_by_line = load_distribution("#{it_prefix}coverage_line_hits_data") | |||||
@conditions_by_line = load_distribution("#{it_prefix}conditions_by_line") | |||||
@covered_conditions_by_line = load_distribution("#{it_prefix}covered_conditions_by_line") | |||||
@hits_by_line.each_pair do |line_id,hits| | @hits_by_line.each_pair do |line_id,hits| | ||||
line=@lines[line_id-1] | |||||
line = @lines[line_id-1] | |||||
if line | if line | ||||
line.hits=hits.to_i | |||||
line.conditions=@conditions_by_line[line_id].to_i | |||||
line.covered_conditions=@covered_conditions_by_line[line_id].to_i | |||||
line.hits = hits.to_i | |||||
line.conditions = @conditions_by_line[line_id].to_i | |||||
line.covered_conditions = @covered_conditions_by_line[line_id].to_i | |||||
end | end | ||||
end | end | ||||
if @snapshot.measure('conditions_by_line').nil? | |||||
if @snapshot.measure("#{it_prefix}conditions_by_line").nil? | |||||
# TODO remove this code when branch_coverage_hits_data is fully removed from CoreMetrics | # TODO remove this code when branch_coverage_hits_data is fully removed from CoreMetrics | ||||
deprecated_branches_by_line=load_distribution('branch_coverage_hits_data') | |||||
deprecated_branches_by_line = load_distribution("#{it_prefix}branch_coverage_hits_data") | |||||
deprecated_branches_by_line.each_pair do |line_id,label| | deprecated_branches_by_line.each_pair do |line_id,label| | ||||
line=@lines[line_id-1] | |||||
line = @lines[line_id-1] | |||||
if line | if line | ||||
line.deprecated_conditions_label=label | |||||
line.deprecated_conditions_label = label | |||||
end | end | ||||
end | end | ||||
end | end | ||||
to=(@period && @snapshot.period_datetime(@period) ? Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000) : nil) | |||||
metric=Metric.by_key(params[:coverage_filter]||params[:metric]) | |||||
@coverage_filter=(metric ? metric.key : 'coverage') | |||||
@filtered=true | |||||
to = (@period && @snapshot.period_datetime(@period) ? Java::JavaUtil::Date.new(@snapshot.period_datetime(@period).to_f * 1000) : nil) | |||||
@filtered = true | |||||
if ('lines_to_cover'==@coverage_filter || 'coverage'==@coverage_filter || 'line_coverage'==@coverage_filter || | if ('lines_to_cover'==@coverage_filter || 'coverage'==@coverage_filter || 'line_coverage'==@coverage_filter || | ||||
'new_lines_to_cover'==@coverage_filter || 'new_coverage'==@coverage_filter || 'new_line_coverage'==@coverage_filter) | |||||
@coverage_filter='lines_to_cover' | |||||
'new_lines_to_cover'==@coverage_filter || 'new_coverage'==@coverage_filter || 'new_line_coverage'==@coverage_filter || | |||||
'it_lines_to_cover'==@coverage_filter || 'it_coverage'==@coverage_filter || 'it_line_coverage'==@coverage_filter) | |||||
@coverage_filter = "#{it_prefix}lines_to_cover" | |||||
filter_lines{|line| line.hits && line.after(to)} | filter_lines{|line| line.hits && line.after(to)} | ||||
elsif 'uncovered_lines'==@coverage_filter || 'new_uncovered_lines'==@coverage_filter | |||||
@coverage_filter='uncovered_lines' | |||||
elsif 'uncovered_lines'==@coverage_filter || 'new_uncovered_lines'==@coverage_filter || 'it_uncovered_lines'==@coverage_filter | |||||
@coverage_filter = "#{it_prefix}uncovered_lines" | |||||
filter_lines{|line| line.hits && line.hits==0 && line.after(to)} | filter_lines{|line| line.hits && line.hits==0 && line.after(to)} | ||||
elsif 'conditions_to_cover'==@coverage_filter || 'branch_coverage'==@coverage_filter || | elsif 'conditions_to_cover'==@coverage_filter || 'branch_coverage'==@coverage_filter || | ||||
'new_conditions_to_cover'==@coverage_filter || 'new_branch_coverage'==@coverage_filter | |||||
@coverage_filter='conditions_to_cover' | |||||
'new_conditions_to_cover'==@coverage_filter || 'new_branch_coverage'==@coverage_filter || | |||||
'it_conditions_to_cover'==@coverage_filter || 'it_branch_coverage'==@coverage_filter | |||||
@coverage_filter="#{it_prefix}conditions_to_cover" | |||||
filter_lines{|line| line.conditions && line.conditions>0 && line.after(to)} | filter_lines{|line| line.conditions && line.conditions>0 && line.after(to)} | ||||
elsif 'uncovered_conditions'==@coverage_filter || 'new_uncovered_conditions'==@coverage_filter | |||||
@coverage_filter='uncovered_conditions' | |||||
elsif 'uncovered_conditions'==@coverage_filter || 'new_uncovered_conditions'==@coverage_filter || 'it_uncovered_conditions'==@coverage_filter | |||||
@coverage_filter="#{it_prefix}uncovered_conditions" | |||||
filter_lines{|line| line.conditions && line.covered_conditions && line.covered_conditions<line.conditions && line.after(to)} | filter_lines{|line| line.conditions && line.covered_conditions && line.covered_conditions<line.conditions && line.after(to)} | ||||
end | end | ||||
end | end |
}.compact.uniq.sort | }.compact.uniq.sort | ||||
end | end | ||||
def self.i18n_domain_for(to_translate) | |||||
return nil if to_translate.nil? | |||||
# Localized domain name | |||||
def self.domain_for(domain_key) | |||||
return nil if domain_key.nil? | |||||
localeMap = Metric.i18n_domain_cache[to_translate] | |||||
localeMap = Metric.i18n_domain_cache[domain_key] | |||||
locale = I18n.locale | locale = I18n.locale | ||||
return localeMap[locale] if not localeMap.nil? and localeMap.has_key?(locale) | |||||
return localeMap[locale] if localeMap && localeMap.has_key?(locale) | |||||
i18n_key = 'metric_domain.' + to_translate | |||||
result = Api::Utils.message(i18n_key, :default => to_translate) | |||||
i18n_key = 'metric_domain.' + domain_key | |||||
result = Api::Utils.message(i18n_key, :default => domain_key) | |||||
localeMap[locale] = result if localeMap | localeMap[locale] = result if localeMap | ||||
result | result | ||||
end | end | ||||
def self.name_for(metric_key) | |||||
m=by_key(metric_key) | |||||
m ? m.short_name : nil | |||||
end | |||||
def key | def key | ||||
name | name | ||||
def domain(translate=true) | def domain(translate=true) | ||||
default_string = read_attribute(:domain) | default_string = read_attribute(:domain) | ||||
return default_string unless translate | return default_string unless translate | ||||
Metric.i18n_domain_for(default_string) | |||||
Metric.domain_for(default_string) | |||||
end | end | ||||
def domain=(value) | def domain=(value) |
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<% if m=measure('new_line_coverage') %> | <% if m=measure('new_line_coverage') %> | ||||
<td class="name"><%= message('metric.line_coverage.name') -%>:</td> | |||||
<td class="name"><%= Metric.name_for('line_coverage') -%>:</td> | |||||
<td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%></td> | <td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%></td> | ||||
<% else %> | <% else %> | ||||
<td colspan="2"></td> | <td colspan="2"></td> | ||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<% if m=measure('new_branch_coverage') %> | <% if m=measure('new_branch_coverage') %> | ||||
<td class="name"><%= message('metric.branch_coverage.name') -%>:</td> | |||||
<td class="name"><%= Metric.name_for('branch_coverage') -%>:</td> | |||||
<td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%></td> | <td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%></td> | ||||
<% else %> | <% else %> | ||||
<td colspan="2"></td> | <td colspan="2"></td> | ||||
<tr> | <tr> | ||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<% if m=measure('new_uncovered_lines') %> | <% if m=measure('new_uncovered_lines') %> | ||||
<td class="name"><%= message('metric.uncovered_lines.name') -%>:</td> | |||||
<td class="name"><%= Metric.name_for('uncovered_lines') -%>:</td> | |||||
<td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%>/<%= format_variation('new_lines_to_cover', :period => @period, :style => 'none') -%></td> | <td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%>/<%= format_variation('new_lines_to_cover', :period => @period, :style => 'none') -%></td> | ||||
<% else %> | <% else %> | ||||
<td colspan="2"></td> | <td colspan="2"></td> | ||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<% if m=measure('new_uncovered_conditions') %> | <% if m=measure('new_uncovered_conditions') %> | ||||
<td class="name"><%= message('metric.uncovered_conditions.name') -%>: </td> | |||||
<td class="name"><%= Metric.name_for('uncovered_conditions') -%>: </td> | |||||
<td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%>/<%= format_variation('new_conditions_to_cover', :period => @period, :style => 'none') -%></td> | <td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%>/<%= format_variation('new_conditions_to_cover', :period => @period, :style => 'none') -%></td> | ||||
<% else %> | <% else %> | ||||
<td colspan="2"></td> | <td colspan="2"></td> | ||||
</table> | </table> | ||||
<% else %> | <% else %> | ||||
<table> | <table> | ||||
<% if @display_it_coverage %> | |||||
<tr> | |||||
<td colspan="8"><%= message('coverage_tab.unit_tests') -%></td> | |||||
<td colspan="7"><%= message('coverage_tab.integration_tests') -%></td> | |||||
</tr> | |||||
<% end %> | |||||
<tr> | <tr> | ||||
<td class="big" rowspan="2"><%= format_measure('coverage', :default => '-') -%></td> | <td class="big" rowspan="2"><%= format_measure('coverage', :default => '-') -%></td> | ||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<%= render :partial => 'measure', :locals => {:measure => measure('line_coverage'), :title => message('metric.line_coverage.name')} -%> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('line_coverage'), :title => Metric.name_for('line_coverage')} -%> | |||||
<td class="sep"> </td> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('branch_coverage'), :title => Metric.name_for('branch_coverage')} -%> | |||||
<td class="sep"> </td> | |||||
<% if @display_it_coverage %> | |||||
<td class="big" rowspan="2"><%= format_measure('it_coverage', :default => '-') -%></td> | |||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<%= render :partial => 'measure', :locals => {:measure => measure('branch_coverage'), :title => message('metric.branch_coverage.name')} -%> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('it_line_coverage'), :title => Metric.name_for('it_line_coverage')} -%> | |||||
<td class="sep"> </td> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('it_branch_coverage'), :title => Metric.name_for('it_branch_coverage')} -%> | |||||
<% end %> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<%= render :partial => 'measure', :locals => {:measure => measure('uncovered_lines'), :title => message('metric.uncovered_lines.name'), :ratio => measure('lines_to_cover')} -%> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('uncovered_lines'), :title => Metric.name_for('uncovered_lines'), :ratio => measure('lines_to_cover')} -%> | |||||
<td class="sep"> </td> | <td class="sep"> </td> | ||||
<%= render :partial => 'measure', :locals => {:measure => measure('uncovered_conditions'), :title => message('metric.uncovered_conditions.name'), :ratio => measure('conditions_to_cover')} -%> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('uncovered_conditions'), :title => Metric.name_for('uncovered_conditions'), :ratio => measure('conditions_to_cover')} -%> | |||||
<td class="sep"> </td> | |||||
<% if @display_it_coverage %> | |||||
<td class="sep"> </td> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('it_uncovered_lines'), :title => Metric.name_for('it_uncovered_lines'), :ratio => measure('it_lines_to_cover')} -%> | |||||
<td class="sep"> </td> | |||||
<%= render :partial => 'measure', :locals => {:measure => measure('it_uncovered_conditions'), :title => Metric.name_for('it_uncovered_conditions'), :ratio => measure('it_conditions_to_cover')} -%> | |||||
<% end %> | |||||
</tr> | </tr> | ||||
</table> | </table> | ||||
<% end %> | <% end %> |
<% if @display_coverage %> | <% if @display_coverage %> | ||||
<td class="<%= 'first' if first -%>"> | <td class="<%= 'first' if first -%>"> | ||||
<select id="coverage_filter" name="coverage_filter" onchange="applyOptions()"> | <select id="coverage_filter" name="coverage_filter" onchange="applyOptions()"> | ||||
<option value="lines_to_cover" <%= 'selected' if @coverage_filter=='lines_to_cover' -%>><%= message('metric.lines_to_cover.name') -%></option> | |||||
<option value="uncovered_lines" <%= 'selected' if @coverage_filter=='uncovered_lines' -%>><%= message('metric.uncovered_lines.name') -%></option> | |||||
<option value="conditions_to_cover" <%= 'selected' if @coverage_filter=='conditions_to_cover' -%>><%= message('metric.conditions_to_cover.name') -%></option> | |||||
<option value="uncovered_conditions" <%= 'selected' if @coverage_filter=='uncovered_conditions' -%>><%= message('metric.uncovered_conditions.name') -%></option> | |||||
<optgroup label="<%= h message('coverage_tab.unit_tests') -%>"> | |||||
<option value="lines_to_cover" <%= 'selected' if @coverage_filter=='lines_to_cover' -%>><%= Metric.name_for('lines_to_cover') -%></option> | |||||
<option value="uncovered_lines" <%= 'selected' if @coverage_filter=='uncovered_lines' -%>><%= Metric.name_for('uncovered_lines') -%></option> | |||||
<option value="conditions_to_cover" <%= 'selected' if @coverage_filter=='conditions_to_cover' -%>><%= Metric.name_for('conditions_to_cover') -%></option> | |||||
<option value="uncovered_conditions" <%= 'selected' if @coverage_filter=='uncovered_conditions' -%>><%= Metric.name_for('uncovered_conditions') -%></option> | |||||
</optgroup> | |||||
<% if @display_it_coverage %> | |||||
<optgroup label="<%= h message('coverage_tab.integration_tests') -%>"> | |||||
<option value="it_lines_to_cover" <%= 'selected' if @coverage_filter=='it_lines_to_cover' -%>><%= Metric.name_for('it_lines_to_cover') -%></option> | |||||
<option value="it_uncovered_lines" <%= 'selected' if @coverage_filter=='it_uncovered_lines' -%>><%= Metric.name_for('it_uncovered_lines') -%></option> | |||||
<option value="it_conditions_to_cover" <%= 'selected' if @coverage_filter=='it_conditions_to_cover' -%>><%= Metric.name_for('it_conditions_to_cover') -%></option> | |||||
<option value="it_uncovered_conditions" <%= 'selected' if @coverage_filter=='it_uncovered_conditions' -%>><%= Metric.name_for('it_uncovered_conditions') -%></option> | |||||
</optgroup> | |||||
<% end %> | |||||
</select> | </select> | ||||
</td> | </td> | ||||
<% first=false | <% first=false |
padding-right: 7px; | padding-right: 7px; | ||||
} | } | ||||
.tab_header td.name { | .tab_header td.name { | ||||
font-weight: bold; | |||||
text-align: left; | text-align: left; | ||||
white-space: nowrap; | white-space: nowrap; | ||||
} | } | ||||
.tab_header td.value { | .tab_header td.value { | ||||
font-weight: bold; | |||||
text-align: right; | text-align: right; | ||||
white-space: nowrap; | white-space: nowrap; | ||||
} | } |