private final MeasureRepository measureRepository;
private final List<Formula> formulas;
- private FormulaExecutorComponentVisitor(Builder builder, List<Formula> formulas) {
+ private FormulaExecutorComponentVisitor(Builder builder, Iterable<Formula> formulas) {
super(CrawlerDepthLimit.LEAVES, ComponentVisitor.Order.POST_ORDER, COUNTERS_FACTORY);
this.periodsHolder = builder.periodsHolder;
this.measureRepository = builder.measureRepository;
return this;
}
- public FormulaExecutorComponentVisitor buildFor(List<Formula> formulas) {
+ public FormulaExecutorComponentVisitor buildFor(Iterable<Formula> formulas) {
return new FormulaExecutorComponentVisitor(this, formulas);
}
}
package org.sonar.server.computation.formula.coverage;
import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.formula.CounterInitializationContext;
+import org.sonar.server.computation.formula.CreateMeasureContext;
import org.sonar.server.computation.measure.Measure;
import org.sonar.server.computation.measure.MeasureVariations;
import org.sonar.server.computation.period.Period;
+import static com.google.common.collect.FluentIterable.from;
import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
public final class CoverageUtils {
}
return 0L;
}
+
+ /**
+ * Since Periods 4 and 5 can be customized per project and/or per view/subview, aggregating values on this period
+ * will only generate garbage data which will make no sense. These Periods should be ignored when processing views/subviews.
+ */
+ static Iterable<Period> supportedPeriods(CreateMeasureContext context) {
+ return supportedPeriods(context.getComponent().getType(), context.getPeriods());
+ }
+
+ /**
+ * Since Periods 4 and 5 can be customized per project and/or per view/subview, aggregating values on this period
+ * will only generate garbage data which will make no sense. These Periods should be ignored when processing views/subviews.
+ */
+ public static Iterable<Period> supportedPeriods(CounterInitializationContext context) {
+ return supportedPeriods(context.getLeaf().getType(), context.getPeriods());
+ }
+
+ private static Iterable<Period> supportedPeriods(Component.Type type, List<Period> periods) {
+ if (type.isReportType()) {
+ return periods;
+ }
+ return from(periods).filter(ViewsSupportedPeriods.INSTANCE);
+ }
+
+ private enum ViewsSupportedPeriods implements Predicate<Period> {
+ INSTANCE;
+
+ @Override
+ public boolean apply(@Nonnull Period input) {
+ return input.getIndex() < 4;
+ }
+ }
}
import org.sonar.server.computation.period.Period;
import static org.sonar.server.computation.formula.coverage.CoverageUtils.calculateCoverage;
+import static org.sonar.server.computation.formula.coverage.CoverageUtils.supportedPeriods;
import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
/**
private MeasureVariations.Builder createAndPopulateBuilder(T counter, CreateMeasureContext context) {
MeasureVariations.Builder builder = MeasureVariations.newMeasureVariationsBuilder();
- for (Period period : context.getPeriods()) {
+ for (Period period : supportedPeriods(context)) {
LongVariationValue elements = counter.elements.get(period);
if (elements.isSet() && elements.getValue() > 0d) {
LongVariationValue coveredElements = counter.coveredElements.get(period);
}
return builder;
}
-
}
@Override
public void initialize(CounterInitializationContext context) {
- if (context.getLeaf().getFileAttributes().isUnitTest()) {
+ if (context.getLeaf().getType().isReportType() && context.getLeaf().getFileAttributes().isUnitTest()) {
return;
}
initializeForSupportedLeaf(context);
import org.sonar.server.computation.measure.MeasureVariations;
import org.sonar.server.computation.period.Period;
+import static org.sonar.server.computation.formula.coverage.CoverageUtils.supportedPeriods;
+
public final class LinesAndConditionsWithUncoveredVariationCounter extends ElementsAndCoveredElementsVariationCounter {
private final LinesAndConditionsWithUncoveredMetricKeys metricKeys;
MeasureVariations newConditions = CoverageUtils.getMeasureVariations(counterContext, metricKeys.getConditions());
MeasureVariations uncoveredLines = CoverageUtils.getMeasureVariations(counterContext, metricKeys.getUncoveredLines());
MeasureVariations uncoveredConditions = CoverageUtils.getMeasureVariations(counterContext, metricKeys.getUncoveredConditions());
- for (Period period : counterContext.getPeriods()) {
+ for (Period period : supportedPeriods(counterContext)) {
if (!newLines.hasVariation(period.getIndex())) {
continue;
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.formula.coverage;
+
+import com.google.common.base.Optional;
+import org.sonar.server.computation.component.CrawlerDepthLimit;
+import org.sonar.server.computation.formula.Counter;
+import org.sonar.server.computation.formula.CounterInitializationContext;
+import org.sonar.server.computation.formula.CreateMeasureContext;
+import org.sonar.server.computation.formula.Formula;
+import org.sonar.server.computation.formula.counter.DoubleVariationValue;
+import org.sonar.server.computation.measure.Measure;
+import org.sonar.server.computation.measure.MeasureVariations;
+import org.sonar.server.computation.period.Period;
+
+import static java.util.Objects.requireNonNull;
+import static org.sonar.server.computation.formula.coverage.CoverageUtils.supportedPeriods;
+import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+
+/**
+ * A Formula which aggregates a new coverage measure by simply making the sums of its variations.
+ */
+public class NewCoverageVariationSumFormula implements Formula<NewCoverageVariationSumFormula.VariationSumCounter> {
+ private final String metricKey;
+
+ public NewCoverageVariationSumFormula(String metricKey) {
+ this.metricKey = requireNonNull(metricKey, "Metric key cannot be null");
+ }
+
+ @Override
+ public VariationSumCounter createNewCounter() {
+ return new VariationSumCounter(metricKey);
+ }
+
+ @Override
+ public Optional<Measure> createMeasure(VariationSumCounter counter, CreateMeasureContext context) {
+ if (!CrawlerDepthLimit.LEAVES.isDeeperThan(context.getComponent().getType())) {
+ return Optional.absent();
+ }
+ MeasureVariations.Builder variations = createAndPopulateBuilder(counter.array, context);
+ if (variations.isEmpty()) {
+ return Optional.absent();
+ }
+ return Optional.of(newMeasureBuilder().setVariations(variations.build()).createNoValue());
+ }
+
+ private static MeasureVariations.Builder createAndPopulateBuilder(DoubleVariationValue.Array array, CreateMeasureContext context) {
+ MeasureVariations.Builder builder = MeasureVariations.newMeasureVariationsBuilder();
+ for (Period period : supportedPeriods(context)) {
+ DoubleVariationValue elements = array.get(period);
+ if (elements.isSet()) {
+ builder.setVariation(period, elements.getValue());
+ }
+ }
+ return builder;
+ }
+
+ @Override
+ public String[] getOutputMetricKeys() {
+ return new String[] { metricKey };
+ }
+
+ public static final class VariationSumCounter implements Counter<VariationSumCounter> {
+ private final DoubleVariationValue.Array array = DoubleVariationValue.newArray();
+ private final String metricKey;
+
+ private VariationSumCounter(String metricKey) {
+ this.metricKey = metricKey;
+ }
+
+ @Override
+ public void aggregate(VariationSumCounter counter) {
+ array.incrementAll(counter.array);
+ }
+
+ @Override
+ public void initialize(CounterInitializationContext context) {
+ Optional<Measure> measure = context.getMeasure(metricKey);
+ if (!measure.isPresent() || !measure.get().hasVariations()) {
+ return;
+ }
+ MeasureVariations variations = measure.get().getVariations();
+ for (Period period : supportedPeriods(context)) {
+ if (variations.hasVariation(period.getIndex())) {
+ double variation = variations.getVariation(period.getIndex());
+ if (variation > 0) {
+ array.increment(period, variations.getVariation(period.getIndex()));
+ }
+ }
+ }
+ }
+ }
+}
import static java.util.Objects.requireNonNull;
import static org.sonar.server.computation.formula.coverage.CoverageUtils.getLongVariation;
import static org.sonar.server.computation.formula.coverage.CoverageUtils.getMeasureVariations;
+import static org.sonar.server.computation.formula.coverage.CoverageUtils.supportedPeriods;
public final class SingleWithUncoveredVariationCounter extends ElementsAndCoveredElementsVariationCounter {
private final SingleWithUncoveredMetricKeys metricKeys;
protected void initializeForSupportedLeaf(CounterInitializationContext counterContext) {
MeasureVariations newConditions = getMeasureVariations(counterContext, metricKeys.getCovered());
MeasureVariations uncoveredConditions = getMeasureVariations(counterContext, metricKeys.getUncovered());
- for (Period period : counterContext.getPeriods()) {
+ for (Period period : supportedPeriods(counterContext)) {
long elements = getLongVariation(newConditions, period);
this.elements.increment(period, elements);
coveredElements.increment(period, elements - getLongVariation(uncoveredConditions, period));
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.apache.commons.lang.ObjectUtils;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.PathAwareCrawler;
import org.sonar.server.computation.component.TreeRootHolder;
-import org.sonar.server.computation.formula.CreateMeasureContext;
import org.sonar.server.computation.formula.CounterInitializationContext;
+import org.sonar.server.computation.formula.CreateMeasureContext;
import org.sonar.server.computation.formula.Formula;
import org.sonar.server.computation.formula.FormulaExecutorComponentVisitor;
+import org.sonar.server.computation.formula.coverage.NewCoverageVariationSumFormula;
import org.sonar.server.computation.formula.counter.IntVariationValue;
import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredVariationFormula;
* Computes measures related to the New Coverage. These measures do not have values, only variations.
*/
public class NewCoverageMeasuresStep implements ComputationStep {
+ private static final List<Formula> FORMULAS = ImmutableList.<Formula>of(
+ // UT coverage
+ new NewCoverageFormula()
+ ,
+ new NewBranchCoverageFormula(),
+ new NewLineCoverageFormula(),
+ // IT File coverage
+ new NewItCoverageFormula(),
+ new NewItBranchCoverageFormula(),
+ new NewItLinesCoverageFormula(),
+ // Overall coverage
+ new NewOverallCodeCoverageFormula(),
+ new NewOverallBranchCoverageFormula(),
+ new NewOverallLineCoverageFormula()
+ );
+
private final TreeRootHolder treeRootHolder;
private final PeriodsHolder periodsHolder;
+ @CheckForNull
private final BatchReportReader batchReportReader;
private final MetricRepository metricRepository;
private final MeasureRepository measureRepository;
+ /**
+ * Constructor used when processing a Report (ie. a {@link BatchReportReader} instance is available in the container)
+ */
public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, PeriodsHolder periodsHolder, BatchReportReader batchReportReader,
MeasureRepository measureRepository, final MetricRepository metricRepository) {
this.treeRootHolder = treeRootHolder;
this.measureRepository = measureRepository;
}
+ /**
+ * Constructor used when processing Views (ie. no {@link BatchReportReader} instance is available in the container)
+ */
+ public NewCoverageMeasuresStep(TreeRootHolder treeRootHolder, PeriodsHolder periodsHolder,
+ MeasureRepository measureRepository, final MetricRepository metricRepository) {
+ this.treeRootHolder = treeRootHolder;
+ this.periodsHolder = periodsHolder;
+ this.batchReportReader = null;
+ this.metricRepository = metricRepository;
+ this.measureRepository = measureRepository;
+ }
+
@Override
public void execute() {
new PathAwareCrawler<>(
FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
.withVariationSupport(periodsHolder)
- .buildFor(ImmutableList.<Formula>of(
- // UT coverage
- new NewLinesAndConditionsCoverageFormula(batchReportReader),
- new NewCoverageFormula(),
- new NewBranchCoverageFormula(),
- new NewLineCoverageFormula(),
- // IT File coverage
- new NewItLinesAndConditionsCoverageFormula(batchReportReader),
- new NewItCoverageFormula(),
- new NewItBranchCoverageFormula(),
- new NewItLinesCoverageFormula(),
- // Overall coverage
- new NewOverallLinesAndConditionsCoverageFormula(batchReportReader),
- new NewOverallCodeCoverageFormula(),
- new NewOverallBranchCoverageFormula(),
- new NewOverallLineCoverageFormula())))
- .visit(treeRootHolder.getRoot());
+ .buildFor(
+ Iterables.concat(
+ NewLinesAndConditionsCoverageFormula.from(batchReportReader),
+ NewItLinesAndConditionsCoverageFormula.from(batchReportReader),
+ NewOverallLinesAndConditionsCoverageFormula.from(batchReportReader),
+ FORMULAS)))
+ .visit(treeRootHolder.getRoot());
}
@Override
}
private static class NewLinesAndConditionsCoverageFormula extends NewLinesAndConditionsFormula {
- public NewLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
+
+ private static final NewCoverageOutputMetricKeys OUTPUT_METRIC_KEYS = new NewCoverageOutputMetricKeys(
+ CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_LINES_KEY,
+ CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY);
+ private static final Iterable<Formula<?>> VIEWS_FORMULAS = intSumFormulas(OUTPUT_METRIC_KEYS);
+
+ private NewLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
super(batchReportReader,
new NewCoverageInputMetricKeys(
CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, CoreMetrics.CONDITIONS_BY_LINE_KEY, CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY),
- new NewCoverageOutputMetricKeys(
- CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_LINES_KEY,
- CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY));
+ OUTPUT_METRIC_KEYS);
+ }
+
+ public static Iterable<Formula<?>> from(@Nullable BatchReportReader batchReportReader) {
+ if (batchReportReader == null) {
+ return VIEWS_FORMULAS;
+ }
+ return Collections.<Formula<?>>singleton(new NewLinesAndConditionsCoverageFormula(batchReportReader));
}
}
private static class NewBranchCoverageFormula extends SingleWithUncoveredVariationFormula {
public NewBranchCoverageFormula() {
super(
- new SingleWithUncoveredMetricKeys(
- CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY),
+ new SingleWithUncoveredMetricKeys(CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY),
CoreMetrics.NEW_BRANCH_COVERAGE_KEY);
}
}
}
private static class NewItLinesAndConditionsCoverageFormula extends NewLinesAndConditionsFormula {
- public NewItLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
+
+ private static final NewCoverageOutputMetricKeys OUTPUT_METRIC_KEYS = new NewCoverageOutputMetricKeys(
+ CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY,
+ CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY);
+ private static final Iterable<Formula<?>> VIEWS_FORMULAS = intSumFormulas(OUTPUT_METRIC_KEYS);
+
+ private NewItLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
super(batchReportReader,
new NewCoverageInputMetricKeys(
CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY, CoreMetrics.IT_CONDITIONS_BY_LINE_KEY, CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY),
- new NewCoverageOutputMetricKeys(
- CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY,
- CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY));
+ OUTPUT_METRIC_KEYS);
+ }
+
+ public static Iterable<Formula<?>> from(@Nullable BatchReportReader batchReportReader) {
+ if (batchReportReader == null) {
+ return VIEWS_FORMULAS;
+ }
+ return Collections.<Formula<?>>singleton(new NewItLinesAndConditionsCoverageFormula(batchReportReader));
}
}
}
private static class NewOverallLinesAndConditionsCoverageFormula extends NewLinesAndConditionsFormula {
- public NewOverallLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
+
+ private static final NewCoverageOutputMetricKeys OUTPUT_METRIC_KEYS = new NewCoverageOutputMetricKeys(
+ CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY,
+ CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY);
+ private static final Iterable<Formula<?>> VIEWS_FORMULAS = intSumFormulas(OUTPUT_METRIC_KEYS);
+
+ private NewOverallLinesAndConditionsCoverageFormula(BatchReportReader batchReportReader) {
super(batchReportReader,
new NewCoverageInputMetricKeys(
CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY, CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY, CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY),
- new NewCoverageOutputMetricKeys(
- CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY,
- CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY));
+ OUTPUT_METRIC_KEYS);
+ }
+
+ public static Iterable<Formula<?>> from(@Nullable BatchReportReader batchReportReader) {
+ if (batchReportReader == null) {
+ return VIEWS_FORMULAS;
+ }
+ return Collections.<Formula<?>>singleton(new NewOverallLinesAndConditionsCoverageFormula(batchReportReader));
}
}
}
}
+ /**
+ * Creates a List of {@link org.sonar.server.computation.formula.SumFormula.IntSumFormula} for each
+ * metric key of the specified {@link NewCoverageOutputMetricKeys} instance.
+ */
+ private static Iterable<Formula<?>> intSumFormulas(NewCoverageOutputMetricKeys outputMetricKeys) {
+ return ImmutableList.<Formula<?>>of(
+ new NewCoverageVariationSumFormula(outputMetricKeys.getNewLinesToCover()),
+ new NewCoverageVariationSumFormula(outputMetricKeys.getNewUncoveredLines()),
+ new NewCoverageVariationSumFormula(outputMetricKeys.getNewConditionsToCover()),
+ new NewCoverageVariationSumFormula(outputMetricKeys.getNewUncoveredConditions()));
+ }
+
public static class NewLinesAndConditionsFormula implements Formula<NewCoverageCounter> {
private final BatchReportReader batchReportReader;
private final NewCoverageInputMetricKeys inputMetricKeys;
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.step;
-
-import javax.annotation.Nullable;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.batch.TreeRootHolderRule;
-import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.ReportComponent;
-import org.sonar.server.computation.component.FileAttributes;
-import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
-import org.sonar.server.computation.measure.Measure;
-import org.sonar.server.computation.measure.MeasureRepoEntry;
-import org.sonar.server.computation.measure.MeasureRepositoryRule;
-import org.sonar.server.computation.measure.MeasureVariations;
-import org.sonar.server.computation.metric.MetricRepositoryRule;
-import org.sonar.server.computation.period.Period;
-import org.sonar.server.computation.period.PeriodsHolderRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
-import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
-import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_LINES_TO_COVER_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY;
-import static org.sonar.api.measures.CoreMetrics.NEW_UNCOVERED_LINES_KEY;
-import static org.sonar.api.utils.DateUtils.parseDate;
-import static org.sonar.batch.protocol.output.BatchReport.Changesets;
-import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
-import static org.sonar.server.computation.component.Component.Type.FILE;
-import static org.sonar.server.computation.component.Component.Type.MODULE;
-import static org.sonar.server.computation.component.Component.Type.PROJECT;
-import static org.sonar.server.computation.component.ReportComponent.builder;
-import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
-import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf;
-import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries;
-import static org.sonar.server.computation.measure.MeasureVariations.newMeasureVariationsBuilder;
-
-public class NewCoverageMeasuresStepTest {
-
- private static final int ROOT_REF = 1;
- private static final int MODULE_REF = 11;
- private static final int SUB_MODULE_REF = 111;
- private static final int DIRECTORY_1_REF = 1111;
- private static final int FILE_1_REF = 11111;
- private static final int DIRECTORY_2_REF = 1112;
- private static final int FILE_2_REF = 11121;
- private static final int FILE_3_REF = 11122;
-
- private static final ReportComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF)
- .addChildren(
- builder(MODULE, MODULE_REF)
- .addChildren(
- builder(MODULE, SUB_MODULE_REF)
- .addChildren(
- builder(DIRECTORY, DIRECTORY_1_REF)
- .addChildren(
- builder(FILE, FILE_1_REF).build()
- ).build(),
- builder(DIRECTORY, DIRECTORY_2_REF)
- .addChildren(
- builder(FILE, FILE_2_REF).build(),
- builder(FILE, FILE_3_REF).build()
- ).build()
- )
- .build()
- ).build()
- ).build();
-
- @Rule
- public BatchReportReaderRule reportReader = new BatchReportReaderRule();
- @Rule
- public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
- @Rule
- public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
- @Rule
- public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
- .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
- .add(CoreMetrics.CONDITIONS_BY_LINE)
- .add(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
- .add(CoreMetrics.NEW_LINES_TO_COVER)
- .add(CoreMetrics.NEW_UNCOVERED_LINES)
- .add(CoreMetrics.NEW_CONDITIONS_TO_COVER)
- .add(CoreMetrics.NEW_UNCOVERED_CONDITIONS)
- .add(CoreMetrics.NEW_COVERAGE)
- .add(CoreMetrics.NEW_BRANCH_COVERAGE)
- .add(CoreMetrics.NEW_LINE_COVERAGE)
-
- .add(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA)
- .add(CoreMetrics.IT_CONDITIONS_BY_LINE)
- .add(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE)
- .add(CoreMetrics.NEW_IT_LINES_TO_COVER)
- .add(CoreMetrics.NEW_IT_UNCOVERED_LINES)
- .add(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER)
- .add(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS)
- .add(CoreMetrics.NEW_IT_COVERAGE)
- .add(CoreMetrics.NEW_IT_BRANCH_COVERAGE)
- .add(CoreMetrics.NEW_IT_LINE_COVERAGE)
-
- .add(CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA)
- .add(CoreMetrics.OVERALL_CONDITIONS_BY_LINE)
- .add(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE)
- .add(CoreMetrics.NEW_OVERALL_LINES_TO_COVER)
- .add(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES)
- .add(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER)
- .add(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS)
- .add(CoreMetrics.NEW_OVERALL_COVERAGE)
- .add(CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE)
- .add(CoreMetrics.NEW_OVERALL_LINE_COVERAGE)
- ;
- @Rule
- public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
-
- private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, reportReader,
- measureRepository, metricRepository);
- public static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_1_REF)
- .setFileAttributes(new FileAttributes(false, null)).build();
-
- @Before
- public void setUp() {
- periodsHolder.setPeriods(
- new Period(2, "mode_p_1", null, parseDate("2009-12-25").getTime(), 1),
- new Period(5, "mode_p_5", null, parseDate("2011-02-18").getTime(), 2));
- }
-
- @Test
- public void no_measure_for_PROJECT_component() {
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, ROOT_REF).build());
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void no_measure_for_MODULE_component() {
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.MODULE, MODULE_REF).build());
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void no_measure_for_DIRECTORY_component() {
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.DIRECTORY, DIRECTORY_1_REF).build());
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void no_measure_for_unit_test_FILE_component() {
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(true, null)).build());
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void no_measures_for_FILE_component_without_code() {
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null)).build());
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void verify_measure_of_condition_not_computed_if_there_is_none() {
- treeRootHolder.setRoot(FILE_COMPONENT);
- reportReader.putChangesets(Changesets.newBuilder()
- .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
- .addChangeset(Changesets.Changeset.newBuilder().build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2007-01-15").getTime())
- .build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2011-01-01").getTime())
- .build())
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(1)
- .addChangesetIndexByLine(2)
- .build()
- );
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void verify_no_measure_when_nothing_has_changed() {
- treeRootHolder.setRoot(FILE_COMPONENT);
- reportReader.putChangesets(BatchReport.Changesets.newBuilder()
- .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2008-08-02").getTime())
- .build())
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(0)
- .build());
- measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERAGE_LINE_HITS_DATA_KEY, newMeasureBuilder().create("2=1;3=1"));
- measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
- measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERED_CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
-
- underTest.execute();
-
- assertThat(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef())).isEmpty();
- }
-
- @Test
- public void no_measures_for_FILE_component_without_CoverageData() {
- ReportComponent fileComponent = ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null)).build();
-
- treeRootHolder.setRoot(fileComponent);
- reportReader.putChangesets(Changesets.newBuilder()
- .setComponentRef(fileComponent.getReportAttributes().getRef())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2008-05-18").getTime())
- .build())
- .addChangesetIndexByLine(0)
- .build());
-
- underTest.execute();
-
- assertThat(measureRepository.isEmpty()).isTrue();
- }
-
- @Test
- public void verify_computation_of_measures_for_new_lines_for_FILE() {
- String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
- String newLinesToCover = NEW_LINES_TO_COVER_KEY;
- String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
- String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
-
- verify_computation_of_measures_for_new_lines(coverageLineHitsData,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
- }
-
- @Test
- public void verify_computation_of_measures_for_new_lines_for_IT_FILE() {
- String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
- String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
- String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
- String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
-
- verify_computation_of_measures_for_new_lines(coverageLineHitsData,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
- }
-
- @Test
- public void verify_computation_of_measures_for_new_lines_for_Overall() {
- String coverageLineHitsData = CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
- String newLinesToCover = CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY;
- String newUncoveredLines = CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY;
- String newConditionsToCover = CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY;
-
- verify_computation_of_measures_for_new_lines(coverageLineHitsData,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
- }
-
- private void verify_computation_of_measures_for_new_lines(String coverageLineHitsData,
- String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
- treeRootHolder.setRoot(FILE_COMPONENT);
- reportReader.putChangesets(Changesets.newBuilder()
- .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
- .addChangeset(Changesets.Changeset.newBuilder().build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2007-01-15").getTime())
- .build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2011-01-01").getTime())
- .build())
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(2) // line 2
- .addChangesetIndexByLine(1) // line 3
- .addChangesetIndexByLine(2) // line 4
- .build());
- measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=3"));
-
- underTest.execute();
-
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
- entryOf(newLinesToCover, createMeasure(2d, null)),
- entryOf(newUncoveredLines, createMeasure(1d, null)),
- entryOf(newConditionsToCover, createMeasure(0d, null)),
- entryOf(newUncoveredConditions, createMeasure(0d, null))
- );
- }
-
- @Test
- public void verify_computation_of_measures_for_new_conditions_for_FILE() {
- String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
- String conditionsByLine = CONDITIONS_BY_LINE_KEY;
- String coveredConditionsByLine = COVERED_CONDITIONS_BY_LINE_KEY;
- String newLinesToCover = NEW_LINES_TO_COVER_KEY;
- String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
- String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
-
- verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
- }
-
- @Test
- public void verify_computation_of_measures_for_new_conditions_for_IT_FILE() {
- String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
- String conditionsByLine = CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
- String coveredConditionsByLine = CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
- String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
- String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
- String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
-
- verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
- }
-
- @Test
- public void verify_computation_of_measures_for_new_conditions_Overall() {
- String coverageLineHitsData = CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
- String conditionsByLine = CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY;
- String coveredConditionsByLine = CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY;
- String newLinesToCover = CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY;
- String newUncoveredLines = CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY;
- String newConditionsToCover = CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY;
-
- verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
- }
-
- @Test
- public void verify_aggregation_of_measures_for_new_conditions() {
- String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
- String conditionsByLine = CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
- String coveredConditionsByLine = CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
- String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
- String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
- String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
- String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
-
- MetricKeys metricKeys = new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
- newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
-
- treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
- defineChangeSetsAndMeasures(FILE_1_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
- defineChangeSetsAndMeasures(FILE_2_REF, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7));
- defineChangeSetsAndMeasures(FILE_3_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7));
-
- underTest.execute();
-
- // files
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(
- entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
- );
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(
- entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(4d, 2d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(27d, 13d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(14d, 6d))
- );
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_3_REF))).contains(
- entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(2d, 1d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(17d, 13d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(9d, 6d))
- );
- // directories
- assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).contains(
- entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
- );
- assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).contains(
- entryOf(metricKeys.newLinesToCover, createMeasure(10d, 6d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(6d, 3d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(44d, 26d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(23d, 12d))
- );
- // submodule
- MeasureRepoEntry[] repoEntriesFromSubModuleUp = {entryOf(metricKeys.newLinesToCover, createMeasure(15d, 9d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(9d, 5d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(51d, 29d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(27d, 13d))};
- assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(repoEntriesFromSubModuleUp);
- // module
- assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(repoEntriesFromSubModuleUp);
- // project
- assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(repoEntriesFromSubModuleUp);
- }
-
- @Test
- public void verify_aggregates_variations_for_new_code_line_and_branch_Coverage() {
- LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
- CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY,
- CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY
- );
- String codeCoverageKey = CoreMetrics.NEW_COVERAGE_KEY;
- String lineCoverageKey = CoreMetrics.NEW_LINE_COVERAGE_KEY;
- String branchCoverageKey = CoreMetrics.NEW_BRANCH_COVERAGE_KEY;
-
- verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
- }
-
- @Test
- public void verify_aggregates_variations_for_new_IT_code_line_and_branch_Coverage() {
- LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
- CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY,
- CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY
- );
- String codeCoverageKey = CoreMetrics.NEW_IT_COVERAGE_KEY;
- String lineCoverageKey = CoreMetrics.NEW_IT_LINE_COVERAGE_KEY;
- String branchCoverageKey = CoreMetrics.NEW_IT_BRANCH_COVERAGE_KEY;
-
- verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
- }
-
- @Test
- public void verify_aggregates_variations_for_new_Overall_code_line_and_branch_Coverage() {
- LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
- CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY,
- CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY
- );
- String codeCoverageKey = CoreMetrics.NEW_OVERALL_COVERAGE_KEY;
- String lineCoverageKey = CoreMetrics.NEW_OVERALL_LINE_COVERAGE_KEY;
- String branchCoverageKey = CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE_KEY;
-
- verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
- }
-
- private void verify_aggregates_variations(LinesAndConditionsWithUncoveredMetricKeys metricKeys, String codeCoverageKey, String lineCoverageKey, String branchCoverageKey) {
- treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
- measureRepository
- .addRawMeasure(FILE_1_REF, metricKeys.getLines(), createMeasure(3000d, 2000d))
- .addRawMeasure(FILE_1_REF, metricKeys.getConditions(), createMeasure(300d, 400d))
- .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredLines(), createMeasure(30d, 200d))
- .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredConditions(), createMeasure(9d, 16d))
-
- .addRawMeasure(FILE_2_REF, metricKeys.getLines(), createMeasure(2000d, 3000d))
- .addRawMeasure(FILE_2_REF, metricKeys.getConditions(), createMeasure(400d, 300d))
- .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredLines(), createMeasure(200d, 30d))
- .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredConditions(), createMeasure(16d, 9d));
-
- underTest.execute();
-
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).containsOnly(
- entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
- entryOf(lineCoverageKey, createMeasure(99d, 90d)),
- entryOf(branchCoverageKey, createMeasure(97d, 96d))
- );
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).containsOnly(
- entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
- entryOf(lineCoverageKey, createMeasure(90d, 99d)),
- entryOf(branchCoverageKey, createMeasure(96d, 97d))
- );
- assertThat(measureRepository.getAddedRawMeasures(FILE_3_REF)).isEmpty();
-
- assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).containsOnly(
- entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
- entryOf(lineCoverageKey, createMeasure(99d, 90d)),
- entryOf(branchCoverageKey, createMeasure(97d, 96d))
- );
-
- assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).containsOnly(
- entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
- entryOf(lineCoverageKey, createMeasure(90d, 99d)),
- entryOf(branchCoverageKey, createMeasure(96d, 97d))
- );
-
- MeasureRepoEntry[] modulesAndProjectEntries = {
- entryOf(codeCoverageKey, createMeasure(95.5d, 95.5d)),
- entryOf(lineCoverageKey, createMeasure(95.4d, 95.4d)),
- entryOf(branchCoverageKey, createMeasure(96.4d, 96.4d))
- };
-
- assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).containsOnly(modulesAndProjectEntries);
- assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).containsOnly(modulesAndProjectEntries);
- assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).containsOnly(modulesAndProjectEntries);
- }
-
- private void defineChangeSetsAndMeasures(int componentRef, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) {
- reportReader.putChangesets(Changesets.newBuilder()
- .setComponentRef(componentRef)
- .addChangeset(Changesets.Changeset.newBuilder().build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2007-01-15").getTime())
- .build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2011-01-01").getTime())
- .build())
- .addChangeset(Changesets.Changeset.newBuilder()
- .setDate(parseDate("2012-02-23").getTime())
- .build())
- .addChangesetIndexByLine(0)
- .addChangesetIndexByLine(2) // line 2
- .addChangesetIndexByLine(1) // line 3
- .addChangesetIndexByLine(2) // line 4
- .addChangesetIndexByLine(3) // line 5
- .addChangesetIndexByLine(3) // line 6
- .addChangesetIndexByLine(3) // line 7
- .build());
- measureRepository.addRawMeasure(componentRef, metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0"));
- measureRepository.addRawMeasure(componentRef, metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions));
- measureRepository.addRawMeasure(componentRef, metricKeys.coveredConditionsByLine,
- newMeasureBuilder().create("4=" + line4.uncoveredConditions + ";6=" + line6.uncoveredConditions));
- }
-
- private static final class MetricKeys {
- private final String coverageLineHitsData;
- private final String conditionsByLine;
- private final String coveredConditionsByLine;
- private final String newLinesToCover;
- private final String newUncoveredLines;
- private final String newConditionsToCover;
- private final String newUncoveredConditions;
-
- public MetricKeys(String coverageLineHitsData, String conditionsByLine, String coveredConditionsByLine,
- String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
- this.coverageLineHitsData = coverageLineHitsData;
- this.conditionsByLine = conditionsByLine;
- this.coveredConditionsByLine = coveredConditionsByLine;
- this.newLinesToCover = newLinesToCover;
- this.newUncoveredLines = newUncoveredLines;
- this.newConditionsToCover = newConditionsToCover;
- this.newUncoveredConditions = newUncoveredConditions;
- }
- }
-
- private static final class MeasureValues {
- private final int lineHits;
- private final int coveredConditions;
- private final int uncoveredConditions;
-
- public MeasureValues(int lineHits, int coveredConditions, int uncoveredConditions) {
- this.lineHits = lineHits;
- this.coveredConditions = coveredConditions;
- this.uncoveredConditions = uncoveredConditions;
- }
- }
-
- private void verify_computation_of_measures_for_new_conditions(MetricKeys metricKeys) {
- treeRootHolder.setRoot(FILE_COMPONENT);
- defineChangeSetsAndMeasures(FILE_COMPONENT.getReportAttributes().getRef(), metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
-
- underTest.execute();
-
- assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
- entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
- entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
- entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
- entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
- );
- }
-
- private static Measure createMeasure(@Nullable Double variationPeriod2, @Nullable Double variationPeriod5) {
- MeasureVariations.Builder variationBuilder = newMeasureVariationsBuilder();
- if (variationPeriod2 != null) {
- variationBuilder.setVariation(new Period(2, "", null, 1L, 2L), variationPeriod2);
- }
- if (variationPeriod5 != null) {
- variationBuilder.setVariation(new Period(5, "", null, 1L, 2L), variationPeriod5);
- }
- return newMeasureBuilder()
- .setVariations(variationBuilder.build())
- .createNoValue();
- }
-
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.step;
+
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.server.computation.batch.BatchReportReaderRule;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.ReportComponent;
+import org.sonar.server.computation.component.FileAttributes;
+import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
+import org.sonar.server.computation.measure.Measure;
+import org.sonar.server.computation.measure.MeasureRepoEntry;
+import org.sonar.server.computation.measure.MeasureRepositoryRule;
+import org.sonar.server.computation.measure.MeasureVariations;
+import org.sonar.server.computation.metric.MetricRepositoryRule;
+import org.sonar.server.computation.period.Period;
+import org.sonar.server.computation.period.PeriodsHolderRule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE_KEY;
+import static org.sonar.api.measures.CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY;
+import static org.sonar.api.measures.CoreMetrics.COVERED_CONDITIONS_BY_LINE_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_LINES_TO_COVER_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY;
+import static org.sonar.api.measures.CoreMetrics.NEW_UNCOVERED_LINES_KEY;
+import static org.sonar.api.utils.DateUtils.parseDate;
+import static org.sonar.batch.protocol.output.BatchReport.Changesets;
+import static org.sonar.server.computation.component.Component.Type.DIRECTORY;
+import static org.sonar.server.computation.component.Component.Type.FILE;
+import static org.sonar.server.computation.component.Component.Type.MODULE;
+import static org.sonar.server.computation.component.Component.Type.PROJECT;
+import static org.sonar.server.computation.component.ReportComponent.builder;
+import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf;
+import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries;
+import static org.sonar.server.computation.measure.MeasureVariations.newMeasureVariationsBuilder;
+
+public class ReportNewCoverageMeasuresStepTest {
+
+ private static final int ROOT_REF = 1;
+ private static final int MODULE_REF = 11;
+ private static final int SUB_MODULE_REF = 111;
+ private static final int DIRECTORY_1_REF = 1111;
+ private static final int FILE_1_REF = 11111;
+ private static final int DIRECTORY_2_REF = 1112;
+ private static final int FILE_2_REF = 11121;
+ private static final int FILE_3_REF = 11122;
+
+ private static final ReportComponent MULTIPLE_FILES_TREE = builder(PROJECT, ROOT_REF)
+ .addChildren(
+ builder(MODULE, MODULE_REF)
+ .addChildren(
+ builder(MODULE, SUB_MODULE_REF)
+ .addChildren(
+ builder(DIRECTORY, DIRECTORY_1_REF)
+ .addChildren(
+ builder(FILE, FILE_1_REF).build()
+ ).build(),
+ builder(DIRECTORY, DIRECTORY_2_REF)
+ .addChildren(
+ builder(FILE, FILE_2_REF).build(),
+ builder(FILE, FILE_3_REF).build()
+ ).build()
+ )
+ .build()
+ ).build()
+ ).build();
+
+ @Rule
+ public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+ @Rule
+ public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+ @Rule
+ public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
+ @Rule
+ public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
+ .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
+ .add(CoreMetrics.CONDITIONS_BY_LINE)
+ .add(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.NEW_LINES_TO_COVER)
+ .add(CoreMetrics.NEW_UNCOVERED_LINES)
+ .add(CoreMetrics.NEW_CONDITIONS_TO_COVER)
+ .add(CoreMetrics.NEW_UNCOVERED_CONDITIONS)
+ .add(CoreMetrics.NEW_COVERAGE)
+ .add(CoreMetrics.NEW_BRANCH_COVERAGE)
+ .add(CoreMetrics.NEW_LINE_COVERAGE)
+
+ .add(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA)
+ .add(CoreMetrics.IT_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.NEW_IT_LINES_TO_COVER)
+ .add(CoreMetrics.NEW_IT_UNCOVERED_LINES)
+ .add(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER)
+ .add(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS)
+ .add(CoreMetrics.NEW_IT_COVERAGE)
+ .add(CoreMetrics.NEW_IT_BRANCH_COVERAGE)
+ .add(CoreMetrics.NEW_IT_LINE_COVERAGE)
+
+ .add(CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA)
+ .add(CoreMetrics.OVERALL_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.NEW_OVERALL_LINES_TO_COVER)
+ .add(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES)
+ .add(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER)
+ .add(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS)
+ .add(CoreMetrics.NEW_OVERALL_COVERAGE)
+ .add(CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE)
+ .add(CoreMetrics.NEW_OVERALL_LINE_COVERAGE)
+ ;
+ @Rule
+ public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
+
+ private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder, reportReader,
+ measureRepository, metricRepository);
+ public static final ReportComponent FILE_COMPONENT = ReportComponent.builder(Component.Type.FILE, FILE_1_REF)
+ .setFileAttributes(new FileAttributes(false, null)).build();
+
+ @Before
+ public void setUp() {
+ periodsHolder.setPeriods(
+ new Period(2, "mode_p_1", null, parseDate("2009-12-25").getTime(), 1),
+ new Period(5, "mode_p_5", null, parseDate("2011-02-18").getTime(), 2));
+ }
+
+ @Test
+ public void no_measure_for_PROJECT_component() {
+ treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, ROOT_REF).build());
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void no_measure_for_MODULE_component() {
+ treeRootHolder.setRoot(ReportComponent.builder(Component.Type.MODULE, MODULE_REF).build());
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void no_measure_for_DIRECTORY_component() {
+ treeRootHolder.setRoot(ReportComponent.builder(Component.Type.DIRECTORY, DIRECTORY_1_REF).build());
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void no_measure_for_unit_test_FILE_component() {
+ treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(true, null)).build());
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void no_measures_for_FILE_component_without_code() {
+ treeRootHolder.setRoot(ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null)).build());
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void verify_measure_of_condition_not_computed_if_there_is_none() {
+ treeRootHolder.setRoot(FILE_COMPONENT);
+ reportReader.putChangesets(Changesets.newBuilder()
+ .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
+ .addChangeset(Changesets.Changeset.newBuilder().build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2007-01-15").getTime())
+ .build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2011-01-01").getTime())
+ .build())
+ .addChangesetIndexByLine(0)
+ .addChangesetIndexByLine(1)
+ .addChangesetIndexByLine(2)
+ .build()
+ );
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void verify_no_measure_when_nothing_has_changed() {
+ treeRootHolder.setRoot(FILE_COMPONENT);
+ reportReader.putChangesets(BatchReport.Changesets.newBuilder()
+ .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2008-08-02").getTime())
+ .build())
+ .addChangesetIndexByLine(0)
+ .addChangesetIndexByLine(0)
+ .addChangesetIndexByLine(0)
+ .addChangesetIndexByLine(0)
+ .build());
+ measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERAGE_LINE_HITS_DATA_KEY, newMeasureBuilder().create("2=1;3=1"));
+ measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
+ measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), COVERED_CONDITIONS_BY_LINE_KEY, newMeasureBuilder().create("2=1"));
+
+ underTest.execute();
+
+ assertThat(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef())).isEmpty();
+ }
+
+ @Test
+ public void no_measures_for_FILE_component_without_CoverageData() {
+ ReportComponent fileComponent = ReportComponent.builder(Component.Type.FILE, FILE_1_REF).setFileAttributes(new FileAttributes(false, null)).build();
+
+ treeRootHolder.setRoot(fileComponent);
+ reportReader.putChangesets(Changesets.newBuilder()
+ .setComponentRef(fileComponent.getReportAttributes().getRef())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2008-05-18").getTime())
+ .build())
+ .addChangesetIndexByLine(0)
+ .build());
+
+ underTest.execute();
+
+ assertThat(measureRepository.isEmpty()).isTrue();
+ }
+
+ @Test
+ public void verify_computation_of_measures_for_new_lines_for_FILE() {
+ String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
+ String newLinesToCover = NEW_LINES_TO_COVER_KEY;
+ String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
+
+ verify_computation_of_measures_for_new_lines(coverageLineHitsData,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
+ }
+
+ @Test
+ public void verify_computation_of_measures_for_new_lines_for_IT_FILE() {
+ String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
+ String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
+ String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
+
+ verify_computation_of_measures_for_new_lines(coverageLineHitsData,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
+ }
+
+ @Test
+ public void verify_computation_of_measures_for_new_lines_for_Overall() {
+ String coverageLineHitsData = CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
+ String newLinesToCover = CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY;
+ String newUncoveredLines = CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY;
+
+ verify_computation_of_measures_for_new_lines(coverageLineHitsData,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
+ }
+
+ private void verify_computation_of_measures_for_new_lines(String coverageLineHitsData,
+ String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
+ treeRootHolder.setRoot(FILE_COMPONENT);
+ reportReader.putChangesets(Changesets.newBuilder()
+ .setComponentRef(FILE_COMPONENT.getReportAttributes().getRef())
+ .addChangeset(Changesets.Changeset.newBuilder().build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2007-01-15").getTime())
+ .build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2011-01-01").getTime())
+ .build())
+ .addChangesetIndexByLine(0)
+ .addChangesetIndexByLine(2) // line 2
+ .addChangesetIndexByLine(1) // line 3
+ .addChangesetIndexByLine(2) // line 4
+ .build());
+ measureRepository.addRawMeasure(FILE_COMPONENT.getReportAttributes().getRef(), coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=3"));
+
+ underTest.execute();
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
+ entryOf(newLinesToCover, createMeasure(2d, null)),
+ entryOf(newUncoveredLines, createMeasure(1d, null)),
+ entryOf(newConditionsToCover, createMeasure(0d, null)),
+ entryOf(newUncoveredConditions, createMeasure(0d, null))
+ );
+ }
+
+ @Test
+ public void verify_computation_of_measures_for_new_conditions_for_FILE() {
+ String coverageLineHitsData = COVERAGE_LINE_HITS_DATA_KEY;
+ String conditionsByLine = CONDITIONS_BY_LINE_KEY;
+ String coveredConditionsByLine = COVERED_CONDITIONS_BY_LINE_KEY;
+ String newLinesToCover = NEW_LINES_TO_COVER_KEY;
+ String newUncoveredLines = NEW_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = NEW_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = NEW_UNCOVERED_CONDITIONS_KEY;
+
+ verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
+ }
+
+ @Test
+ public void verify_computation_of_measures_for_new_conditions_for_IT_FILE() {
+ String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
+ String conditionsByLine = CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
+ String coveredConditionsByLine = CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
+ String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
+ String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
+
+ verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
+ }
+
+ @Test
+ public void verify_computation_of_measures_for_new_conditions_Overall() {
+ String coverageLineHitsData = CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA_KEY;
+ String conditionsByLine = CoreMetrics.OVERALL_CONDITIONS_BY_LINE_KEY;
+ String coveredConditionsByLine = CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE_KEY;
+ String newLinesToCover = CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY;
+ String newUncoveredLines = CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY;
+
+ verify_computation_of_measures_for_new_conditions(new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions));
+ }
+
+ @Test
+ public void verify_aggregation_of_measures_for_new_conditions() {
+ String coverageLineHitsData = CoreMetrics.IT_COVERAGE_LINE_HITS_DATA_KEY;
+ String conditionsByLine = CoreMetrics.IT_CONDITIONS_BY_LINE_KEY;
+ String coveredConditionsByLine = CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE_KEY;
+ String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
+ String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
+
+ MetricKeys metricKeys = new MetricKeys(coverageLineHitsData, conditionsByLine, coveredConditionsByLine,
+ newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
+
+ treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
+ defineChangeSetsAndMeasures(FILE_1_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
+ defineChangeSetsAndMeasures(FILE_2_REF, metricKeys, new MeasureValues(0, 14, 6), new MeasureValues(0, 13, 7));
+ defineChangeSetsAndMeasures(FILE_3_REF, metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(1, 13, 7));
+
+ underTest.execute();
+
+ // files
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
+ );
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(4d, 2d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(27d, 13d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(14d, 6d))
+ );
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_3_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(2d, 1d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(17d, 13d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(9d, 6d))
+ );
+ // directories
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
+ );
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(10d, 6d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(6d, 3d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(44d, 26d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(23d, 12d))
+ );
+ // submodule
+ MeasureRepoEntry[] repoEntriesFromSubModuleUp = {entryOf(metricKeys.newLinesToCover, createMeasure(15d, 9d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(9d, 5d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(51d, 29d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(27d, 13d))};
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).contains(repoEntriesFromSubModuleUp);
+ // module
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).contains(repoEntriesFromSubModuleUp);
+ // project
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(repoEntriesFromSubModuleUp);
+ }
+
+ @Test
+ public void verify_aggregates_variations_for_new_code_line_and_branch_Coverage() {
+ LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
+ CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY,
+ CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY
+ );
+ String codeCoverageKey = CoreMetrics.NEW_COVERAGE_KEY;
+ String lineCoverageKey = CoreMetrics.NEW_LINE_COVERAGE_KEY;
+ String branchCoverageKey = CoreMetrics.NEW_BRANCH_COVERAGE_KEY;
+
+ verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
+ }
+
+ @Test
+ public void verify_aggregates_variations_for_new_IT_code_line_and_branch_Coverage() {
+ LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
+ CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY,
+ CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY
+ );
+ String codeCoverageKey = CoreMetrics.NEW_IT_COVERAGE_KEY;
+ String lineCoverageKey = CoreMetrics.NEW_IT_LINE_COVERAGE_KEY;
+ String branchCoverageKey = CoreMetrics.NEW_IT_BRANCH_COVERAGE_KEY;
+
+ verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
+ }
+
+ @Test
+ public void verify_aggregates_variations_for_new_Overall_code_line_and_branch_Coverage() {
+ LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
+ CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY,
+ CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY
+ );
+ String codeCoverageKey = CoreMetrics.NEW_OVERALL_COVERAGE_KEY;
+ String lineCoverageKey = CoreMetrics.NEW_OVERALL_LINE_COVERAGE_KEY;
+ String branchCoverageKey = CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE_KEY;
+
+ verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
+ }
+
+ private void verify_aggregates_variations(LinesAndConditionsWithUncoveredMetricKeys metricKeys, String codeCoverageKey, String lineCoverageKey, String branchCoverageKey) {
+ treeRootHolder.setRoot(MULTIPLE_FILES_TREE);
+ measureRepository
+ .addRawMeasure(FILE_1_REF, metricKeys.getLines(), createMeasure(3000d, 2000d))
+ .addRawMeasure(FILE_1_REF, metricKeys.getConditions(), createMeasure(300d, 400d))
+ .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredLines(), createMeasure(30d, 200d))
+ .addRawMeasure(FILE_1_REF, metricKeys.getUncoveredConditions(), createMeasure(9d, 16d))
+
+ .addRawMeasure(FILE_2_REF, metricKeys.getLines(), createMeasure(2000d, 3000d))
+ .addRawMeasure(FILE_2_REF, metricKeys.getConditions(), createMeasure(400d, 300d))
+ .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredLines(), createMeasure(200d, 30d))
+ .addRawMeasure(FILE_2_REF, metricKeys.getUncoveredConditions(), createMeasure(16d, 9d));
+
+ underTest.execute();
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).containsOnly(
+ entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
+ entryOf(lineCoverageKey, createMeasure(99d, 90d)),
+ entryOf(branchCoverageKey, createMeasure(97d, 96d))
+ );
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_2_REF))).containsOnly(
+ entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
+ entryOf(lineCoverageKey, createMeasure(90d, 99d)),
+ entryOf(branchCoverageKey, createMeasure(96d, 97d))
+ );
+ assertThat(measureRepository.getAddedRawMeasures(FILE_3_REF)).isEmpty();
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_1_REF))).containsOnly(
+ entryOf(codeCoverageKey, createMeasure(98.8d, 91d)),
+ entryOf(lineCoverageKey, createMeasure(99d, 90d)),
+ entryOf(branchCoverageKey, createMeasure(97d, 96d))
+ );
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(DIRECTORY_2_REF))).containsOnly(
+ entryOf(codeCoverageKey, createMeasure(91d, 98.8d)),
+ entryOf(lineCoverageKey, createMeasure(90d, 99d)),
+ entryOf(branchCoverageKey, createMeasure(96d, 97d))
+ );
+
+ MeasureRepoEntry[] modulesAndProjectEntries = {
+ entryOf(codeCoverageKey, createMeasure(95.5d, 95.5d)),
+ entryOf(lineCoverageKey, createMeasure(95.4d, 95.4d)),
+ entryOf(branchCoverageKey, createMeasure(96.4d, 96.4d))
+ };
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_MODULE_REF))).containsOnly(modulesAndProjectEntries);
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(MODULE_REF))).containsOnly(modulesAndProjectEntries);
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).containsOnly(modulesAndProjectEntries);
+ }
+
+ private void defineChangeSetsAndMeasures(int componentRef, MetricKeys metricKeys, MeasureValues line4, MeasureValues line6) {
+ reportReader.putChangesets(Changesets.newBuilder()
+ .setComponentRef(componentRef)
+ .addChangeset(Changesets.Changeset.newBuilder().build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2007-01-15").getTime())
+ .build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2011-01-01").getTime())
+ .build())
+ .addChangeset(Changesets.Changeset.newBuilder()
+ .setDate(parseDate("2012-02-23").getTime())
+ .build())
+ .addChangesetIndexByLine(0)
+ .addChangesetIndexByLine(2) // line 2
+ .addChangesetIndexByLine(1) // line 3
+ .addChangesetIndexByLine(2) // line 4
+ .addChangesetIndexByLine(3) // line 5
+ .addChangesetIndexByLine(3) // line 6
+ .addChangesetIndexByLine(3) // line 7
+ .build());
+ measureRepository.addRawMeasure(componentRef, metricKeys.coverageLineHitsData, newMeasureBuilder().create("2=0;3=2;4=" + line4.lineHits + ";5=1;6=" + line6.lineHits + ";7=0"));
+ measureRepository.addRawMeasure(componentRef, metricKeys.conditionsByLine, newMeasureBuilder().create("4=" + line4.coveredConditions + ";6=" + line6.coveredConditions));
+ measureRepository.addRawMeasure(componentRef, metricKeys.coveredConditionsByLine,
+ newMeasureBuilder().create("4=" + line4.uncoveredConditions + ";6=" + line6.uncoveredConditions));
+ }
+
+ private static final class MetricKeys {
+ private final String coverageLineHitsData;
+ private final String conditionsByLine;
+ private final String coveredConditionsByLine;
+ private final String newLinesToCover;
+ private final String newUncoveredLines;
+ private final String newConditionsToCover;
+ private final String newUncoveredConditions;
+
+ public MetricKeys(String coverageLineHitsData, String conditionsByLine, String coveredConditionsByLine,
+ String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
+ this.coverageLineHitsData = coverageLineHitsData;
+ this.conditionsByLine = conditionsByLine;
+ this.coveredConditionsByLine = coveredConditionsByLine;
+ this.newLinesToCover = newLinesToCover;
+ this.newUncoveredLines = newUncoveredLines;
+ this.newConditionsToCover = newConditionsToCover;
+ this.newUncoveredConditions = newUncoveredConditions;
+ }
+ }
+
+ private static final class MeasureValues {
+ private final int lineHits;
+ private final int coveredConditions;
+ private final int uncoveredConditions;
+
+ public MeasureValues(int lineHits, int coveredConditions, int uncoveredConditions) {
+ this.lineHits = lineHits;
+ this.coveredConditions = coveredConditions;
+ this.uncoveredConditions = uncoveredConditions;
+ }
+ }
+
+ private void verify_computation_of_measures_for_new_conditions(MetricKeys metricKeys) {
+ treeRootHolder.setRoot(FILE_COMPONENT);
+ defineChangeSetsAndMeasures(FILE_COMPONENT.getReportAttributes().getRef(), metricKeys, new MeasureValues(3, 4, 1), new MeasureValues(0, 3, 2));
+
+ underTest.execute();
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_COMPONENT.getReportAttributes().getRef()))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(5d, 3d)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(3d, 2d)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(7d, 3d)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(4d, 1d))
+ );
+ }
+
+ private static Measure createMeasure(@Nullable Double variationPeriod2, @Nullable Double variationPeriod5) {
+ MeasureVariations.Builder variationBuilder = newMeasureVariationsBuilder();
+ if (variationPeriod2 != null) {
+ variationBuilder.setVariation(new Period(2, "", null, 1L, 2L), variationPeriod2);
+ }
+ if (variationPeriod5 != null) {
+ variationBuilder.setVariation(new Period(5, "", null, 1L, 2L), variationPeriod5);
+ }
+ return newMeasureBuilder()
+ .setVariations(variationBuilder.build())
+ .createNoValue();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.step;
+
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.ViewsComponent;
+import org.sonar.server.computation.formula.coverage.LinesAndConditionsWithUncoveredMetricKeys;
+import org.sonar.server.computation.measure.Measure;
+import org.sonar.server.computation.measure.MeasureRepositoryRule;
+import org.sonar.server.computation.measure.MeasureVariations;
+import org.sonar.server.computation.metric.MetricRepositoryRule;
+import org.sonar.server.computation.period.Period;
+import org.sonar.server.computation.period.PeriodsHolderRule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.sonar.api.utils.DateUtils.parseDate;
+import static org.sonar.server.computation.component.Component.Type.PROJECT_VIEW;
+import static org.sonar.server.computation.component.Component.Type.SUBVIEW;
+import static org.sonar.server.computation.component.Component.Type.VIEW;
+import static org.sonar.server.computation.component.ViewsComponent.builder;
+import static org.sonar.server.computation.measure.Measure.newMeasureBuilder;
+import static org.sonar.server.computation.measure.MeasureRepoEntry.entryOf;
+import static org.sonar.server.computation.measure.MeasureRepoEntry.toEntries;
+import static org.sonar.server.computation.measure.MeasureVariations.newMeasureVariationsBuilder;
+
+public class ViewsNewCoverageMeasuresStepTest {
+
+ private static final int ROOT_REF = 1;
+ private static final int SUBVIEW_REF = 11;
+ private static final int SUB_SUBVIEW_1_REF = 111;
+ private static final int PROJECT_VIEW_1_REF = 1111;
+ private static final int SUB_SUBVIEW_2_REF = 112;
+ private static final int PROJECT_VIEW_2_REF = 1121;
+ private static final int PROJECT_VIEW_3_REF = 1122;
+ private static final int PROJECT_VIEW_4_REF = 12;
+
+ private static final ViewsComponent VIEWS_TREE = builder(VIEW, ROOT_REF)
+ .addChildren(
+ builder(SUBVIEW, SUBVIEW_REF)
+ .addChildren(
+ builder(SUBVIEW, SUB_SUBVIEW_1_REF)
+ .addChildren(
+ builder(PROJECT_VIEW, PROJECT_VIEW_1_REF).build())
+ .build(),
+ builder(SUBVIEW, SUB_SUBVIEW_2_REF)
+ .addChildren(
+ builder(PROJECT_VIEW, PROJECT_VIEW_2_REF).build(),
+ builder(PROJECT_VIEW, PROJECT_VIEW_3_REF).build())
+ .build(),
+ builder(PROJECT_VIEW, PROJECT_VIEW_4_REF).build())
+ .build())
+ .build();
+ private static final Double NO_PERIOD_4_OR_5_IN_VIEWS = null;
+
+ @Rule
+ public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+ @Rule
+ public PeriodsHolderRule periodsHolder = new PeriodsHolderRule();
+ @Rule
+ public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
+ .add(CoreMetrics.COVERAGE_LINE_HITS_DATA)
+ .add(CoreMetrics.CONDITIONS_BY_LINE)
+ .add(CoreMetrics.COVERED_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.NEW_LINES_TO_COVER)
+ .add(CoreMetrics.NEW_UNCOVERED_LINES)
+ .add(CoreMetrics.NEW_CONDITIONS_TO_COVER)
+ .add(CoreMetrics.NEW_UNCOVERED_CONDITIONS)
+ .add(CoreMetrics.NEW_COVERAGE)
+ .add(CoreMetrics.NEW_BRANCH_COVERAGE)
+ .add(CoreMetrics.NEW_LINE_COVERAGE)
+
+ .add(CoreMetrics.IT_COVERAGE_LINE_HITS_DATA)
+ .add(CoreMetrics.IT_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.IT_COVERED_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.NEW_IT_LINES_TO_COVER)
+ .add(CoreMetrics.NEW_IT_UNCOVERED_LINES)
+ .add(CoreMetrics.NEW_IT_CONDITIONS_TO_COVER)
+ .add(CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS)
+ .add(CoreMetrics.NEW_IT_COVERAGE)
+ .add(CoreMetrics.NEW_IT_BRANCH_COVERAGE)
+ .add(CoreMetrics.NEW_IT_LINE_COVERAGE)
+
+ .add(CoreMetrics.OVERALL_COVERAGE_LINE_HITS_DATA)
+ .add(CoreMetrics.OVERALL_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.OVERALL_COVERED_CONDITIONS_BY_LINE)
+ .add(CoreMetrics.NEW_OVERALL_LINES_TO_COVER)
+ .add(CoreMetrics.NEW_OVERALL_UNCOVERED_LINES)
+ .add(CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER)
+ .add(CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS)
+ .add(CoreMetrics.NEW_OVERALL_COVERAGE)
+ .add(CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE)
+ .add(CoreMetrics.NEW_OVERALL_LINE_COVERAGE);
+ @Rule
+ public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
+
+ private NewCoverageMeasuresStep underTest = new NewCoverageMeasuresStep(treeRootHolder, periodsHolder,
+ measureRepository, metricRepository);
+
+ @Before
+ public void setUp() {
+ periodsHolder.setPeriods(
+ new Period(2, "mode_p_1", null, parseDate("2009-12-25").getTime(), 1),
+ new Period(5, "mode_p_5", null, parseDate("2011-02-18").getTime(), 2));
+ }
+
+ @Test
+ public void verify_aggregation_of_measures_for_new_conditions() {
+ String newLinesToCover = CoreMetrics.NEW_IT_LINES_TO_COVER_KEY;
+ String newUncoveredLines = CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY;
+ String newConditionsToCover = CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY;
+ String newUncoveredConditions = CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY;
+
+ MetricKeys metricKeys = new MetricKeys(newLinesToCover, newUncoveredLines, newConditionsToCover, newUncoveredConditions);
+
+ treeRootHolder.setRoot(VIEWS_TREE);
+ // PROJECT_VIEW_1_REF has no measure
+ measureRepository.addRawMeasure(PROJECT_VIEW_2_REF, newLinesToCover, createMeasure(1d, 2d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_2_REF, newUncoveredLines, createMeasure(10d, 20d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_2_REF, newConditionsToCover, createMeasure(4d, 5d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_2_REF, newUncoveredConditions, createMeasure(40d, 50d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_3_REF, newLinesToCover, createMeasure(11d, 12d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_3_REF, newUncoveredLines, createMeasure(20d, 30d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_3_REF, newConditionsToCover, createMeasure(14d, 15d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_3_REF, newUncoveredConditions, createMeasure(50d, 60d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_4_REF, newLinesToCover, createMeasure(21d, 22d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_4_REF, newUncoveredLines, createMeasure(30d, 40d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_4_REF, newConditionsToCover, createMeasure(24d, 25d));
+ measureRepository.addRawMeasure(PROJECT_VIEW_4_REF, newUncoveredConditions, createMeasure(60d, 70d));
+
+ underTest.execute();
+
+ assertNoAddedRawMeasureOnProjectViews();
+ assertNoAddedRawMeasures(SUB_SUBVIEW_1_REF);
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_SUBVIEW_2_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(12d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(30d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(18d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(90d, NO_PERIOD_4_OR_5_IN_VIEWS)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(
+ entryOf(metricKeys.newLinesToCover, createMeasure(33d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(metricKeys.newUncoveredLines, createMeasure(60d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(metricKeys.newConditionsToCover, createMeasure(42d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(metricKeys.newUncoveredConditions, createMeasure(150d, NO_PERIOD_4_OR_5_IN_VIEWS)));
+ }
+
+ @Test
+ public void verify_aggregates_variations_for_new_code_line_and_branch_Coverage() {
+ LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
+ CoreMetrics.NEW_LINES_TO_COVER_KEY, CoreMetrics.NEW_CONDITIONS_TO_COVER_KEY,
+ CoreMetrics.NEW_UNCOVERED_LINES_KEY, CoreMetrics.NEW_UNCOVERED_CONDITIONS_KEY);
+ String codeCoverageKey = CoreMetrics.NEW_COVERAGE_KEY;
+ String lineCoverageKey = CoreMetrics.NEW_LINE_COVERAGE_KEY;
+ String branchCoverageKey = CoreMetrics.NEW_BRANCH_COVERAGE_KEY;
+
+ verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
+ }
+
+ @Test
+ public void verify_aggregates_variations_for_new_IT_code_line_and_branch_Coverage() {
+ LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
+ CoreMetrics.NEW_IT_LINES_TO_COVER_KEY, CoreMetrics.NEW_IT_CONDITIONS_TO_COVER_KEY,
+ CoreMetrics.NEW_IT_UNCOVERED_LINES_KEY, CoreMetrics.NEW_IT_UNCOVERED_CONDITIONS_KEY);
+ String codeCoverageKey = CoreMetrics.NEW_IT_COVERAGE_KEY;
+ String lineCoverageKey = CoreMetrics.NEW_IT_LINE_COVERAGE_KEY;
+ String branchCoverageKey = CoreMetrics.NEW_IT_BRANCH_COVERAGE_KEY;
+
+ verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
+ }
+
+ @Test
+ public void verify_aggregates_variations_for_new_Overall_code_line_and_branch_Coverage() {
+ LinesAndConditionsWithUncoveredMetricKeys metricKeys = new LinesAndConditionsWithUncoveredMetricKeys(
+ CoreMetrics.NEW_OVERALL_LINES_TO_COVER_KEY, CoreMetrics.NEW_OVERALL_CONDITIONS_TO_COVER_KEY,
+ CoreMetrics.NEW_OVERALL_UNCOVERED_LINES_KEY, CoreMetrics.NEW_OVERALL_UNCOVERED_CONDITIONS_KEY);
+ String codeCoverageKey = CoreMetrics.NEW_OVERALL_COVERAGE_KEY;
+ String lineCoverageKey = CoreMetrics.NEW_OVERALL_LINE_COVERAGE_KEY;
+ String branchCoverageKey = CoreMetrics.NEW_OVERALL_BRANCH_COVERAGE_KEY;
+
+ verify_aggregates_variations(metricKeys, codeCoverageKey, lineCoverageKey, branchCoverageKey);
+ }
+
+ private void verify_aggregates_variations(LinesAndConditionsWithUncoveredMetricKeys metricKeys, String codeCoverageKey, String lineCoverageKey, String branchCoverageKey) {
+ treeRootHolder.setRoot(VIEWS_TREE);
+ measureRepository
+ .addRawMeasure(PROJECT_VIEW_1_REF, metricKeys.getLines(), createMeasure(3000d, 2000d))
+ .addRawMeasure(PROJECT_VIEW_1_REF, metricKeys.getConditions(), createMeasure(300d, 400d))
+ .addRawMeasure(PROJECT_VIEW_1_REF, metricKeys.getUncoveredLines(), createMeasure(30d, 200d))
+ .addRawMeasure(PROJECT_VIEW_1_REF, metricKeys.getUncoveredConditions(), createMeasure(9d, 16d))
+ // PROJECT_VIEW_2_REF
+ .addRawMeasure(PROJECT_VIEW_2_REF, metricKeys.getLines(), createMeasure(2000d, 3000d))
+ .addRawMeasure(PROJECT_VIEW_2_REF, metricKeys.getConditions(), createMeasure(400d, 300d))
+ .addRawMeasure(PROJECT_VIEW_2_REF, metricKeys.getUncoveredLines(), createMeasure(200d, 30d))
+ .addRawMeasure(PROJECT_VIEW_2_REF, metricKeys.getUncoveredConditions(), createMeasure(16d, 9d))
+ // PROJECT_VIEW_3_REF has no measure
+ // PROJECT_VIEW_4_REF
+ .addRawMeasure(PROJECT_VIEW_4_REF, metricKeys.getLines(), createMeasure(1000d, 2000d))
+ .addRawMeasure(PROJECT_VIEW_4_REF, metricKeys.getConditions(), createMeasure(300d, 200d))
+ .addRawMeasure(PROJECT_VIEW_4_REF, metricKeys.getUncoveredLines(), createMeasure(100d, 20d))
+ .addRawMeasure(PROJECT_VIEW_4_REF, metricKeys.getUncoveredConditions(), createMeasure(6d, 9d));
+
+ underTest.execute();
+
+ assertNoAddedRawMeasureOnProjectViews();
+
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_SUBVIEW_1_REF))).contains(
+ entryOf(codeCoverageKey, createMeasure(98.8d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(lineCoverageKey, createMeasure(99d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(branchCoverageKey, createMeasure(97d, NO_PERIOD_4_OR_5_IN_VIEWS)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUB_SUBVIEW_2_REF))).contains(
+ entryOf(codeCoverageKey, createMeasure(91d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(lineCoverageKey, createMeasure(90d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(branchCoverageKey, createMeasure(96d, NO_PERIOD_4_OR_5_IN_VIEWS)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(SUBVIEW_REF))).contains(
+ entryOf(codeCoverageKey, createMeasure(94.8d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(lineCoverageKey, createMeasure(94.5d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(branchCoverageKey, createMeasure(96.9d, NO_PERIOD_4_OR_5_IN_VIEWS)));
+ assertThat(toEntries(measureRepository.getAddedRawMeasures(ROOT_REF))).contains(
+ entryOf(codeCoverageKey, createMeasure(94.8d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(lineCoverageKey, createMeasure(94.5d, NO_PERIOD_4_OR_5_IN_VIEWS)),
+ entryOf(branchCoverageKey, createMeasure(96.9d, NO_PERIOD_4_OR_5_IN_VIEWS)));
+ }
+
+ private static final class MetricKeys {
+ private final String newLinesToCover;
+ private final String newUncoveredLines;
+ private final String newConditionsToCover;
+ private final String newUncoveredConditions;
+
+ public MetricKeys(String newLinesToCover, String newUncoveredLines, String newConditionsToCover, String newUncoveredConditions) {
+ this.newLinesToCover = newLinesToCover;
+ this.newUncoveredLines = newUncoveredLines;
+ this.newConditionsToCover = newConditionsToCover;
+ this.newUncoveredConditions = newUncoveredConditions;
+ }
+ }
+
+ private static Measure createMeasure(@Nullable Double variationPeriod2, @Nullable Double variationPeriod5) {
+ MeasureVariations.Builder variationBuilder = newMeasureVariationsBuilder();
+ if (variationPeriod2 != null) {
+ variationBuilder.setVariation(new Period(2, "", null, 1L, 2L), variationPeriod2);
+ }
+ if (variationPeriod5 != null) {
+ variationBuilder.setVariation(new Period(5, "", null, 1L, 2L), variationPeriod5);
+ }
+ return newMeasureBuilder()
+ .setVariations(variationBuilder.build())
+ .createNoValue();
+ }
+
+ private void assertNoAddedRawMeasureOnProjectViews() {
+ assertNoAddedRawMeasures(PROJECT_VIEW_1_REF);
+ assertNoAddedRawMeasures(PROJECT_VIEW_2_REF);
+ assertNoAddedRawMeasures(PROJECT_VIEW_3_REF);
+ }
+
+ private void assertNoAddedRawMeasures(int componentRef) {
+ assertThat(measureRepository.getAddedRawMeasures(componentRef)).isEmpty();
+ }
+
+}