also looking at this
fix: honor discovery-mode CLI options
#17
10 files
+192
-24
| @@ -11,7 +11,7 @@ pub const CLIOptions = struct { | ||
| 11 | 11 | quiet: bool = false, |
| 12 | 12 | no_color: bool = false, |
| 13 | 13 | // Test discovery options |
| 14 | test_dir: ?[]const u8 = null, | |
| 14 | test_dir: ?[]const u8 = ".", | |
| 15 | 15 | pattern: []const u8 = "*.test.zig", |
| 16 | 16 | no_recursive: bool = false, |
| 17 | 17 | // Coverage options |
| @@ -140,6 +140,12 @@ pub const CLI = struct { | ||
| 140 | 140 | } |
| 141 | 141 | i += 1; |
| 142 | 142 | self.options.coverage_tool = args[i]; |
| 143 | if (!std.mem.eql(u8, self.options.coverage_tool, "kcov") and | |
| 144 | !std.mem.eql(u8, self.options.coverage_tool, "grindcov")) | |
| 145 | { | |
| 146 | std.debug.print("Error: --coverage-tool must be 'kcov' or 'grindcov'\n", .{}); | |
| 147 | return CLIError.InvalidArgument; | |
| 148 | } | |
| 143 | 149 | } else if (std.mem.eql(u8, arg, "--parallel") or std.mem.eql(u8, arg, "-p")) { |
| 144 | 150 | self.options.parallel = true; |
| 145 | 151 | } else if (std.mem.eql(u8, arg, "--jobs") or std.mem.eql(u8, arg, "-j")) { |
| @@ -153,6 +159,10 @@ pub const CLI = struct { | ||
| 153 | 159 | std.debug.print("Error: --jobs must be a valid number\n", .{}); |
| 154 | 160 | return CLIError.InvalidArgument; |
| 155 | 161 | }; |
| 162 | if (self.options.jobs.? == 0) { | |
| 163 | std.debug.print("Error: --jobs must be greater than zero\n", .{}); | |
| 164 | return CLIError.InvalidArgument; | |
| 165 | } | |
| 156 | 166 | } else if (std.mem.eql(u8, arg, "--ui")) { |
| 157 | 167 | self.options.ui = true; |
| 158 | 168 | } else if (std.mem.eql(u8, arg, "--ui-port")) { |
| @@ -245,6 +255,31 @@ pub const CLI = struct { | ||
| 245 | 255 | } |
| 246 | 256 | } |
| 247 | 257 | |
| 258 | /// Return the first option that discovery mode cannot currently honor. | |
| 259 | /// Discovery must reject these options explicitly instead of silently | |
| 260 | /// behaving differently from programmatic mode. | |
| 261 | pub fn unsupportedDiscoveryOption(self: Self) ?[]const u8 { | |
| 262 | if (!self.options.coverage and !std.mem.eql(u8, self.options.coverage_dir, "coverage")) return "--coverage-dir"; | |
| 263 | if (!self.options.coverage and !std.mem.eql(u8, self.options.coverage_tool, "kcov")) return "--coverage-tool"; | |
| 264 | if (!self.options.watch and self.options.watch_debounce != 300) return "--watch-debounce"; | |
| 265 | if (!self.options.ui and self.options.ui_port != 8080) return "--ui-port"; | |
| 266 | if (!self.options.ui and !std.mem.eql(u8, self.options.ui_host, "127.0.0.1")) return "--ui-host"; | |
| 267 | if (self.options.reporter != .spec) return "--reporter"; | |
| 268 | if (self.options.quiet) return "--quiet"; | |
| 269 | if (self.options.parallel) return "--parallel"; | |
| 270 | if (self.options.jobs != null) return "--jobs"; | |
| 271 | if (self.options.update_snapshots) return "--update-snapshots"; | |
| 272 | if (!std.mem.eql(u8, self.options.snapshot_dir, ".snapshots")) return "--snapshot-dir"; | |
| 273 | if (self.options.profile_memory) return "--profile-memory"; | |
| 274 | if (self.options.memory_threshold != 0) return "--memory-threshold"; | |
| 275 | if (self.options.fail_on_leak) return "--fail-on-leak"; | |
| 276 | if (self.options.config != null) return "--config"; | |
| 277 | if (self.options.junit_output != null) return "--junit-output"; | |
| 278 | if (self.options.timeout != null) return "--timeout"; | |
| 279 | if (self.options.ui) return "--ui"; | |
| 280 | return null; | |
| 281 | } | |
| 282 | ||
| 248 | 283 | /// Print help message |
| 249 | 284 | pub fn printHelp(self: Self) void { |
| 250 | 285 | _ = self; |
| @@ -467,6 +502,7 @@ test "CLI default values" { | ||
| 467 | 502 | try std.testing.expectEqualStrings("coverage", cli.options.coverage_dir); |
| 468 | 503 | try std.testing.expectEqualStrings("kcov", cli.options.coverage_tool); |
| 469 | 504 | try std.testing.expectEqualStrings("*.test.zig", cli.options.pattern); |
| 505 | try std.testing.expectEqualStrings(".", cli.options.test_dir.?); | |
| 470 | 506 | try std.testing.expect(!cli.options.ui); |
| 471 | 507 | try std.testing.expectEqual(@as(u16, 8080), cli.options.ui_port); |
| 472 | 508 | try std.testing.expectEqualStrings("127.0.0.1", cli.options.ui_host); |
| @@ -531,6 +567,52 @@ test "CLI parse timeout" { | ||
| 531 | 567 | try std.testing.expectEqual(@as(?u64, 5000), cli.options.timeout); |
| 532 | 568 | } |
| 533 | 569 | |
| 570 | test "CLI rejects invalid coverage tool" { | |
| 571 | var cli = CLI.init(std.testing.allocator); | |
| 572 | const args = [_][]const u8{ "zig-test", "--coverage-tool", "unknown" }; | |
| 573 | try std.testing.expectError(CLIError.InvalidArgument, cli.parse(&args)); | |
| 574 | } | |
| 575 | ||
| 576 | test "CLI rejects zero jobs" { | |
| 577 | var cli = CLI.init(std.testing.allocator); | |
| 578 | const args = [_][]const u8{ "zig-test", "--jobs", "0" }; | |
| 579 | try std.testing.expectError(CLIError.InvalidArgument, cli.parse(&args)); | |
| 580 | } | |
| 581 | ||
| 582 | test "discovery accepts implemented options" { | |
| 583 | var cli = CLI.init(std.testing.allocator); | |
| 584 | const args = [_][]const u8{ | |
| 585 | "zig-test", | |
| 586 | "--test-dir", | |
| 587 | "tests", | |
| 588 | "--filter", | |
| 589 | "math", | |
| 590 | "--no-color", | |
| 591 | "--bail", | |
| 592 | "--verbose", | |
| 593 | }; | |
| 594 | try cli.parse(&args); | |
| 595 | try std.testing.expectEqual(@as(?[]const u8, null), cli.unsupportedDiscoveryOption()); | |
| 596 | } | |
| 597 | ||
| 598 | test "discovery identifies unsupported options" { | |
| 599 | var cli = CLI.init(std.testing.allocator); | |
| 600 | const args = [_][]const u8{ "zig-test", "--test-dir", "tests", "--reporter", "json" }; | |
| 601 | try cli.parse(&args); | |
| 602 | try std.testing.expectEqualStrings("--reporter", cli.unsupportedDiscoveryOption().?); | |
| 603 | } | |
| 604 | ||
| 605 | test "discovery reports timeout and parallel options as unsupported" { | |
| 606 | var cli = CLI.init(std.testing.allocator); | |
| 607 | ||
| 608 | cli.options.timeout = 1000; | |
| 609 | try std.testing.expectEqualStrings("--timeout", cli.unsupportedDiscoveryOption().?); | |
| 610 | ||
| 611 | cli.options.timeout = null; | |
| 612 | cli.options.parallel = true; | |
| 613 | try std.testing.expectEqualStrings("--parallel", cli.unsupportedDiscoveryOption().?); | |
| 614 | } | |
| 615 | ||
| 534 | 616 | test "CLI parse update-snapshots short flag" { |
| 535 | 617 | var cli = CLI.init(std.testing.allocator); |
| 536 | 618 | const args = [_][]const u8{ "zig-test", "-u" }; |