1
2
3
4
5
6 package integration.tests;
7
8 import static java.lang.reflect.Modifier.isAbstract;
9 import static java.lang.reflect.Modifier.isFinal;
10
11 import static org.junit.jupiter.api.Assertions.assertEquals;
12 import static org.junit.jupiter.api.Assertions.assertFalse;
13 import static org.junit.jupiter.api.Assertions.assertNotNull;
14 import static org.junit.jupiter.api.Assertions.assertTrue;
15
16 import edu.umd.cs.findbugs.annotations.NonNull;
17 import edu.umd.cs.findbugs.annotations.Nullable;
18
19 import java.lang.reflect.Field;
20 import java.util.List;
21 import java.util.Map;
22
23 import mockit.coverage.CallPoint;
24 import mockit.coverage.data.CoverageData;
25 import mockit.coverage.data.FileCoverageData;
26 import mockit.coverage.dataItems.InstanceFieldData;
27 import mockit.coverage.dataItems.PerFileDataCoverage;
28 import mockit.coverage.dataItems.StaticFieldData;
29 import mockit.coverage.lines.BranchCoverageData;
30 import mockit.coverage.lines.LineCoverageData;
31 import mockit.coverage.lines.PerFileLineCoverage;
32
33 import org.checkerframework.checker.index.qual.NonNegative;
34 import org.junit.jupiter.api.BeforeEach;
35
36 @SuppressWarnings("JUnitTestCaseWithNoTests")
37 public class CoverageTest {
38 @Nullable
39 protected static FileCoverageData fileData;
40 @Nullable
41 private static String testedClassSimpleName;
42
43 @BeforeEach
44 protected final void findCoverageData() throws Exception {
45 Field testedField = getClass().getDeclaredField("tested");
46 Class<?> testedClass = testedField.getType();
47
48 if (testedClass != Object.class) {
49 findFileDate(testedClass);
50 setTestedFieldToNewInstanceIfApplicable(testedField);
51 }
52 }
53
54 private void findFileDate(@NonNull Class<?> testedClass) {
55 testedClassSimpleName = testedClass.getSimpleName();
56
57 String classFilePath = testedClass.getName().replace('.', '/') + ".java";
58 Map<String, FileCoverageData> data = CoverageData.instance().getFileToFileData();
59 fileData = data.get(classFilePath);
60
61 assertNotNull(fileData, "FileCoverageData not found for " + classFilePath);
62 }
63
64 private void setTestedFieldToNewInstanceIfApplicable(@NonNull Field testedField) throws Exception {
65 Class<?> testedClass = testedField.getType();
66
67 if (!testedClass.isEnum() && !isAbstract(testedClass.getModifiers()) && !isFinal(testedField.getModifiers())) {
68 testedField.setAccessible(true);
69
70 if (testedField.get(this) == null) {
71
72 Object newTestedInstance = testedClass.getDeclaredConstructor().newInstance();
73
74 testedField.set(this, newTestedInstance);
75 }
76 }
77 }
78
79 @NonNull
80 private FileCoverageData fileData() {
81 if (fileData == null) {
82 Object testedInstance;
83
84 try {
85 Field testedField = getClass().getDeclaredField("tested");
86 testedInstance = testedField.get(this);
87 } catch (NoSuchFieldException | IllegalAccessException e) {
88 throw new RuntimeException(e);
89 }
90
91 Class<?> testedClass = testedInstance.getClass();
92 findFileDate(testedClass);
93 }
94
95 return fileData;
96 }
97
98
99
100
101 protected final void assertLines(@NonNegative int startingLine, @NonNegative int endingLine,
102 @NonNegative int expectedLinesExecuted) {
103 PerFileLineCoverage lineCoverageInfo = fileData().lineCoverageInfo;
104 int lineCount = lineCoverageInfo.getLineCount();
105 assertTrue(lineCount >= startingLine, "Starting line not found");
106 assertTrue(lineCount >= endingLine, "Ending line not found");
107
108 int linesExecuted = 0;
109
110 for (int line = startingLine; line <= endingLine; line++) {
111 if (lineCoverageInfo.getExecutionCount(line) > 0) {
112 linesExecuted++;
113 }
114 }
115
116 assertEquals(expectedLinesExecuted, linesExecuted, "Unexpected number of lines executed:");
117 }
118
119 protected final void assertLine(@NonNegative int line, @NonNegative int expectedSegments,
120 @NonNegative int expectedCoveredSegments, int... expectedExecutionCounts) {
121 PerFileLineCoverage info = fileData().lineCoverageInfo;
122 LineCoverageData lineData = info.getLineData(line);
123
124 assertEquals(expectedSegments, info.getNumberOfSegments(line), "Segments:");
125 assertEquals(expectedCoveredSegments, lineData.getNumberOfCoveredSegments(), "Covered segments:");
126 assertEquals(expectedExecutionCounts[0], info.getExecutionCount(line), "Execution count:");
127
128 for (int i = 1; i < expectedExecutionCounts.length; i++) {
129 BranchCoverageData segmentData = lineData.getBranchData(i - 1);
130
131 int executionCount = segmentData.getExecutionCount();
132 assertEquals(expectedExecutionCounts[i], executionCount,
133 "Execution count for line " + line + ", segment " + i + ':');
134
135 List<CallPoint> callPoints = segmentData.getCallPoints();
136
137 if (callPoints != null) {
138 int callPointCount = 0;
139
140 for (CallPoint callPoint : callPoints) {
141 callPointCount++;
142 callPointCount += callPoint.getRepetitionCount();
143 }
144
145 assertEquals(executionCount, callPointCount, "Missing call points for line " + line + ", segment " + i);
146 }
147 }
148 }
149
150 protected final void assertBranchingPoints(@NonNegative int line, @NonNegative int expectedSourcesAndTargets,
151 @NonNegative int expectedCoveredSourcesAndTargets) {
152 PerFileLineCoverage lineCoverageInfo = fileData().lineCoverageInfo;
153 LineCoverageData lineData = lineCoverageInfo.getLineData(line);
154
155 int sourcesAndTargets = lineCoverageInfo.getNumberOfBranchingSourcesAndTargets(line);
156 assertEquals(expectedSourcesAndTargets, sourcesAndTargets, "Sources and targets:");
157
158 int coveredSourcesAndTargets = lineData.getNumberOfCoveredBranchingSourcesAndTargets();
159 assertEquals(expectedCoveredSourcesAndTargets, coveredSourcesAndTargets, "Covered sources and targets:");
160 }
161
162
163
164
165 protected final void assertFieldIgnored(@NonNull String fieldName) {
166 String fieldId = testedClassSimpleName + '.' + fieldName;
167 PerFileDataCoverage info = fileData().dataCoverageInfo;
168 assertFalse(info.staticFieldsData.containsKey(fieldId),
169 "Field " + fieldName + " should not have static coverage data");
170 assertFalse(info.instanceFieldsData.containsKey(fieldId),
171 "Field " + fieldName + " should not have instance coverage data");
172 }
173
174 protected static void assertStaticFieldCovered(@NonNull String fieldName) {
175 assertTrue(isStaticFieldCovered(fieldName), "Static field " + fieldName + " should be covered");
176 }
177
178 private static boolean isStaticFieldCovered(@NonNull String fieldName) {
179 String classAndFieldNames = testedClassSimpleName + '.' + fieldName;
180 StaticFieldData staticFieldData = fileData.dataCoverageInfo.staticFieldsData.get(classAndFieldNames);
181
182 return staticFieldData.isCovered();
183 }
184
185 protected static void assertStaticFieldUncovered(@NonNull String fieldName) {
186 assertFalse(isStaticFieldCovered(fieldName), "Static field " + fieldName + " should not be covered");
187 }
188
189 protected static void assertInstanceFieldCovered(@NonNull String fieldName) {
190 assertTrue(isInstanceFieldCovered(fieldName), "Instance field " + fieldName + " should be covered");
191 }
192
193 private static boolean isInstanceFieldCovered(@NonNull String fieldName) {
194 return getInstanceFieldData(fieldName).isCovered();
195 }
196
197 private static InstanceFieldData getInstanceFieldData(@NonNull String fieldName) {
198 String classAndFieldNames = testedClassSimpleName + '.' + fieldName;
199 return fileData.dataCoverageInfo.instanceFieldsData.get(classAndFieldNames);
200 }
201
202 protected static void assertInstanceFieldUncovered(@NonNull String fieldName) {
203 assertFalse(isInstanceFieldCovered(fieldName), "Instance field " + fieldName + " should not be covered");
204 }
205
206 protected static void assertInstanceFieldUncovered(@NonNull String fieldName,
207 @NonNull Object... uncoveredInstances) {
208 String msg = "Instance field " + fieldName + " should not be covered";
209 InstanceFieldData fieldData = getInstanceFieldData(fieldName);
210 List<Integer> ownerInstances = fieldData.getOwnerInstancesWithUnreadAssignments();
211
212 assertEquals(uncoveredInstances.length, ownerInstances.size(), msg);
213
214 for (Object uncoveredInstance : uncoveredInstances) {
215 Integer instanceId = System.identityHashCode(uncoveredInstance);
216 assertTrue(ownerInstances.contains(instanceId), msg);
217 }
218 }
219
220 protected static void verifyDataCoverage(@NonNegative int expectedItems, @NonNegative int expectedCoveredItems,
221 @NonNegative int expectedCoverage) {
222 PerFileDataCoverage info = fileData.dataCoverageInfo;
223 assertEquals(expectedItems, info.getTotalItems(), "Total data items:");
224 assertEquals(expectedCoveredItems, info.getCoveredItems(), "Covered data items:");
225 assertEquals(expectedCoverage, info.getCoveragePercentage(), "Data coverage:");
226 }
227 }