1
2
3
4
5 package mockit.coverage;
6
7 import edu.umd.cs.findbugs.annotations.NonNull;
8 import edu.umd.cs.findbugs.annotations.Nullable;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.nio.file.Path;
13
14 import mockit.coverage.data.CoverageData;
15 import mockit.coverage.reporting.CoverageReport;
16
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 @SuppressWarnings("DynamicRegexReplaceableByCompiledPattern")
21 final class OutputFileGenerator {
22
23
24 private static final Logger logger = LoggerFactory.getLogger(CoverageReport.class);
25
26 private static final String[] ALL_SOURCE_DIRS = {};
27
28 @NonNull
29 private final String[] outputFormats;
30 @NonNull
31 private final String outputDir;
32 @Nullable
33 private final String[] sourceDirs;
34
35 OutputFileGenerator() {
36 outputFormats = getOutputFormat();
37 outputDir = Configuration.getProperty("outputDir", "");
38
39 String commaSeparatedDirs = Configuration.getProperty("srcDirs");
40
41 if (commaSeparatedDirs == null) {
42 sourceDirs = ALL_SOURCE_DIRS;
43 } else if (commaSeparatedDirs.isEmpty()) {
44 sourceDirs = null;
45 } else {
46 sourceDirs = commaSeparatedDirs.split("\\s*,\\s*");
47 }
48 }
49
50 @NonNull
51 private static String[] getOutputFormat() {
52 String format = Configuration.getProperty("output", "");
53 return format.isEmpty() ? new String[] { "html" } : format.trim().split("\\s*,\\s*|\\s+");
54 }
55
56 boolean isOutputToBeGenerated() {
57 return isHTMLWithNoCallPoints() || isWithCallPoints() || hasOutputFormat("serial")
58 || hasOutputFormat("serial-append") || hasOutputFormat("xml");
59 }
60
61 private boolean isHTMLWithNoCallPoints() {
62 return hasOutputFormat("html") || hasOutputFormat("html-nocp");
63 }
64
65 boolean isWithCallPoints() {
66 return hasOutputFormat("html-cp");
67 }
68
69 private boolean hasOutputFormat(@NonNull String format) {
70 for (String outputFormat : outputFormats) {
71 if (format.equals(outputFormat)) {
72 return true;
73 }
74 }
75
76 return false;
77 }
78
79 void generate() {
80 CoverageData coverageData = CoverageData.instance();
81
82 if (coverageData.isEmpty()) {
83 logger.info("JMockit: No classes were instrumented for coverage; please make sure that ");
84
85 String classesRegexp = Configuration.getProperty("classes");
86
87 if (classesRegexp == null) {
88 logger.info("classes exercised by tests are in a directory included in the runtime classpath");
89 } else {
90 logger.info(
91 "classes selected for coverage through the regular expression '{}' are available from the runtime classpath",
92 classesRegexp);
93 }
94
95 logger.info(", and that they have been compiled with debug information.");
96 return;
97 }
98
99 boolean outputDirCreated = createOutputDirIfSpecifiedButNotExists();
100
101 try {
102 generateAccretionDataFileIfRequested(coverageData);
103 generateXmlDataFileIfRequested(coverageData);
104 generateHTMLReportIfRequested(coverageData, outputDirCreated);
105 } catch (IOException e) {
106 throw new RuntimeException(e);
107 }
108 }
109
110 void generateAggregateReportFromInputFiles(@NonNull String[] inputPaths) {
111 boolean outputDirCreated = createOutputDirIfSpecifiedButNotExists();
112
113 try {
114 CoverageData coverageData = new DataFileMerging(inputPaths).merge();
115 generateHTMLReportIfRequested(coverageData, outputDirCreated);
116 } catch (IOException e) {
117 throw new RuntimeException(e);
118 }
119 }
120
121 private boolean createOutputDirIfSpecifiedButNotExists() {
122 if (outputDir.isEmpty()) {
123 return false;
124 }
125
126 File outDir = Path.of(outputDir).toFile();
127 return outDir.mkdirs();
128 }
129
130 private void generateAccretionDataFileIfRequested(@NonNull CoverageData newData) throws IOException {
131 if (hasOutputFormat("serial")) {
132 new AccretionFile(outputDir, newData).generate();
133 } else if (hasOutputFormat("serial-append")) {
134 AccretionFile accretionFile = new AccretionFile(outputDir, newData);
135 accretionFile.mergeDataFromExistingFileIfAny();
136 accretionFile.generate();
137 }
138 }
139
140 private void generateXmlDataFileIfRequested(@NonNull CoverageData newData) throws IOException {
141 if (hasOutputFormat("xml")) {
142 new XmlFile(outputDir, newData).generate();
143 }
144 }
145
146 private void generateHTMLReportIfRequested(@NonNull CoverageData coverageData, boolean outputDirCreated)
147 throws IOException {
148 if (isHTMLWithNoCallPoints()) {
149 new CoverageReport(outputDir, outputDirCreated, sourceDirs, coverageData, false).generate();
150 } else if (isWithCallPoints()) {
151 new CoverageReport(outputDir, outputDirCreated, sourceDirs, coverageData, true).generate();
152 }
153 }
154 }