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