DeltaReport.java

1
package org.egothor.methodatlas;
2
3
import java.io.IOException;
4
import java.nio.charset.StandardCharsets;
5
import java.nio.file.Files;
6
import java.nio.file.Path;
7
import java.util.ArrayList;
8
import java.util.Collections;
9
import java.util.Comparator;
10
import java.util.HashMap;
11
import java.util.HashSet;
12
import java.util.LinkedHashMap;
13
import java.util.LinkedHashSet;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Optional;
17
import java.util.Set;
18
19
import org.egothor.methodatlas.api.ScanRecord;
20
21
/**
22
 * Computes the difference between two MethodAtlas scan outputs.
23
 *
24
 * <h2>Overview</h2>
25
 *
26
 * <p>
27
 * {@link #compute(Path, Path)} parses two MethodAtlas CSV files produced by
28
 * separate scan runs and returns a {@link DeltaResult} that enumerates every
29
 * test method that was added, removed, or modified between the runs. Unchanged
30
 * methods are counted but not listed individually.
31
 * </p>
32
 *
33
 * <h2>Method identity</h2>
34
 *
35
 * <p>
36
 * Two records are considered to represent the same method when their
37
 * {@code fqcn} and {@code method} columns match exactly. If a class or method
38
 * is renamed between scans, the old name appears as {@code REMOVED} and the
39
 * new name appears as {@code ADDED}. MethodAtlas does not attempt to track
40
 * renames.
41
 * </p>
42
 *
43
 * <h2>Comparable fields</h2>
44
 *
45
 * <p>
46
 * For each method present in both scans, the following fields are compared:
47
 * </p>
48
 *
49
 * <ul>
50
 * <li>{@code loc} — lines of code; always compared</li>
51
 * <li>{@code tags} — JUnit {@code @Tag} set; always compared (order-independent)</li>
52
 * <li>{@code display_name} — {@code @DisplayName} annotation value; always compared;
53
 *     {@code null} (column absent from the CSV) and {@code ""} (column present but
54
 *     no annotation on the method) are both treated as "no annotation" and considered
55
 *     equal, so comparing an old-format file against a new-format file does not
56
 *     produce false positives for methods that have no annotation in either scan</li>
57
 * <li>{@code content_hash} — source fingerprint; compared only when both records
58
 *     have a non-{@code null} value (i.e., both scans were run with
59
 *     {@code -content-hash}); a hash difference indicates the enclosing class
60
 *     source was edited</li>
61
 * <li>{@code ai_security_relevant} — compared only when both records carry a
62
 *     non-{@code null} value (both scans used {@code -ai})</li>
63
 * <li>{@code ai_tags} — compared only when both records carry a non-{@code null}
64
 *     value; comparison is order-independent</li>
65
 * </ul>
66
 *
67
 * <p>
68
 * Fields absent from either record (i.e., produced by scans with different flag
69
 * sets) are skipped so that a scan with {@code -content-hash} can be meaningfully
70
 * compared with one that did not use that flag.
71
 * </p>
72
 *
73
 * <h2>CSV format compatibility</h2>
74
 *
75
 * <p>
76
 * The parser handles the MethodAtlas CSV dialect (RFC 4180, comma-delimited,
77
 * double-quote escaping). {@code #}-prefixed comment lines emitted by
78
 * {@code -emit-metadata} are skipped; the {@code scan_timestamp} metadata value
79
 * is extracted and forwarded to {@link DeltaResult} for display. Blank lines
80
 * are ignored. Unknown column names are ignored, making the parser
81
 * forward-compatible with columns added in future versions.
82
 * </p>
83
 *
84
 * @see DeltaEntry
85
 * @see org.egothor.methodatlas.emit.DeltaEmitter
86
 */
87
public final class DeltaReport {
88
89
    private static final char CSV_QUOTE = '"';
90
    private static final char CSV_COMMA = ',';
91
92
    private DeltaReport() {
93
    }
94
95
    // -------------------------------------------------------------------------
96
    // Public API
97
    // -------------------------------------------------------------------------
98
99
    /**
100
     * Computes the difference between two MethodAtlas scan CSV files.
101
     *
102
     * <p>
103
     * Both files must be readable and must contain at least a CSV header row
104
     * with {@code fqcn} and {@code method} columns. Empty files (no data rows)
105
     * are handled gracefully and produce only {@code ADDED} or {@code REMOVED}
106
     * entries as appropriate.
107
     * </p>
108
     *
109
     * @param beforeCsv path to the scan output from the earlier run
110
     * @param afterCsv  path to the scan output from the later run
111
     * @return delta result; never {@code null}
112
     * @throws IOException              if either file cannot be read
113
     * @throws IllegalArgumentException if a required column ({@code fqcn} or
114
     *                                  {@code method}) is absent from a file
115
     */
116
    public static DeltaResult compute(Path beforeCsv, Path afterCsv) throws IOException {
117
        ParsedCsv before = parseCsv(beforeCsv);
118
        ParsedCsv after = parseCsv(afterCsv);
119
120
        // Build key → record maps; LinkedHashMap preserves file order, which produces
121
        // stable output when two runs scan the same sources in the same order.
122
        Map<String, ScanRecord> beforeMap = buildMap(before.records());
123
        Map<String, ScanRecord> afterMap = buildMap(after.records());
124
125
        List<DeltaEntry> entries = new ArrayList<>();
126
        int unchanged = 0;
127
128
        // Pass 1: check every before record against after.
129
        for (Map.Entry<String, ScanRecord> e : beforeMap.entrySet()) {
130
            ScanRecord afterRecord = afterMap.get(e.getKey());
131 2 1. compute : removed conditional - replaced equality check with true → KILLED
2. compute : removed conditional - replaced equality check with false → KILLED
            if (afterRecord == null) {
132
                entries.add(DeltaEntry.removed(e.getValue()));
133
            } else {
134
                Set<String> changed = findChangedFields(e.getValue(), afterRecord);
135 2 1. compute : removed conditional - replaced equality check with false → KILLED
2. compute : removed conditional - replaced equality check with true → KILLED
                if (changed.isEmpty()) {
136 1 1. compute : Changed increment from 1 to -1 → KILLED
                    unchanged++;
137
                } else {
138
                    entries.add(DeltaEntry.modified(e.getValue(), afterRecord, changed));
139
                }
140
            }
141
        }
142
143
        // Pass 2: find records in after that are not in before (ADDED).
144
        for (Map.Entry<String, ScanRecord> e : afterMap.entrySet()) {
145 2 1. compute : removed conditional - replaced equality check with false → KILLED
2. compute : removed conditional - replaced equality check with true → KILLED
            if (!beforeMap.containsKey(e.getKey())) {
146
                entries.add(DeltaEntry.added(e.getValue()));
147
            }
148
        }
149
150
        // Sort by (fqcn, method) so all changes to a class are grouped together.
151 1 1. compute : removed call to java/util/List::sort → SURVIVED
        entries.sort(Comparator
152 1 1. lambda$compute$0 : replaced return value with "" for org/egothor/methodatlas/DeltaReport::lambda$compute$0 → SURVIVED
                .<DeltaEntry, String>comparing(e -> e.record().fqcn())
153 1 1. lambda$compute$1 : replaced return value with "" for org/egothor/methodatlas/DeltaReport::lambda$compute$1 → SURVIVED
                .thenComparing(e -> e.record().method()));
154
155 1 1. compute : replaced return value with null for org/egothor/methodatlas/DeltaReport::compute → KILLED
        return new DeltaResult(
156
                beforeCsv, afterCsv,
157
                before.scanTimestamp(), after.scanTimestamp(),
158
                beforeMap.size(), afterMap.size(),
159
                countSecurityRelevant(before.records()),
160
                countSecurityRelevant(after.records()),
161
                Collections.unmodifiableList(entries),
162
                unchanged);
163
    }
164
165
    // -------------------------------------------------------------------------
166
    // Result type
167
    // -------------------------------------------------------------------------
168
169
    /**
170
     * The aggregate result of comparing two MethodAtlas scan outputs.
171
     *
172
     * <p>
173
     * The {@link #entries()} list contains only changed methods (ADDED, REMOVED,
174
     * MODIFIED). Unchanged methods are represented only by the
175
     * {@link #unchangedCount()} counter to keep the report concise.
176
     * </p>
177
     *
178
     * @param beforePath               path to the <em>before</em> CSV file
179
     * @param afterPath                path to the <em>after</em> CSV file
180
     * @param beforeTimestamp          {@code scan_timestamp} metadata extracted
181
     *                                 from the <em>before</em> file, or
182
     *                                 {@code null} when the file was produced
183
     *                                 without {@code -emit-metadata}
184
     * @param afterTimestamp           {@code scan_timestamp} metadata extracted
185
     *                                 from the <em>after</em> file, or {@code null}
186
     * @param totalBefore              total number of test methods in the
187
     *                                 <em>before</em> scan
188
     * @param totalAfter               total number of test methods in the
189
     *                                 <em>after</em> scan
190
     * @param securityRelevantBefore   number of security-relevant methods in the
191
     *                                 <em>before</em> scan; {@code 0} when no AI
192
     *                                 columns were present
193
     * @param securityRelevantAfter    number of security-relevant methods in the
194
     *                                 <em>after</em> scan; {@code 0} when no AI
195
     *                                 columns were present
196
     * @param entries                  unmodifiable list of changed entries in
197
     *                                 (fqcn, method) order
198
     * @param unchangedCount           number of methods present in both scans
199
     *                                 with no detected differences
200
     */
201
    public record DeltaResult(
202
            Path beforePath,
203
            Path afterPath,
204
            String beforeTimestamp,
205
            String afterTimestamp,
206
            int totalBefore,
207
            int totalAfter,
208
            int securityRelevantBefore,
209
            int securityRelevantAfter,
210
            List<DeltaEntry> entries,
211
            int unchangedCount) {
212
213
        /** Returns the number of {@link DeltaEntry.ChangeType#ADDED} entries. */
214
        public int addedCount() {
215 1 1. addedCount : replaced int return with 0 for org/egothor/methodatlas/DeltaReport$DeltaResult::addedCount → KILLED
            return (int) entries.stream()
216 3 1. lambda$addedCount$0 : removed conditional - replaced equality check with true → KILLED
2. lambda$addedCount$0 : removed conditional - replaced equality check with false → KILLED
3. lambda$addedCount$0 : replaced boolean return with true for org/egothor/methodatlas/DeltaReport$DeltaResult::lambda$addedCount$0 → KILLED
                    .filter(e -> e.changeType() == DeltaEntry.ChangeType.ADDED).count();
217
        }
218
219
        /** Returns the number of {@link DeltaEntry.ChangeType#REMOVED} entries. */
220
        public int removedCount() {
221 1 1. removedCount : replaced int return with 0 for org/egothor/methodatlas/DeltaReport$DeltaResult::removedCount → KILLED
            return (int) entries.stream()
222 3 1. lambda$removedCount$1 : removed conditional - replaced equality check with false → KILLED
2. lambda$removedCount$1 : replaced boolean return with true for org/egothor/methodatlas/DeltaReport$DeltaResult::lambda$removedCount$1 → KILLED
3. lambda$removedCount$1 : removed conditional - replaced equality check with true → KILLED
                    .filter(e -> e.changeType() == DeltaEntry.ChangeType.REMOVED).count();
223
        }
224
225
        /** Returns the number of {@link DeltaEntry.ChangeType#MODIFIED} entries. */
226
        public int modifiedCount() {
227 1 1. modifiedCount : replaced int return with 0 for org/egothor/methodatlas/DeltaReport$DeltaResult::modifiedCount → KILLED
            return (int) entries.stream()
228 3 1. lambda$modifiedCount$2 : removed conditional - replaced equality check with false → KILLED
2. lambda$modifiedCount$2 : replaced boolean return with true for org/egothor/methodatlas/DeltaReport$DeltaResult::lambda$modifiedCount$2 → KILLED
3. lambda$modifiedCount$2 : removed conditional - replaced equality check with true → KILLED
                    .filter(e -> e.changeType() == DeltaEntry.ChangeType.MODIFIED).count();
229
        }
230
    }
231
232
    // -------------------------------------------------------------------------
233
    // CSV parsing — package-private for testing
234
    // -------------------------------------------------------------------------
235
236
    /**
237
     * Returns all scan records from the given MethodAtlas CSV file.
238
     *
239
     * <p>Used by {@link AiResultCache} to build an in-memory lookup from a previous
240
     * scan output without going through the full delta-comparison path.</p>
241
     *
242
     * @param csvPath path to a MethodAtlas CSV output file
243
     * @return unmodifiable list of parsed records; empty when the file has no data rows
244
     * @throws IOException if the file cannot be read
245
     */
246
    /* default */ static List<ScanRecord> loadRecords(Path csvPath) throws IOException {
247 1 1. loadRecords : replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::loadRecords → KILLED
        return parseCsv(csvPath).records();
248
    }
249
250
    /**
251
     * Parses one line of a MethodAtlas CSV file according to RFC 4180.
252
     *
253
     * <p>
254
     * Fields may be optionally enclosed in double quotes. A double-quote
255
     * character within a quoted field is escaped as two consecutive
256
     * double-quotes ({@code ""}). The delimiter is a comma. A line ending with
257
     * a comma produces a trailing empty field.
258
     * </p>
259
     *
260
     * @param line the raw CSV line to parse (no line terminator)
261
     * @return list of unescaped field values; never {@code null}
262
     */
263
    /* default */ static List<String> parseCsvLine(String line) {
264
        List<String> result = new ArrayList<>();
265
        StringBuilder field = new StringBuilder();
266
        int pos = 0;
267
268 3 1. parseCsvLine : changed conditional boundary → KILLED
2. parseCsvLine : removed conditional - replaced comparison check with true → KILLED
3. parseCsvLine : removed conditional - replaced comparison check with false → KILLED
        while (pos < line.length()) {
269
            char c = line.charAt(pos);
270 2 1. parseCsvLine : removed conditional - replaced equality check with true → KILLED
2. parseCsvLine : removed conditional - replaced equality check with false → KILLED
            if (c == CSV_QUOTE) {
271 1 1. parseCsvLine : Replaced integer addition with subtraction → KILLED
                pos = parseQuotedField(line, pos + 1, field);
272
                // pos now points one past the closing quote (or end of string)
273 2 1. parseCsvLine : removed conditional - replaced equality check with true → KILLED
2. parseCsvLine : removed conditional - replaced equality check with false → KILLED
            } else if (c == CSV_COMMA) {
274
                result.add(field.toString());
275 1 1. parseCsvLine : removed call to java/lang/StringBuilder::setLength → KILLED
                field.setLength(0);
276 1 1. parseCsvLine : Changed increment from 1 to -1 → TIMED_OUT
                pos++;
277
            } else {
278
                field.append(c);
279 1 1. parseCsvLine : Changed increment from 1 to -1 → KILLED
                pos++;
280
            }
281
        }
282
        result.add(field.toString()); // always add the last (or only) field
283 1 1. parseCsvLine : replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseCsvLine → KILLED
        return result;
284
    }
285
286
    /**
287
     * Parses characters of a quoted CSV field starting just after the opening quote,
288
     * appending unescaped characters to {@code field}.
289
     *
290
     * @param line  the full CSV line
291
     * @param start position of the first character inside the quoted field
292
     * @param field buffer receiving unescaped field content
293
     * @return position of the character immediately after the closing quote,
294
     *         or {@code line.length()} when the line ends before a closing quote
295
     */
296
    private static int parseQuotedField(String line, int start, StringBuilder field) {
297
        int pos = start;
298 3 1. parseQuotedField : changed conditional boundary → SURVIVED
2. parseQuotedField : removed conditional - replaced comparison check with true → SURVIVED
3. parseQuotedField : removed conditional - replaced comparison check with false → KILLED
        while (pos < line.length()) {
299
            char c = line.charAt(pos);
300 2 1. parseQuotedField : removed conditional - replaced equality check with true → KILLED
2. parseQuotedField : removed conditional - replaced equality check with false → KILLED
            if (c == CSV_QUOTE) {
301 7 1. parseQuotedField : removed conditional - replaced comparison check with true → SURVIVED
2. parseQuotedField : changed conditional boundary → SURVIVED
3. parseQuotedField : Replaced integer addition with subtraction → SURVIVED
4. parseQuotedField : removed conditional - replaced equality check with false → KILLED
5. parseQuotedField : removed conditional - replaced comparison check with false → KILLED
6. parseQuotedField : Replaced integer addition with subtraction → KILLED
7. parseQuotedField : removed conditional - replaced equality check with true → KILLED
                if (pos + 1 < line.length() && line.charAt(pos + 1) == CSV_QUOTE) {
302
                    field.append(CSV_QUOTE);
303 1 1. parseQuotedField : Changed increment from 2 to -2 → KILLED
                    pos += 2; // skip both quotes of the escape sequence
304
                } else {
305 2 1. parseQuotedField : replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseQuotedField → TIMED_OUT
2. parseQuotedField : Replaced integer addition with subtraction → KILLED
                    return pos + 1; // closing quote consumed; return position after it
306
                }
307
            } else {
308
                field.append(c);
309 1 1. parseQuotedField : Changed increment from 1 to -1 → KILLED
                pos++;
310
            }
311
        }
312 1 1. parseQuotedField : replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseQuotedField → NO_COVERAGE
        return pos; // unterminated quoted field — treat end-of-line as closing
313
    }
314
315
    // -------------------------------------------------------------------------
316
    // Private helpers
317
    // -------------------------------------------------------------------------
318
319
    /** Intermediate result of reading a CSV file. */
320
    private record ParsedCsv(List<ScanRecord> records, String scanTimestamp) {
321
    }
322
323
    private static ParsedCsv parseCsv(Path path) throws IOException {
324
        List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
325
326
        String timestamp = null;
327
        List<String> dataLines = new ArrayList<>();
328
329
        for (String line : lines) {
330 2 1. parseCsv : removed conditional - replaced equality check with true → KILLED
2. parseCsv : removed conditional - replaced equality check with false → KILLED
            if (line.startsWith("#")) {
331 2 1. parseCsv : removed conditional - replaced equality check with false → KILLED
2. parseCsv : removed conditional - replaced equality check with true → KILLED
                if (line.startsWith("# scan_timestamp:")) {
332
                    timestamp = line.substring("# scan_timestamp:".length()).trim();
333
                }
334 2 1. parseCsv : removed conditional - replaced equality check with true → SURVIVED
2. parseCsv : removed conditional - replaced equality check with false → KILLED
            } else if (!line.isBlank()) {
335
                dataLines.add(line);
336
            }
337
        }
338
339 2 1. parseCsv : removed conditional - replaced equality check with false → SURVIVED
2. parseCsv : removed conditional - replaced equality check with true → KILLED
        if (dataLines.isEmpty()) {
340 1 1. parseCsv : replaced return value with null for org/egothor/methodatlas/DeltaReport::parseCsv → NO_COVERAGE
            return new ParsedCsv(List.of(), timestamp);
341
        }
342
343
        // First non-comment, non-blank line is the CSV header.
344
        List<String> header = parseCsvLine(dataLines.get(0));
345
        Map<String, Integer> colIndex = new HashMap<>();
346 3 1. parseCsv : changed conditional boundary → KILLED
2. parseCsv : removed conditional - replaced comparison check with true → KILLED
3. parseCsv : removed conditional - replaced comparison check with false → KILLED
        for (int i = 0; i < header.size(); i++) {
347
            colIndex.put(header.get(i).trim(), i);
348
        }
349
350 1 1. parseCsv : Replaced integer subtraction with addition → SURVIVED
        List<ScanRecord> records = new ArrayList<>(dataLines.size() - 1);
351 3 1. parseCsv : removed conditional - replaced comparison check with true → KILLED
2. parseCsv : changed conditional boundary → KILLED
3. parseCsv : removed conditional - replaced comparison check with false → KILLED
        for (int i = 1; i < dataLines.size(); i++) {
352
            List<String> fields = parseCsvLine(dataLines.get(i));
353
            records.add(toScanRecord(fields, colIndex));
354
        }
355
356 1 1. parseCsv : replaced return value with null for org/egothor/methodatlas/DeltaReport::parseCsv → KILLED
        return new ParsedCsv(Collections.unmodifiableList(records), timestamp);
357
    }
358
359
    private static ScanRecord toScanRecord(List<String> fields, Map<String, Integer> colIndex) {
360 1 1. toScanRecord : replaced return value with null for org/egothor/methodatlas/DeltaReport::toScanRecord → KILLED
        return new ScanRecord(
361
                requireField(fields, colIndex, "fqcn"),
362
                requireField(fields, colIndex, "method"),
363
                parseInt(getField(fields, colIndex, "loc"), 0),
364
                parseSemicolonList(getField(fields, colIndex, "tags")),
365
                getFieldPreserveEmpty(fields, colIndex, "display_name"),
366
                getField(fields, colIndex, "content_hash"),
367
                parseBoolean(getField(fields, colIndex, "ai_security_relevant")).orElse(null),
368
                getField(fields, colIndex, "ai_display_name"),
369
                parseSemicolonListOrNull(fields, colIndex, "ai_tags"),
370
                getField(fields, colIndex, "ai_reason"),
371
                parseDouble(getField(fields, colIndex, "ai_confidence")),
372
                parseDouble(getField(fields, colIndex, "ai_interaction_score")),
373
                getField(fields, colIndex, "tag_ai_drift"));
374
    }
375
376
    private static Map<String, ScanRecord> buildMap(List<ScanRecord> records) {
377 1 1. buildMap : Replaced integer multiplication with division → SURVIVED
        Map<String, ScanRecord> map = new LinkedHashMap<>(records.size() * 2);
378
        for (ScanRecord r : records) {
379
            map.put(key(r), r);
380
        }
381 1 1. buildMap : replaced return value with Collections.emptyMap for org/egothor/methodatlas/DeltaReport::buildMap → KILLED
        return map;
382
    }
383
384
    private static String key(ScanRecord r) {
385 1 1. key : replaced return value with "" for org/egothor/methodatlas/DeltaReport::key → KILLED
        return r.fqcn() + "::" + r.method();
386
    }
387
388
    private static int countSecurityRelevant(List<ScanRecord> records) {
389 1 1. countSecurityRelevant : replaced int return with 0 for org/egothor/methodatlas/DeltaReport::countSecurityRelevant → KILLED
        return (int) records.stream()
390 2 1. lambda$countSecurityRelevant$2 : replaced boolean return with true for org/egothor/methodatlas/DeltaReport::lambda$countSecurityRelevant$2 → KILLED
2. lambda$countSecurityRelevant$2 : replaced boolean return with false for org/egothor/methodatlas/DeltaReport::lambda$countSecurityRelevant$2 → KILLED
                .filter(r -> Boolean.TRUE.equals(r.aiSecurityRelevant())).count();
391
    }
392
393
    /**
394
     * Returns the set of field names whose values differ between {@code before} and
395
     * {@code after}.
396
     *
397
     * <p>
398
     * A field is included in the result only when it is non-{@code null} in
399
     * <em>both</em> records, ensuring that differences caused by different scan
400
     * flag sets (e.g. one run with {@code -content-hash}, one without) are not
401
     * falsely reported as modifications.
402
     * </p>
403
     */
404
    private static Set<String> findChangedFields(ScanRecord before, ScanRecord after) {
405
        Set<String> changed = new LinkedHashSet<>();
406
407 2 1. findChangedFields : removed conditional - replaced equality check with true → KILLED
2. findChangedFields : removed conditional - replaced equality check with false → KILLED
        if (before.loc() != after.loc()) {
408
            changed.add("loc");
409
        }
410 2 1. findChangedFields : removed conditional - replaced equality check with false → SURVIVED
2. findChangedFields : removed conditional - replaced equality check with true → KILLED
        if (!tagsEqual(before.tags(), after.tags())) {
411
            changed.add("tags");
412
        }
413 2 1. findChangedFields : removed conditional - replaced equality check with true → KILLED
2. findChangedFields : removed conditional - replaced equality check with false → KILLED
        if (!displayNameEqual(before.displayName(), after.displayName())) {
414
            changed.add("display_name");
415
        }
416 1 1. findChangedFields : removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → KILLED
        addIfBothPresentAndChanged(changed, "source", before.contentHash(), after.contentHash());
417 1 1. findChangedFields : removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → KILLED
        addIfBothPresentAndChanged(changed, "ai_security_relevant",
418
                before.aiSecurityRelevant(), after.aiSecurityRelevant());
419 4 1. findChangedFields : removed conditional - replaced equality check with true → SURVIVED
2. findChangedFields : removed conditional - replaced equality check with true → SURVIVED
3. findChangedFields : removed conditional - replaced equality check with false → KILLED
4. findChangedFields : removed conditional - replaced equality check with false → KILLED
        if (before.aiTags() != null && after.aiTags() != null
420 2 1. findChangedFields : removed conditional - replaced equality check with true → SURVIVED
2. findChangedFields : removed conditional - replaced equality check with false → KILLED
                && !new HashSet<>(before.aiTags()).equals(new HashSet<>(after.aiTags()))) {
421
            changed.add("ai_tags");
422
        }
423 1 1. findChangedFields : removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → SURVIVED
        addIfBothPresentAndChanged(changed, "ai_interaction_score",
424
                before.aiInteractionScore(), after.aiInteractionScore());
425 1 1. findChangedFields : removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → SURVIVED
        addIfBothPresentAndChanged(changed, "tag_ai_drift", before.tagAiDrift(), after.tagAiDrift());
426
427 1 1. findChangedFields : replaced return value with Collections.emptySet for org/egothor/methodatlas/DeltaReport::findChangedFields → KILLED
        return changed;
428
    }
429
430
    /**
431
     * Adds {@code fieldName} to {@code changed} when both values are non-{@code null}
432
     * and not equal.  Fields absent from either record (produced by scans with different
433
     * flag sets) are skipped so that they are not falsely reported as modifications.
434
     */
435
    private static void addIfBothPresentAndChanged(Set<String> changed, String fieldName,
436
            Object before, Object after) {
437 6 1. addIfBothPresentAndChanged : removed conditional - replaced equality check with true → SURVIVED
2. addIfBothPresentAndChanged : removed conditional - replaced equality check with true → SURVIVED
3. addIfBothPresentAndChanged : removed conditional - replaced equality check with true → KILLED
4. addIfBothPresentAndChanged : removed conditional - replaced equality check with false → KILLED
5. addIfBothPresentAndChanged : removed conditional - replaced equality check with false → KILLED
6. addIfBothPresentAndChanged : removed conditional - replaced equality check with false → KILLED
        if (before != null && after != null && !before.equals(after)) {
438
            changed.add(fieldName);
439
        }
440
    }
441
442
    private static boolean tagsEqual(List<String> a, List<String> b) {
443 2 1. tagsEqual : replaced boolean return with true for org/egothor/methodatlas/DeltaReport::tagsEqual → SURVIVED
2. tagsEqual : replaced boolean return with false for org/egothor/methodatlas/DeltaReport::tagsEqual → KILLED
        return new HashSet<>(a).equals(new HashSet<>(b));
444
    }
445
446
    /**
447
     * Returns {@code true} when two {@code display_name} values are semantically
448
     * equal. {@code null} (column absent from the CSV) and {@code ""} (column
449
     * present but no {@code @DisplayName} annotation) both mean "no annotation",
450
     * so they are treated as equal. Any non-empty value must match exactly.
451
     */
452
    private static boolean displayNameEqual(String a, String b) {
453 2 1. displayNameEqual : removed conditional - replaced equality check with true → SURVIVED
2. displayNameEqual : removed conditional - replaced equality check with false → KILLED
        String normalA = a == null ? "" : a;
454 2 1. displayNameEqual : removed conditional - replaced equality check with true → KILLED
2. displayNameEqual : removed conditional - replaced equality check with false → KILLED
        String normalB = b == null ? "" : b;
455 2 1. displayNameEqual : replaced boolean return with false for org/egothor/methodatlas/DeltaReport::displayNameEqual → KILLED
2. displayNameEqual : replaced boolean return with true for org/egothor/methodatlas/DeltaReport::displayNameEqual → KILLED
        return normalA.equals(normalB);
456
    }
457
458
    // -------------------------------------------------------------------------
459
    // Field extraction helpers
460
    // -------------------------------------------------------------------------
461
462
    /**
463
     * Returns the field value at the named column, or {@code null} when the column
464
     * is absent or the value is empty.
465
     */
466
    private static String getField(List<String> fields, Map<String, Integer> colIndex, String col) {
467
        Integer idx = colIndex.get(col);
468 5 1. getField : removed conditional - replaced comparison check with false → SURVIVED
2. getField : changed conditional boundary → SURVIVED
3. getField : removed conditional - replaced comparison check with true → KILLED
4. getField : removed conditional - replaced equality check with true → KILLED
5. getField : removed conditional - replaced equality check with false → KILLED
        if (idx == null || idx >= fields.size()) {
469 1 1. getField : replaced return value with "" for org/egothor/methodatlas/DeltaReport::getField → KILLED
            return null;
470
        }
471
        String val = fields.get(idx);
472 5 1. getField : removed conditional - replaced equality check with false → SURVIVED
2. getField : removed conditional - replaced equality check with true → SURVIVED
3. getField : removed conditional - replaced equality check with true → KILLED
4. getField : replaced return value with "" for org/egothor/methodatlas/DeltaReport::getField → KILLED
5. getField : removed conditional - replaced equality check with false → KILLED
        return (val == null || val.isEmpty()) ? null : val;
473
    }
474
475
    /**
476
     * Returns the field value at the named column preserving empty strings as
477
     * distinct from a missing column.
478
     *
479
     * <p>Returns {@code null} when the column is absent from the header. Returns
480
     * {@code ""} when the column is present but the cell value is empty. Returns
481
     * the raw value otherwise.
482
     *
483
     * <p>Use this instead of {@link #getField} for columns where an empty value
484
     * carries semantics different from a missing column — e.g. {@code display_name}
485
     * where empty means "remove the annotation" and absent means "leave unchanged".
486
     */
487
    private static String getFieldPreserveEmpty(List<String> fields, Map<String, Integer> colIndex, String col) {
488
        Integer idx = colIndex.get(col);
489 5 1. getFieldPreserveEmpty : changed conditional boundary → KILLED
2. getFieldPreserveEmpty : removed conditional - replaced comparison check with false → KILLED
3. getFieldPreserveEmpty : removed conditional - replaced comparison check with true → KILLED
4. getFieldPreserveEmpty : removed conditional - replaced equality check with true → KILLED
5. getFieldPreserveEmpty : removed conditional - replaced equality check with false → KILLED
        if (idx == null || idx >= fields.size()) {
490 1 1. getFieldPreserveEmpty : replaced return value with "" for org/egothor/methodatlas/DeltaReport::getFieldPreserveEmpty → KILLED
            return null;
491
        }
492
        String val = fields.get(idx);
493 3 1. getFieldPreserveEmpty : removed conditional - replaced equality check with false → SURVIVED
2. getFieldPreserveEmpty : replaced return value with "" for org/egothor/methodatlas/DeltaReport::getFieldPreserveEmpty → KILLED
3. getFieldPreserveEmpty : removed conditional - replaced equality check with true → KILLED
        return val == null ? "" : val;
494
    }
495
496
    /**
497
     * Returns the field value at the named column; throws when the column is absent
498
     * from the header.
499
     */
500
    private static String requireField(List<String> fields, Map<String, Integer> colIndex, String col) {
501
        Integer idx = colIndex.get(col);
502 2 1. requireField : removed conditional - replaced equality check with false → KILLED
2. requireField : removed conditional - replaced equality check with true → KILLED
        if (idx == null) {
503
            throw new IllegalArgumentException("Required CSV column missing: " + col);
504
        }
505 3 1. requireField : changed conditional boundary → SURVIVED
2. requireField : removed conditional - replaced comparison check with false → SURVIVED
3. requireField : removed conditional - replaced comparison check with true → KILLED
        if (idx >= fields.size()) {
506
            return "";
507
        }
508
        String val = fields.get(idx);
509 2 1. requireField : removed conditional - replaced equality check with true → SURVIVED
2. requireField : removed conditional - replaced equality check with false → KILLED
        return val != null ? val : "";
510
    }
511
512
    private static int parseInt(String val, int defaultValue) {
513 2 1. parseInt : removed conditional - replaced equality check with false → SURVIVED
2. parseInt : removed conditional - replaced equality check with true → KILLED
        if (val == null) {
514 1 1. parseInt : replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseInt → NO_COVERAGE
            return defaultValue;
515
        }
516
        try {
517 1 1. parseInt : replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseInt → KILLED
            return Integer.parseInt(val.trim());
518
        } catch (NumberFormatException e) {
519 1 1. parseInt : replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseInt → NO_COVERAGE
            return defaultValue;
520
        }
521
    }
522
523
    private static Optional<Boolean> parseBoolean(String val) {
524 4 1. parseBoolean : removed conditional - replaced equality check with false → SURVIVED
2. parseBoolean : removed conditional - replaced equality check with true → KILLED
3. parseBoolean : removed conditional - replaced equality check with true → KILLED
4. parseBoolean : removed conditional - replaced equality check with false → KILLED
        if (val == null || val.isEmpty()) {
525
            return Optional.empty();
526
        }
527 1 1. parseBoolean : replaced return value with Optional.empty for org/egothor/methodatlas/DeltaReport::parseBoolean → KILLED
        return Optional.of(Boolean.parseBoolean(val.trim()));
528
    }
529
530
    private static Double parseDouble(String val) {
531 2 1. parseDouble : removed conditional - replaced equality check with false → KILLED
2. parseDouble : removed conditional - replaced equality check with true → KILLED
        if (val == null) {
532 1 1. parseDouble : replaced Double return value with 0 for org/egothor/methodatlas/DeltaReport::parseDouble → SURVIVED
            return null;
533
        }
534
        try {
535 1 1. parseDouble : replaced Double return value with 0 for org/egothor/methodatlas/DeltaReport::parseDouble → KILLED
            return Double.parseDouble(val.trim());
536
        } catch (NumberFormatException e) {
537 1 1. parseDouble : replaced Double return value with 0 for org/egothor/methodatlas/DeltaReport::parseDouble → NO_COVERAGE
            return null;
538
        }
539
    }
540
541
    /**
542
     * Parses a semicolon-separated tag list. Returns an empty list for a blank
543
     * value; never {@code null}.
544
     */
545
    private static List<String> parseSemicolonList(String val) {
546 4 1. parseSemicolonList : removed conditional - replaced equality check with false → SURVIVED
2. parseSemicolonList : removed conditional - replaced equality check with true → KILLED
3. parseSemicolonList : removed conditional - replaced equality check with false → KILLED
4. parseSemicolonList : removed conditional - replaced equality check with true → KILLED
        if (val == null || val.isEmpty()) {
547
            return List.of();
548
        }
549
        List<String> result = new ArrayList<>();
550
        for (String part : val.split(";", -1)) {
551
            String trimmed = part.trim();
552 2 1. parseSemicolonList : removed conditional - replaced equality check with true → SURVIVED
2. parseSemicolonList : removed conditional - replaced equality check with false → KILLED
            if (!trimmed.isEmpty()) {
553
                result.add(trimmed);
554
            }
555
        }
556 1 1. parseSemicolonList : replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseSemicolonList → KILLED
        return Collections.unmodifiableList(result);
557
    }
558
559
    /**
560
     * Like {@link #parseSemicolonList(String)} but returns {@code null} when the
561
     * column is entirely absent from the file (versus present but empty). This
562
     * distinction matters for AI tag comparison: a column absent from the header
563
     * means AI was not run at all, while an empty column value means AI ran but
564
     * assigned no tags.
565
     */
566
    @SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull")
567
    private static List<String> parseSemicolonListOrNull(List<String> fields,
568
            Map<String, Integer> colIndex, String col) {
569
        Integer idx = colIndex.get(col);
570 2 1. parseSemicolonListOrNull : removed conditional - replaced equality check with true → KILLED
2. parseSemicolonListOrNull : removed conditional - replaced equality check with false → KILLED
        if (idx == null) {
571 1 1. parseSemicolonListOrNull : replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseSemicolonListOrNull → SURVIVED
            return null; // column absent — AI not run; null is semantically distinct from empty list
572
        }
573 3 1. parseSemicolonListOrNull : removed conditional - replaced comparison check with true → SURVIVED
2. parseSemicolonListOrNull : changed conditional boundary → SURVIVED
3. parseSemicolonListOrNull : removed conditional - replaced comparison check with false → KILLED
        String val = idx < fields.size() ? fields.get(idx) : null;
574 1 1. parseSemicolonListOrNull : replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseSemicolonListOrNull → KILLED
        return parseSemicolonList(val);
575
    }
576
}

Mutations

131

1.1
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

135

1.1
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

136

1.1
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_identicalFiles_noEntries(java.nio.file.Path)]
Changed increment from 1 to -1 → KILLED

145

1.1
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_methodAddedInAfter_detectedAsAdded(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

151

1.1
Location : compute
Killed by : none
removed call to java/util/List::sort → SURVIVED
Covering tests

152

1.1
Location : lambda$compute$0
Killed by : none
replaced return value with "" for org/egothor/methodatlas/DeltaReport::lambda$compute$0 → SURVIVED
Covering tests

153

1.1
Location : lambda$compute$1
Killed by : none
replaced return value with "" for org/egothor/methodatlas/DeltaReport::lambda$compute$1 → SURVIVED
Covering tests

155

1.1
Location : compute
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
replaced return value with null for org/egothor/methodatlas/DeltaReport::compute → KILLED

215

1.1
Location : addedCount
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
replaced int return with 0 for org/egothor/methodatlas/DeltaReport$DeltaResult::addedCount → KILLED

216

1.1
Location : lambda$addedCount$0
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : lambda$addedCount$0
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : lambda$addedCount$0
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
replaced boolean return with true for org/egothor/methodatlas/DeltaReport$DeltaResult::lambda$addedCount$0 → KILLED

221

1.1
Location : removedCount
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
replaced int return with 0 for org/egothor/methodatlas/DeltaReport$DeltaResult::removedCount → KILLED

222

1.1
Location : lambda$removedCount$1
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : lambda$removedCount$1
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
replaced boolean return with true for org/egothor/methodatlas/DeltaReport$DeltaResult::lambda$removedCount$1 → KILLED

3.3
Location : lambda$removedCount$1
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
removed conditional - replaced equality check with true → KILLED

227

1.1
Location : modifiedCount
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
replaced int return with 0 for org/egothor/methodatlas/DeltaReport$DeltaResult::modifiedCount → KILLED

228

1.1
Location : lambda$modifiedCount$2
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : lambda$modifiedCount$2
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
replaced boolean return with true for org/egothor/methodatlas/DeltaReport$DeltaResult::lambda$modifiedCount$2 → KILLED

3.3
Location : lambda$modifiedCount$2
Killed by : org.egothor.methodatlas.DeltaEmitterTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaEmitterTest]/[method:emit_summary_showsAllCounts()]
removed conditional - replaced equality check with true → KILLED

247

1.1
Location : loadRecords
Killed by : org.egothor.methodatlas.AiResultCacheTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.AiResultCacheTest]/[method:load_multipleMethodsSameHash_groupedIntoOneSuggestion(java.nio.file.Path)]
replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::loadRecords → KILLED

268

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
changed conditional boundary → KILLED

2.2
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
removed conditional - replaced comparison check with true → KILLED

3.3
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
removed conditional - replaced comparison check with false → KILLED

270

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
removed conditional - replaced equality check with false → KILLED

271

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
Replaced integer addition with subtraction → KILLED

273

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
removed conditional - replaced equality check with false → KILLED

275

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
removed call to java/lang/StringBuilder::setLength → KILLED

276

1.1
Location : parseCsvLine
Killed by : none
Changed increment from 1 to -1 → TIMED_OUT

279

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
Changed increment from 1 to -1 → KILLED

283

1.1
Location : parseCsvLine
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_unquotedFields_parsed()]
replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseCsvLine → KILLED

298

1.1
Location : parseQuotedField
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

2.2
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
removed conditional - replaced comparison check with false → KILLED

3.3
Location : parseQuotedField
Killed by : none
removed conditional - replaced comparison check with true → SURVIVED Covering tests

300

1.1
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
removed conditional - replaced equality check with false → KILLED

301

1.1
Location : parseQuotedField
Killed by : none
removed conditional - replaced comparison check with true → SURVIVED
Covering tests

2.2
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_escapedDoubleQuote_parsedCorrectly()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_escapedDoubleQuote_parsedCorrectly()]
removed conditional - replaced comparison check with false → KILLED

4.4
Location : parseQuotedField
Killed by : none
changed conditional boundary → SURVIVED Covering tests

5.5
Location : parseQuotedField
Killed by : none
Replaced integer addition with subtraction → SURVIVED Covering tests

6.6
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_escapedDoubleQuote_parsedCorrectly()]
Replaced integer addition with subtraction → KILLED

7.7
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
removed conditional - replaced equality check with true → KILLED

303

1.1
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_escapedDoubleQuote_parsedCorrectly()]
Changed increment from 2 to -2 → KILLED

305

1.1
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
Replaced integer addition with subtraction → KILLED

2.2
Location : parseQuotedField
Killed by : none
replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseQuotedField → TIMED_OUT

309

1.1
Location : parseQuotedField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:parseCsvLine_quotedFieldWithComma_parsedCorrectly()]
Changed increment from 1 to -1 → KILLED

312

1.1
Location : parseQuotedField
Killed by : none
replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseQuotedField → NO_COVERAGE

330

1.1
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_metadataTimestamp_extractedCorrectly(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

331

1.1
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_metadataTimestamp_extractedCorrectly(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_metadataTimestamp_extractedCorrectly(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

334

1.1
Location : parseCsv
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

2.2
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

339

1.1
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseCsv
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

340

1.1
Location : parseCsv
Killed by : none
replaced return value with null for org/egothor/methodatlas/DeltaReport::parseCsv → NO_COVERAGE

346

1.1
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
changed conditional boundary → KILLED

2.2
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
removed conditional - replaced comparison check with true → KILLED

3.3
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced comparison check with false → KILLED

350

1.1
Location : parseCsv
Killed by : none
Replaced integer subtraction with addition → SURVIVED
Covering tests

351

1.1
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced comparison check with true → KILLED

2.2
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
changed conditional boundary → KILLED

3.3
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
removed conditional - replaced comparison check with false → KILLED

356

1.1
Location : parseCsv
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
replaced return value with null for org/egothor/methodatlas/DeltaReport::parseCsv → KILLED

360

1.1
Location : toScanRecord
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
replaced return value with null for org/egothor/methodatlas/DeltaReport::toScanRecord → KILLED

377

1.1
Location : buildMap
Killed by : none
Replaced integer multiplication with division → SURVIVED
Covering tests

381

1.1
Location : buildMap
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
replaced return value with Collections.emptyMap for org/egothor/methodatlas/DeltaReport::buildMap → KILLED

385

1.1
Location : key
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
replaced return value with "" for org/egothor/methodatlas/DeltaReport::key → KILLED

389

1.1
Location : countSecurityRelevant
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_securityRelevantCounts_correct(java.nio.file.Path)]
replaced int return with 0 for org/egothor/methodatlas/DeltaReport::countSecurityRelevant → KILLED

390

1.1
Location : lambda$countSecurityRelevant$2
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_securityRelevantCounts_correct(java.nio.file.Path)]
replaced boolean return with true for org/egothor/methodatlas/DeltaReport::lambda$countSecurityRelevant$2 → KILLED

2.2
Location : lambda$countSecurityRelevant$2
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_securityRelevantCounts_correct(java.nio.file.Path)]
replaced boolean return with false for org/egothor/methodatlas/DeltaReport::lambda$countSecurityRelevant$2 → KILLED

407

1.1
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

410

1.1
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : findChangedFields
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

413

1.1
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

416

1.1
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashDiffers_reportedAsSourceModified(java.nio.file.Path)]
removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → KILLED

417

1.1
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → KILLED

419

1.1
Location : findChangedFields
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

2.2
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

3.3
Location : findChangedFields
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

4.4
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

420

1.1
Location : findChangedFields
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

2.2
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

423

1.1
Location : findChangedFields
Killed by : none
removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → SURVIVED
Covering tests

425

1.1
Location : findChangedFields
Killed by : none
removed call to org/egothor/methodatlas/DeltaReport::addIfBothPresentAndChanged → SURVIVED
Covering tests

427

1.1
Location : findChangedFields
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
replaced return value with Collections.emptySet for org/egothor/methodatlas/DeltaReport::findChangedFields → KILLED

437

1.1
Location : addIfBothPresentAndChanged
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : addIfBothPresentAndChanged
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashDiffers_reportedAsSourceModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

3.3
Location : addIfBothPresentAndChanged
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

4.4
Location : addIfBothPresentAndChanged
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashDiffers_reportedAsSourceModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

5.5
Location : addIfBothPresentAndChanged
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashDiffers_reportedAsSourceModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

6.6
Location : addIfBothPresentAndChanged
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

443

1.1
Location : tagsEqual
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
replaced boolean return with false for org/egothor/methodatlas/DeltaReport::tagsEqual → KILLED

2.2
Location : tagsEqual
Killed by : none
replaced boolean return with true for org/egothor/methodatlas/DeltaReport::tagsEqual → SURVIVED
Covering tests

453

1.1
Location : displayNameEqual
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : displayNameEqual
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

454

1.1
Location : displayNameEqual
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : displayNameEqual
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_methodRemovedInAfter_detectedAsRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

455

1.1
Location : displayNameEqual
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
replaced boolean return with false for org/egothor/methodatlas/DeltaReport::displayNameEqual → KILLED

2.2
Location : displayNameEqual
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
replaced boolean return with true for org/egothor/methodatlas/DeltaReport::displayNameEqual → KILLED

468

1.1
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced comparison check with true → KILLED

2.2
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

3.3
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

4.4
Location : getField
Killed by : none
removed conditional - replaced comparison check with false → SURVIVED
Covering tests

5.5
Location : getField
Killed by : none
changed conditional boundary → SURVIVED Covering tests

469

1.1
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_contentHashOnlyInOne_notReportedAsModified(java.nio.file.Path)]
replaced return value with "" for org/egothor/methodatlas/DeltaReport::getField → KILLED

472

1.1
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : getField
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

3.3
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
replaced return value with "" for org/egothor/methodatlas/DeltaReport::getField → KILLED

4.4
Location : getField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

5.5
Location : getField
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

489

1.1
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
changed conditional boundary → KILLED

2.2
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced comparison check with false → KILLED

3.3
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced comparison check with true → KILLED

4.4
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAbsentInBeforeEmptyInAfter_notReportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

5.5
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

490

1.1
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.MethodAtlasAppApplyTagsFromCsvTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.MethodAtlasAppApplyTagsFromCsvTest]/[method:applyTagsFromCsv_oldCsvWithoutDisplayNameColumn_leavesDisplayNameUntouched(java.nio.file.Path)]
replaced return value with "" for org/egothor/methodatlas/DeltaReport::getFieldPreserveEmpty → KILLED

493

1.1
Location : getFieldPreserveEmpty
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

2.2
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
replaced return value with "" for org/egothor/methodatlas/DeltaReport::getFieldPreserveEmpty → KILLED

3.3
Location : getFieldPreserveEmpty
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_displayNameAdded_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

502

1.1
Location : requireField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_missingFqcnColumn_throwsIllegalArgumentException(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : requireField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

505

1.1
Location : requireField
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

2.2
Location : requireField
Killed by : none
removed conditional - replaced comparison check with false → SURVIVED Covering tests

3.3
Location : requireField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced comparison check with true → KILLED

509

1.1
Location : requireField
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : requireField
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

513

1.1
Location : parseInt
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

2.2
Location : parseInt
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

514

1.1
Location : parseInt
Killed by : none
replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseInt → NO_COVERAGE

517

1.1
Location : parseInt
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_locChanged_reportedAsModified(java.nio.file.Path)]
replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseInt → KILLED

519

1.1
Location : parseInt
Killed by : none
replaced int return with 0 for org/egothor/methodatlas/DeltaReport::parseInt → NO_COVERAGE

524

1.1
Location : parseBoolean
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseBoolean
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

3.3
Location : parseBoolean
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_securityRelevantCounts_correct(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

4.4
Location : parseBoolean
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_securityRelevantCounts_correct(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

527

1.1
Location : parseBoolean
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_securityRelevantCounts_correct(java.nio.file.Path)]
replaced return value with Optional.empty for org/egothor/methodatlas/DeltaReport::parseBoolean → KILLED

531

1.1
Location : parseDouble
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

2.2
Location : parseDouble
Killed by : org.egothor.methodatlas.AiResultCacheTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.AiResultCacheTest]/[method:load_methodSuggestionFieldsRestoredCorrectly(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

532

1.1
Location : parseDouble
Killed by : none
replaced Double return value with 0 for org/egothor/methodatlas/DeltaReport::parseDouble → SURVIVED
Covering tests

535

1.1
Location : parseDouble
Killed by : org.egothor.methodatlas.AiResultCacheTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.AiResultCacheTest]/[method:load_methodSuggestionFieldsRestoredCorrectly(java.nio.file.Path)]
replaced Double return value with 0 for org/egothor/methodatlas/DeltaReport::parseDouble → KILLED

537

1.1
Location : parseDouble
Killed by : none
replaced Double return value with 0 for org/egothor/methodatlas/DeltaReport::parseDouble → NO_COVERAGE

546

1.1
Location : parseSemicolonList
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseSemicolonList
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

3.3
Location : parseSemicolonList
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

4.4
Location : parseSemicolonList
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

552

1.1
Location : parseSemicolonList
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

2.2
Location : parseSemicolonList
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

556

1.1
Location : parseSemicolonList
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseSemicolonList → KILLED

570

1.1
Location : parseSemicolonListOrNull
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : parseSemicolonListOrNull
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_emptyAfterFile_allRemoved(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

571

1.1
Location : parseSemicolonListOrNull
Killed by : none
replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseSemicolonListOrNull → SURVIVED
Covering tests

573

1.1
Location : parseSemicolonListOrNull
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : parseSemicolonListOrNull
Killed by : none
removed conditional - replaced comparison check with true → SURVIVED
Covering tests

3.3
Location : parseSemicolonListOrNull
Killed by : none
changed conditional boundary → SURVIVED Covering tests

574

1.1
Location : parseSemicolonListOrNull
Killed by : org.egothor.methodatlas.DeltaReportTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.DeltaReportTest]/[method:compute_aiSecurityRelevantFlips_reportedAsModified(java.nio.file.Path)]
replaced return value with Collections.emptyList for org/egothor/methodatlas/DeltaReport::parseSemicolonListOrNull → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1