authorgravatar for k4@noreply.codeberg.orgK4 <k4@noreply.codeberg.org> 2026-07-28 23:47:54+03:00
committergravatar for k4@noreply.codeberg.orgK4 <k4@noreply.codeberg.org> 2026-08-05 11:38:11+03:00
log960469dc8a3c132c95e51bad304a23811675472f
tree96abb1d739c2263f3185d8e2f9618a68651eb1d3
parent5ce96175327328f4b039ce44e646653a5b2725ba

std.testing: small reorganizing and tests


1 files changed, 56 insertions(+), 42 deletions(-)

lib/std/testing.zig+56-42
......@@ -18,10 +18,7 @@ var failing_allocator_instance = FailingAllocator.init(base_allocator_instance.a
1818var base_allocator_instance = std.heap.FixedBufferAllocator.init("");
1919
2020pub var allocator_instance: std.heap.SafeAllocator = undefined;
21pub const allocator = if (builtin.is_test)
22 allocator_instance.allocator()
23else
24 @compileError("not testing");
21pub const allocator = if (builtin.is_test) allocator_instance.allocator() else @compileError("not testing");
2522
2623pub var io_instance: Io.Threaded = undefined;
2724pub const io = if (builtin.is_test) io_instance.io() else @compileError("not testing");
......@@ -50,23 +47,6 @@ pub fn failPrint(comptime fmt: []const u8, args: anytype) void {
5047 }
5148}
5249
53/// This function is intended to be used only in tests. When `actual_error_union` is not
54/// `expected_error`, it prints diagnostics to stderr, then returns a test failure error.
55pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void {
56 if (actual_error_union) |actual_payload| {
57 failPrint("expected error.{s}, found {any}\n", .{ @errorName(expected_error), actual_payload });
58 return error.TestExpectedError;
59 } else |actual_error| {
60 if (expected_error != actual_error) {
61 failPrint("expected error.{s}, found error.{s}\n", .{
62 @errorName(expected_error),
63 @errorName(actual_error),
64 });
65 return error.TestUnexpectedError;
66 }
67 }
68}
69
7050/// This function is intended to be used only in tests. When the two values are not
7151/// equal, prints diagnostics to stderr to show exactly how they are not equal,
7252/// then returns a test failure error.
......@@ -219,7 +199,7 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
219199 }
220200}
221201
222test "expectEqual.union(enum)" {
202test "expectEqual union(enum)" {
223203 const T = union(enum) {
224204 a: i32,
225205 b: f32,
......@@ -268,20 +248,6 @@ test "expectEqual null" {
268248 try expectEqual(a, b);
269249}
270250
271/// This function is intended to be used only in tests. When the formatted result of the template
272/// and its arguments does not equal the expected text, it prints diagnostics to stderr to show how
273/// they are not equal, then returns an error. It depends on `expectEqualStrings` for printing
274/// diagnostics.
275pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anytype) !void {
276 if (@inComptime()) {
277 var buffer: [std.fmt.count(template, args)]u8 = undefined;
278 return expectEqualStrings(expected, try std.fmt.bufPrint(&buffer, template, args));
279 }
280 const actual = try std.fmt.allocPrint(allocator, template, args);
281 defer allocator.free(actual);
282 return expectEqualStrings(expected, actual);
283}
284
285251/// This function is intended to be used only in tests. When the actual value is
286252/// not approximately equal to the expected value, prints diagnostics to stderr
287253/// to show exactly how they are not equal, then returns a test failure error.
......@@ -553,7 +519,7 @@ const BytesDiffer = struct {
553519 }
554520};
555521
556test {
522test expectEqualSlices {
557523 try expectEqualSlices(u8, "foo\x00", "foo\x00");
558524 try expectEqualSlices(u16, &[_]u16{ 100, 200, 300, 400 }, &[_]u16{ 100, 200, 300, 400 });
559525 const E = enum { foo, bar };
......@@ -656,7 +622,47 @@ pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir {
656622 };
657623}
658624
659/// This function is intended to be used only in test. When the two strings are not equal,
625/// This function is intended to be used only in tests. When `actual_error_union` is not
626/// `expected_error`, it prints diagnostics to stderr, then returns a test failure error.
627pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void {
628 if (actual_error_union) |actual_payload| {
629 failPrint("expected error.{s}, found {any}\n", .{ @errorName(expected_error), actual_payload });
630 return error.TestExpectedError;
631 } else |actual_error| {
632 if (expected_error != actual_error) {
633 failPrint("expected error.{s}, found error.{s}\n", .{
634 @errorName(expected_error),
635 @errorName(actual_error),
636 });
637 return error.TestUnexpectedError;
638 }
639 }
640}
641
642fn returnErrorUnion() !u8 {
643 return error.Expected;
644}
645
646test expectError {
647 const actualErrorUnion = returnErrorUnion();
648 try expectError(error.Expected, actualErrorUnion);
649}
650
651/// This function is intended to be used only in tests. When the formatted result of the template
652/// and its arguments does not equal the expected text, it prints diagnostics to stderr to show how
653/// they are not equal, then returns an error. It depends on `expectEqualStrings` for printing
654/// diagnostics.
655pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anytype) !void {
656 if (@inComptime()) {
657 var buffer: [std.fmt.count(template, args)]u8 = undefined;
658 return expectEqualStrings(expected, try std.fmt.bufPrint(&buffer, template, args));
659 }
660 const actual = try std.fmt.allocPrint(allocator, template, args);
661 defer allocator.free(actual);
662 return expectEqualStrings(expected, actual);
663}
664
665// This function is intended to be used only in test. When the two strings are not equal,
660666/// it prints diagnostics to stderr to show how they are not equal, then returns an error.
661667pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {
662668 if (std.mem.findDiff(u8, actual, expected)) |diff_index| {
......@@ -687,6 +693,10 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {
687693 }
688694}
689695
696test expectEqualStrings {
697 try expectEqualStrings("foo", "foo");
698}
699
690700/// This function is intended to be used only in test. When the start of `actual` and `expected_starts_with`
691701/// are not equal, it prints diagnostics to stderr to show how they are not equal, then returns an error.
692702pub fn expectStringStartsWith(actual: []const u8, expected_starts_with: []const u8) !void {
......@@ -709,6 +719,10 @@ pub fn expectStringStartsWith(actual: []const u8, expected_starts_with: []const
709719 return error.TestExpectedStartsWith;
710720}
711721
722test expectStringStartsWith {
723 try expectStringStartsWith("foobar", "foo");
724}
725
712726/// This function is intended to be used only in test. When the end of `actual` and `expected_ends_with`
713727/// are not equal, it prints diagnostics to stderr to show how they are not equal, then returns an error.
714728pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) !void {
......@@ -731,6 +745,10 @@ pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8)
731745 return error.TestExpectedEndsWith;
732746}
733747
748test expectStringEndsWith {
749 try expectStringEndsWith("foobar", "bar");
750}
751
734752/// This function is intended to be used only in tests. When the two values are not
735753/// deeply equal, prints diagnostics to stderr to show exactly how they are not equal,
736754/// then returns a test failure error.
......@@ -1045,10 +1063,6 @@ pub fn failPrintLine(line: []const u8) void {
10451063 failPrint("{s}\n", .{line});
10461064}
10471065
1048test {
1049 try expectEqualStrings("foo", "foo");
1050}
1051
10521066/// Exhaustively check that allocation failures within `test_fn` are handled without
10531067/// introducing memory leaks. If used with the `testing.allocator` as the `backing_allocator`,
10541068/// it will also be able to detect double frees, etc (when runtime safety is enabled).