public final class OutputFile extends PrintWriter { private static final Pattern PATH_SEPARATOR = Pattern.compile("/"); @Nonnull private final String relPathToOutDir; private final boolean withPrettyPrint; public OutputFile(@Nonnull File file) throws IOException { super(file, "UTF-8"); relPathToOutDir = ""; withPrettyPrint = false; } public OutputFile(@Nonnull String outputDir, @Nonnull String sourceFilePath) throws IOException { super(getOutputFileCreatingDirIfNeeded(outputDir, sourceFilePath)); relPathToOutDir = getRelativeSubPathToOutputDir(sourceFilePath); withPrettyPrint = true; } @Nonnull private static File getOutputFileCreatingDirIfNeeded( @Nonnull String outputDir, @Nonnull String sourceFilePath) { File outputFile = getOutputFile(outputDir, sourceFilePath); File parentDir = outputFile.getParentFile(); if (!parentDir.exists()) { boolean outputDirCreated = parentDir.mkdirs(); assert outputDirCreated : "Failed to create output dir: " + outputDir; } return outputFile; } @Nonnull static File getOutputFile(@Nonnull String outputDir, @Nonnull String sourceFilePath) { int p = sourceFilePath.lastIndexOf('.'); String outputFileName = sourceFilePath.substring(0, p) + ".html"; File outputFile = new File(outputDir, outputFileName); return outputFile; } @Nonnull private static String getRelativeSubPathToOutputDir(@Nonnull String filePath) { StringBuilder cssRelPath = new StringBuilder(); int n = PATH_SEPARATOR.split(filePath).length; for (int i = 1; i < n; i++) { cssRelPath.append("../"); } return cssRelPath.toString(); } public void writeCommonHeader(@Nonnull String pageTitle) { println("<!DOCTYPE html>"); println("<html>"); println("<head>"); println(" <title>" + pageTitle + "</title>"); println(" <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>"); println( " <link rel='stylesheet' type='text/css' href='" + relPathToOutDir + "coverage.css'/>"); println( " <link rel='shortcut icon' type='image/png' href='" + relPathToOutDir + "logo.png'/>"); println(" <script type='text/javascript' src='" + relPathToOutDir + "coverage.js'></script>"); if (withPrettyPrint) { println( " <script type='text/javascript' src='" + relPathToOutDir + "prettify.js'></script>"); } println("</head>"); println(withPrettyPrint ? "<body onload='prettyPrint()'>" : "<body>"); } public void writeCommonFooter() { println("</body>"); println("</html>"); } }
public final class ListOfCallPoints { @Nonnull private static final String EOL = System.getProperty("line.separator"); private static final Pattern LESS_THAN_CHAR = Pattern.compile("<"); @Nonnull private final StringBuilder content; public ListOfCallPoints() { content = new StringBuilder(100); } public void insertListOfCallPoints(@Nullable List<CallPoint> callPoints) { if (content.length() == 0) { content.append(EOL).append(" "); } content.append(" <ol style='display:none'>"); if (callPoints == null) { content.append("</ol>").append(EOL).append(" "); return; } content.append(EOL); CallPoint currentCP = callPoints.get(0); appendTestMethod(currentCP.getStackTraceElement()); appendRepetitionCountIfNeeded(currentCP); for (int i = 1, n = callPoints.size(); i < n; i++) { CallPoint nextCP = callPoints.get(i); StackTraceElement ste = nextCP.getStackTraceElement(); if (nextCP.isSameTestMethod(currentCP)) { content.append(", ").append(ste.getLineNumber()); } else { content.append("</li>").append(EOL); appendTestMethod(ste); } appendRepetitionCountIfNeeded(nextCP); currentCP = nextCP; } content.append("</li>").append(EOL).append(" </ol>").append(EOL).append(" "); } private void appendTestMethod(@Nonnull StackTraceElement current) { content.append(" <li>"); content.append(current.getClassName()).append('#'); content .append(LESS_THAN_CHAR.matcher(current.getMethodName()).replaceFirst("<")) .append(": "); content.append(current.getLineNumber()); } private void appendRepetitionCountIfNeeded(@Nonnull CallPoint callPoint) { int repetitionCount = callPoint.getRepetitionCount(); if (repetitionCount > 0) { content.append('x').append(1 + repetitionCount); } } @Nonnull public String getContents() { String result = content.toString(); content.setLength(0); return result; } }