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