Browse Source

SONAR-2952 Make the coverage tab support integration test measures

tags/2.12
simonbrandhof 12 years ago
parent
commit
72f2552808
23 changed files with 912 additions and 1239 deletions
  1. 6
    28
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java
  2. 6
    5
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItBranchCoverageDecorator.java
  3. 9
    8
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItCoverageDecorator.java
  4. 6
    5
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItLineCoverageDecorator.java
  5. 0
    130
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItMetrics.java
  6. 7
    7
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItSensor.java
  7. 0
    39
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewerDefinition.java
  8. 0
    150
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/CoveragePanel.java
  9. 0
    69
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/CoverageViewer.java
  10. 0
    42
      plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/Metrics.java
  11. 0
    9
      plugins/sonar-jacoco-plugin/src/main/resources/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewer.gwt.xml
  12. 0
    6
      plugins/sonar-jacoco-plugin/src/main/resources/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewerDev.gwt.xml
  13. 3
    23
      plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JaCoCoPluginTest.java
  14. 0
    34
      plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItMetricsTest.java
  15. 20
    16
      plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItSensorTest.java
  16. 46
    0
      plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties
  17. 708
    615
      sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
  18. 14
    8
      sonar-server/src/main/java/org/sonar/server/ui/DefaultPages.java
  19. 30
    25
      sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
  20. 13
    7
      sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb
  21. 29
    8
      sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb
  22. 14
    4
      sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
  23. 1
    1
      sonar-server/src/main/webapp/stylesheets/style.css

+ 6
- 28
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java View File

@@ -19,14 +19,13 @@
*/
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.Property;
import org.sonar.api.SonarPlugin;
import org.sonar.plugins.jacoco.itcoverage.*;
import org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewerDefinition;

import java.util.Arrays;
import java.util.List;

@Properties({
@Property(
@@ -87,20 +86,7 @@ import org.sonar.plugins.jacoco.itcoverage.viewer.CoverageViewerDefinition;
module = 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() {
return Arrays.asList(
@@ -115,18 +101,10 @@ public class JaCoCoPlugin implements Plugin {
JaCoCoSensor.class,

// Integration tests
JaCoCoItMetrics.class,
JaCoCoItSensor.class,
ItCoverageWidget.class,
ItCoverageDecorator.class,
ItLineCoverageDecorator.class,
ItBranchCoverageDecorator.class,
CoverageViewerDefinition.class);
ItBranchCoverageDecorator.class);
}

@Override
public String toString() {
return getKey();
}

}

+ 6
- 5
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItBranchCoverageDecorator.java View File

@@ -21,6 +21,7 @@ package org.sonar.plugins.jacoco.itcoverage;

import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.MeasureUtils;
import org.sonar.api.measures.Metric;

@@ -33,23 +34,23 @@ import java.util.List;
public final class ItBranchCoverageDecorator extends AbstractCoverageDecorator {
@Override
protected Metric getTargetMetric() {
return JaCoCoItMetrics.IT_BRANCH_COVERAGE;
return CoreMetrics.IT_BRANCH_COVERAGE;
}

@DependsUpon
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
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;
}

@Override
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);
}
}

+ 9
- 8
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItCoverageDecorator.java View File

@@ -21,6 +21,7 @@ package org.sonar.plugins.jacoco.itcoverage;

import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.MeasureUtils;
import org.sonar.api.measures.Metric;

@@ -34,27 +35,27 @@ public class ItCoverageDecorator extends AbstractCoverageDecorator {

@Override
protected Metric getTargetMetric() {
return JaCoCoItMetrics.IT_COVERAGE;
return CoreMetrics.IT_COVERAGE;
}

@DependsUpon
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
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;
}

@Override
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;
}


+ 6
- 5
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/ItLineCoverageDecorator.java View File

@@ -21,6 +21,7 @@ package org.sonar.plugins.jacoco.itcoverage;

import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.MeasureUtils;
import org.sonar.api.measures.Metric;

@@ -33,23 +34,23 @@ import java.util.List;
public class ItLineCoverageDecorator extends AbstractCoverageDecorator {
@Override
protected Metric getTargetMetric() {
return JaCoCoItMetrics.IT_LINE_COVERAGE;
return CoreMetrics.IT_LINE_COVERAGE;
}

@DependsUpon
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
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;
}

@Override
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);
}
}

+ 0
- 130
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItMetrics.java View File

@@ -1,130 +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);
}

}

+ 7
- 7
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItSensor.java View File

@@ -72,25 +72,25 @@ public class JaCoCoItSensor implements Sensor {
private Measure convertForIT(Measure measure) {
Measure itMeasure = null;
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())) {
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())) {
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())) {
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())) {
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())) {
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())) {
itMeasure = new Measure(JaCoCoItMetrics.IT_CONDITIONS_BY_LINE, measure.getData());
itMeasure = new Measure(CoreMetrics.IT_CONDITIONS_BY_LINE, measure.getData());
}
return itMeasure;
}

+ 0
- 39
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewerDefinition.java View File

@@ -1,39 +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.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";
}
}

+ 0
- 150
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/CoveragePanel.java View File

@@ -1,150 +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.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("&nbsp;", "");
row.setValue2("&nbsp;", "");

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("&nbsp;", "red");
}
}
return Arrays.asList(row);
}
}

+ 0
- 69
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/CoverageViewer.java View File

@@ -1,69 +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.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));
}
}
}

+ 0
- 42
plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/itcoverage/viewer/client/Metrics.java View File

@@ -1,42 +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.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";
}

+ 0
- 9
plugins/sonar-jacoco-plugin/src/main/resources/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewer.gwt.xml View File

@@ -1,9 +0,0 @@
<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>

+ 0
- 6
plugins/sonar-jacoco-plugin/src/main/resources/org/sonar/plugins/jacoco/itcoverage/viewer/CoverageViewerDev.gwt.xml View File

@@ -1,6 +0,0 @@
<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>

+ 3
- 23
plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/JaCoCoPluginTest.java View File

@@ -19,35 +19,15 @@
*/
package org.sonar.plugins.jacoco;

import org.junit.Test;

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 org.junit.Before;
import org.junit.Test;

/**
* @author Evgeny Mandrikov
*/
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
public void testExtensions() {
assertThat(plugin.getExtensions().size(), greaterThan(0));
assertThat(new JaCoCoPlugin().getExtensions().size(), greaterThan(0));
}
}

+ 0
- 34
plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItMetricsTest.java View File

@@ -1,34 +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 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));
}

}

+ 20
- 16
plugins/sonar-jacoco-plugin/src/test/java/org/sonar/plugins/jacoco/itcoverage/JaCoCoItSensorTest.java View File

@@ -19,25 +19,29 @@
*/
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.Test;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.measures.CoreMetrics;
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.ProjectFileSystem;
import org.sonar.api.resources.Resource;
import org.sonar.api.test.IsMeasure;
import org.sonar.plugins.jacoco.JacocoConfiguration;

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 {
private JacocoConfiguration configuration;
private JaCoCoItSensor sensor;
@@ -88,14 +92,14 @@ public class JaCoCoItSensorTest {
sensor.analyse(project, context);

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),
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);
}


+ 46
- 0
plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties View File

@@ -607,6 +607,14 @@ duplications.expand=Expand
duplications.collapse=Collapse


#------------------------------------------------------------------------------
#
# COVERAGE TAB
#
#------------------------------------------------------------------------------
coverage_tab.unit_tests=Unit Tests
coverage_tab.integration_tests=Integration Tests

#------------------------------------------------------------------------------
#
# MANUAL MEASURES
@@ -917,6 +925,7 @@ severity.INFO=Info

metric_domain.Size=Size
metric_domain.Tests=Tests
metric_domain.Integration Tests=L10n Integration Tests
metric_domain.Complexity=Complexity
metric_domain.Documentation=Documentation
metric_domain.Rules=Rules
@@ -1103,6 +1112,43 @@ metric.conditions_by_line.description=Branches by line
metric.covered_conditions_by_line.name=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

+ 708
- 615
sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
File diff suppressed because it is too large
View File


+ 14
- 8
sonar-server/src/main/java/org/sonar/server/ui/DefaultPages.java View File

@@ -28,7 +28,7 @@ import org.sonar.api.web.*;
*/
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() {
}
@@ -60,10 +60,16 @@ public final class DefaultPages {

@NavigationSection(NavigationSection.RESOURCE_TAB)
@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)
private static final class CoverageTab implements RubyRailsPage {
@@ -83,9 +89,9 @@ public final class DefaultPages {

@NavigationSection(NavigationSection.RESOURCE_TAB)
@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})
/* all exept unit tests...*/
@UserRole(UserRole.CODEVIEWER)

+ 30
- 25
sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb View File

@@ -131,53 +131,58 @@ class ResourceController < ApplicationController

def render_coverage
load_sources()
@display_coverage=true
@expandable=(@lines!=nil)
@display_coverage = true
@display_it_coverage = (! @snapshot.measure('it_coverage').nil?)
@expandable = (@lines!=nil)
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|
line=@lines[line_id-1]
line = @lines[line_id-1]
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

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
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|
line=@lines[line_id-1]
line = @lines[line_id-1]
if line
line.deprecated_conditions_label=label
line.deprecated_conditions_label = label
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 ||
'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)}

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)}

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)}

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)}
end
end

+ 13
- 7
sonar-server/src/main/webapp/WEB-INF/app/models/metric.rb View File

@@ -68,19 +68,25 @@ class Metric < ActiveRecord::Base
}.compact.uniq.sort
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
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
result
end

def self.name_for(metric_key)
m=by_key(metric_key)
m ? m.short_name : nil
end
def key
name
@@ -89,7 +95,7 @@ class Metric < ActiveRecord::Base
def domain(translate=true)
default_string = read_attribute(:domain)
return default_string unless translate
Metric.i18n_domain_for(default_string)
Metric.domain_for(default_string)
end
def domain=(value)

+ 29
- 8
sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb View File

@@ -8,7 +8,7 @@
<td class="sep"> </td>

<% 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>
<% else %>
<td colspan="2"></td>
@@ -16,7 +16,7 @@

<td class="sep"> </td>
<% 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>
<% else %>
<td colspan="2"></td>
@@ -25,7 +25,7 @@
<tr>
<td class="sep"> </td>
<% 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>
<% else %>
<td colspan="2"></td>
@@ -33,7 +33,7 @@

<td class="sep"> </td>
<% 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>
<% else %>
<td colspan="2"></td>
@@ -42,19 +42,40 @@
</table>
<% else %>
<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>
<td class="big" rowspan="2"><%= format_measure('coverage', :default => '-') -%></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>
<%= 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>
<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>
<%= 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>
</table>
<% end %>

+ 14
- 4
sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb View File

@@ -67,10 +67,20 @@
<% if @display_coverage %>
<td class="<%= 'first' if first -%>">
<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>
</td>
<% first=false

+ 1
- 1
sonar-server/src/main/webapp/stylesheets/style.css View File

@@ -902,11 +902,11 @@ span.rulename a:hover {
padding-right: 7px;
}
.tab_header td.name {
font-weight: bold;
text-align: left;
white-space: nowrap;
}
.tab_header td.value {
font-weight: bold;
text-align: right;
white-space: nowrap;
}

Loading…
Cancel
Save