CliArgs.java

1
package org.egothor.methodatlas;
2
3
import java.io.IOException;
4
import java.nio.file.Path;
5
import java.nio.file.Paths;
6
import java.time.Duration;
7
import java.util.ArrayList;
8
import java.util.LinkedHashMap;
9
import java.util.LinkedHashSet;
10
import java.util.List;
11
import java.util.Locale;
12
import java.util.Map;
13
import java.util.Set;
14
15
import org.egothor.methodatlas.ai.AiOptions;
16
import org.egothor.methodatlas.ai.AiProvider;
17
18
/**
19
 * Parses command-line arguments into a {@link CliConfig}.
20
 *
21
 * <p>
22
 * This class centralises all argument-parsing logic for the MethodAtlas
23
 * application. It is intentionally separated from {@link MethodAtlasApp} to
24
 * keep each class focused and below the project's cyclomatic-complexity
25
 * threshold.
26
 * </p>
27
 *
28
 * <p>
29
 * When a {@code -config <file>} argument is present it is processed first
30
 * (via a pre-scan) so that the YAML file provides default values before
31
 * individual command-line flags are evaluated. Command-line flags always take
32
 * precedence over values from the YAML configuration file.
33
 * </p>
34
 *
35
 * <p>
36
 * This class is a non-instantiable utility holder.
37
 * </p>
38
 *
39
 * @see CliConfig
40
 * @see MethodAtlasApp
41
 */
42
@SuppressWarnings("PMD.CyclomaticComplexity")
43
final class CliArgs {
44
45
    private static final String DEFAULT_FILE_SUFFIX = "java:Test.java";
46
    private static final String FLAG_CONFIG = "-config";
47
    private static final String FLAG_AI_CACHE = "-ai-cache";
48
    private static final String FLAG_DRIFT_DETECT = "-drift-detect";
49
    private static final String FLAG_EMIT_SOURCE_ROOT = "-emit-source-root";
50
    private static final String FLAG_INCLUDE_NON_SECURITY = "-include-non-security";
51
    private static final String FLAG_SARIF_OMIT_SCORES = "-sarif-omit-scores";
52
    private static final String FLAG_APPLY_TAGS_FROM_CSV = "-apply-tags-from-csv";
53
    private static final String FLAG_MISMATCH_LIMIT = "-mismatch-limit";
54
55
    /**
56
     * Prevents instantiation of this utility class.
57
     */
58
    private CliArgs() {
59
    }
60
61
    /**
62
     * Parses command-line arguments into a structured configuration object.
63
     *
64
     * <p>
65
     * If a {@code -config <file>} argument is present it is loaded first and
66
     * its values seed the initial configuration. Subsequent command-line flags
67
     * override those defaults.
68
     * </p>
69
     *
70
     * <p>
71
     * <b>SARIF mode and security filtering:</b> when {@code -sarif} is selected
72
     * (or {@code outputMode: sarif} is set in YAML), the security-only filter is
73
     * applied automatically — only security-relevant methods are emitted. This
74
     * default exists because SARIF is consumed by GitHub Code Scanning and
75
     * equivalent security tooling that expects actionable security findings, not
76
     * an exhaustive inventory of all test methods. Use {@code -include-non-security}
77
     * to override this behaviour and include all methods in the SARIF document.
78
     * </p>
79
     *
80
     * <p>
81
     * The {@code -security-only} flag continues to work independently and applies
82
     * the same filter to CSV and plain-text output modes.
83
     * </p>
84
     *
85
     * @param args raw command-line arguments
86
     * @return parsed command-line configuration
87
     * @throws IllegalArgumentException if an option value is missing, malformed,
88
     *                                  or unsupported, or if the config file
89
     *                                  cannot be read
90
     */
91
    @SuppressWarnings({"PMD.AvoidReassigningLoopVariables", "PMD.CyclomaticComplexity", "PMD.NPathComplexity", "PMD.NcssCount"})
92
    /* default */ static CliConfig parse(String... args) {
93
        // Pre-scan for -config to load YAML defaults before processing other flags.
94
        YamlConfig.YamlConfigFile yamlConfig = loadYamlConfigFromArgs(args);
95
96
        // Seed initial values from YAML (command-line flags will override these).
97
        OutputMode outputMode = resolveOutputModeFromYaml(yamlConfig);
98 4 1. parse : removed conditional - replaced equality check with false → SURVIVED
2. parse : removed conditional - replaced equality check with false → SURVIVED
3. parse : removed conditional - replaced equality check with true → KILLED
4. parse : removed conditional - replaced equality check with true → KILLED
        boolean emitMetadata = yamlConfig != null && yamlConfig.emitMetadata;
99 4 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
3. parse : removed conditional - replaced equality check with false → KILLED
4. parse : removed conditional - replaced equality check with false → KILLED
        List<String> fileSuffixes = yamlConfig != null && yamlConfig.fileSuffixes != null
100
                ? new ArrayList<>(yamlConfig.fileSuffixes) : new ArrayList<>();
101 4 1. parse : removed conditional - replaced equality check with false → SURVIVED
2. parse : removed conditional - replaced equality check with false → SURVIVED
3. parse : removed conditional - replaced equality check with true → KILLED
4. parse : removed conditional - replaced equality check with true → KILLED
        Set<String> testMarkers = yamlConfig != null && yamlConfig.testMarkers != null
102
                ? new LinkedHashSet<>(yamlConfig.testMarkers) : new LinkedHashSet<>();
103
        Map<String, List<String>> properties = new LinkedHashMap<>();
104 4 1. parse : removed conditional - replaced equality check with false → SURVIVED
2. parse : removed conditional - replaced equality check with false → SURVIVED
3. parse : removed conditional - replaced equality check with true → KILLED
4. parse : removed conditional - replaced equality check with true → KILLED
        if (yamlConfig != null && yamlConfig.properties != null) {
105 1 1. parse : removed call to java/util/Map::forEach → NO_COVERAGE
            yamlConfig.properties.forEach((k, v) -> properties.put(k, new ArrayList<>(v)));
106
        }
107
        AiOptions.Builder aiBuilder = AiOptions.builder();
108 4 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
3. parse : removed conditional - replaced equality check with false → KILLED
4. parse : removed conditional - replaced equality check with true → KILLED
        if (yamlConfig != null && yamlConfig.ai != null) {
109 1 1. parse : removed call to org/egothor/methodatlas/CliArgs::applyYamlAiConfig → KILLED
            applyYamlAiConfig(aiBuilder, yamlConfig.ai);
110
        }
111
112
        List<Path> paths = new ArrayList<>();
113
        String manualWorkDir = null;
114
        String manualResponseDir = null;
115
        boolean manualIsConsume = false;
116
        boolean applyTags = false;
117 4 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
3. parse : removed conditional - replaced equality check with false → KILLED
4. parse : removed conditional - replaced equality check with false → KILLED
        boolean contentHash = yamlConfig != null && yamlConfig.contentHash;
118 4 1. parse : removed conditional - replaced equality check with false → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
3. parse : removed conditional - replaced equality check with false → KILLED
4. parse : removed conditional - replaced equality check with true → KILLED
        Path overrideFilePath = yamlConfig != null && yamlConfig.overrideFile != null
119
                ? Paths.get(yamlConfig.overrideFile) : null;
120 4 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
3. parse : removed conditional - replaced equality check with true → KILLED
4. parse : removed conditional - replaced equality check with false → KILLED
        boolean securityOnly = yamlConfig != null && yamlConfig.securityOnly;
121 4 1. parse : removed conditional - replaced equality check with false → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
3. parse : removed conditional - replaced equality check with true → KILLED
4. parse : removed conditional - replaced equality check with true → KILLED
        boolean includeNonSecurity = yamlConfig != null && yamlConfig.includeNonSecurity;
122 4 1. parse : removed conditional - replaced equality check with true → SURVIVED
2. parse : removed conditional - replaced equality check with false → SURVIVED
3. parse : removed conditional - replaced equality check with false → SURVIVED
4. parse : removed conditional - replaced equality check with true → KILLED
        boolean sarifOmitScores = yamlConfig != null && yamlConfig.sarifOmitScores;
123 4 1. parse : removed conditional - replaced equality check with false → SURVIVED
2. parse : removed conditional - replaced equality check with true → SURVIVED
3. parse : removed conditional - replaced equality check with false → SURVIVED
4. parse : removed conditional - replaced equality check with true → KILLED
        boolean driftDetect = yamlConfig != null && yamlConfig.driftDetect;
124
        boolean emitSourceRoot = false;
125
        Path aiCacheFile = null;
126
        Path applyTagsFromCsvFile = null;
127
        int mismatchLimit = -1;
128
        // Tracks whether the first CLI -file-suffix has been seen; when it is,
129
        // subsequent -file-suffix values are appended rather than replacing defaults.
130
        boolean cliFileSuffixSet = false;
131
132 3 1. parse : removed conditional - replaced comparison check with true → KILLED
2. parse : changed conditional boundary → KILLED
3. parse : removed conditional - replaced comparison check with false → KILLED
        for (int i = 0; i < args.length; i++) {
133
            String arg = args[i];
134 2 1. parse : removed conditional - replaced equality check with false → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
            if (FLAG_AI_CACHE.equals(arg)) {
135 1 1. parse : Changed increment from 1 to -1 → TIMED_OUT
                aiCacheFile = Paths.get(nextArg(args, ++i, arg));
136
                continue;
137
            }
138 2 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
            if (FLAG_APPLY_TAGS_FROM_CSV.equals(arg)) {
139 1 1. parse : Changed increment from 1 to -1 → KILLED
                applyTagsFromCsvFile = Paths.get(nextArg(args, ++i, arg));
140
                continue;
141
            }
142 2 1. parse : removed conditional - replaced equality check with false → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
            if (FLAG_MISMATCH_LIMIT.equals(arg)) {
143 1 1. parse : Changed increment from 1 to -1 → KILLED
                mismatchLimit = Integer.parseInt(nextArg(args, ++i, arg));
144
                continue;
145
            }
146 2 1. parse : removed conditional - replaced equality check with false → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
            if (arg.startsWith("-ai")) {
147
                i = applyAiArg(arg, args, i, aiBuilder);
148
                continue;
149
            }
150 1 1. parse : Changed switch default to be first case → KILLED
            switch (arg) {
151
                case "-plain" -> outputMode = OutputMode.PLAIN;
152
                case "-sarif" -> outputMode = OutputMode.SARIF;
153
                case "-github-annotations" -> outputMode = OutputMode.GITHUB_ANNOTATIONS;
154
                case "-apply-tags" -> applyTags = true;
155
                case "-content-hash" -> contentHash = true;
156 1 1. parse : Changed increment from 1 to -1 → TIMED_OUT
                case FLAG_CONFIG -> i++; // value already consumed in pre-scan; skip here
157
                case "-file-suffix" -> {
158 2 1. parse : removed conditional - replaced equality check with false → SURVIVED
2. parse : removed conditional - replaced equality check with true → KILLED
                    if (!cliFileSuffixSet) {
159
                        // First CLI -file-suffix replaces YAML defaults
160 1 1. parse : removed call to java/util/List::clear → SURVIVED
                        fileSuffixes.clear();
161
                        cliFileSuffixSet = true;
162
                    }
163 1 1. parse : Changed increment from 1 to -1 → KILLED
                    fileSuffixes.add(nextArg(args, ++i, arg));
164
                }
165 1 1. parse : Changed increment from 1 to -1 → KILLED
                case "-test-marker", "-test-annotation" -> testMarkers.add(nextArg(args, ++i, arg));
166
                case "-property" -> {
167 1 1. parse : Changed increment from 1 to -1 → KILLED
                    String kv = nextArg(args, ++i, arg);
168
                    int eq = kv.indexOf('=');
169 3 1. parse : changed conditional boundary → SURVIVED
2. parse : removed conditional - replaced comparison check with true → KILLED
3. parse : removed conditional - replaced comparison check with false → KILLED
                    if (eq < 0) {
170
                        throw new IllegalArgumentException(
171
                                "Invalid -property value: '" + kv + "'; expected key=value format");
172
                    }
173 2 1. lambda$parse$1 : replaced return value with Collections.emptyList for org/egothor/methodatlas/CliArgs::lambda$parse$1 → KILLED
2. parse : Replaced integer addition with subtraction → KILLED
                    properties.computeIfAbsent(kv.substring(0, eq), k -> new ArrayList<>()) // NOPMD - one list per unique key, not per iteration
174
                            .add(kv.substring(eq + 1));
175
                }
176
                case "-emit-metadata" -> emitMetadata = true;
177
                case "-security-only" -> securityOnly = true;
178
                case FLAG_INCLUDE_NON_SECURITY -> includeNonSecurity = true;
179
                case FLAG_SARIF_OMIT_SCORES -> sarifOmitScores = true;
180
                case FLAG_DRIFT_DETECT -> driftDetect = true;
181
                case FLAG_EMIT_SOURCE_ROOT -> emitSourceRoot = true;
182 1 1. parse : Changed increment from 1 to -1 → KILLED
                case "-override-file" -> overrideFilePath = Paths.get(nextArg(args, ++i, arg));
183
                case "-manual-prepare" -> {
184 1 1. parse : Changed increment from 1 to -1 → KILLED
                    manualWorkDir = nextArg(args, ++i, arg);
185 1 1. parse : Changed increment from 1 to -1 → KILLED
                    manualResponseDir = nextArg(args, ++i, arg);
186
                    manualIsConsume = false;
187
                }
188
                case "-manual-consume" -> {
189 1 1. parse : Changed increment from 1 to -1 → KILLED
                    manualWorkDir = nextArg(args, ++i, arg);
190 1 1. parse : Changed increment from 1 to -1 → KILLED
                    manualResponseDir = nextArg(args, ++i, arg);
191
                    manualIsConsume = true;
192
                }
193
                default -> {
194 2 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
                    if (arg.startsWith("-")) {
195
                        throw new IllegalArgumentException("Unknown argument: " + arg);
196
                    }
197
                    paths.add(Paths.get(arg));
198
                }
199
            }
200
        }
201
202
        ManualMode manualMode = null;
203 2 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
        if (manualWorkDir != null) {
204
            Path workDir = Paths.get(manualWorkDir);
205
            Path responseDir = Paths.get(manualResponseDir);
206 2 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
            manualMode = manualIsConsume
207
                    ? new ManualMode.Consume(workDir, responseDir)
208
                    : new ManualMode.Prepare(workDir, responseDir);
209
        }
210
211
        // SARIF is consumed by security tooling that expects findings, not a full
212
        // test inventory. Apply the security-only filter implicitly unless the
213
        // caller has explicitly opted in to the full-inventory form.
214 4 1. parse : removed conditional - replaced equality check with false → KILLED
2. parse : removed conditional - replaced equality check with true → KILLED
3. parse : removed conditional - replaced equality check with true → KILLED
4. parse : removed conditional - replaced equality check with false → KILLED
        if (outputMode == OutputMode.SARIF && !includeNonSecurity) {
215
            securityOnly = true;
216
        }
217
218 2 1. parse : removed conditional - replaced equality check with true → KILLED
2. parse : removed conditional - replaced equality check with false → KILLED
        List<String> resolvedSuffixes = fileSuffixes.isEmpty() ? List.of(DEFAULT_FILE_SUFFIX) : fileSuffixes;
219 2 1. parse : removed conditional - replaced equality check with false → SURVIVED
2. parse : removed conditional - replaced equality check with true → KILLED
        Set<String> resolvedMarkers = testMarkers.isEmpty() ? Set.of() : testMarkers;
220 1 1. parse : replaced return value with null for org/egothor/methodatlas/CliArgs::parse → KILLED
        return new CliConfig(outputMode, aiBuilder.build(), paths, resolvedSuffixes, resolvedMarkers,
221
                Map.copyOf(properties), emitMetadata, manualMode, applyTags, contentHash, overrideFilePath,
222
                securityOnly, aiCacheFile, driftDetect, applyTagsFromCsvFile, mismatchLimit, emitSourceRoot,
223
                sarifOmitScores);
224
    }
225
226
    // -------------------------------------------------------------------------
227
    // YAML config helpers
228
    // -------------------------------------------------------------------------
229
230
    /**
231
     * Pre-scans {@code args} for a {@code -config <file>} argument and loads the
232
     * YAML file if found.
233
     *
234
     * @param args raw command-line arguments
235
     * @return parsed YAML config, or {@code null} when no {@code -config} flag is
236
     *         present
237
     * @throws IllegalArgumentException if the config file cannot be read
238
     */
239
    private static YamlConfig.YamlConfigFile loadYamlConfigFromArgs(String... args) {
240 4 1. loadYamlConfigFromArgs : changed conditional boundary → SURVIVED
2. loadYamlConfigFromArgs : removed conditional - replaced comparison check with true → KILLED
3. loadYamlConfigFromArgs : Replaced integer subtraction with addition → KILLED
4. loadYamlConfigFromArgs : removed conditional - replaced comparison check with false → KILLED
        for (int i = 0; i < args.length - 1; i++) {
241 2 1. loadYamlConfigFromArgs : removed conditional - replaced equality check with true → KILLED
2. loadYamlConfigFromArgs : removed conditional - replaced equality check with false → KILLED
            if (FLAG_CONFIG.equals(args[i])) {
242 1 1. loadYamlConfigFromArgs : Replaced integer addition with subtraction → KILLED
                Path configPath = Paths.get(args[i + 1]);
243
                try {
244 1 1. loadYamlConfigFromArgs : replaced return value with null for org/egothor/methodatlas/CliArgs::loadYamlConfigFromArgs → KILLED
                    return YamlConfig.load(configPath);
245
                } catch (IOException e) {
246
                    throw new IllegalArgumentException("Cannot load config file: " + configPath, e);
247
                }
248
            }
249
        }
250
        return null;
251
    }
252
253
    /**
254
     * Derives the initial {@link OutputMode} from a loaded YAML config.
255
     *
256
     * @param yamlConfig YAML config, or {@code null}
257
     * @return resolved output mode; defaults to {@link OutputMode#CSV}
258
     */
259
    private static OutputMode resolveOutputModeFromYaml(YamlConfig.YamlConfigFile yamlConfig) {
260 4 1. resolveOutputModeFromYaml : removed conditional - replaced equality check with false → KILLED
2. resolveOutputModeFromYaml : removed conditional - replaced equality check with true → KILLED
3. resolveOutputModeFromYaml : removed conditional - replaced equality check with false → KILLED
4. resolveOutputModeFromYaml : removed conditional - replaced equality check with true → KILLED
        if (yamlConfig == null || yamlConfig.outputMode == null) {
261 1 1. resolveOutputModeFromYaml : replaced return value with null for org/egothor/methodatlas/CliArgs::resolveOutputModeFromYaml → KILLED
            return OutputMode.CSV;
262
        }
263 2 1. resolveOutputModeFromYaml : Changed switch default to be first case → KILLED
2. resolveOutputModeFromYaml : replaced return value with null for org/egothor/methodatlas/CliArgs::resolveOutputModeFromYaml → KILLED
        return switch (yamlConfig.outputMode.toLowerCase(Locale.ROOT)) {
264
            case "plain" -> OutputMode.PLAIN;
265
            case "sarif" -> OutputMode.SARIF;
266
            default -> OutputMode.CSV;
267
        };
268
    }
269
270
    /**
271
     * Seeds the AI options builder from YAML configuration values.
272
     *
273
     * @param builder   AI options builder to update
274
     * @param aiConfig  AI section of the YAML config; never {@code null}
275
     */
276
    @SuppressWarnings("PMD.NPathComplexity")
277
    private static void applyYamlAiConfig(AiOptions.Builder builder, YamlConfig.YamlAiConfig aiConfig) {
278 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (Boolean.TRUE.equals(aiConfig.enabled)) {
279
            builder.enabled(true);
280
        }
281 2 1. applyYamlAiConfig : removed conditional - replaced equality check with true → SURVIVED
2. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
        if (aiConfig.provider != null) {
282
            builder.provider(AiProvider.valueOf(aiConfig.provider.toUpperCase(Locale.ROOT)));
283
        }
284 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (aiConfig.model != null) {
285
            builder.modelName(aiConfig.model);
286
        }
287 2 1. applyYamlAiConfig : removed conditional - replaced equality check with true → SURVIVED
2. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
        if (aiConfig.baseUrl != null) {
288
            builder.baseUrl(aiConfig.baseUrl);
289
        }
290 2 1. applyYamlAiConfig : removed conditional - replaced equality check with true → SURVIVED
2. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
        if (aiConfig.apiKey != null) {
291
            builder.apiKey(aiConfig.apiKey);
292
        }
293 2 1. applyYamlAiConfig : removed conditional - replaced equality check with true → SURVIVED
2. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
        if (aiConfig.apiKeyEnv != null) {
294
            builder.apiKeyEnv(aiConfig.apiKeyEnv);
295
        }
296 2 1. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
        if (aiConfig.taxonomyFile != null) {
297
            builder.taxonomyFile(Paths.get(aiConfig.taxonomyFile));
298
        }
299 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (aiConfig.taxonomyMode != null) {
300
            builder.taxonomyMode(
301
                    AiOptions.TaxonomyMode.valueOf(aiConfig.taxonomyMode.toUpperCase(Locale.ROOT)));
302
        }
303 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (aiConfig.maxClassChars != null) {
304
            builder.maxClassChars(aiConfig.maxClassChars);
305
        }
306 2 1. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
        if (aiConfig.timeoutSec != null) {
307
            builder.timeout(Duration.ofSeconds(aiConfig.timeoutSec));
308
        }
309 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (aiConfig.maxRetries != null) {
310
            builder.maxRetries(aiConfig.maxRetries);
311
        }
312 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → KILLED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (Boolean.TRUE.equals(aiConfig.confidence)) {
313
            builder.confidence(true);
314
        }
315 2 1. applyYamlAiConfig : removed conditional - replaced equality check with false → SURVIVED
2. applyYamlAiConfig : removed conditional - replaced equality check with true → KILLED
        if (aiConfig.apiVersion != null) {
316
            builder.apiVersion(aiConfig.apiVersion);
317
        }
318
    }
319
320
    // -------------------------------------------------------------------------
321
    // AI argument helper
322
    // -------------------------------------------------------------------------
323
324
    /**
325
     * Applies a single AI-related command-line argument to the builder.
326
     *
327
     * <p>
328
     * Handles all {@code -ai*} flags. Returns the updated argument index so
329
     * the caller's loop counter stays consistent when the flag consumes an
330
     * additional value token.
331
     * </p>
332
     *
333
     * @param arg     the flag token being processed
334
     * @param args    full argument array
335
     * @param i       current position in {@code args}
336
     * @param builder AI options builder to update
337
     * @return updated value of {@code i} after consuming any argument value
338
     * @throws IllegalArgumentException if a required value token is missing or
339
     *                                  the flag is unrecognised
340
     */
341
    private static int applyAiArg(String arg, String[] args, int i, AiOptions.Builder builder) {
342
        int idx = i;
343 1 1. applyAiArg : Changed switch default to be first case → KILLED
        switch (arg) {
344
            case "-ai" -> builder.enabled(true);
345
            case "-ai-confidence" -> builder.confidence(true);
346
            case "-ai-provider" ->
347 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
                builder.provider(AiProvider.valueOf(nextArg(args, ++idx, arg).toUpperCase(Locale.ROOT)));
348 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
            case "-ai-model" -> builder.modelName(nextArg(args, ++idx, arg));
349 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
            case "-ai-base-url" -> builder.baseUrl(nextArg(args, ++idx, arg));
350 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
            case "-ai-api-key" -> builder.apiKey(nextArg(args, ++idx, arg));
351 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
            case "-ai-api-key-env" -> builder.apiKeyEnv(nextArg(args, ++idx, arg));
352 1 1. applyAiArg : Changed increment from 1 to -1 → TIMED_OUT
            case "-ai-taxonomy" -> builder.taxonomyFile(Paths.get(nextArg(args, ++idx, arg)));
353
            case "-ai-taxonomy-mode" ->
354 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
                builder.taxonomyMode(
355
                        AiOptions.TaxonomyMode.valueOf(nextArg(args, ++idx, arg).toUpperCase(Locale.ROOT)));
356 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
            case "-ai-max-class-chars" -> builder.maxClassChars(Integer.parseInt(nextArg(args, ++idx, arg)));
357
            case "-ai-timeout-sec" ->
358 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
                builder.timeout(Duration.ofSeconds(Long.parseLong(nextArg(args, ++idx, arg))));
359 1 1. applyAiArg : Changed increment from 1 to -1 → KILLED
            case "-ai-max-retries" -> builder.maxRetries(Integer.parseInt(nextArg(args, ++idx, arg)));
360 1 1. applyAiArg : Changed increment from 1 to -1 → NO_COVERAGE
            case "-ai-api-version" -> builder.apiVersion(nextArg(args, ++idx, arg));
361
            default -> throw new IllegalArgumentException("Unknown AI argument: " + arg);
362
        }
363 1 1. applyAiArg : replaced int return with 0 for org/egothor/methodatlas/CliArgs::applyAiArg → TIMED_OUT
        return idx;
364
    }
365
366
    /**
367
     * Returns the argument value following an option token.
368
     *
369
     * @param args   full command-line argument array
370
     * @param index  index of the expected option value
371
     * @param option option whose value is being retrieved
372
     * @return argument value at {@code index}
373
     * @throws IllegalArgumentException if {@code index} is outside the bounds of
374
     *                                  {@code args}
375
     */
376
    private static String nextArg(String[] args, int index, String option) {
377 3 1. nextArg : removed conditional - replaced comparison check with true → KILLED
2. nextArg : removed conditional - replaced comparison check with false → KILLED
3. nextArg : changed conditional boundary → KILLED
        if (index >= args.length) {
378
            throw new IllegalArgumentException("Missing value for " + option);
379
        }
380 1 1. nextArg : replaced return value with "" for org/egothor/methodatlas/CliArgs::nextArg → KILLED
        return args[index];
381
    }
382
}

Mutations

98

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

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

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

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

99

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

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

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

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

101

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

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

3.3
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

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

104

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

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

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

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

105

1.1
Location : parse
Killed by : none
removed call to java/util/Map::forEach → NO_COVERAGE

108

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

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

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

4.4
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

109

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_configWithAiEnabledFalseAndConfidenceFalse_doesNotActivate(java.nio.file.Path)]
removed call to org/egothor/methodatlas/CliArgs::applyYamlAiConfig → KILLED

117

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

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

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

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

118

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

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

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

4.4
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

120

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

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

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

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

121

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

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

3.3
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

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

122

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

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

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

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

123

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

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

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

4.4
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

132

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_noEmitSourceRoot_defaultsFalse()]
removed conditional - replaced comparison check with true → KILLED

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_noEmitSourceRoot_defaultsFalse()]
changed conditional boundary → KILLED

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

134

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

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_propertyMissingEquals_throwsException()]
removed conditional - replaced equality check with true → KILLED

135

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

138

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

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

139

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

142

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

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_applyTagsFlag_setsApplyTagsTrue()]
removed conditional - replaced equality check with true → KILLED

143

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

146

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_aiModelMissingValue_throwsIllegalArgumentException()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_fileSuffixMissingValue_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

150

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_fileSuffixMissingValue_throwsIllegalArgumentException()]
Changed switch default to be first case → KILLED

156

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

158

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

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

160

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

163

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

165

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

167

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

169

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_singleProperty_stored()]
removed conditional - replaced comparison check with true → KILLED

2.2
Location : parse
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

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

173

1.1
Location : lambda$parse$1
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_singleProperty_stored()]
replaced return value with Collections.emptyList for org/egothor/methodatlas/CliArgs::lambda$parse$1 → KILLED

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_singleProperty_stored()]
Replaced integer addition with subtraction → KILLED

182

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

184

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

185

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

189

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

190

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

194

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

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

203

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

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

206

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

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

214

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_sarifFlag_impliesSecurityOnly()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_sarifWithIncludeNonSecurity_disablesImplicitFilter()]
removed conditional - replaced equality check with true → KILLED

3.3
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_noArgs_returnsDefaults()]
removed conditional - replaced equality check with true → KILLED

4.4
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_sarifFlag_impliesSecurityOnly()]
removed conditional - replaced equality check with false → KILLED

218

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

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

219

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

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

220

1.1
Location : parse
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_noEmitSourceRoot_defaultsFalse()]
replaced return value with null for org/egothor/methodatlas/CliArgs::parse → KILLED

240

1.1
Location : loadYamlConfigFromArgs
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced comparison check with true → KILLED

2.2
Location : loadYamlConfigFromArgs
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
Replaced integer subtraction with addition → KILLED

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

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

241

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

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

242

1.1
Location : loadYamlConfigFromArgs
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_configNonExistentFile_throwsIllegalArgumentException(java.nio.file.Path)]
Replaced integer addition with subtraction → KILLED

244

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

260

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

2.2
Location : resolveOutputModeFromYaml
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
removed conditional - replaced equality check with true → KILLED

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

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

261

1.1
Location : resolveOutputModeFromYaml
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_noArgs_returnsDefaults()]
replaced return value with null for org/egothor/methodatlas/CliArgs::resolveOutputModeFromYaml → KILLED

263

1.1
Location : resolveOutputModeFromYaml
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_yamlSarifMode_impliesSecurityOnly(java.nio.file.Path)]
Changed switch default to be first case → KILLED

2.2
Location : resolveOutputModeFromYaml
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_yamlSarifMode_impliesSecurityOnly(java.nio.file.Path)]
replaced return value with null for org/egothor/methodatlas/CliArgs::resolveOutputModeFromYaml → KILLED

278

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

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

281

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

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

284

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

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

287

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

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

290

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

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

293

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

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

296

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

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

299

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

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

303

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

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

306

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

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

309

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

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

312

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

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

315

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

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

343

1.1
Location : applyAiArg
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_unknownAiFlag_throwsIllegalArgumentException()]
Changed switch default to be first case → KILLED

347

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

348

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

349

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

350

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

351

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

352

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

354

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

356

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

358

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

359

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

360

1.1
Location : applyAiArg
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

363

1.1
Location : applyAiArg
Killed by : none
replaced int return with 0 for org/egothor/methodatlas/CliArgs::applyAiArg → TIMED_OUT

377

1.1
Location : nextArg
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_twoTestMarkers_bothPresent()]
removed conditional - replaced comparison check with true → KILLED

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

3.3
Location : nextArg
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_fileSuffixMissingValue_throwsIllegalArgumentException()]
changed conditional boundary → KILLED

380

1.1
Location : nextArg
Killed by : org.egothor.methodatlas.CliArgsTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.CliArgsTest]/[method:parse_twoTestMarkers_bothPresent()]
replaced return value with "" for org/egothor/methodatlas/CliArgs::nextArg → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1