• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/main/src/main/java/mockit/coverage/lines/PerFileLineCoverage.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.coverage.lines;
7

8
import edu.umd.cs.findbugs.annotations.NonNull;
9
import edu.umd.cs.findbugs.annotations.Nullable;
10

11
import java.io.IOException;
12
import java.io.ObjectInputStream;
13
import java.util.HashMap;
14
import java.util.Map;
15
import java.util.Map.Entry;
16

17
import mockit.coverage.CallPoint;
18
import mockit.coverage.CoveragePercentage;
19
import mockit.coverage.data.PerFileCoverage;
20

21
import org.checkerframework.checker.index.qual.NonNegative;
22

23
public final class PerFileLineCoverage implements PerFileCoverage {
24
    private static final long serialVersionUID = 6318915843739466316L;
25
    private static final int[] NO_EXECUTIONS_YET = {};
×
26

27
    @NonNull
×
28
    private final Map<Integer, LineCoverageData> lineToLineData = new HashMap<>(128);
29

30
    @NonNull
×
31
    private int[] executionCounts = NO_EXECUTIONS_YET;
32

33
    @NonNull
34
    private transient LineCoverageData sharedLineData;
35

36
    // Computed on demand:
37
    @NonNegative
38
    private int lastLine;
39
    private transient int totalSegments;
40
    private transient int coveredSegments;
41

42
    public PerFileLineCoverage() {
×
43
        sharedLineData = new LineCoverageData();
×
44
        initializeCache();
×
45
    }
×
46

47
    private void initializeCache() {
48
        totalSegments = coveredSegments = -1;
×
49
    }
×
50

51
    private void readObject(@NonNull ObjectInputStream in) throws IOException, ClassNotFoundException {
52
        sharedLineData = new LineCoverageData();
×
53
        initializeCache();
×
54
        in.defaultReadObject();
×
55

56
        if (executionCounts.length == 0) {
×
57
            executionCounts = NO_EXECUTIONS_YET;
×
58
        }
59
    }
×
60

61
    public void addLine(@NonNegative int line) {
62
        if (!lineToLineData.containsKey(line)) {
×
63
            lineToLineData.put(line, null);
×
64
        }
65

66
        if (line > lastLine) {
×
67
            // Happens for source files with multiple types, where one is only loaded
68
            // after another has already executed some code.
69
            int[] initialExecutionCounts = executionCounts;
×
70

71
            if (initialExecutionCounts != NO_EXECUTIONS_YET && line >= initialExecutionCounts.length) {
×
72
                int[] newCounts = new int[line + 30];
×
73
                System.arraycopy(initialExecutionCounts, 0, newCounts, 0, initialExecutionCounts.length);
×
74
                executionCounts = newCounts;
×
75
            }
76

77
            lastLine = line;
×
78
        }
79
    }
×
80

81
    @NonNull
82
    public LineCoverageData getOrCreateLineData(@NonNegative int line) {
83
        LineCoverageData lineData = lineToLineData.get(line);
×
84

85
        if (lineData == null) {
×
86
            lineData = new LineCoverageData();
×
87
            lineToLineData.put(line, lineData);
×
88
        }
89

90
        return lineData;
×
91
    }
92

93
    @NonNull
94
    public BranchCoverageData getBranchData(@NonNegative int line, @NonNegative int index) {
95
        LineCoverageData lineData = lineToLineData.get(line);
×
96
        return lineData.getBranchData(index);
×
97
    }
98

99
    public void markLastLineSegmentAsEmpty(@NonNegative int line) {
100
        LineCoverageData lineData = lineToLineData.get(line);
×
101
        lineData.markLastSegmentAsEmpty();
×
102
    }
×
103

104
    public boolean acceptsAdditionalCallPoints(@NonNegative int line) {
105
        LineCoverageData lineData = getOrCreateLineData(line);
×
106
        return lineData.acceptsAdditionalCallPoints();
×
107
    }
108

109
    @NonNegative
110
    public int registerExecution(@NonNegative int line, @Nullable CallPoint callPoint) {
111
        if (executionCounts == NO_EXECUTIONS_YET) {
×
112
            executionCounts = new int[lastLine + 1];
×
113
        }
114

115
        int previousExecutionCount = executionCounts[line]++;
×
116

117
        if (callPoint != null) {
×
118
            LineCoverageData lineData = lineToLineData.get(line);
×
119
            lineData.registerExecution(callPoint);
×
120
        }
121

122
        return previousExecutionCount;
×
123
    }
124

125
    public boolean hasValidBranch(@NonNegative int line, @NonNegative int branchIndex) {
126
        LineCoverageData lineData = lineToLineData.get(line);
×
127
        return lineData.isValidBranch(branchIndex);
×
128
    }
129

130
    public boolean acceptsAdditionalCallPoints(@NonNegative int line, @NonNegative int branchIndex) {
131
        LineCoverageData lineData = lineToLineData.get(line);
×
132
        return lineData.acceptsAdditionalCallPoints(branchIndex);
×
133
    }
134

135
    @NonNegative
136
    public int registerExecution(@NonNegative int line, @NonNegative int branchIndex, @Nullable CallPoint callPoint) {
137
        LineCoverageData lineData = lineToLineData.get(line);
×
138
        return lineData.registerExecution(branchIndex, callPoint);
×
139
    }
140

141
    @NonNegative
142
    public int getLineCount() {
143
        return lastLine;
×
144
    }
145

146
    @NonNegative
147
    public int getExecutableLineCount() {
148
        return lineToLineData.size();
×
149
    }
150

151
    public boolean hasLineData(@NonNegative int line) {
152
        return executionCounts != NO_EXECUTIONS_YET && lineToLineData.containsKey(line);
×
153
    }
154

155
    @NonNull
156
    public LineCoverageData getLineData(@NonNegative int line) {
157
        LineCoverageData data = lineToLineData.get(line);
×
158

159
        if (data == null) {
×
160
            data = sharedLineData;
×
161
        }
162

163
        data.setExecutionCount(executionCounts[line]);
×
164
        return data;
×
165
    }
166

167
    public void markLineAsReachable(@NonNegative int line) {
168
        LineCoverageData data = lineToLineData.get(line);
×
169

170
        if (data != null) {
×
171
            data.markAsReachable();
×
172
        }
173
    }
×
174

175
    public int getExecutionCount(@NonNegative int line) {
176
        return line < executionCounts.length ? executionCounts[line] : -1;
×
177
    }
178

179
    @Override
180
    @NonNegative
181
    public int getTotalItems() {
182
        computeValuesIfNeeded();
×
183
        return totalSegments;
×
184
    }
185

186
    @Override
187
    @NonNegative
188
    public int getCoveredItems() {
189
        computeValuesIfNeeded();
×
190
        return coveredSegments;
×
191
    }
192

193
    @Override
194
    public int getCoveragePercentage() {
195
        computeValuesIfNeeded();
×
196
        return CoveragePercentage.calculate(coveredSegments, totalSegments);
×
197
    }
198

199
    private void computeValuesIfNeeded() {
200
        if (totalSegments >= 0) {
×
201
            return;
×
202
        }
203
        totalSegments = coveredSegments = 0;
×
204

205
        for (int line = 1, n = lastLine; line <= n; line++) {
×
206
            if (lineToLineData.containsKey(line)) {
×
207
                LineCoverageData lineData = lineToLineData.get(line);
×
208
                int executionCount = executionCounts == NO_EXECUTIONS_YET ? 0 : executionCounts[line];
×
209

210
                if (lineData == null) {
×
211
                    totalSegments++;
×
212

213
                    if (executionCount > 0) {
×
214
                        coveredSegments++;
×
215
                    }
216
                } else {
217
                    lineData.setExecutionCount(executionCount);
×
218
                    totalSegments += lineData.getNumberOfSegments();
×
219
                    coveredSegments += lineData.getNumberOfCoveredSegments();
×
220
                }
221
            }
222
        }
223
    }
×
224

225
    @NonNegative
226
    public int getNumberOfSegments(@NonNegative int line) {
227
        if (!lineToLineData.containsKey(line)) {
×
228
            return 0;
×
229
        }
230

231
        LineCoverageData lineData = lineToLineData.get(line);
×
232
        return lineData == null ? 1 : lineData.getNumberOfSegments();
×
233
    }
234

235
    @NonNegative
236
    public int getNumberOfBranchingSourcesAndTargets(@NonNegative int line) {
237
        LineCoverageData lineData = lineToLineData.get(line);
×
238

239
        if (lineData == null) {
×
240
            return 0;
×
241
        }
242

243
        return lineData.getNumberOfBranchingSourcesAndTargets();
×
244
    }
245

246
    public void mergeInformation(@NonNull PerFileLineCoverage previousCoverage) {
247
        Map<Integer, LineCoverageData> previousInfo = previousCoverage.lineToLineData;
×
248
        boolean previousRunHadLinesExecuted = previousCoverage.executionCounts.length > 0;
×
249

250
        for (Entry<Integer, LineCoverageData> lineAndInfo : lineToLineData.entrySet()) {
×
251
            Integer line = lineAndInfo.getKey();
×
252
            LineCoverageData previousLineInfo = previousInfo.get(line);
×
253

254
            if (previousLineInfo != null) {
×
255
                LineCoverageData lineInfo = lineAndInfo.getValue();
×
256

257
                if (lineInfo == null) {
×
258
                    lineInfo = new LineCoverageData();
×
259
                    lineAndInfo.setValue(lineInfo);
×
260
                }
261

262
                lineInfo.addCountsFromPreviousTestRun(previousLineInfo);
×
263

264
                if (previousRunHadLinesExecuted) {
×
265
                    createExecutionCountsArrayIfNeeded(previousCoverage);
×
266
                    executionCounts[line] += previousCoverage.executionCounts[line];
×
267
                }
268
            }
269
        }
×
270

271
        for (Entry<Integer, LineCoverageData> lineAndInfo : previousInfo.entrySet()) {
×
272
            Integer line = lineAndInfo.getKey();
×
273

274
            if (!lineToLineData.containsKey(line)) {
×
275
                LineCoverageData previousLineInfo = lineAndInfo.getValue();
×
276
                lineToLineData.put(line, previousLineInfo);
×
277

278
                if (previousRunHadLinesExecuted) {
×
279
                    createExecutionCountsArrayIfNeeded(previousCoverage);
×
280
                    executionCounts[line] = previousCoverage.executionCounts[line];
×
281
                }
282
            }
283
        }
×
284
    }
×
285

286
    private void createExecutionCountsArrayIfNeeded(@NonNull PerFileLineCoverage previousCoverage) {
287
        if (executionCounts == NO_EXECUTIONS_YET) {
×
288
            executionCounts = new int[previousCoverage.executionCounts.length];
×
289
        }
290
    }
×
291
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc