Index: PhpUnitCoverageResultParser.java =================================================================== --- PhpUnitCoverageResultParser.java (revision 602) +++ PhpUnitCoverageResultParser.java (revision 606) @@ -38,6 +38,7 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.PropertiesBuilder; import org.sonar.api.resources.Project; +import org.sonar.api.utils.ParsingUtils; import org.sonar.api.utils.SonarException; import org.sonar.plugins.php.core.PhpFile; import org.sonar.plugins.php.core.PhpPackage; @@ -57,6 +58,8 @@ /** The logger. */ private static Logger logger = LoggerFactory.getLogger(PhpUnitCoverageResultParser.class); + private static final double PERCENT = 100d; + /** The project. */ private Project project; @@ -116,8 +119,17 @@ private void parseFile(SensorContext context, File coverageReportFile) { CoverageNode coverage = getCoverage(coverageReportFile); // Used to record the number of covered statements (lines) - double totalStatements = 0; - double coveredStatements = 0; + + double elements = 0; + double statements = 0; + double methods = 0; + + double coveredElements = 0; + double coveredStatements = 0; + double coveredMethods = 0; + + double coverageProcent = 0; + double lineCoverageProcent = 0; List projects = coverage.getProjects(); if (projects != null && !projects.isEmpty()) { @@ -125,13 +137,29 @@ for (FileNode file : projectNode.getFiles()) { cumulateResults(file); } - MetricsNode metrics = projectNode.getMetrics(); - totalStatements += metrics.getTotalStatementsCount(); - coveredStatements += metrics.getCoveredStatements(); saveMeasures(classByPackage); + + elements = projectNode.getMetrics().getTotalElementsCount(); + statements = projectNode.getMetrics().getTotalStatementsCount(); + methods = projectNode.getMetrics().getTotalMethodsCount(); + + coveredElements = projectNode.getMetrics().getCoveredElements(); + coveredStatements = projectNode.getMetrics().getCoveredStatements(); + coveredMethods = projectNode.getMetrics().getCoveredMethods(); + + if (elements > 0) { + coverageProcent = coveredElements / elements; + } + + if (methods + statements > 0) { + lineCoverageProcent = (coveredMethods + coveredStatements) / (methods + statements); + } } - context.saveMeasure(CoreMetrics.LINES_TO_COVER, totalStatements); - context.saveMeasure(CoreMetrics.UNCOVERED_LINES, totalStatements - coveredStatements); + + context.saveMeasure(CoreMetrics.COVERAGE, convertPercentage(coverageProcent)); + context.saveMeasure(CoreMetrics.LINE_COVERAGE, convertPercentage(lineCoverageProcent)); + context.saveMeasure(CoreMetrics.LINES_TO_COVER, statements + methods); + context.saveMeasure(CoreMetrics.UNCOVERED_LINES, statements + methods - coveredStatements - coveredMethods); } /** @@ -149,7 +177,7 @@ PhpPackage phpPackage = phpFile.getParent(); PackageNode packageNode = classByPackage.get(phpPackage.getName()); if (packageNode == null) { - packageNode = new PackageNode(); + packageNode = new PackageNode(phpPackage); classByPackage.put(phpPackage.getName(), packageNode); } packageNode.addClassByFileNode(file, phpFile); @@ -166,15 +194,31 @@ // For each package Collection nodes = classByPackage.values(); for (PackageNode node : nodes) { + PhpPackage phpPackage = node.getPackage(); + double coveragePercent = 0d; // Saves the class measures and adds its coverage percent - Map classByFileNode = node.getClassByFileNode(); - for (Entry entry : classByFileNode.entrySet()) { - saveClassMeasure(entry.getKey(), entry.getValue()); + for (FileNode fileNode : node.getClassByFileNode().keySet()) { + coveragePercent += saveClassMeasure(fileNode, node.getClassByFileNode().get(fileNode)); } + double percentageByPackage = coveragePercent / node.getClassByFileNode().size(); + + // Saves the measure for the package + context.saveMeasure(phpPackage, CoreMetrics.COVERAGE, convertPercentage(percentageByPackage)); } } /** + * Convert percentage. + * + * @param percentage + * the percentage + * @return the double + */ + private double convertPercentage(Number percentage) { + return ParsingUtils.scaleValue(percentage.doubleValue() * PERCENT); + } + + /** * Saves one class measure and calls {@link #saveLineMeasure(LineNode, PropertiesBuilder, String))} for each class lines. * * @param fileNode @@ -183,21 +227,34 @@ * the php file * @return the double */ - private void saveClassMeasure(FileNode fileNode, PhpFile phpFile) { + private double saveClassMeasure(FileNode fileNode, PhpFile phpFile) { // Properties builder will generate the data associate with COVERAGE_LINE_HITS_DATA metrics. // This should look like (lineNumner=Count) : 1=0;2=1;3=1.... PropertiesBuilder lineHits = new PropertiesBuilder(CoreMetrics.COVERAGE_LINE_HITS_DATA); for (LineNode line : fileNode.getLines()) { saveLineMeasure(line, lineHits); } - MetricsNode metrics = fileNode.getMetrics(); + + double elements = fileNode.getMetrics().getTotalElementsCount(); + double statements = fileNode.getMetrics().getTotalStatementsCount(); + double methods = fileNode.getMetrics().getTotalMethodsCount(); +// double conditionals = fileNode.getMetrics().getTotalConditionalsCount(); + double coveredElements = fileNode.getMetrics().getCoveredElements(); + double coveredStatements = fileNode.getMetrics().getCoveredStatements(); + double coveredMethods = fileNode.getMetrics().getCoveredMethods(); +// double coveredConditionals = fileNode.getMetrics().getCoveredConditionals(); + + double coverageProcent = coveredElements / elements; + + context.saveMeasure(phpFile, CoreMetrics.COVERAGE, convertPercentage(coverageProcent)); + + context.saveMeasure(phpFile, CoreMetrics.LINE_COVERAGE, + convertPercentage( (coveredMethods + coveredStatements) / (methods + statements))); + context.saveMeasure(phpFile, CoreMetrics.LINES_TO_COVER, statements + methods); + context.saveMeasure(phpFile, CoreMetrics.UNCOVERED_LINES, (statements + methods - coveredStatements - coveredMethods)); context.saveMeasure(phpFile, lineHits.build()); - // Save uncovered statements (lines) - double totalStatementsCount = metrics.getTotalStatementsCount(); - double uncoveredLines = totalStatementsCount - metrics.getCoveredStatements(); - context.saveMeasure(phpFile, CoreMetrics.LINES_TO_COVER, totalStatementsCount); - context.saveMeasure(phpFile, CoreMetrics.UNCOVERED_LINES, uncoveredLines); + return coverageProcent; } /** @@ -207,8 +264,6 @@ * the line * @param lineHits * the line hits - * @param fileName - * the class name */ private void saveLineMeasure(LineNode line, PropertiesBuilder lineHits) { lineHits.add(line.getNum(), line.getCount()); @@ -246,6 +301,9 @@ */ private static class PackageNode { + /** The php package. */ + private PhpPackage phpPackage; + /** The class by file node. */ private Map classByFileNode; @@ -264,8 +322,9 @@ * @param phpPackage * the php package */ - public PackageNode() { + public PackageNode(PhpPackage phpPackage) { super(); + this.phpPackage = phpPackage; classByFileNode = new HashMap(); } @@ -280,6 +339,16 @@ public void addClassByFileNode(FileNode fileNode, PhpFile phpFile) { classByFileNode.put(fileNode, phpFile); } + + /** + * Gets the package. + * + * @return the package + */ + public PhpPackage getPackage() { + return phpPackage; + } + } } Index: PhpUnitResultParser.java =================================================================== --- PhpUnitResultParser.java (revision 602) +++ PhpUnitResultParser.java (revision 606) @@ -199,7 +199,7 @@ * the project */ private void saveClassMeasure(SensorContext context, PhpUnitTestReport fileReport, Metric metric, double value, Project project) { - if ( !Double.isNaN(value)) { + if ( !Double.isNaN(value) && fileReport.getFile() != null) { context.saveMeasure(getUnitTestResource(fileReport, project), metric, value); } } Index: PhpUnitTestReport.java =================================================================== --- PhpUnitTestReport.java (revision 602) +++ PhpUnitTestReport.java (revision 606) @@ -132,7 +132,7 @@ * @return true, if is valid */ public boolean isValid() { - return classKey != null; + return classKey != null && file != null; } /**