Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#194) Fix numbers decimal separator #196

Merged
merged 2 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -108,12 +106,12 @@ protected File resolve(File file, String relativePath) {
return file.toPath().resolve(relativePath).toFile();
}

private Double coverage(File reportDir, CoverageType coverageType) throws IOException, SAXException, ParseException {
private Double coverage(File reportDir, CoverageType coverageType) throws IOException, SAXException, NumberFormatException {

File reportFile = reportDir.toPath().resolve(coverageType.getFileName()).toFile();
Node xml = parser.parse(reportFile);
Object attribute = xml.attribute(coverageType.getParamName());
double rawValue = NumberFormat.getInstance().parse(attribute.toString()).doubleValue();
double rawValue = Double.parseDouble(attribute.toString());
return coverageType.normalize(rawValue) * 100.0;
}

Expand Down
20 changes: 7 additions & 13 deletions src/main/groovy/org/scoverage/CoverageChecker.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import org.gradle.api.logging.Logger
import org.gradle.internal.impldep.com.google.common.annotations.VisibleForTesting

import java.text.DecimalFormat
import java.text.NumberFormat
import java.text.DecimalFormatSymbols

/**
* Handles different types of coverage Scoverage can measure.
Expand Down Expand Up @@ -56,38 +56,32 @@ class CoverageChecker {
}

public void checkLineCoverage(File reportDir, CoverageType coverageType, double minimumRate) throws GradleException {
NumberFormat defaultNf = NumberFormat.getInstance(Locale.getDefault())
checkLineCoverage(reportDir, coverageType, minimumRate, defaultNf)
}

public void checkLineCoverage(File reportDir, CoverageType coverageType, double minimumRate, NumberFormat nf) throws GradleException {
logger.info("Checking coverage. Type: {}. Minimum rate: {}", coverageType, minimumRate)

XmlParser parser = new XmlParser()
parser.setFeature('http://apache.org/xml/features/disallow-doctype-decl', false)
parser.setFeature('http://apache.org/xml/features/nonvalidating/load-external-dtd', false)

DecimalFormat df = new DecimalFormat("#.##")

try {
File reportFile = new File(reportDir, coverageType.fileName)
Node xml = parser.parse(reportFile)
Double coverageValue = nf.parse(xml.attribute(coverageType.paramName) as String).doubleValue()
Double coverageValue = (xml.attribute(coverageType.paramName) as String).toDouble()
Double overallRate = coverageType.normalize(coverageValue)
def difference = (minimumRate - overallRate)

if (difference > 1e-7) {
String is = df.format(overallRate * 100)
String needed = df.format(minimumRate * 100)
throw new GradleException(errorMsg(is, needed, coverageType))
throw new GradleException(errorMsg(overallRate, minimumRate, coverageType))
}
} catch (FileNotFoundException fnfe) {
throw new GradleException(fileNotFoundErrorMsg(coverageType), fnfe)
}
}

@VisibleForTesting
protected static String errorMsg(String actual, String expected, CoverageType type) {
protected static String errorMsg(double overallRate, double minimumRate, CoverageType type) {
DecimalFormat df = new DecimalFormat("#.##", DecimalFormatSymbols.getInstance(Locale.US))
String actual = df.format(overallRate * 100)
String expected = df.format(minimumRate * 100)
"Only $actual% of project is covered by tests instead of $expected% (coverageType: $type)"
}

Expand Down
38 changes: 21 additions & 17 deletions src/test/groovy/org/scoverage/CoverageCheckerTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ import org.junit.rules.TemporaryFolder
import org.slf4j.LoggerFactory

import java.nio.file.Paths
import java.text.NumberFormat

import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertThat
import static org.junit.jupiter.api.Assertions.assertThrows

class CoverageCheckerTest {

private NumberFormat numberFormat = NumberFormat.getInstance(Locale.US)

private File reportDir = Paths.get(getClass().getClassLoader().getResource("checkTask").toURI()).toFile()

private CoverageChecker checker = new CoverageChecker(LoggerFactory.getLogger(CoverageCheckerTest.class))
Expand All @@ -31,68 +29,74 @@ class CoverageCheckerTest {
@Test
void failsWhenReportFileIsNotFound() {
assertFailure(CoverageChecker.fileNotFoundErrorMsg(CoverageType.Line), {
checker.checkLineCoverage(tempDir.getRoot(), CoverageType.Line, 0.0, numberFormat)
checker.checkLineCoverage(tempDir.getRoot(), CoverageType.Line, 0.0)
})
}

// line coverage

@Test
void failsWhenLineRateIsBelowTarget() {
assertFailure(CoverageChecker.errorMsg("66", "100", CoverageType.Line), {
checker.checkLineCoverage(reportDir, CoverageType.Line, 1.0, numberFormat)
assertFailure(CoverageChecker.errorMsg(0.66, 1.0, CoverageType.Line), {
checker.checkLineCoverage(reportDir, CoverageType.Line, 1.0)
})
}

@Test
void doesNotFailWhenLineRateIsAtTarget() {
checker.checkLineCoverage(reportDir, CoverageType.Line, 0.66, numberFormat)
checker.checkLineCoverage(reportDir, CoverageType.Line, 0.66)
}

@Test
void doesNotFailWhenLineRateIsAboveTarget() {
checker.checkLineCoverage(reportDir, CoverageType.Line, 0.6, numberFormat)
checker.checkLineCoverage(reportDir, CoverageType.Line, 0.6)
}

// Statement coverage

@Test
void failsWhenStatementRateIsBelowTarget() {
assertFailure(CoverageChecker.errorMsg(numberFormat.format(new Double(33.33)), "100", CoverageType.Statement), {
checker.checkLineCoverage(reportDir, CoverageType.Statement, 1.0, numberFormat)
assertFailure(CoverageChecker.errorMsg(0.3333, 1.0, CoverageType.Statement), {
checker.checkLineCoverage(reportDir, CoverageType.Statement, 1.0)
})
}

@Test
void doesNotFailWhenStatementRateIsAtTarget() {
checker.checkLineCoverage(reportDir, CoverageType.Statement, 0.33, numberFormat)
checker.checkLineCoverage(reportDir, CoverageType.Statement, 0.33)
}

@Test
void doesNotFailWhenStatementRateIsAboveTarget() {
checker.checkLineCoverage(reportDir, CoverageType.Statement, 0.3, numberFormat)
checker.checkLineCoverage(reportDir, CoverageType.Statement, 0.3)
}

// Branch coverage

@Test
void failsWhenBranchRateIsBelowTarget() {
assertFailure(CoverageChecker.errorMsg("50", "100", CoverageType.Branch), {
checker.checkLineCoverage(reportDir, CoverageType.Branch, 1.0, numberFormat)
assertFailure(CoverageChecker.errorMsg(0.5, 1.0, CoverageType.Branch), {
checker.checkLineCoverage(reportDir, CoverageType.Branch, 1.0)
})
}

@Test
void doesNotFailWhenBranchRateIsAtTarget() {
checker.checkLineCoverage(reportDir, CoverageType.Branch, 0.5, numberFormat)
checker.checkLineCoverage(reportDir, CoverageType.Branch, 0.5)
}

@Test
void doesNotFailWhenBranchRateIsAboveTarget() {
checker.checkLineCoverage(reportDir, CoverageType.Branch, 0.45, numberFormat)
checker.checkLineCoverage(reportDir, CoverageType.Branch, 0.45)
}

@Test
void printsErrorMsgInEnglishWithUpTwoDecimalPointsPrecision() {
assertEquals("Only 54.32% of project is covered by tests instead of 90% (coverageType: Branch)",
CoverageChecker.errorMsg(0.54321, 0.9, CoverageType.Branch))
}

private void assertFailure(String message, Executable executable) {
private static void assertFailure(String message, Executable executable) {
GradleException e = assertThrows(GradleException.class, executable)
assertThat(e, new CauseMatcher(message))
}
Expand Down