aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java4
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java72
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java85
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java73
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java216
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java9
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java178
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java66
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java18
-rw-r--r--plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java5
-rw-r--r--plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties51
-rw-r--r--sonar-core/src/main/java/org/sonar/jpa/session/CustomHibernateConnectionProvider.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java68
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb14
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb3
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb78
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb4
17 files changed, 724 insertions, 222 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
index 82e3a1c8723..00ea4547077 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
@@ -268,6 +268,9 @@ public class CorePlugin extends SonarPlugin {
extensions.add(LineCoverageDecorator.class);
extensions.add(CoverageDecorator.class);
extensions.add(BranchCoverageDecorator.class);
+ extensions.add(ItLineCoverageDecorator.class);
+ extensions.add(ItCoverageDecorator.class);
+ extensions.add(ItBranchCoverageDecorator.class);
extensions.add(ApplyProjectRolesDecorator.class);
extensions.add(ExcludedResourceFilter.class);
extensions.add(CommentDensityDecorator.class);
@@ -286,6 +289,7 @@ public class CorePlugin extends SonarPlugin {
extensions.add(NewViolationsDecorator.class);
extensions.add(TimeMachineConfigurationPersister.class);
extensions.add(NewCoverageFileAnalyzer.class);
+ extensions.add(NewItCoverageFileAnalyzer.class);
extensions.add(NewCoverageAggregator.class);
return extensions;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java
new file mode 100644
index 00000000000..90a624305d7
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItBranchCoverageDecorator.java
@@ -0,0 +1,72 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.sensors;
+
+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;
+
+import java.util.Arrays;
+import java.util.List;
+
+public final class ItBranchCoverageDecorator extends AbstractCoverageDecorator {
+
+ @DependsUpon
+ public List<Metric> dependsUponMetrics() {
+ return Arrays.asList(CoreMetrics.IT_UNCOVERED_CONDITIONS, CoreMetrics.IT_CONDITIONS_TO_COVER,
+ CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER);
+ }
+
+ @Override
+ protected Metric getGeneratedMetric() {
+ return CoreMetrics.IT_BRANCH_COVERAGE;
+ }
+
+ @Override
+ protected Long countElements(DecoratorContext context) {
+ return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+ }
+
+ @Override
+ protected long countCoveredElements(DecoratorContext context) {
+ long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0L);
+ long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+ return conditions - uncoveredConditions;
+ }
+
+ @Override
+ protected Metric getGeneratedMetricForNewCode() {
+ return CoreMetrics.NEW_IT_BRANCH_COVERAGE;
+ }
+
+ @Override
+ protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+ return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex);
+ }
+
+ @Override
+ protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+ long uncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS), periodIndex, 0L);
+ long conditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
+ return conditions - uncoveredConditions;
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java
new file mode 100644
index 00000000000..ce538aa1f1f
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItCoverageDecorator.java
@@ -0,0 +1,85 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.sensors;
+
+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;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+public final class ItCoverageDecorator extends AbstractCoverageDecorator {
+
+ @DependsUpon
+ public Collection<Metric> usedMetrics() {
+ return Arrays.asList(CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_LINES_TO_COVER,
+ CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.IT_CONDITIONS_TO_COVER, CoreMetrics.IT_UNCOVERED_CONDITIONS,
+ CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
+ }
+
+ @Override
+ protected Metric getGeneratedMetric() {
+ return CoreMetrics.IT_COVERAGE;
+ }
+
+ @Override
+ protected Long countElements(DecoratorContext context) {
+ long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+ long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+ return lines + conditions;
+ }
+
+ @Override
+ protected long countCoveredElements(DecoratorContext context) {
+ long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0L);
+ long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+ long uncoveredConditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_CONDITIONS), 0L);
+ long conditions = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_CONDITIONS_TO_COVER), 0L);
+ return lines + conditions - uncoveredConditions - uncoveredLines;
+ }
+
+
+ @Override
+ protected Metric getGeneratedMetricForNewCode() {
+ return CoreMetrics.NEW_IT_COVERAGE;
+ }
+
+ @Override
+ protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+ Long newLinesToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex);
+ if (newLinesToCover != null) {
+ long newConditionsToCover = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
+ return newLinesToCover + newConditionsToCover;
+ }
+ return null;
+ }
+
+ @Override
+ protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+ long newLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex, 0L);
+ long newUncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES), periodIndex, 0L);
+ long newUncoveredConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS), periodIndex, 0L);
+ long newConditions = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER), periodIndex, 0L);
+ return newLines + newConditions - newUncoveredConditions - newUncoveredLines;
+ }
+} \ No newline at end of file
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java
new file mode 100644
index 00000000000..53c46fd4119
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ItLineCoverageDecorator.java
@@ -0,0 +1,73 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.sensors;
+
+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;
+
+import java.util.Arrays;
+import java.util.List;
+
+public final class ItLineCoverageDecorator extends AbstractCoverageDecorator {
+
+ @DependsUpon
+ public List<Metric> dependsUponMetrics() {
+ return Arrays.asList(CoreMetrics.IT_UNCOVERED_LINES, CoreMetrics.IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES,
+ CoreMetrics.NEW_IT_LINES_TO_COVER);
+ }
+
+ @Override
+ protected Metric getGeneratedMetric() {
+ return CoreMetrics.IT_LINE_COVERAGE;
+ }
+
+ @Override
+ protected Long countElements(DecoratorContext context) {
+ return MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+ }
+
+ @Override
+ protected long countCoveredElements(DecoratorContext context) {
+ long uncoveredLines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_UNCOVERED_LINES), 0L);
+ long lines = MeasureUtils.getValueAsLong(context.getMeasure(CoreMetrics.IT_LINES_TO_COVER), 0L);
+ return lines - uncoveredLines;
+ }
+
+
+ @Override
+ protected Metric getGeneratedMetricForNewCode() {
+ return CoreMetrics.NEW_IT_LINE_COVERAGE;
+ }
+
+ @Override
+ protected Long countElementsForNewCode(DecoratorContext context, int periodIndex) {
+ return MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex);
+ }
+
+ @Override
+ protected long countCoveredElementsForNewCode(DecoratorContext context, int periodIndex) {
+ long uncoveredLines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_UNCOVERED_LINES), periodIndex, 0L);
+ long lines = MeasureUtils.getVariationAsLong(context.getMeasure(CoreMetrics.NEW_IT_LINES_TO_COVER), periodIndex, 0L);
+ return lines - uncoveredLines;
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java
new file mode 100644
index 00000000000..f5740ffebf1
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java
@@ -0,0 +1,216 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.timemachine;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.ObjectUtils;
+import org.sonar.api.batch.*;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.batch.components.PastSnapshot;
+import org.sonar.batch.components.TimeMachineConfiguration;
+import org.sonar.core.NotDryRun;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @since 2.7
+ */
+@NotDryRun
+@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
+public abstract class AbstractNewCoverageFileAnalyzer implements Decorator {
+
+ private List<PeriodStruct> structs;
+
+ public AbstractNewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration) {
+ structs = Lists.newArrayList();
+ for (PastSnapshot pastSnapshot : timeMachineConfiguration.getProjectPastSnapshots()) {
+ structs.add(new PeriodStruct(pastSnapshot));
+ }
+ }
+
+ AbstractNewCoverageFileAnalyzer(List<PeriodStruct> structs) {
+ this.structs = structs;
+ }
+
+ public abstract Metric getCoverageLineHitsDataMetric();
+
+ public abstract Metric getConditionsByLineMetric();
+
+ public abstract Metric getCoveredConditionsByLineMetric();
+
+ public abstract Metric getNewLinesToCoverMetric();
+
+ public abstract Metric getNewUncoveredLinesMetric();
+
+ public abstract Metric getNewConditionsToCoverMetric();
+
+ public abstract Metric getNewUncoveredConditionsMetric();
+
+ public boolean shouldExecuteOnProject(Project project) {
+ return project.isLatestAnalysis() && !structs.isEmpty();
+ }
+
+ private boolean shouldDecorate(Resource resource) {
+ return Scopes.isFile(resource) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier());
+ }
+
+ @DependsUpon
+ public List<Metric> dependsOnMetrics() {
+
+ return Arrays.asList(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE,
+ getCoverageLineHitsDataMetric(), getConditionsByLineMetric(), getCoveredConditionsByLineMetric());
+ }
+
+ @DependedUpon
+ public List<Metric> generatesNewCoverageMetrics() {
+ return Arrays.asList(getNewLinesToCoverMetric(), getNewUncoveredLinesMetric(), getNewConditionsToCoverMetric(), getNewUncoveredConditionsMetric());
+ }
+
+ public void decorate(Resource resource, DecoratorContext context) {
+ if (shouldDecorate(resource)) {
+ doDecorate(context);
+ }
+ }
+
+ void doDecorate(DecoratorContext context) {
+ if (parse(context)) {
+ compute(context);
+ }
+ }
+
+ private boolean parse(DecoratorContext context) {
+ Measure lastCommits = context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE);
+ Measure hitsByLineMeasure = context.getMeasure(getCoverageLineHitsDataMetric());
+
+ if (lastCommits != null && lastCommits.hasData() && hitsByLineMeasure != null && hitsByLineMeasure.hasData()) {
+ Map<Integer, Date> datesByLine = KeyValueFormat.parseIntDateTime(lastCommits.getData());
+ Map<Integer, Integer> hitsByLine = parseCountByLine(hitsByLineMeasure);
+ Map<Integer, Integer> conditionsByLine = parseCountByLine(context.getMeasure(getConditionsByLineMetric()));
+ Map<Integer, Integer> coveredConditionsByLine = parseCountByLine(context.getMeasure(getCoveredConditionsByLineMetric()));
+
+ reset();
+
+ for (Map.Entry<Integer, Integer> entry : hitsByLine.entrySet()) {
+ int lineId = entry.getKey();
+ int hits = entry.getValue();
+ int conditions = (Integer) ObjectUtils.defaultIfNull(conditionsByLine.get(lineId), 0);
+ int coveredConditions = (Integer) ObjectUtils.defaultIfNull(coveredConditionsByLine.get(lineId), 0);
+ Date date = datesByLine.get(lineId);
+ for (PeriodStruct struct : structs) {
+ struct.analyze(date, hits, conditions, coveredConditions);
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ private void reset() {
+ for (PeriodStruct struct : structs) {
+ struct.reset();
+ }
+ }
+
+ private void compute(DecoratorContext context) {
+ Measure newLines = new Measure(getNewLinesToCoverMetric());
+ Measure newUncoveredLines = new Measure(getNewUncoveredLinesMetric());
+ Measure newConditions = new Measure(getNewConditionsToCoverMetric());
+ Measure newUncoveredConditions = new Measure(getNewUncoveredConditionsMetric());
+
+ for (PeriodStruct struct : structs) {
+ newLines.setVariation(struct.index, (double) struct.newLines);
+ newUncoveredLines.setVariation(struct.index, (double) (struct.newLines - struct.newCoveredLines));
+ newConditions.setVariation(struct.index, (double) struct.newConditions);
+ newUncoveredConditions.setVariation(struct.index, (double) struct.newConditions - struct.newCoveredConditions);
+ }
+
+ context.saveMeasure(newLines);
+ context.saveMeasure(newUncoveredLines);
+ context.saveMeasure(newConditions);
+ context.saveMeasure(newUncoveredConditions);
+ }
+
+ private Map<Integer, Integer> parseCountByLine(Measure measure) {
+ if (measure != null && measure.hasData()) {
+ return KeyValueFormat.parseIntInt(measure.getData());
+ }
+ return Maps.newHashMap();
+ }
+
+ public static final class PeriodStruct {
+ int index;
+ Date date;
+ int newLines = 0, newCoveredLines = 0, newConditions = 0, newCoveredConditions = 0;
+
+ PeriodStruct(PastSnapshot pastSnapshot) {
+ this.index = pastSnapshot.getIndex();
+ this.date = pastSnapshot.getTargetDate();
+ }
+
+ PeriodStruct(int index, Date date) {
+ this.index = index;
+ this.date = date;
+ }
+
+ void reset() {
+ newLines = 0;
+ newCoveredLines = 0;
+ newConditions = 0;
+ newCoveredConditions = 0;
+ }
+
+ void analyze(Date lineDate, int hits, int conditions, int coveredConditions) {
+ if (lineDate == null) {
+ // TODO warning
+
+ } else if (date == null || lineDate.after(date)) {
+ // TODO test if string comparison is faster or not
+ addLine(hits > 0);
+ addConditions(conditions, coveredConditions);
+ }
+ }
+
+ void addLine(boolean covered) {
+ newLines += 1;
+ if (covered) {
+ newCoveredLines += 1;
+ }
+ }
+
+ void addConditions(int count, int countCovered) {
+ newConditions += count;
+ if (count > 0) {
+ newCoveredConditions += countCovered;
+ }
+ }
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java
index 15d0e7a1f68..c4ffc776450 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageAggregator.java
@@ -44,8 +44,9 @@ public final class NewCoverageAggregator implements Decorator {
@DependedUpon
public List<Metric> generatesNewCoverageMetrics() {
- return Arrays.asList(CoreMetrics.NEW_LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES,
- CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS);
+ return Arrays.asList(
+ CoreMetrics.NEW_LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS,
+ CoreMetrics.NEW_IT_LINES_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_LINES, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS);
}
public void decorate(Resource resource, DecoratorContext context) {
@@ -55,6 +56,10 @@ public final class NewCoverageAggregator implements Decorator {
aggregate(context, CoreMetrics.NEW_UNCOVERED_LINES, maxPeriods);
aggregate(context, CoreMetrics.NEW_CONDITIONS_TO_COVER, maxPeriods);
aggregate(context, CoreMetrics.NEW_UNCOVERED_CONDITIONS, maxPeriods);
+ aggregate(context, CoreMetrics.NEW_IT_LINES_TO_COVER, maxPeriods);
+ aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_LINES, maxPeriods);
+ aggregate(context, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER, maxPeriods);
+ aggregate(context, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS, maxPeriods);
}
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java
index d44ffd056e1..59929b27d88 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzer.java
@@ -19,184 +19,54 @@
*/
package org.sonar.plugins.core.timemachine;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.lang.ObjectUtils;
-import org.sonar.api.batch.*;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.batch.components.PastSnapshot;
import org.sonar.batch.components.TimeMachineConfiguration;
-import org.sonar.core.NotDryRun;
-import java.util.Arrays;
-import java.util.Date;
import java.util.List;
-import java.util.Map;
-/**
- * @since 2.7
- */
-@NotDryRun
-@DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE)
-public final class NewCoverageFileAnalyzer implements Decorator {
-
- private List<PeriodStruct> structs;
+public class NewCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
public NewCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration) {
- structs = Lists.newArrayList();
- for (PastSnapshot pastSnapshot : timeMachineConfiguration.getProjectPastSnapshots()) {
- structs.add(new PeriodStruct(pastSnapshot));
- }
+ super(timeMachineConfiguration);
}
NewCoverageFileAnalyzer(List<PeriodStruct> structs) {
- this.structs = structs;
- }
-
- public boolean shouldExecuteOnProject(Project project) {
- return project.isLatestAnalysis() && !structs.isEmpty();
- }
-
- private boolean shouldDecorate(Resource resource) {
- return Scopes.isFile(resource) && !Qualifiers.UNIT_TEST_FILE.equals(resource.getQualifier());
+ super(structs);
}
- @DependsUpon
- public List<Metric> dependsOnMetrics() {
- return Arrays.asList(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, CoreMetrics.COVERAGE_LINE_HITS_DATA,
- CoreMetrics.CONDITIONS_BY_LINE, CoreMetrics.COVERED_CONDITIONS_BY_LINE);
+ @Override
+ public Metric getCoverageLineHitsDataMetric() {
+ return CoreMetrics.COVERAGE_LINE_HITS_DATA;
}
- @DependedUpon
- public List<Metric> generatesNewCoverageMetrics() {
- return Arrays.asList(CoreMetrics.NEW_LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES,
- CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS);
+ @Override
+ public Metric getConditionsByLineMetric() {
+ return CoreMetrics.CONDITIONS_BY_LINE;
}
- public void decorate(Resource resource, DecoratorContext context) {
- if (shouldDecorate(resource)) {
- doDecorate(context);
- }
+ @Override
+ public Metric getCoveredConditionsByLineMetric() {
+ return CoreMetrics.COVERED_CONDITIONS_BY_LINE;
}
- void doDecorate(DecoratorContext context) {
- if (parse(context)) {
- compute(context);
- }
+ @Override
+ public Metric getNewLinesToCoverMetric() {
+ return CoreMetrics.NEW_LINES_TO_COVER;
}
- private boolean parse(DecoratorContext context) {
- Measure lastCommits = context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE);
- Measure hitsByLineMeasure = context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA);
-
- if (lastCommits != null && lastCommits.hasData() && hitsByLineMeasure != null && hitsByLineMeasure.hasData()) {
- Map<Integer, Date> datesByLine = KeyValueFormat.parseIntDateTime(lastCommits.getData());
- Map<Integer, Integer> hitsByLine = parseCountByLine(hitsByLineMeasure);
- Map<Integer, Integer> conditionsByLine = parseCountByLine(context.getMeasure(CoreMetrics.CONDITIONS_BY_LINE));
- Map<Integer, Integer> coveredConditionsByLine = parseCountByLine(context.getMeasure(CoreMetrics.COVERED_CONDITIONS_BY_LINE));
-
- reset();
-
- for (Map.Entry<Integer, Integer> entry : hitsByLine.entrySet()) {
- int lineId = entry.getKey();
- int hits = entry.getValue();
- int conditions = (Integer)ObjectUtils.defaultIfNull(conditionsByLine.get(lineId), 0);
- int coveredConditions = (Integer)ObjectUtils.defaultIfNull(coveredConditionsByLine.get(lineId), 0);
- Date date = datesByLine.get(lineId);
- for (PeriodStruct struct : structs) {
- struct.analyze(date, hits, conditions, coveredConditions);
- }
- }
-
- return true;
- }
- return false;
+ @Override
+ public Metric getNewUncoveredLinesMetric() {
+ return CoreMetrics.NEW_UNCOVERED_LINES;
}
- private void reset() {
- for (PeriodStruct struct : structs) {
- struct.reset();
- }
+ @Override
+ public Metric getNewConditionsToCoverMetric() {
+ return CoreMetrics.NEW_CONDITIONS_TO_COVER;
}
- private void compute(DecoratorContext context) {
- Measure newLines = new Measure(CoreMetrics.NEW_LINES_TO_COVER);
- Measure newUncoveredLines = new Measure(CoreMetrics.NEW_UNCOVERED_LINES);
- Measure newConditions = new Measure(CoreMetrics.NEW_CONDITIONS_TO_COVER);
- Measure newUncoveredConditions = new Measure(CoreMetrics.NEW_UNCOVERED_CONDITIONS);
-
- for (PeriodStruct struct : structs) {
- newLines.setVariation(struct.index, (double)struct.newLines);
- newUncoveredLines.setVariation(struct.index, (double) (struct.newLines - struct.newCoveredLines));
- newConditions.setVariation(struct.index, (double)struct.newConditions);
- newUncoveredConditions.setVariation(struct.index, (double)struct.newConditions-struct.newCoveredConditions);
- }
-
- context.saveMeasure(newLines);
- context.saveMeasure(newUncoveredLines);
- context.saveMeasure(newConditions);
- context.saveMeasure(newUncoveredConditions);
- }
-
- private Map<Integer, Integer> parseCountByLine(Measure measure) {
- if (measure != null && measure.hasData()) {
- return KeyValueFormat.parseIntInt(measure.getData());
- }
- return Maps.newHashMap();
- }
-
- public static final class PeriodStruct {
- int index;
- Date date;
- int newLines = 0, newCoveredLines = 0, newConditions = 0, newCoveredConditions = 0;
-
- PeriodStruct(PastSnapshot pastSnapshot) {
- this.index = pastSnapshot.getIndex();
- this.date = pastSnapshot.getTargetDate();
- }
-
- PeriodStruct(int index, Date date) {
- this.index = index;
- this.date = date;
- }
-
- void reset() {
- newLines = 0;
- newCoveredLines = 0;
- newConditions = 0;
- newCoveredConditions = 0;
- }
-
- void analyze(Date lineDate, int hits, int conditions, int coveredConditions) {
- if (lineDate == null) {
- // TODO warning
-
- } else if (date == null || lineDate.after(date)) {
- // TODO test if string comparison is faster or not
- addLine(hits > 0);
- addConditions(conditions, coveredConditions);
- }
- }
-
- void addLine(boolean covered) {
- newLines += 1;
- if (covered) {
- newCoveredLines += 1;
- }
- }
-
- void addConditions(int count, int countCovered) {
- newConditions += count;
- if (count > 0) {
- newCoveredConditions += countCovered;
- }
- }
+ @Override
+ public Metric getNewUncoveredConditionsMetric() {
+ return CoreMetrics.NEW_UNCOVERED_CONDITIONS;
}
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java
new file mode 100644
index 00000000000..d3492f73935
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/NewItCoverageFileAnalyzer.java
@@ -0,0 +1,66 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.plugins.core.timemachine;
+
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Metric;
+import org.sonar.batch.components.TimeMachineConfiguration;
+
+public class NewItCoverageFileAnalyzer extends AbstractNewCoverageFileAnalyzer {
+
+ public NewItCoverageFileAnalyzer(TimeMachineConfiguration timeMachineConfiguration) {
+ super(timeMachineConfiguration);
+ }
+
+ @Override
+ public Metric getCoverageLineHitsDataMetric() {
+ return CoreMetrics.IT_COVERAGE_LINE_HITS_DATA;
+ }
+
+ @Override
+ public Metric getConditionsByLineMetric() {
+ return CoreMetrics.IT_CONDITIONS_BY_LINE;
+ }
+
+ @Override
+ public Metric getCoveredConditionsByLineMetric() {
+ return CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE;
+ }
+
+ @Override
+ public Metric getNewLinesToCoverMetric() {
+ return CoreMetrics.NEW_IT_LINES_TO_COVER;
+ }
+
+ @Override
+ public Metric getNewUncoveredLinesMetric() {
+ return CoreMetrics.NEW_IT_UNCOVERED_LINES;
+ }
+
+ @Override
+ public Metric getNewConditionsToCoverMetric() {
+ return CoreMetrics.NEW_IT_CONDITIONS_TO_COVER;
+ }
+
+ @Override
+ public Metric getNewUncoveredConditionsMetric() {
+ return CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS;
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java
index 3eb6a0f27ed..85d1eb5b6c2 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/timemachine/NewCoverageFileAnalyzerTest.java
@@ -44,7 +44,7 @@ public class NewCoverageFileAnalyzerTest {
when(context.getMeasure(CoreMetrics.COVERAGE_LINE_HITS_DATA))
.thenReturn(new Measure(CoreMetrics.COVERAGE_LINE_HITS_DATA, "1=10"));
- NewCoverageFileAnalyzer decorator = newDecorator();
+ AbstractNewCoverageFileAnalyzer decorator = newDecorator();
decorator.doDecorate(context);
verify(context, never()).saveMeasure((Measure) anyObject());
}
@@ -55,7 +55,7 @@ public class NewCoverageFileAnalyzerTest {
when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE))
.thenReturn(new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2008-05-18T00:00:00+0000"));
- NewCoverageFileAnalyzer decorator = newDecorator();
+ AbstractNewCoverageFileAnalyzer decorator = newDecorator();
decorator.doDecorate(context);
verify(context, never()).saveMeasure((Measure) anyObject());
@@ -69,7 +69,7 @@ public class NewCoverageFileAnalyzerTest {
when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn(
new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000"));
- NewCoverageFileAnalyzer decorator = newDecorator();
+ AbstractNewCoverageFileAnalyzer decorator = newDecorator();
decorator.doDecorate(context);
// line 11 has been updated after date1 (2009-12-25). This line is covered.
@@ -101,7 +101,7 @@ public class NewCoverageFileAnalyzerTest {
when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn(
new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000"));
- NewCoverageFileAnalyzer decorator = newDecorator();
+ AbstractNewCoverageFileAnalyzer decorator = newDecorator();
decorator.doDecorate(context);
// line 11 has been updated after date1 (2009-12-25). This line has 1 covered condition amongst 4
@@ -133,7 +133,7 @@ public class NewCoverageFileAnalyzerTest {
when(context.getMeasure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE)).thenReturn(
new Measure(CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, "10=2007-01-15T00:00:00+0000;11=2011-01-01T00:00:00+0000"));
- NewCoverageFileAnalyzer decorator = newDecorator();
+ AbstractNewCoverageFileAnalyzer decorator = newDecorator();
decorator.doDecorate(context);
// line 11 has been updated after date1 (2009-12-25) but it has no conditions
@@ -169,10 +169,10 @@ public class NewCoverageFileAnalyzerTest {
}
}
- private NewCoverageFileAnalyzer newDecorator() throws ParseException {
- List<NewCoverageFileAnalyzer.PeriodStruct> structs = Arrays.asList(
- new NewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")),
- new NewCoverageFileAnalyzer.PeriodStruct(3, newDate("2011-02-18")));
+ private AbstractNewCoverageFileAnalyzer newDecorator() throws ParseException {
+ List<AbstractNewCoverageFileAnalyzer.PeriodStruct> structs = Arrays.asList(
+ new AbstractNewCoverageFileAnalyzer.PeriodStruct(1, newDate("2009-12-25")),
+ new AbstractNewCoverageFileAnalyzer.PeriodStruct(3, newDate("2011-02-18")));
return new NewCoverageFileAnalyzer(structs);
}
diff --git a/plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java b/plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java
index 18be4847537..aee588e9d47 100644
--- a/plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java
+++ b/plugins/sonar-jacoco-plugin/src/main/java/org/sonar/plugins/jacoco/JaCoCoPlugin.java
@@ -102,9 +102,6 @@ public class JaCoCoPlugin extends SonarPlugin {
// Integration tests
JaCoCoItSensor.class,
- ItCoverageWidget.class,
- ItCoverageDecorator.class,
- ItLineCoverageDecorator.class,
- ItBranchCoverageDecorator.class);
+ ItCoverageWidget.class);
}
}
diff --git a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties
index 283b3cd524b..0a60f2e9a89 100644
--- a/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties
+++ b/plugins/sonar-l10n-en-plugin/src/main/resources/org/sonar/l10n/core.properties
@@ -593,11 +593,11 @@ violations_drilldown.no_violations=No violations
#------------------------------------------------------------------------------
#
-# DUPLICATION TAB
+# DUPLICATION VIEWER
#
#------------------------------------------------------------------------------
-duplications.no_duplicated_block=No duplicated block.
+duplications.no_duplicated_block=No duplicated blocks.
duplications.blocks=Blocks
duplications.number_of_lines=Nb Lines
duplications.from_line=From line
@@ -609,11 +609,12 @@ duplications.collapse=Collapse
#------------------------------------------------------------------------------
#
-# COVERAGE TAB
+# COVERAGE VIEWER
#
#------------------------------------------------------------------------------
-coverage_tab.unit_tests=Unit Tests
-coverage_tab.integration_tests=Integration Tests
+coverage_viewer.on_new_code=On new code
+coverage_viewer.unit_tests=Unit Tests
+coverage_viewer.integration_tests=Integration Tests
#------------------------------------------------------------------------------
#
@@ -1119,35 +1120,35 @@ metric.covered_conditions_by_line.description=Covered branches by line
#
#--------------------------------------------------------------------------------------------------------------------
-metric.it_coverage.name=Coverage
-metric.it_coverage.description=Coverage by unit tests
+metric.it_coverage.name=IT Coverage
+metric.it_coverage.description=Coverage by Integration Tests
-metric.it_lines_to_cover.name=Lines to cover
-metric.it_lines_to_cover.description=Lines to cover
+metric.it_lines_to_cover.name=Lines to cover by IT
+metric.it_lines_to_cover.description=Lines to cover by Integration Tests
-metric.it_uncovered_lines.name=Uncovered lines
-metric.it_uncovered_lines.description=Uncovered lines
+metric.it_uncovered_lines.name=Uncovered lines by IT
+metric.it_uncovered_lines.description=Uncovered lines by Integration Tests
-metric.it_line_coverage.name=Line coverage
-metric.it_line_coverage.description=Line coverage
+metric.it_line_coverage.name=Line coverage by IT
+metric.it_line_coverage.description=Line coverage by Integration Tests
-metric.it_coverage_line_hits_data.name=Coverage hits by line
-metric.it_coverage_line_hits_data.description=Coverage hits by line
+metric.it_coverage_line_hits_data.name=IT Coverage hits by line
+metric.it_coverage_line_hits_data.description=Coverage hits by line by Integration Tests
-metric.it_conditions_to_cover.name=Branches to cover
-metric.it_conditions_to_cover.description=Branches to cover
+metric.it_conditions_to_cover.name=Branches to cover by IT
+metric.it_conditions_to_cover.description=Branches to cover by Integration Tests
-metric.it_uncovered_conditions.name=Uncovered branches
-metric.it_uncovered_conditions.description=Uncovered branches
+metric.it_uncovered_conditions.name=Uncovered branches by IT
+metric.it_uncovered_conditions.description=Uncovered branches by Integration Tests
-metric.it_branch_coverage.name=Branch coverage
-metric.it_branch_coverage.description=Branch coverage
+metric.it_branch_coverage.name=Branch coverage by IT
+metric.it_branch_coverage.description=Branch coverage by Integration Tests
-metric.it_conditions_by_line.name=Branches by line
-metric.it_conditions_by_line.description=Branches by line
+metric.it_conditions_by_line.name=IT Branches by line
+metric.it_conditions_by_line.description=IT 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
+metric.it_covered_conditions_by_line.name=IT Covered branches by line
+metric.it_covered_conditions_by_line.description=IT Covered branches by line
#--------------------------------------------------------------------------------------------------------------------
#
diff --git a/sonar-core/src/main/java/org/sonar/jpa/session/CustomHibernateConnectionProvider.java b/sonar-core/src/main/java/org/sonar/jpa/session/CustomHibernateConnectionProvider.java
index e391d3ad130..5f8490a3858 100644
--- a/sonar-core/src/main/java/org/sonar/jpa/session/CustomHibernateConnectionProvider.java
+++ b/sonar-core/src/main/java/org/sonar/jpa/session/CustomHibernateConnectionProvider.java
@@ -27,7 +27,7 @@ import java.util.Properties;
public class CustomHibernateConnectionProvider extends InjectedDataSourceConnectionProvider {
static DataSource datasource;
-
+
@Override
public void configure(Properties props) {
setDataSource(datasource);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
index 555d753440a..c498bc00ca9 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java
@@ -618,9 +618,20 @@ public final class CoreMetrics {
.setBestValue(100.0)
.create();
+public static final String NEW_IT_COVERAGE_KEY = "new_it_coverage";
+ public static final Metric NEW_IT_COVERAGE = new Metric.Builder(NEW_IT_COVERAGE_KEY, "New IT coverage", Metric.ValueType.PERCENT)
+ .setDescription("Integration Tests Coverage of new/changed code")
+ .setDirection(Metric.DIRECTION_BETTER)
+ .setQualitative(true)
+ .setDomain(DOMAIN_INTEGRATION_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")
+ .setDescription("Lines to cover by Integration Tests")
.setDirection(Metric.DIRECTION_BETTER)
.setDomain(DOMAIN_INTEGRATION_TESTS)
.setQualitative(false)
@@ -628,6 +639,16 @@ public final class CoreMetrics {
.setHidden(true)
.create();
+public static final String NEW_IT_LINES_TO_COVER_KEY = "new_it_lines_to_cover";
+ public static final Metric NEW_IT_LINES_TO_COVER = new Metric.Builder(NEW_IT_LINES_TO_COVER_KEY, "New lines to cover by IT", Metric.ValueType.INT)
+ .setDescription("New lines to cover by Integration Tests")
+ .setDirection(Metric.DIRECTION_WORST)
+ .setQualitative(false)
+ .setDomain(DOMAIN_INTEGRATION_TESTS)
+ .setFormula(new SumChildValuesFormula(false))
+ .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")
@@ -637,6 +658,15 @@ public final class CoreMetrics {
.setFormula(new SumChildValuesFormula(false))
.create();
+ public static final String NEW_IT_UNCOVERED_LINES_KEY = "new_it_uncovered_lines";
+ public static final Metric NEW_IT_UNCOVERED_LINES = new Metric.Builder(NEW_IT_UNCOVERED_LINES_KEY, "New uncovered lines by IT", Metric.ValueType.INT)
+ .setDescription("New uncovered lines by Integration Tests")
+ .setDirection(Metric.DIRECTION_WORST)
+ .setDomain(DOMAIN_INTEGRATION_TESTS)
+ .setFormula(new SumChildValuesFormula(false))
+ .setBestValue(0.0)
+ .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")
@@ -645,6 +675,16 @@ public final class CoreMetrics {
.setDomain(DOMAIN_INTEGRATION_TESTS)
.create();
+ public static final String NEW_IT_LINE_COVERAGE_KEY = "new_it_line_coverage";
+ public static final Metric NEW_IT_LINE_COVERAGE = new Metric.Builder(NEW_IT_LINE_COVERAGE_KEY, "New line coverage by IT", Metric.ValueType.PERCENT)
+ .setDescription("Line Coverage by Integration Tests of added/changed code")
+ .setDirection(Metric.DIRECTION_BETTER)
+ .setQualitative(true)
+ .setWorstValue(0.0)
+ .setBestValue(100.0)
+ .setDomain(DOMAIN_INTEGRATION_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")
@@ -663,6 +703,13 @@ public final class CoreMetrics {
.setHidden(true)
.create();
+ public static final String NEW_IT_CONDITIONS_TO_COVER_KEY = "new_it_conditions_to_cover";
+ public static final Metric NEW_IT_CONDITIONS_TO_COVER = new Metric.Builder(NEW_IT_CONDITIONS_TO_COVER_KEY, "New conditions to cover by IT", Metric.ValueType.INT)
+ .setDescription("New conditions to cover by Integration Tests")
+ .setDomain(DOMAIN_INTEGRATION_TESTS)
+ .setFormula(new SumChildValuesFormula(false))
+ .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 branches", Metric.ValueType.INT)
.setDescription("IT Uncovered conditions")
@@ -671,6 +718,15 @@ public final class CoreMetrics {
.setFormula(new SumChildValuesFormula(false))
.create();
+ public static final String NEW_IT_UNCOVERED_CONDITIONS_KEY = "new_it_uncovered_conditions";
+ public static final Metric NEW_IT_UNCOVERED_CONDITIONS = new Metric.Builder(NEW_IT_UNCOVERED_CONDITIONS_KEY, "New uncovered conditions by IT", Metric.ValueType.INT)
+ .setDescription("New uncovered conditions by Integration Tests")
+ .setDirection(Metric.DIRECTION_WORST)
+ .setDomain(DOMAIN_INTEGRATION_TESTS)
+ .setFormula(new SumChildValuesFormula(false))
+ .setBestValue(0.0)
+ .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")
@@ -681,6 +737,16 @@ public final class CoreMetrics {
.setBestValue(100.0)
.create();
+ public static final String NEW_IT_BRANCH_COVERAGE_KEY = "new_it_branch_coverage";
+ public static final Metric NEW_IT_BRANCH_COVERAGE = new Metric.Builder(NEW_IT_BRANCH_COVERAGE_KEY, "New branch coverage by IT", Metric.ValueType.PERCENT)
+ .setDescription("Branch coverage by Integration Tests of new/changed code")
+ .setDirection(Metric.DIRECTION_BETTER)
+ .setQualitative(true)
+ .setDomain(DOMAIN_INTEGRATION_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 Branches by line", Metric.ValueType.DATA)
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
index 2b753e44d7a..d977d296130 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/resource_controller.rb
@@ -167,21 +167,25 @@ class ResourceController < ApplicationController
@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 ||
- 'it_lines_to_cover'==@coverage_filter || 'it_coverage'==@coverage_filter || 'it_line_coverage'==@coverage_filter)
+ 'it_lines_to_cover'==@coverage_filter || 'it_coverage'==@coverage_filter || 'it_line_coverage'==@coverage_filter ||
+ 'new_it_lines_to_cover'==@coverage_filter || 'new_it_coverage'==@coverage_filter || 'new_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 || 'it_uncovered_lines'==@coverage_filter
+ elsif ('uncovered_lines'==@coverage_filter || 'new_uncovered_lines'==@coverage_filter ||
+ 'it_uncovered_lines'==@coverage_filter || 'new_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 ||
+ elsif ('conditions_to_cover'==@coverage_filter || 'branch_coverage'==@coverage_filter ||
'new_conditions_to_cover'==@coverage_filter || 'new_branch_coverage'==@coverage_filter ||
- 'it_conditions_to_cover'==@coverage_filter || 'it_branch_coverage'==@coverage_filter
+ 'it_conditions_to_cover'==@coverage_filter || 'it_branch_coverage'==@coverage_filter ||
+ 'new_it_conditions_to_cover' == @coverage_filter || 'new_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 || 'it_uncovered_conditions'==@coverage_filter
+ elsif ('uncovered_conditions' == @coverage_filter || 'new_uncovered_conditions' == @coverage_filter ||
+ 'it_uncovered_conditions'==@coverage_filter || 'new_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
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
index 1745af879e9..de128aa09bb 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/helpers/application_helper.rb
@@ -542,9 +542,8 @@ module ApplicationHelper
end
html="<span class='#{css_class}'>#{formatted_val}</span>"
end
- else
- html = options[:default].to_s
end
+ html = options[:default].to_s if html.nil? && options[:default]
html
end
end
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb
index abcf4e4c397..c3b9e18b935 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_header_coverage.html.erb
@@ -1,15 +1,15 @@
<div id="coverage_header" class="tab_header">
- <% if @period && measure('new_coverage') %>
- <p>On new code:</p>
+ <% if @period && (measure('new_coverage') || measure('new_it_coverage')) %>
+ <p><%= message('coverage_viewer.on_new_code') -%> :</p>
<table>
<tr>
- <td class="big" rowspan="2"><%= format_variation('new_coverage', :period => @period, :style => 'none') -%></td>
+ <td class="big" rowspan="2"><%= format_variation('new_coverage', :period => @period, :default => '-', :style => 'none') -%></td>
<td class="sep"> </td>
<% if m=measure('new_line_coverage') %>
<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, :default => '-', :style => 'none') -%></td>
<% else %>
<td colspan="2"></td>
<% end %>
@@ -17,7 +17,7 @@
<td class="sep"> </td>
<% if m=measure('new_branch_coverage') %>
<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, :default => '-', :style => 'none') -%></td>
<% else %>
<td colspan="2"></td>
<% end %>
@@ -39,13 +39,54 @@
<td colspan="2"></td>
<% end %>
</tr>
+ <% if measure('new_it_coverage') %>
+ <tr>
+ <td colspan="7"><br/><%= message('coverage_viewer.integration_tests') -%></td>
+ </tr>
+ <tr>
+ <td class="big" rowspan="2"><%= format_variation('new_it_coverage', :period => @period, :default => '-', :style => 'none') -%></td>
+
+ <td class="sep"> </td>
+
+ <% if m=measure('new_it_line_coverage') %>
+ <td class="name"><%= Metric.name_for('it_line_coverage') -%>:</td>
+ <td class="value"><%= format_variation(m, :period => @period, :default => '-', :style => 'none') -%></td>
+ <% else %>
+ <td colspan="2"></td>
+ <% end %>
+
+ <td class="sep"> </td>
+ <% if m=measure('new_it_branch_coverage') %>
+ <td class="name"><%= Metric.name_for('it_branch_coverage') -%>:</td>
+ <td class="value"><%= format_variation(m, :period => @period, :default => '-', :style => 'none') -%></td>
+ <% else %>
+ <td colspan="2"></td>
+ <% end %>
+ </tr>
+ <tr>
+ <td class="sep"> </td>
+ <% if m=measure('new_it_uncovered_lines') %>
+ <td class="name"><%= Metric.name_for('it_uncovered_lines') -%>:</td>
+ <td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%>/<%= format_variation('new_it_lines_to_cover', :period => @period, :style => 'none') -%></td>
+ <% else %>
+ <td colspan="2"></td>
+ <% end %>
+
+ <td class="sep"> </td>
+ <% if m=measure('new_it_uncovered_conditions') %>
+ <td class="name"><%= Metric.name_for('it_uncovered_conditions') -%>: </td>
+ <td class="value"><%= format_variation(m, :period => @period, :style => 'none') -%>/<%= format_variation('new_it_conditions_to_cover', :period => @period, :style => 'none') -%></td>
+ <% else %>
+ <td colspan="2"></td>
+ <% end %>
+ </tr>
+ <% end %>
</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>
+ <td colspan="7"><%= message('coverage_viewer.unit_tests') -%></td>
</tr>
<% end %>
<tr>
@@ -54,32 +95,35 @@
<%= 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')} -%>
+ </tr>
+ <tr>
<td class="sep"> </td>
+ <%= 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 => Metric.name_for('uncovered_conditions'), :ratio => measure('conditions_to_cover')} -%>
+ </tr>
- <% if @display_it_coverage %>
+ <% if @display_it_coverage %>
+ <tr>
+ <td colspan="7"><br/><%= message('coverage_viewer.integration_tests') -%></td>
+ </tr>
+ <tr>
<td class="big" rowspan="2"><%= format_measure('it_coverage', :default => '-') -%></td>
<td class="sep"> </td>
<%= 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 => Metric.name_for('uncovered_lines'), :ratio => measure('lines_to_cover')} -%>
- <td class="sep"> </td>
- <%= 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>
+ <% end %>
</table>
<% end %>
-
+
<%= render :partial => 'options' -%>
</div>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
index d625f26280d..221c1b3680f 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/resource/_options.html.erb
@@ -67,14 +67,14 @@
<% if @display_coverage %>
<td class="<%= 'first' if first -%>">
<select id="coverage_filter" name="coverage_filter" onchange="applyOptions()">
- <optgroup label="<%= h message('coverage_tab.unit_tests') -%>">
+ <optgroup label="<%= h message('coverage_viewer.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') -%>">
+ <optgroup label="<%= h message('coverage_viewer.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>