diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilder.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilder.java index 1e2b1ac7..839fe495 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilder.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilder.java @@ -32,10 +32,15 @@ protected Map computeSeries(final CoverageStatistics statistics) add(statistics, Metric.BRANCH, BRANCH_COVERAGE, series); add(statistics, Metric.MUTATION, MUTATION_COVERAGE, series); add(statistics, Metric.TEST_STRENGTH, TEST_STRENGTH, series); - add(statistics, Metric.MCDC_PAIR, MCDC_PAIR_COVERAGE, series); - add(statistics, Metric.FUNCTION_CALL, FUNCTION_CALL_COVERAGE, series); - add(statistics, Metric.METHOD, METHOD_COVERAGE, series); - + add(statistics, Metric.MCDC_PAIR, MCDC_PAIR_COVERAGE, series); + add(statistics, Metric.FUNCTION_CALL, FUNCTION_CALL_COVERAGE, series); + + if (statistics.containsValue(Baseline.PROJECT, Metric.MCDC_PAIR) + || statistics.containsValue(Baseline.PROJECT, Metric.FUNCTION_CALL)) { + // Method coverage is only relevant if MC/DC pair or function call coverage is available + add(statistics, Metric.METHOD, METHOD_COVERAGE, series); + } + return series; } diff --git a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java index ab9ab534..4d2ba705 100644 --- a/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java +++ b/plugin/src/main/java/io/jenkins/plugins/coverage/metrics/charts/CoverageTrendChart.java @@ -23,26 +23,6 @@ * @see JacksonFacade */ public class CoverageTrendChart { - /* Line Mode used to indicate whether is should be a filled line chart or line chart */ - private static FilledMode lineMode; - - /** - * Sets the line mode for the trend chart. - * - * @param dataSet - * - */ - private void setLineMode(final LinesDataSet dataSet) { - // If the dataset contains MCDC or Function Call Coverage - if (dataSet.containsSeries(CoverageSeriesBuilder.MCDC_PAIR_COVERAGE) - || dataSet.containsSeries(CoverageSeriesBuilder.FUNCTION_CALL_COVERAGE)) { - lineMode = FilledMode.LINES; - } - else { - lineMode = FilledMode.FILLED; - } - } - /** * Creates the chart for the specified results. * @@ -58,13 +38,13 @@ public LinesChartModel create(final Iterable> re final ChartModelConfiguration configuration) { CoverageSeriesBuilder builder = new CoverageSeriesBuilder(); LinesDataSet dataSet = builder.createDataSet(configuration, results); - - setLineMode(dataSet); + + var filledMode = computeFilledMode(dataSet); LinesChartModel model = new LinesChartModel(dataSet); if (dataSet.isNotEmpty()) { LineSeries lineSeries = new LineSeries(Messages.Metric_LINE(), - JenkinsPalette.GREEN.normal(), StackedMode.SEPARATE_LINES, lineMode, + JenkinsPalette.GREEN.normal(), StackedMode.SEPARATE_LINES, filledMode, dataSet.getSeries(CoverageSeriesBuilder.LINE_COVERAGE)); model.addSeries(lineSeries); model.useContinuousRangeAxis(); @@ -72,28 +52,44 @@ public LinesChartModel create(final Iterable> re model.setRangeMin(dataSet.getMinimumValue()); addSeries(dataSet, model, Messages.Metric_BRANCH(), CoverageSeriesBuilder.BRANCH_COVERAGE, - JenkinsPalette.GREEN.dark()); + JenkinsPalette.GREEN.dark(), filledMode); addSeries(dataSet, model, Messages.Metric_MUTATION(), CoverageSeriesBuilder.MUTATION_COVERAGE, - JenkinsPalette.GREEN.dark()); + JenkinsPalette.GREEN.dark(), filledMode); addSeries(dataSet, model, Messages.Metric_TEST_STRENGTH(), CoverageSeriesBuilder.TEST_STRENGTH, - JenkinsPalette.GREEN.light()); + JenkinsPalette.GREEN.light(), filledMode); addSeries(dataSet, model, Messages.Metric_MCDC_PAIR(), CoverageSeriesBuilder.MCDC_PAIR_COVERAGE, - JenkinsPalette.RED.light()); + JenkinsPalette.RED.light(), filledMode); addSeries(dataSet, model, Messages.Metric_METHOD(), CoverageSeriesBuilder.METHOD_COVERAGE, - JenkinsPalette.RED.normal()); + JenkinsPalette.RED.normal(), filledMode); addSeries(dataSet, model, Messages.Metric_FUNCTION_CALL(), CoverageSeriesBuilder.FUNCTION_CALL_COVERAGE, - JenkinsPalette.RED.dark()); + JenkinsPalette.RED.dark(), filledMode); } return model; } - private static void addSeries(final LinesDataSet dataSet, final LinesChartModel model, - final String name, final String seriesId, final String color) { + /** + * Returns the filled mode based on the contained coverage values. If the dataset contains MCDC or Function Call + * coverage, then the filled mode is set to LINES, otherwise FILLED. + * + * @param dataSet + * the dataset to check + * + * @return the filled mode + */ + private FilledMode computeFilledMode(final LinesDataSet dataSet) { + if (dataSet.containsSeries(CoverageSeriesBuilder.MCDC_PAIR_COVERAGE) + || dataSet.containsSeries(CoverageSeriesBuilder.FUNCTION_CALL_COVERAGE)) { + return FilledMode.LINES; + } + return FilledMode.FILLED; + } + + private void addSeries(final LinesDataSet dataSet, final LinesChartModel model, + final String name, final String seriesId, final String color, final FilledMode filledMode) { if (dataSet.containsSeries(seriesId)) { LineSeries branchSeries = new LineSeries(name, - color, StackedMode.SEPARATE_LINES, lineMode, - dataSet.getSeries(seriesId)); + color, StackedMode.SEPARATE_LINES, filledMode, dataSet.getSeries(seriesId)); model.addSeries(branchSeries); } diff --git a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilderTest.java b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilderTest.java index 99e41435..bf10edd5 100644 --- a/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilderTest.java +++ b/plugin/src/test/java/io/jenkins/plugins/coverage/metrics/charts/CoverageSeriesBuilderTest.java @@ -5,6 +5,8 @@ import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import edu.hm.hafner.coverage.Coverage; import edu.hm.hafner.coverage.Coverage.CoverageBuilder; @@ -61,11 +63,48 @@ void shouldCreateChart() { verifySeriesDetails(branchCoverage); } + @Test + void shouldCreateStackedChartByDefault() { + CoverageTrendChart trendChart = new CoverageTrendChart(); + + BuildResult smallLineCoverage = createResult(1, + new CoverageBuilder().withMetric(Metric.LINE).withCovered(1).withMissed(1).build(), + new CoverageBuilder().withMetric(Metric.BRANCH).withCovered(3).withMissed(1).build()); + + LinesChartModel lineCoverage = trendChart.create(Collections.singletonList(smallLineCoverage), + createConfiguration()); + assertThat(lineCoverage.getBuildNumbers()).containsExactly(1); + assertThat(lineCoverage.getSeries()).hasSize(2).allSatisfy( + series -> assertThat(series.getAreaStyle()).isNotNull() + ); + assertThat(lineCoverage.getRangeMax()).isEqualTo(100.0); + assertThat(lineCoverage.getRangeMin()).isEqualTo(50.0); + } + + @ParameterizedTest @EnumSource(value = Metric.class, names = {"MCDC_PAIR", "FUNCTION_CALL"}) + void shouldCreateLineChartForVectorCoverage(final Metric vector) { + CoverageTrendChart trendChart = new CoverageTrendChart(); + + BuildResult smallLineCoverage = createResult(1, + new CoverageBuilder().withMetric(Metric.LINE).withCovered(1).withMissed(1).build(), + new CoverageBuilder().withMetric(Metric.BRANCH).withCovered(2).withMissed(1).build(), + new CoverageBuilder().withMetric(vector).withCovered(1).withMissed(2).build()); + + LinesChartModel lineCoverage = trendChart.create(Collections.singletonList(smallLineCoverage), + createConfiguration()); + assertThat(lineCoverage.getBuildNumbers()).containsExactly(1); + assertThat(lineCoverage.getSeries()).hasSize(3).allSatisfy( + series -> assertThat(series.getAreaStyle()).isNull() + ); + assertThat(lineCoverage.getRangeMax()).isEqualTo(100.0); + assertThat(lineCoverage.getRangeMin()).isEqualTo(33.33); + } + @VisibleForTesting private BuildResult createResult(final int buildNumber, - final Coverage lineCoverage, final Coverage branchCoverage) { + final Coverage... coverages) { var statistics = new CoverageStatistics( - List.of(lineCoverage, branchCoverage), Collections.emptyNavigableMap(), + List.of(coverages), Collections.emptyNavigableMap(), Collections.emptyList(), Collections.emptyNavigableMap(), Collections.emptyList(), Collections.emptyNavigableMap()); Build build = new Build(buildNumber);