also looking at this
test: make CI exercise maintained integrations
#18
16 files
+390
-139
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -1,19 +1,30 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for assertions module | |
| 4 | // TODO: Implement comprehensive tests for all assertion methods | |
| 5 | ||
| 6 | test "assertions basic equality" { | |
| 7 | // Test toBe and toEqual | |
| 8 | try std.testing.expect(true); | |
| 4 | test "assertions report equality failures and support negation" { | |
| 5 | const allocator = std.testing.allocator; | |
| 6 | try ztf.expect(allocator, @as(i32, 42)).toBe(42); | |
| 7 | try ztf.expect(allocator, @as(i32, 42)).not().toBe(7); | |
| 8 | try std.testing.expectError(ztf.AssertionError.AssertionFailed, ztf.expect(allocator, @as(i32, 42)).toBe(7)); | |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | test "assertions comparison operators" { | |
| 12 | // Test toBeGreaterThan, toBeLessThan, etc. | |
| 13 | try std.testing.expect(true); | |
| 11 | test "assertions cover comparisons and optionals" { | |
| 12 | const allocator = std.testing.allocator; | |
| 13 | try ztf.expect(allocator, @as(i32, 10)).toBeGreaterThan(5); | |
| 14 | try ztf.expect(allocator, @as(i32, 5)).toBeLessThan(10); | |
| 15 | try ztf.expect(allocator, @as(?i32, null)).toBeNull(); | |
| 16 | try ztf.expect(allocator, @as(?i32, 3)).toBeDefined(); | |
| 14 | 17 | } |
| 15 | 18 | |
| 16 | test "assertions string operations" { | |
| 17 | // Test string-specific assertions | |
| 18 | try std.testing.expect(true); | |
| 19 | test "assertions cover strings and error unions" { | |
| 20 | const allocator = std.testing.allocator; | |
| 21 | const Failing = struct { | |
| 22 | fn call() !void { | |
| 23 | return error.ExpectedFailure; | |
| 24 | } | |
| 25 | }; | |
| 26 | try ztf.expect(allocator, "zig test framework").toContain("test"); | |
| 27 | try ztf.expect(allocator, "zig test framework").toStartWith("zig"); | |
| 28 | try ztf.expect(allocator, "zig test framework").toEndWith("framework"); | |
| 29 | try ztf.expect(allocator, Failing.call).toThrowError(error.ExpectedFailure); | |
| 19 | 30 | } |
| @@ -1,19 +1,25 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for CLI module | |
| 4 | // TODO: Implement comprehensive tests for CLI parsing | |
| 5 | ||
| 6 | test "CLI parse help flag" { | |
| 7 | // Test --help flag parsing | |
| 8 | try std.testing.expect(true); | |
| 4 | test "CLI parses the help flag" { | |
| 5 | var cli = ztf.CLI.init(std.testing.allocator); | |
| 6 | try cli.parse(&.{ "zig-test", "--help" }); | |
| 7 | try std.testing.expect(cli.options.help); | |
| 9 | 8 | } |
| 10 | 9 | |
| 11 | test "CLI parse reporter option" { | |
| 12 | // Test --reporter option parsing | |
| 13 | try std.testing.expect(true); | |
| 10 | test "CLI parses a representative discovery invocation" { | |
| 11 | var cli = ztf.CLI.init(std.testing.allocator); | |
| 12 | try cli.parse(&.{ "zig-test", "--test-dir", "specs", "--grep", "database", "--coverage", "--no-color", "--bail" }); | |
| 13 | try std.testing.expectEqualStrings("specs", cli.options.test_dir.?); | |
| 14 | try std.testing.expectEqualStrings("database", cli.options.filter.?); | |
| 15 | try std.testing.expect(cli.options.coverage); | |
| 16 | try std.testing.expect(cli.options.no_color); | |
| 17 | try std.testing.expect(cli.options.bail); | |
| 14 | 18 | } |
| 15 | 19 | |
| 16 | test "CLI parse filter option" { | |
| 17 | // Test --filter option parsing | |
| 18 | try std.testing.expect(true); | |
| 20 | test "CLI rejects missing and invalid values" { | |
| 21 | var missing = ztf.CLI.init(std.testing.allocator); | |
| 22 | try std.testing.expectError(ztf.cli.CLIError.MissingValue, missing.parse(&.{ "zig-test", "--reporter" })); | |
| 23 | var invalid = ztf.CLI.init(std.testing.allocator); | |
| 24 | try std.testing.expectError(ztf.cli.CLIError.InvalidArgument, invalid.parse(&.{ "zig-test", "--jobs", "0" })); | |
| 19 | 25 | } |
| @@ -1,19 +1,26 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for matchers module | |
| 4 | // TODO: Implement comprehensive tests for advanced matchers | |
| 5 | ||
| 6 | test "matchers numeric operations" { | |
| 7 | // Test toBeCloseTo, toBeNaN, etc. | |
| 8 | try std.testing.expect(true); | |
| 4 | test "numeric matchers accept special and approximate values" { | |
| 5 | try ztf.toBeCloseTo(0.1 + 0.2, 0.3, 10); | |
| 6 | try ztf.toBeNaN(std.math.nan(f64)); | |
| 7 | try ztf.toBeInfinite(std.math.inf(f64)); | |
| 8 | try std.testing.expectError(ztf.AssertionError.AssertionFailed, ztf.toBeCloseTo(1.0, 2.0, 4)); | |
| 9 | 9 | } |
| 10 | 10 | |
| 11 | test "matchers array operations" { | |
| 12 | // Test array-specific matchers | |
| 13 | try std.testing.expect(true); | |
| 11 | test "array matchers inspect contents and length" { | |
| 12 | const values = [_]i32{ 1, 2, 3, 5, 8 }; | |
| 13 | const matcher = ztf.expectArray(std.testing.allocator, &values); | |
| 14 | try matcher.toHaveLength(5); | |
| 15 | try matcher.toContain(5); | |
| 16 | try matcher.toContainAll(&.{ 1, 3, 8 }); | |
| 17 | try std.testing.expectError(ztf.AssertionError.AssertionFailed, matcher.toContain(13)); | |
| 14 | 18 | } |
| 15 | 19 | |
| 16 | test "matchers struct operations" { | |
| 17 | // Test struct-specific matchers | |
| 18 | try std.testing.expect(true); | |
| 20 | test "struct matchers inspect named fields" { | |
| 21 | const User = struct { name: []const u8, active: bool }; | |
| 22 | const matcher = ztf.expectStruct(std.testing.allocator, User{ .name = "Ada", .active = true }); | |
| 23 | try matcher.toHaveField("name", "Ada"); | |
| 24 | try matcher.toHaveField("active", true); | |
| 25 | try std.testing.expectError(ztf.AssertionError.AssertionFailed, matcher.toHaveField("name", "Grace")); | |
| 19 | 26 | } |
| @@ -1,19 +1,34 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for mock module | |
| 4 | // TODO: Implement comprehensive tests for mocking and spying | |
| 5 | ||
| 6 | test "mock function call tracking" { | |
| 7 | // Test mock call recording | |
| 8 | try std.testing.expect(true); | |
| 4 | test "mock records calls and exposes the latest invocation" { | |
| 5 | var mock = ztf.createMock(std.testing.allocator, i32); | |
| 6 | defer mock.deinit(); | |
| 7 | try mock.recordCall("first"); | |
| 8 | try mock.recordCall("second"); | |
| 9 | try std.testing.expectEqual(@as(usize, 2), mock.callCount()); | |
| 10 | try std.testing.expectEqualStrings("second", mock.getLastCall().?.args); | |
| 11 | try mock.toHaveBeenCalledWith("first"); | |
| 9 | 12 | } |
| 10 | 13 | |
| 11 | test "mock return values" { | |
| 12 | // Test mock return value functionality | |
| 13 | try std.testing.expect(true); | |
| 14 | test "mock returns configured values in order" { | |
| 15 | var mock = ztf.createMock(std.testing.allocator, i32); | |
| 16 | defer mock.deinit(); | |
| 17 | _ = try mock.mockReturnValueOnce(10); | |
| 18 | _ = try mock.mockReturnValue(20); | |
| 19 | try std.testing.expectEqual(@as(?i32, 10), mock.getReturnValue()); | |
| 20 | try std.testing.expectEqual(@as(?i32, 20), mock.getReturnValue()); | |
| 21 | try std.testing.expectEqual(@as(?i32, 20), mock.getReturnValue()); | |
| 14 | 22 | } |
| 15 | 23 | |
| 16 | test "spy functionality" { | |
| 17 | // Test spy wrapping of functions | |
| 18 | try std.testing.expect(true); | |
| 24 | test "mock clear preserves return values while reset removes them" { | |
| 25 | var mock = ztf.createMock(std.testing.allocator, i32); | |
| 26 | defer mock.deinit(); | |
| 27 | try mock.recordCall("call"); | |
| 28 | _ = try mock.mockReturnValue(7); | |
| 29 | _ = mock.mockClear(); | |
| 30 | try std.testing.expectEqual(@as(usize, 0), mock.callCount()); | |
| 31 | try std.testing.expectEqual(@as(?i32, 7), mock.getReturnValue()); | |
| 32 | _ = mock.mockReset(); | |
| 33 | try std.testing.expectEqual(@as(?i32, null), mock.getReturnValue()); | |
| 19 | 34 | } |
| @@ -1,19 +1,71 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for reporter module | |
| 4 | // TODO: Implement comprehensive tests for all reporter types | |
| 4 | fn passingTest(_: std.mem.Allocator) !void {} | |
| 5 | 5 | |
| 6 | 6 | test "reporter spec output" { |
| 7 | // Test SpecReporter formatting | |
| 8 | try std.testing.expect(true); | |
| 7 | var buffer: [2048]u8 = undefined; | |
| 8 | const writer: std.Io.Writer = .fixed(&buffer); | |
| 9 | var reporter = ztf.SpecReporter.init(std.testing.allocator, writer); | |
| 10 | reporter.reporter.use_colors = false; | |
| 11 | var results = ztf.TestResults.init(std.testing.allocator); | |
| 12 | defer results.deinit(); | |
| 13 | results.total = 1; | |
| 14 | results.passed = 1; | |
| 15 | var test_case = ztf.TestCase.init("passes", passingTest); | |
| 16 | test_case.status = .passed; | |
| 17 | ||
| 18 | try reporter.reporter.onRunStart(1); | |
| 19 | try reporter.reporter.onSuiteStart("suite"); | |
| 20 | try reporter.reporter.onTestEnd(&test_case); | |
| 21 | try reporter.reporter.onSuiteEnd("suite"); | |
| 22 | try reporter.reporter.onRunEnd(&results); | |
| 23 | ||
| 24 | const output = buffer[0..reporter.writer.end]; | |
| 25 | try std.testing.expect(std.mem.indexOf(u8, output, "Running 1 test(s)") != null); | |
| 26 | try std.testing.expect(std.mem.indexOf(u8, output, "Passed: 1") != null); | |
| 9 | 27 | } |
| 10 | 28 | |
| 11 | 29 | test "reporter dot output" { |
| 12 | // Test DotReporter formatting | |
| 13 | try std.testing.expect(true); | |
| 30 | var buffer: [1024]u8 = undefined; | |
| 31 | const writer: std.Io.Writer = .fixed(&buffer); | |
| 32 | var reporter = ztf.DotReporter.init(std.testing.allocator, writer); | |
| 33 | reporter.reporter.use_colors = false; | |
| 34 | var results = ztf.TestResults.init(std.testing.allocator); | |
| 35 | defer results.deinit(); | |
| 36 | results.total = 1; | |
| 37 | results.passed = 1; | |
| 38 | var test_case = ztf.TestCase.init("passes", passingTest); | |
| 39 | test_case.status = .passed; | |
| 40 | ||
| 41 | try reporter.reporter.onRunStart(1); | |
| 42 | try reporter.reporter.onTestEnd(&test_case); | |
| 43 | try reporter.reporter.onRunEnd(&results); | |
| 44 | ||
| 45 | const output = buffer[0..reporter.writer.end]; | |
| 46 | try std.testing.expect(std.mem.indexOf(u8, output, ".") != null); | |
| 47 | try std.testing.expect(std.mem.indexOf(u8, output, "Passed: 1") != null); | |
| 14 | 48 | } |
| 15 | 49 | |
| 16 | 50 | test "reporter json output" { |
| 17 | // Test JsonReporter formatting | |
| 18 | try std.testing.expect(true); | |
| 51 | var buffer: [2048]u8 = undefined; | |
| 52 | const writer: std.Io.Writer = .fixed(&buffer); | |
| 53 | var reporter = ztf.JsonReporter.init(std.testing.allocator, writer); | |
| 54 | defer reporter.deinit(); | |
| 55 | var results = ztf.TestResults.init(std.testing.allocator); | |
| 56 | defer results.deinit(); | |
| 57 | results.total = 1; | |
| 58 | results.passed = 1; | |
| 59 | var test_case = ztf.TestCase.init("passes", passingTest); | |
| 60 | test_case.status = .passed; | |
| 61 | ||
| 62 | try reporter.reporter.onRunStart(1); | |
| 63 | try reporter.reporter.onSuiteStart("suite"); | |
| 64 | try reporter.reporter.onTestEnd(&test_case); | |
| 65 | try reporter.reporter.onSuiteEnd("suite"); | |
| 66 | try reporter.reporter.onRunEnd(&results); | |
| 67 | ||
| 68 | const output = buffer[0..reporter.writer.end]; | |
| 69 | try std.testing.expect(std.mem.indexOf(u8, output, "\"name\":\"passes\"") != null); | |
| 70 | try std.testing.expect(std.mem.indexOf(u8, output, "\"passed\":1") != null); | |
| 19 | 71 | } |
| @@ -1,19 +1,51 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for suite module | |
| 4 | // TODO: Implement comprehensive tests for test suite management | |
| 4 | fn passingTest(_: std.mem.Allocator) !void {} | |
| 5 | fn hookOne(_: std.mem.Allocator) !void {} | |
| 6 | fn hookTwo(_: std.mem.Allocator) !void {} | |
| 5 | 7 | |
| 6 | test "suite creation and management" { | |
| 7 | // Test TestSuite initialization | |
| 8 | try std.testing.expect(true); | |
| 8 | test "suite owns tests and nested suites" { | |
| 9 | const allocator = std.testing.allocator; | |
| 10 | const parent = try ztf.TestSuite.init(allocator, "parent"); | |
| 11 | defer parent.deinit(); | |
| 12 | const child = try ztf.TestSuite.init(allocator, "child"); | |
| 13 | try parent.addTest(ztf.TestCase.init("one", passingTest)); | |
| 14 | try child.addTest(ztf.TestCase.init("two", passingTest)); | |
| 15 | try parent.addSuite(child); | |
| 16 | try std.testing.expectEqual(@as(usize, 2), parent.countTests()); | |
| 17 | try std.testing.expectEqual(parent, child.parent.?); | |
| 9 | 18 | } |
| 10 | 19 | |
| 11 | test "suite nested describe blocks" { | |
| 12 | // Test nested test suites | |
| 13 | try std.testing.expect(true); | |
| 20 | test "nested hooks preserve before and after ordering" { | |
| 21 | const allocator = std.testing.allocator; | |
| 22 | const parent = try ztf.TestSuite.init(allocator, "parent"); | |
| 23 | defer parent.deinit(); | |
| 24 | const child = try ztf.TestSuite.init(allocator, "child"); | |
| 25 | try parent.addSuite(child); | |
| 26 | try parent.addBeforeEach(hookOne); | |
| 27 | try child.addBeforeEach(hookTwo); | |
| 28 | try parent.addAfterEach(hookOne); | |
| 29 | try child.addAfterEach(hookTwo); | |
| 30 | ||
| 31 | var before = try child.getAllBeforeEachHooks(allocator); | |
| 32 | defer before.deinit(allocator); | |
| 33 | var after = try child.getAllAfterEachHooks(allocator); | |
| 34 | defer after.deinit(allocator); | |
| 35 | try std.testing.expectEqual(hookOne, before.items[0]); | |
| 36 | try std.testing.expectEqual(hookTwo, before.items[1]); | |
| 37 | try std.testing.expectEqual(hookTwo, after.items[0]); | |
| 38 | try std.testing.expectEqual(hookOne, after.items[1]); | |
| 14 | 39 | } |
| 15 | 40 | |
| 16 | test "suite skip and only functionality" { | |
| 17 | // Test skip and only modifiers | |
| 18 | try std.testing.expect(true); | |
| 41 | test "suite skip and only state inherits from parents" { | |
| 42 | const allocator = std.testing.allocator; | |
| 43 | const parent = try ztf.TestSuite.init(allocator, "parent"); | |
| 44 | defer parent.deinit(); | |
| 45 | const child = try ztf.TestSuite.init(allocator, "child"); | |
| 46 | try parent.addSuite(child); | |
| 47 | parent.skip = true; | |
| 48 | parent.only = true; | |
| 49 | try std.testing.expect(child.shouldSkip()); | |
| 50 | try std.testing.expect(child.hasOnly()); | |
| 19 | 51 | } |
| @@ -1,19 +1,30 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const ztf = ; | |
| 2 | 3 | |
| 3 | // Placeholder tests for test_runner module | |
| 4 | // TODO: Implement comprehensive tests for TestRunner | |
| 4 | fn passingTest(_: std.mem.Allocator) !void {} | |
| 5 | 5 | |
| 6 | 6 | test "test runner initialization" { |
| 7 | // Test that TestRunner can be initialized | |
| 8 | try std.testing.expect(true); | |
| 7 | var registry = ztf.TestRegistry.init(std.testing.allocator); | |
| 8 | defer registry.deinit(); | |
| 9 | var runner = ztf.TestRunner.init(std.testing.allocator, ®istry, .{}); | |
| 10 | defer runner.deinit(); | |
| 11 | try std.testing.expectEqual(@as(usize, 0), runner.results.total); | |
| 12 | try std.testing.expectEqual(ztf.ReporterType.spec, runner.options.reporter_type); | |
| 9 | 13 | } |
| 10 | 14 | |
| 11 | test "test runner executes tests" { | |
| 12 | // Test that TestRunner can execute registered tests | |
| 13 | try std.testing.expect(true); | |
| 14 | } | |
| 15 | test "test runner executes matching tests and skips filtered tests" { | |
| 16 | const allocator = std.testing.allocator; | |
| 17 | var registry = ztf.TestRegistry.init(allocator); | |
| 18 | defer registry.deinit(); | |
| 19 | const suite = try ztf.TestSuite.init(allocator, "runner suite"); | |
| 20 | try suite.addTest(ztf.TestCase.init("selected", passingTest)); | |
| 21 | try suite.addTest(ztf.TestCase.init("ignored", passingTest)); | |
| 22 | try registry.registerSuite(suite); | |
| 15 | 23 | |
| 16 | test "test runner reports results" { | |
| 17 | // Test that TestRunner correctly reports test results | |
| 18 | try std.testing.expect(true); | |
| 24 | var runner = ztf.TestRunner.init(allocator, ®istry, .{ .filter = "selected", .use_colors = false }); | |
| 25 | defer runner.deinit(); | |
| 26 | try std.testing.expect(try runner.run()); | |
| 27 | try std.testing.expectEqual(@as(usize, 2), runner.results.total); | |
| 28 | try std.testing.expectEqual(@as(usize, 1), runner.results.passed); | |
| 29 | try std.testing.expectEqual(@as(usize, 1), runner.results.skipped); | |
| 19 | 30 | } |