From f20affd2aa956dca48e5a3b722646d4b7f953095 Mon Sep 17 00:00:00 2001
From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com>
Date: Tue, 26 Dec 2023 08:06:58 -0800
Subject: [PATCH 1/4] Coverage minima: Add integration tests to check it
---
.../test_coverage_minima/invoker.properties | 1 +
src/it/test_coverage_minima/module01/pom.xml | 16 +++++
.../src/main/scala/pkg01/HelloService1.scala | 12 ++++
.../test/scala/pkg01/HelloServiceTest.scala | 14 +++++
src/it/test_coverage_minima/module02/pom.xml | 16 +++++
.../src/main/scala/pkg01/HelloService1.scala | 12 ++++
.../src/main/scala/pkg02/HelloService1.scala | 12 ++++
.../test/scala/pkg01/HelloServiceTest.scala | 14 +++++
src/it/test_coverage_minima/module03/pom.xml | 36 +++++++++++
.../src/main/scala/pkg01/HelloService1.scala | 12 ++++
.../test/scala/pkg01/HelloServiceTest.scala | 14 +++++
src/it/test_coverage_minima/pom.xml | 63 +++++++++++++++++++
src/it/test_coverage_minima/validate.groovy | 43 +++++++++++++
13 files changed, 265 insertions(+)
create mode 100644 src/it/test_coverage_minima/invoker.properties
create mode 100644 src/it/test_coverage_minima/module01/pom.xml
create mode 100644 src/it/test_coverage_minima/module01/src/main/scala/pkg01/HelloService1.scala
create mode 100644 src/it/test_coverage_minima/module01/src/test/scala/pkg01/HelloServiceTest.scala
create mode 100644 src/it/test_coverage_minima/module02/pom.xml
create mode 100644 src/it/test_coverage_minima/module02/src/main/scala/pkg01/HelloService1.scala
create mode 100644 src/it/test_coverage_minima/module02/src/main/scala/pkg02/HelloService1.scala
create mode 100644 src/it/test_coverage_minima/module02/src/test/scala/pkg01/HelloServiceTest.scala
create mode 100644 src/it/test_coverage_minima/module03/pom.xml
create mode 100644 src/it/test_coverage_minima/module03/src/main/scala/pkg01/HelloService1.scala
create mode 100644 src/it/test_coverage_minima/module03/src/test/scala/pkg01/HelloServiceTest.scala
create mode 100644 src/it/test_coverage_minima/pom.xml
create mode 100644 src/it/test_coverage_minima/validate.groovy
diff --git a/src/it/test_coverage_minima/invoker.properties b/src/it/test_coverage_minima/invoker.properties
new file mode 100644
index 00000000..f4f2d3bc
--- /dev/null
+++ b/src/it/test_coverage_minima/invoker.properties
@@ -0,0 +1 @@
+invoker.goals=clean scoverage:check site -e -ntp
diff --git a/src/it/test_coverage_minima/module01/pom.xml b/src/it/test_coverage_minima/module01/pom.xml
new file mode 100644
index 00000000..eb09e4a1
--- /dev/null
+++ b/src/it/test_coverage_minima/module01/pom.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ it.scoverage-maven-plugin
+ test_coverage_minima
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ module01
+ Test SCoverage Coverage Minima : Module 1
+
+
diff --git a/src/it/test_coverage_minima/module01/src/main/scala/pkg01/HelloService1.scala b/src/it/test_coverage_minima/module01/src/main/scala/pkg01/HelloService1.scala
new file mode 100644
index 00000000..9d7c7380
--- /dev/null
+++ b/src/it/test_coverage_minima/module01/src/main/scala/pkg01/HelloService1.scala
@@ -0,0 +1,12 @@
+package pkg01
+
+class HelloService1
+{
+ def hello =
+ {
+ "Hello from module 1"
+ }
+
+}
+
+object HelloService1 extends HelloService1
diff --git a/src/it/test_coverage_minima/module01/src/test/scala/pkg01/HelloServiceTest.scala b/src/it/test_coverage_minima/module01/src/test/scala/pkg01/HelloServiceTest.scala
new file mode 100644
index 00000000..9cac7025
--- /dev/null
+++ b/src/it/test_coverage_minima/module01/src/test/scala/pkg01/HelloServiceTest.scala
@@ -0,0 +1,14 @@
+package pkg01
+
+import org.junit.Test;
+import org.junit.Assert.assertEquals
+
+class HelloServiceTest
+{
+ @Test
+ def test1()
+ {
+ assertEquals("Hello from module 1", HelloService1.hello)
+ }
+
+}
diff --git a/src/it/test_coverage_minima/module02/pom.xml b/src/it/test_coverage_minima/module02/pom.xml
new file mode 100644
index 00000000..9875282b
--- /dev/null
+++ b/src/it/test_coverage_minima/module02/pom.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ it.scoverage-maven-plugin
+ test_coverage_minima
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ module02
+ Test SCoverage Coverage Minima : Module 2
+
+
diff --git a/src/it/test_coverage_minima/module02/src/main/scala/pkg01/HelloService1.scala b/src/it/test_coverage_minima/module02/src/main/scala/pkg01/HelloService1.scala
new file mode 100644
index 00000000..1d3c8ca0
--- /dev/null
+++ b/src/it/test_coverage_minima/module02/src/main/scala/pkg01/HelloService1.scala
@@ -0,0 +1,12 @@
+package pkg01
+
+class HelloService1
+{
+ def hello =
+ {
+ "Hello from module 2"
+ }
+
+}
+
+object HelloService1 extends HelloService1
diff --git a/src/it/test_coverage_minima/module02/src/main/scala/pkg02/HelloService1.scala b/src/it/test_coverage_minima/module02/src/main/scala/pkg02/HelloService1.scala
new file mode 100644
index 00000000..b5edc85b
--- /dev/null
+++ b/src/it/test_coverage_minima/module02/src/main/scala/pkg02/HelloService1.scala
@@ -0,0 +1,12 @@
+package pkg02
+
+class HelloService1
+{
+ def hello =
+ {
+ "Hello from module 2"
+ }
+
+}
+
+object HelloService1 extends HelloService1
diff --git a/src/it/test_coverage_minima/module02/src/test/scala/pkg01/HelloServiceTest.scala b/src/it/test_coverage_minima/module02/src/test/scala/pkg01/HelloServiceTest.scala
new file mode 100644
index 00000000..8dacc428
--- /dev/null
+++ b/src/it/test_coverage_minima/module02/src/test/scala/pkg01/HelloServiceTest.scala
@@ -0,0 +1,14 @@
+package pkg01
+
+import org.junit.Test;
+import org.junit.Assert.assertEquals
+
+class HelloServiceTest
+{
+ @Test
+ def test1()
+ {
+ assertEquals("Hello from module 2", HelloService1.hello)
+ }
+
+}
diff --git a/src/it/test_coverage_minima/module03/pom.xml b/src/it/test_coverage_minima/module03/pom.xml
new file mode 100644
index 00000000..d8987f45
--- /dev/null
+++ b/src/it/test_coverage_minima/module03/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+ it.scoverage-maven-plugin
+ test_coverage_minima
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ 4.0.0
+ module03
+ Test SCoverage Coverage Minima : Module 3
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+
+ true
+ 100
+
+
+
+
+ check
+
+
+
+
+
+
+
+
diff --git a/src/it/test_coverage_minima/module03/src/main/scala/pkg01/HelloService1.scala b/src/it/test_coverage_minima/module03/src/main/scala/pkg01/HelloService1.scala
new file mode 100644
index 00000000..478fbada
--- /dev/null
+++ b/src/it/test_coverage_minima/module03/src/main/scala/pkg01/HelloService1.scala
@@ -0,0 +1,12 @@
+package pkg01
+
+class HelloService1
+{
+ def hello =
+ {
+ "Hello from module 3"
+ }
+
+}
+
+object HelloService1 extends HelloService1
diff --git a/src/it/test_coverage_minima/module03/src/test/scala/pkg01/HelloServiceTest.scala b/src/it/test_coverage_minima/module03/src/test/scala/pkg01/HelloServiceTest.scala
new file mode 100644
index 00000000..ffe06705
--- /dev/null
+++ b/src/it/test_coverage_minima/module03/src/test/scala/pkg01/HelloServiceTest.scala
@@ -0,0 +1,14 @@
+package pkg01
+
+import org.junit.Test;
+import org.junit.Assert.assertEquals
+
+class HelloServiceTest
+{
+ @Test
+ def test1()
+ {
+ assertEquals("Hello from module 3", HelloService1.hello)
+ }
+
+}
diff --git a/src/it/test_coverage_minima/pom.xml b/src/it/test_coverage_minima/pom.xml
new file mode 100644
index 00000000..e232ac02
--- /dev/null
+++ b/src/it/test_coverage_minima/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+ 4.0.0
+
+
+ it.scoverage-maven-plugin
+ integration_tests_parent
+ 1.0-SNAPSHOT
+ ../integration_tests_parent/pom.xml
+
+
+ test_coverage_minima
+ 1.0-SNAPSHOT
+ pom
+ Test Scoverage coverage minima
+ Test Scoverage coverage minima
+
+
+ 2.13
+ 12
+
+
+
+ module01
+ module02
+ module03
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ @project.groupId@
+ @project.artifactId@
+
+ true
+ 95
+ false
+
+
+
+
+ check
+
+
+
+
+
+
+
diff --git a/src/it/test_coverage_minima/validate.groovy b/src/it/test_coverage_minima/validate.groovy
new file mode 100644
index 00000000..470fb21b
--- /dev/null
+++ b/src/it/test_coverage_minima/validate.groovy
@@ -0,0 +1,43 @@
+def checkModule(logText, module, coverageLog) {
+ assert new File(basedir, module + "/target/scoverage.xml").exists()
+ assert new File(basedir, module + "/target/site/scoverage/index.html").exists()
+ def entry = logText.find {
+ it.startsWith("scoverage") &&
+ it.contains(":check (default-cli) @ " + module + " ---\n")
+ }
+ assert entry != null
+ assert entry.endsWith(" @ " + module + " ---" + coverageLog.replaceAll("\r\n", "\n") + "[INFO] ")
+}
+
+try {
+ // check coverage minima
+ def logText = (new File(basedir, "build.log")).text.replaceAll("\r\n", "\n").split(/\n\[INFO\] \-\-\- /)
+
+ checkModule(logText, "module01",
+ """
+ |[INFO] Statement coverage.: 100.00%
+ |[INFO] Branch coverage....: 100.00%
+ |[INFO] Coverage is above minimum [100.00% >= 95.00%]
+ |""".stripMargin()
+ )
+ checkModule(logText, "module02",
+ """
+ |[INFO] Statement coverage.: 50.00%
+ |[INFO] Branch coverage....: 100.00%
+ |[ERROR] Coverage is below minimum [50.00% < 95.00%]
+ |""".stripMargin()
+ )
+ checkModule(logText, "module03",
+ """
+ |[INFO] Statement coverage.: 100.00%
+ |[INFO] Branch coverage....: 100.00%
+ |[INFO] 100% Coverage !
+ |""".stripMargin()
+ )
+
+ return true
+
+} catch (Throwable e) {
+ e.printStackTrace()
+ return false
+}
From 86f51a37871e758c14b0226333d060b6c9a80610 Mon Sep 17 00:00:00 2001
From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com>
Date: Sun, 31 Dec 2023 10:17:04 -0800
Subject: [PATCH 2/4] Coverage minima: report 100% coverage if min < 100
Previously, it was only reported as such for min = 100.
---
src/it/test_coverage_minima/validate.groovy | 2 +-
src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/it/test_coverage_minima/validate.groovy b/src/it/test_coverage_minima/validate.groovy
index 470fb21b..3542af5b 100644
--- a/src/it/test_coverage_minima/validate.groovy
+++ b/src/it/test_coverage_minima/validate.groovy
@@ -17,7 +17,7 @@ try {
"""
|[INFO] Statement coverage.: 100.00%
|[INFO] Branch coverage....: 100.00%
- |[INFO] Coverage is above minimum [100.00% >= 95.00%]
+ |[INFO] 100% Coverage !
|""".stripMargin()
)
checkModule(logText, "module02",
diff --git a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
index 42d19af2..bf591fae 100644
--- a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
+++ b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
@@ -175,7 +175,7 @@ public void execute() throws MojoFailureException
if ( minimumCoverage > 0.0 )
{
String minimumCoverageFormatted = scoverage.domain.DoubleFormat.twoFractionDigits( minimumCoverage );
- if ( is100( minimumCoverage ) && is100( coverage.statementCoveragePercent() ) )
+ if ( is100( coverage.statementCoveragePercent() ) )
{
getLog().info( "100% Coverage !" );
}
@@ -201,7 +201,7 @@ else if ( coverage.statementCoveragePercent() < minimumCoverage )
// Private utility methods
- private boolean is100( Double d )
+ private static boolean is100( Double d )
{
return Math.abs( 100 - d ) <= 0.00001d;
}
From 6f2b2171196f1500811ac7b95393a3b8edafc420 Mon Sep 17 00:00:00 2001
From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com>
Date: Sun, 31 Dec 2023 10:17:08 -0800
Subject: [PATCH 3/4] Coverage minima: add parameter for branch minima
Also, extract a coverage computation and logging method.
---
README.md | 3 +-
src/it/test_coverage_minima/module03/pom.xml | 1 +
src/it/test_coverage_minima/pom.xml | 1 +
src/it/test_coverage_minima/validate.groovy | 15 +--
.../scoverage/plugin/SCoverageCheckMojo.java | 103 ++++++++++++++----
5 files changed, 89 insertions(+), 34 deletions(-)
diff --git a/README.md b/README.md
index 25394433..e5921d66 100644
--- a/README.md
+++ b/README.md
@@ -335,7 +335,8 @@ Read [SBT SCoverage Plugin documentation](https://github.com/scoverage/sbt-scove
scoverage-maven-plugin
${scoverage.plugin.version}
- 80
+ 95
+ 90
true
diff --git a/src/it/test_coverage_minima/module03/pom.xml b/src/it/test_coverage_minima/module03/pom.xml
index d8987f45..770005fb 100644
--- a/src/it/test_coverage_minima/module03/pom.xml
+++ b/src/it/test_coverage_minima/module03/pom.xml
@@ -21,6 +21,7 @@
true
100
+ 100
diff --git a/src/it/test_coverage_minima/pom.xml b/src/it/test_coverage_minima/pom.xml
index e232ac02..a68c2d67 100644
--- a/src/it/test_coverage_minima/pom.xml
+++ b/src/it/test_coverage_minima/pom.xml
@@ -48,6 +48,7 @@
true
95
+ 90
false
diff --git a/src/it/test_coverage_minima/validate.groovy b/src/it/test_coverage_minima/validate.groovy
index 3542af5b..9e132b80 100644
--- a/src/it/test_coverage_minima/validate.groovy
+++ b/src/it/test_coverage_minima/validate.groovy
@@ -15,23 +15,20 @@ try {
checkModule(logText, "module01",
"""
- |[INFO] Statement coverage.: 100.00%
- |[INFO] Branch coverage....: 100.00%
- |[INFO] 100% Coverage !
+ |[INFO] Coverage is 100%: Statement:Total!
+ |[INFO] Coverage is 100%: Branch:Total!
|""".stripMargin()
)
checkModule(logText, "module02",
"""
- |[INFO] Statement coverage.: 50.00%
- |[INFO] Branch coverage....: 100.00%
- |[ERROR] Coverage is below minimum [50.00% < 95.00%]
+ |[ERROR] Coverage is below minimum [50.00% < 95.00%]: Statement:Total
+ |[INFO] Coverage is 100%: Branch:Total!
|""".stripMargin()
)
checkModule(logText, "module03",
"""
- |[INFO] Statement coverage.: 100.00%
- |[INFO] Branch coverage....: 100.00%
- |[INFO] 100% Coverage !
+ |[INFO] Coverage is 100%: Statement:Total!
+ |[INFO] Coverage is 100%: Branch:Total!
|""".stripMargin()
)
diff --git a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
index bf591fae..5c2eca75 100644
--- a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
+++ b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
@@ -23,6 +23,7 @@
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
@@ -33,6 +34,8 @@
import scala.jdk.javaapi.CollectionConverters;
import scoverage.domain.Coverage;
+import scoverage.domain.CoverageMetrics;
+import scoverage.domain.DoubleFormat;
import scoverage.reporter.IOUtils;
import scoverage.serialize.Serializer;
@@ -70,7 +73,7 @@ public class SCoverageCheckMojo
private File dataDirectory;
/**
- * Required minimum coverage.
+ * Required minimum total statement coverage.
*
*
* See https://github.com/scoverage/sbt-scoverage#minimum-coverage for additional documentation.
@@ -81,6 +84,18 @@ public class SCoverageCheckMojo
@Parameter( property = "scoverage.minimumCoverage", defaultValue = "0" )
private Double minimumCoverage;
+ /**
+ * Required minimum total branch coverage.
+ *
+ *
+ * See https://github.com/scoverage/sbt-scoverage#minimum-coverage for additional documentation.
+ *
+ *
+ * @since 2.0.1
+ */
+ @Parameter( property = "scoverage.minimumCoverageBranchTotal", defaultValue = "0" )
+ private Double minimumCoverageBranchTotal;
+
/**
* Fail the build if minimum coverage was not reached.
*
@@ -168,31 +183,15 @@ public void execute() throws MojoFailureException
int invokedBranchesCount = coverage.invokedBranchesCount();
int invokedStatementCount = coverage.invokedStatementCount();
- getLog().info( String.format( "Statement coverage.: %s%%", coverage.statementCoverageFormatted() ) );
- getLog().info( String.format( "Branch coverage....: %s%%", coverage.branchCoverageFormatted() ) );
getLog().debug( String.format( "invokedBranchesCount:%d / branchCount:%d, invokedStatementCount:%d / statementCount:%d",
invokedBranchesCount, branchCount, invokedStatementCount, statementCount ) );
- if ( minimumCoverage > 0.0 )
+
+ boolean ok = checkCoverage( getLog(), "Total", coverage,
+ minimumCoverage, minimumCoverageBranchTotal, true );
+
+ if ( !ok && failOnMinimumCoverage )
{
- String minimumCoverageFormatted = scoverage.domain.DoubleFormat.twoFractionDigits( minimumCoverage );
- if ( is100( coverage.statementCoveragePercent() ) )
- {
- getLog().info( "100% Coverage !" );
- }
- else if ( coverage.statementCoveragePercent() < minimumCoverage )
- {
- getLog().error( String.format( "Coverage is below minimum [%s%% < %s%%]",
- coverage.statementCoverageFormatted(), minimumCoverageFormatted ) );
- if ( failOnMinimumCoverage )
- {
- throw new MojoFailureException( "Coverage minimum was not reached" );
- }
- }
- else
- {
- getLog().info( String.format( "Coverage is above minimum [%s%% >= %s%%]",
- coverage.statementCoverageFormatted(), minimumCoverageFormatted ) );
- }
+ throw new MojoFailureException( "Coverage minimum was not reached" );
}
long te = System.currentTimeMillis();
@@ -206,4 +205,60 @@ private static boolean is100( Double d )
return Math.abs( 100 - d ) <= 0.00001d;
}
-}
\ No newline at end of file
+ private static boolean checkCoverage( Log logger, String metric, CoverageMetrics metrics,
+ double minStmt, double minBranch, boolean logSuccessInfo )
+ {
+ boolean stmt = checkCoverage( logger, "Statement:" + metric,
+ minStmt, metrics.statementCoveragePercent(), logSuccessInfo );
+ boolean branch = checkCoverage( logger, "Branch:" + metric,
+ minBranch, metrics.branchCoveragePercent(), logSuccessInfo );
+ return stmt && branch;
+ }
+
+ private static boolean checkCoverage( Log logger, String metric,
+ double minimum, double actual, boolean logSuccessInfo )
+ {
+ if ( minimum <= 0 )
+ {
+ return true;
+ }
+
+ if ( is100( actual ) )
+ {
+ logSuccess( logger, String.format( "Coverage is 100%%: %s!", metric ), logSuccessInfo );
+ return true;
+ }
+
+ String minimumFormatted = DoubleFormat.twoFractionDigits( minimum );
+ String actualFormatted = DoubleFormat.twoFractionDigits( actual );
+ boolean ok = minimum <= actual;
+
+ if ( ok )
+ {
+ String message = String.format( "Coverage is above minimum [%s%% >= %s%%]: %s",
+ actualFormatted, minimumFormatted, metric );
+ logSuccess( logger, message, logSuccessInfo );
+ }
+ else
+ {
+ String message = String.format( "Coverage is below minimum [%s%% < %s%%]: %s",
+ actualFormatted, minimumFormatted, metric );
+ logger.error( message );
+ }
+
+ return ok;
+ }
+
+ private static void logSuccess( Log logger, String message, boolean logSuccessInfo )
+ {
+ if ( logSuccessInfo )
+ {
+ logger.info( message );
+ }
+ else
+ {
+ logger.debug( message );
+ }
+ }
+
+}
From 6e1046963b6d70496e8a4dee1c6e42d405cb1b10 Mon Sep 17 00:00:00 2001
From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com>
Date: Sun, 31 Dec 2023 10:21:24 -0800
Subject: [PATCH 4/4] Coverage minima: add more fine-grained control
Along with existing overall coverage, add parameters for statement and
branch minima at the package and file level.
---
README.md | 4 +
src/it/test_coverage_minima/module03/pom.xml | 4 +
src/it/test_coverage_minima/pom.xml | 4 +
src/it/test_coverage_minima/validate.groovy | 4 +
.../scoverage/plugin/SCoverageCheckMojo.java | 77 +++++++++++++++++++
5 files changed, 93 insertions(+)
diff --git a/README.md b/README.md
index e5921d66..65daaa6d 100644
--- a/README.md
+++ b/README.md
@@ -337,6 +337,10 @@ Read [SBT SCoverage Plugin documentation](https://github.com/scoverage/sbt-scove
95
90
+ 90
+ 85
+ 85
+ 80
true
diff --git a/src/it/test_coverage_minima/module03/pom.xml b/src/it/test_coverage_minima/module03/pom.xml
index 770005fb..a6d61023 100644
--- a/src/it/test_coverage_minima/module03/pom.xml
+++ b/src/it/test_coverage_minima/module03/pom.xml
@@ -22,6 +22,10 @@
true
100
100
+ 100
+ 100
+ 100
+ 100
diff --git a/src/it/test_coverage_minima/pom.xml b/src/it/test_coverage_minima/pom.xml
index a68c2d67..0d6ffc03 100644
--- a/src/it/test_coverage_minima/pom.xml
+++ b/src/it/test_coverage_minima/pom.xml
@@ -49,6 +49,10 @@
true
95
90
+ 90
+ 85
+ 85
+ 80
false
diff --git a/src/it/test_coverage_minima/validate.groovy b/src/it/test_coverage_minima/validate.groovy
index 9e132b80..4de80432 100644
--- a/src/it/test_coverage_minima/validate.groovy
+++ b/src/it/test_coverage_minima/validate.groovy
@@ -23,6 +23,10 @@ try {
"""
|[ERROR] Coverage is below minimum [50.00% < 95.00%]: Statement:Total
|[INFO] Coverage is 100%: Branch:Total!
+ |[ERROR] Coverage is below minimum [0.00% < 90.00%]: Statement:Package:pkg02
+ |[ERROR] Coverage is below minimum [0.00% < 85.00%]: Branch:Package:pkg02
+ |[ERROR] Coverage is below minimum [0.00% < 85.00%]: Statement:File:HelloService1.scala
+ |[ERROR] Coverage is below minimum [0.00% < 80.00%]: Branch:File:HelloService1.scala
|""".stripMargin()
)
checkModule(logText, "module03",
diff --git a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
index 5c2eca75..18940379 100644
--- a/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
+++ b/src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java
@@ -20,6 +20,8 @@
import java.io.File;
import java.util.Arrays;
import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
@@ -36,6 +38,8 @@
import scoverage.domain.Coverage;
import scoverage.domain.CoverageMetrics;
import scoverage.domain.DoubleFormat;
+import scoverage.domain.MeasuredFile;
+import scoverage.domain.MeasuredPackage;
import scoverage.reporter.IOUtils;
import scoverage.serialize.Serializer;
@@ -96,6 +100,54 @@ public class SCoverageCheckMojo
@Parameter( property = "scoverage.minimumCoverageBranchTotal", defaultValue = "0" )
private Double minimumCoverageBranchTotal;
+ /**
+ * Required minimum per-package statement coverage.
+ *
+ *
+ * See https://github.com/scoverage/sbt-scoverage#minimum-coverage for additional documentation.
+ *
+ *
+ * @since 2.0.1
+ */
+ @Parameter( property = "scoverage.minimumCoverageStmtPerPackage", defaultValue = "0" )
+ private Double minimumCoverageStmtPerPackage;
+
+ /**
+ * Required minimum per-package branch coverage.
+ *
+ *
+ * See https://github.com/scoverage/sbt-scoverage#minimum-coverage for additional documentation.
+ *
+ *
+ * @since 2.0.1
+ */
+ @Parameter( property = "scoverage.minimumCoverageBranchPerPackage", defaultValue = "0" )
+ private Double minimumCoverageBranchPerPackage;
+
+ /**
+ * Required minimum per-file statement coverage.
+ *
+ *
+ * See https://github.com/scoverage/sbt-scoverage#minimum-coverage for additional documentation.
+ *
+ *
+ * @since 2.0.1
+ */
+ @Parameter( property = "scoverage.minimumCoverageStmtPerFile", defaultValue = "0" )
+ private Double minimumCoverageStmtPerFile;
+
+ /**
+ * Required minimum per-file branch coverage.
+ *
+ *
+ * See https://github.com/scoverage/sbt-scoverage#minimum-coverage for additional documentation.
+ *
+ *
+ * @since 2.0.1
+ */
+ @Parameter( property = "scoverage.minimumCoverageBranchPerFile", defaultValue = "0" )
+ private Double minimumCoverageBranchPerFile;
+
/**
* Fail the build if minimum coverage was not reached.
*
@@ -188,6 +240,10 @@ public void execute() throws MojoFailureException
boolean ok = checkCoverage( getLog(), "Total", coverage,
minimumCoverage, minimumCoverageBranchTotal, true );
+ ok = checkCoverage( getLog(), "Package:", coverage.packages(), MeasuredPackage::name,
+ minimumCoverageStmtPerPackage, minimumCoverageBranchPerPackage ) && ok;
+ ok = checkCoverage( getLog(), "File:", coverage.files(), MeasuredFile::filename,
+ minimumCoverageStmtPerFile, minimumCoverageBranchPerFile ) && ok;
if ( !ok && failOnMinimumCoverage )
{
@@ -205,6 +261,17 @@ private static boolean is100( Double d )
return Math.abs( 100 - d ) <= 0.00001d;
}
+ private static
+ boolean checkCoverage( Log logger, String metricPrefix,
+ scala.collection.Iterable< T > metrics,
+ Function< T, String > toName,
+ double minStmt, double minBranch )
+ {
+ return minStmt <= 0 && minBranch <= 0 || checkAll(metrics, cov ->
+ checkCoverage(logger, metricPrefix + toName.apply(cov), cov, minStmt, minBranch, false)
+ );
+ }
+
private static boolean checkCoverage( Log logger, String metric, CoverageMetrics metrics,
double minStmt, double minBranch, boolean logSuccessInfo )
{
@@ -261,4 +328,14 @@ private static void logSuccess( Log logger, String message, boolean logSuccessIn
}
}
+ private static boolean checkAll( scala.collection.Iterable iterable, Predicate predicate )
+ {
+ boolean ok = true;
+ for ( T elem : CollectionConverters.asJava( iterable ) )
+ {
+ ok = predicate.test( elem ) && ok;
+ }
+ return ok;
+ }
+
}