diff --git a/src/main/java/edu/hm/hafner/grading/CommentBuilder.java b/src/main/java/edu/hm/hafner/grading/CommentBuilder.java index 3e3e2a6c..e244d0ac 100644 --- a/src/main/java/edu/hm/hafner/grading/CommentBuilder.java +++ b/src/main/java/edu/hm/hafner/grading/CommentBuilder.java @@ -26,6 +26,9 @@ * @author Ullrich Hafner */ public abstract class CommentBuilder { + private int warningComments; + private int coverageComments; + /** * Describes the type of the comment. Is the comment for a warning, a missed line, a partially covered line, or a * survived mutation? @@ -101,14 +104,28 @@ protected abstract void createComment(CommentType commentType, String relativePa int columnStart, int columnEnd, String details, String markDownDetails); - private void createComment(final CommentType commentType, final String relativePath, + private void createCoverageComment(final CommentType commentType, final String relativePath, final int lineStart, final int lineEnd, final String message, final String title) { - createComment(commentType, relativePath, lineStart, lineEnd, message, title, + createCoverageComment(commentType, relativePath, lineStart, lineEnd, message, title, NO_COLUMN, NO_COLUMN, NO_ADDITIONAL_DETAILS, NO_ADDITIONAL_DETAILS); } + @SuppressWarnings("checkstyle:ParameterNumber") + private void createCoverageComment(final CommentType commentType, final String relativePath, + final int lineStart, final int lineEnd, + final String message, final String title, + final int columnStart, final int columnEnd, + final String details, final String markDownDetails) { + if (coverageComments < getMaxCoverageComments()) { + coverageComments++; + + createComment(commentType, relativePath, lineStart, lineEnd, message, title, columnStart, columnEnd, + details, markDownDetails); + } + } + private Set extractAdditionalSourcePaths(final List> scores) { return scores.stream() .map(Score::getConfiguration) @@ -128,9 +145,24 @@ private void createAnnotationForIssue(final Issue issue, var text = getDescription(issue); - createComment(CommentType.WARNING, relativePath, issue.getLineStart(), issue.getLineEnd(), - issue.getMessage(), issue.getOriginName() + ": " + issue.getType(), issue.getColumnStart(), - issue.getColumnEnd(), NO_ADDITIONAL_DETAILS, text); + createWarningComment(issue, relativePath, text); + } + + private void createWarningComment(final Issue issue, final String relativePath, final String text) { + if (warningComments < getMaxWarningComments()) { + warningComments++; + createComment(CommentType.WARNING, relativePath, issue.getLineStart(), issue.getLineEnd(), + issue.getMessage(), issue.getOriginName() + ": " + issue.getType(), issue.getColumnStart(), + issue.getColumnEnd(), NO_ADDITIONAL_DETAILS, text); + } + } + + protected int getMaxWarningComments() { + return Integer.MAX_VALUE; + } + + protected int getMaxCoverageComments() { + return Integer.MAX_VALUE; } private String getDescription(final Issue issue) { @@ -163,7 +195,7 @@ private void createAnnotationForMissedLineRange(final FileNode file, final LineR final Set sourcePaths) { var relativePath = createRelativeRepositoryPath(file.getRelativePath(), sourcePaths); - createComment(CommentType.NO_COVERAGE, + createCoverageComment(CommentType.NO_COVERAGE, relativePath, range.getStart(), range.getEnd(), getMissedLinesDescription(range), getMissedLinesMessage(range)); @@ -198,7 +230,7 @@ private void createAnnotationsForMissedBranches(final FileNode file, private void createAnnotationForMissedBranches(final FileNode file, final Entry branchCoverage, final Set sourcePaths) { - createComment(CommentType.PARTIAL_COVERAGE, + createCoverageComment(CommentType.PARTIAL_COVERAGE, createRelativeRepositoryPath(file.getRelativePath(), sourcePaths), branchCoverage.getKey(), branchCoverage.getKey(), createBranchMessage(branchCoverage.getKey(), branchCoverage.getValue()), "Partially covered line"); @@ -242,7 +274,7 @@ private void createAnnotationForSurvivedMutation(final FileNode file, final Entry> mutationsPerLine, final Set sourcePaths) { var mutationDetails = createMutationDetails(mutationsPerLine.getValue()); - createComment(CommentType.MUTATION_SURVIVED, + createCoverageComment(CommentType.MUTATION_SURVIVED, createRelativeRepositoryPath(file.getRelativePath(), sourcePaths), mutationsPerLine.getKey(), mutationsPerLine.getKey(), createMutationMessage(mutationsPerLine.getKey(), mutationsPerLine.getValue()), diff --git a/src/test/java/edu/hm/hafner/grading/AnalysisMarkdownTest.java b/src/test/java/edu/hm/hafner/grading/AnalysisMarkdownTest.java index c4ebcc98..3b5be392 100644 --- a/src/test/java/edu/hm/hafner/grading/AnalysisMarkdownTest.java +++ b/src/test/java/edu/hm/hafner/grading/AnalysisMarkdownTest.java @@ -169,7 +169,7 @@ void shouldShowNoImpactsWithTwoSubResults() { .doesNotContain("Impact"); } - private static Report createSampleReport() { + static Report createSampleReport() { return createReportWith("CheckStyle 1", Severity.ERROR, Severity.WARNING_HIGH, Severity.WARNING_HIGH, diff --git a/src/test/java/edu/hm/hafner/grading/CommentBuilderTest.java b/src/test/java/edu/hm/hafner/grading/CommentBuilderTest.java index 7e4a8f03..bd2827d6 100644 --- a/src/test/java/edu/hm/hafner/grading/CommentBuilderTest.java +++ b/src/test/java/edu/hm/hafner/grading/CommentBuilderTest.java @@ -5,6 +5,7 @@ import edu.hm.hafner.coverage.registry.ParserRegistry.CoverageParserType; import edu.hm.hafner.util.FilteredLog; +import static edu.hm.hafner.grading.AnalysisMarkdownTest.*; import static org.mockito.Mockito.*; class CommentBuilderTest { @@ -30,10 +31,8 @@ class CommentBuilderTest { """; @Test - void shouldRunComments() { - var aggregation = new AggregatedScore(COVERAGE_CONFIGURATION, new FilteredLog("Test")); - aggregation.gradeCoverage((tool, log) -> AggregatedScoreTest.readCoverageReport( - "mutations-dashboard.xml", tool, CoverageParserType.PIT)); + void shouldCreateCoverageComments() { + var aggregation = createCoverageAggregation(); CommentBuilder builder = spy(CommentBuilder.class); @@ -43,4 +42,75 @@ void shouldRunComments() { .createComment(any(), anyString(), anyInt(), anyInt(), anyString(), anyString(), anyInt(), anyInt(), anyString(), anyString()); } + + @Test + void shouldLimitCoverageComments() { + var aggregation = createCoverageAggregation(); + + CommentBuilder builder = spy(CommentBuilder.class); + when(builder.getMaxCoverageComments()).thenReturn(5); + + builder.createAnnotations(aggregation); + + verify(builder, times(5)) + .createComment(any(), anyString(), anyInt(), anyInt(), anyString(), anyString(), + anyInt(), anyInt(), anyString(), anyString()); + } + + @Test + void shouldCreateWarningComments() { + var aggregation = createWarningsAggregation(); + + CommentBuilder builder = spy(CommentBuilder.class); + + builder.createAnnotations(aggregation); + + verify(builder, times(10)) + .createComment(any(), anyString(), anyInt(), anyInt(), anyString(), anyString(), + anyInt(), anyInt(), anyString(), anyString()); + } + + @Test + void shouldLimitWarningComments() { + var aggregation = createWarningsAggregation(); + + CommentBuilder builder = spy(CommentBuilder.class); + when(builder.getMaxWarningComments()).thenReturn(5); + + builder.createAnnotations(aggregation); + + verify(builder, times(5)) + .createComment(any(), anyString(), anyInt(), anyInt(), anyString(), anyString(), + anyInt(), anyInt(), anyString(), anyString()); + } + + private AggregatedScore createWarningsAggregation() { + var aggregation = new AggregatedScore(""" + { + "analysis": [{ + "tools": [ + { + "id": "checkstyle", + "pattern": "target/checkstyle.xml" + } + ], + "name": "CheckStyle", + "errorImpact": -1, + "highImpact": -2, + "normalImpact": -3, + "lowImpact": -4, + "maxScore": 100 + }] + } + """, new FilteredLog("Test")); + aggregation.gradeAnalysis((tool, log) -> createSampleReport()); + return aggregation; + } + + private AggregatedScore createCoverageAggregation() { + var aggregation = new AggregatedScore(COVERAGE_CONFIGURATION, new FilteredLog("Test")); + aggregation.gradeCoverage((tool, log) -> AggregatedScoreTest.readCoverageReport( + "mutations-dashboard.xml", tool, CoverageParserType.PIT)); + return aggregation; + } }