/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit.coverage; import java.io.*; import java.util.Map.*; import javax.annotation.*; import mockit.coverage.data.*; import mockit.coverage.lines.*; /** * Generates a XML file containing the coverage data gathered by the test run. * The XML schema used is the one <a href="http://docs.sonarqube.org/display/PLUG/Generic+Test+Coverage">defined</a> by * the SonarQube project: * <pre> * <coverage version="1"> * <file path="com/example/MyClass.java"> * <lineToCover lineNumber="5" covered="false"/> * <lineToCover lineNumber="8" covered="true" branchesToCover="2" coveredBranches="1"/> * </file> * </coverage> * </pre> */ final class XmlFile { @Nonnull private final String srcDir; @Nonnull private final File outputFile; @Nonnull private final CoverageData coverageData; @Nonnull private Writer output; XmlFile(@Nonnull String outputDir, @Nonnull CoverageData coverageData) { String firstSrcDir = Configuration.getProperty("srcDirs", "").split("\\s*,\\s*")[0]; srcDir = firstSrcDir.isEmpty() ? "" : firstSrcDir + '/'; String parentDir = Configuration.getOrChooseOutputDirectory(outputDir); outputFile = new File(parentDir, "coverage.xml"); this.coverageData = coverageData; } void generate() throws IOException { output = new FileWriter(outputFile); try { output.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); output.write("<coverage version=\"1\">\n"); for (Entry<String, FileCoverageData> fileAndData : coverageData.getFileToFileDataMap().entrySet()) { String sourceFileName = fileAndData.getKey(); writeOpeningXmlElementForSourceFile(sourceFileName); PerFileLineCoverage lineInfo = fileAndData.getValue().lineCoverageInfo; writeXmlElementsForExecutableLines(lineInfo); output.write("\t</file>\n"); } output.write("</coverage>\n"); } finally { output.close(); } System.out.println("JMockit: Coverage data written to " + outputFile.getCanonicalPath()); } private void writeOpeningXmlElementForSourceFile(@Nonnull String sourceFileName) throws IOException { output.write("\t<file path=\""); output.write(srcDir); output.write(sourceFileName); output.write("\">\n"); } private void writeXmlElementsForExecutableLines(@Nonnull PerFileLineCoverage lineInfo) throws IOException { int lineCount = lineInfo.getLineCount(); for (int lineNum = 1; lineNum <= lineCount; lineNum++) { if (lineInfo.hasLineData(lineNum)) { LineCoverageData lineData = lineInfo.getLineData(lineNum); output.write("\t\t<lineToCover lineNumber=\""); writeNumber(lineNum); output.write("\" covered=\""); output.write(Boolean.toString(lineData.isCovered())); if (lineData.containsBranches()) { output.write("\" branchesToCover=\""); writeNumber(lineData.getNumberOfBranchingSourcesAndTargets()); output.write("\" coveredBranches=\""); writeNumber(lineData.getNumberOfCoveredBranchingSourcesAndTargets()); } output.write("\"/>\n"); } } } private void writeNumber(int value) throws IOException { output.write(Integer.toString(value)); } }