Skip to content

Commit 47849fd

Browse files
Albert MeltzerAlbert Meltzer
Albert Meltzer
authored and
Albert Meltzer
committed
Coverage minima: add more fine-grained control
Along with existing statement minimum, add branch minimum. Also, include this pair of control at the package and file level.
1 parent bade98e commit 47849fd

File tree

2 files changed

+115
-24
lines changed

2 files changed

+115
-24
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,12 @@ Read [SBT SCoverage Plugin documentation](https://github.com/scoverage/sbt-scove
333333
<artifactId>scoverage-maven-plugin</artifactId>
334334
<version>${scoverage.plugin.version}</version>
335335
<configuration>
336-
<minimumCoverage>80</minimumCoverage>
336+
<minimumCoverage>95</minimumCoverage>
337+
<minimumCoverageBranchTotal>90</minimumCoverageBranchTotal>
338+
<minimumCoverageStmtPerPackage>90</minimumCoverageStmtPerPackage>
339+
<minimumCoverageBranchPerPackage>85</minimumCoverageBranchPerPackage>
340+
<minimumCoverageStmtPerFile>85</minimumCoverageStmtPerFile>
341+
<minimumCoverageBranchPerFile>80</minimumCoverageBranchPerFile>
337342
<failOnMinimumCoverage>true</failOnMinimumCoverage>
338343
</configuration>
339344
<executions>

src/main/java/org/scoverage/plugin/SCoverageCheckMojo.java

Lines changed: 109 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323

2424
import org.apache.maven.plugin.AbstractMojo;
2525
import org.apache.maven.plugin.MojoFailureException;
26+
import org.apache.maven.plugin.logging.Log;
2627
import org.apache.maven.plugins.annotations.Execute;
2728
import org.apache.maven.plugins.annotations.LifecyclePhase;
2829
import org.apache.maven.plugins.annotations.Mojo;
2930
import org.apache.maven.plugins.annotations.Parameter;
3031
import org.apache.maven.project.MavenProject;
3132

33+
import scala.collection.JavaConversions;
3234
import scala.collection.JavaConverters;
3335

3436
import scoverage.Coverage;
@@ -69,7 +71,7 @@ public class SCoverageCheckMojo
6971
private File dataDirectory;
7072

7173
/**
72-
* Required minimum coverage.
74+
* Required minimum total statement coverage.
7375
* <br>
7476
* <br>
7577
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
@@ -80,6 +82,56 @@ public class SCoverageCheckMojo
8082
@Parameter( property = "scoverage.minimumCoverage", defaultValue = "0" )
8183
private Double minimumCoverage;
8284

85+
/**
86+
* Required minimum total branch coverage.
87+
* <br>
88+
* <br>
89+
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
90+
* <br>
91+
*/
92+
@Parameter( property = "scoverage.minimumCoverageBranchTotal", defaultValue = "0" )
93+
private Double minimumCoverageBranchTotal;
94+
95+
/**
96+
* Required minimum per-package statement coverage.
97+
* <br>
98+
* <br>
99+
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
100+
* <br>
101+
*/
102+
@Parameter( property = "scoverage.minimumCoverageStmtPerPackage", defaultValue = "0" )
103+
private Double minimumCoverageStmtPerPackage;
104+
105+
/**
106+
* Required minimum per-package branch coverage.
107+
* <br>
108+
* <br>
109+
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
110+
* <br>
111+
*/
112+
@Parameter( property = "scoverage.minimumCoverageBranchPerPackage", defaultValue = "0" )
113+
private Double minimumCoverageBranchPerPackage;
114+
115+
/**
116+
* Required minimum per-file statement coverage.
117+
* <br>
118+
* <br>
119+
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
120+
* <br>
121+
*/
122+
@Parameter( property = "scoverage.minimumCoverageStmtPerFile", defaultValue = "0" )
123+
private Double minimumCoverageStmtPerFile;
124+
125+
/**
126+
* Required minimum per-file branch coverage.
127+
* <br>
128+
* <br>
129+
* See <a href="https://github.com/scoverage/sbt-scoverage#minimum-coverage">https://github.com/scoverage/sbt-scoverage#minimum-coverage</a> for additional documentation.
130+
* <br>
131+
*/
132+
@Parameter( property = "scoverage.minimumCoverageBranchPerFile", defaultValue = "0" )
133+
private Double minimumCoverageBranchPerFile;
134+
83135
/**
84136
* Fail the build if minimum coverage was not reached.
85137
* <br>
@@ -161,27 +213,23 @@ public void execute() throws MojoFailureException
161213
getLog().info( String.format( "Branch coverage....: %s%%", coverage.branchCoverageFormatted() ) );
162214
getLog().debug( String.format( "invokedBranchesCount:%d / branchCount:%d, invokedStatementCount:%d / statementCount:%d",
163215
invokedBranchesCount, branchCount, invokedStatementCount, statementCount ) );
164-
if ( minimumCoverage > 0.0 )
216+
217+
boolean ok = checkCoverage( getLog(), "Total", coverage,
218+
minimumCoverage, minimumCoverageBranchTotal );
219+
for ( scoverage.MeasuredPackage pkgCoverage : JavaConversions.asJavaIterable( coverage.packages() ) )
165220
{
166-
String minimumCoverageFormatted = scoverage.DoubleFormat.twoFractionDigits( minimumCoverage );
167-
if ( is100( minimumCoverage ) && is100( coverage.statementCoveragePercent() ) )
168-
{
169-
getLog().info( "100% Coverage !" );
170-
}
171-
else if ( coverage.statementCoveragePercent() < minimumCoverage )
172-
{
173-
getLog().error( String.format( "Coverage is below minimum [%s%% < %s%%]",
174-
coverage.statementCoverageFormatted(), minimumCoverageFormatted ) );
175-
if ( failOnMinimumCoverage )
176-
{
177-
throw new MojoFailureException( "Coverage minimum was not reached" );
178-
}
179-
}
180-
else
181-
{
182-
getLog().info( String.format( "Coverage is above minimum [%s%% >= %s%%]",
183-
coverage.statementCoverageFormatted(), minimumCoverageFormatted ) );
184-
}
221+
ok &= checkCoverage( getLog(), "Package:" + pkgCoverage.name(), pkgCoverage,
222+
minimumCoverageStmtPerPackage, minimumCoverageBranchPerPackage );
223+
}
224+
for ( scoverage.MeasuredFile fileCoverage : JavaConversions.asJavaIterable( coverage.files() ) )
225+
{
226+
ok &= checkCoverage( getLog(), "File:" + fileCoverage.filename(), fileCoverage,
227+
minimumCoverageStmtPerFile, minimumCoverageBranchPerFile );
228+
}
229+
230+
if ( !ok && failOnMinimumCoverage )
231+
{
232+
throw new MojoFailureException( "Coverage minimum was not reached" );
185233
}
186234

187235
long te = System.currentTimeMillis();
@@ -190,9 +238,47 @@ else if ( coverage.statementCoveragePercent() < minimumCoverage )
190238

191239
// Private utility methods
192240

193-
private boolean is100( Double d )
241+
private static boolean is100( Double d )
194242
{
195243
return Math.abs( 100 - d ) <= 0.00001d;
196244
}
197245

198-
}
246+
private static boolean checkCoverage( Log logger, String metric, scoverage.CoverageMetrics metrics,
247+
double minimumStmt, double minimimBranch )
248+
{
249+
return
250+
checkCoverage( logger, "Statement:" + metric, minimumStmt, metrics.statementCoveragePercent() ) &&
251+
checkCoverage( logger, "Branch:" + metric, minimimBranch, metrics.branchCoveragePercent() );
252+
}
253+
254+
private static boolean checkCoverage( Log logger, String metric, double minimum, double actual )
255+
{
256+
if ( minimum <= 0 )
257+
{
258+
return true;
259+
}
260+
261+
if ( is100( minimum ) && is100( actual ) )
262+
{
263+
logger.debug( String.format( "Coverage is 100%: %s!", metric ));
264+
return true;
265+
}
266+
267+
String minimumFormatted = scoverage.DoubleFormat.twoFractionDigits( minimum );
268+
String actualFormatted = scoverage.DoubleFormat.twoFractionDigits( actual );
269+
boolean ok = minimum <= actual;
270+
271+
if ( ok )
272+
{
273+
logger.debug( String.format( "Coverage is above minimum [%s%% >= %s%%]: %s",
274+
actualFormatted, minimumFormatted, metric ) );
275+
}
276+
else
277+
{
278+
logger.error( String.format( "Coverage is below minimum [%s%% < %s%%]: %s",
279+
actualFormatted, minimumFormatted, metric ) );
280+
}
281+
282+
return ok;
283+
}
284+
}

0 commit comments

Comments
 (0)