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...@@ -18,10 +18,7 @@ var failing_allocator_instance = FailingAllocator.init(base_allocator_instance.a
18var base_allocator_instance = std.heap.FixedBufferAllocator.init("");18var base_allocator_instance = std.heap.FixedBufferAllocator.init("");
1919
20pub var allocator_instance: std.heap.SafeAllocator = undefined;20pub var allocator_instance: std.heap.SafeAllocator = undefined;
21pub const allocator = if (builtin.is_test)21pub const allocator = if (builtin.is_test) allocator_instance.allocator() else @compileError("not testing");
22 allocator_instance.allocator()
23else
24 @compileError("not testing");
2522
26pub var io_instance: Io.Threaded = undefined;23pub var io_instance: Io.Threaded = undefined;
27pub const io = if (builtin.is_test) io_instance.io() else @compileError("not testing");24pub 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 {...@@ -50,23 +47,6 @@ pub fn failPrint(comptime fmt: []const u8, args: anytype) void {
50 }47 }
51}48}
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
70/// This function is intended to be used only in tests. When the two values are not50/// This function is intended to be used only in tests. When the two values are not
71/// equal, prints diagnostics to stderr to show exactly how they are not equal,51/// equal, prints diagnostics to stderr to show exactly how they are not equal,
72/// then returns a test failure error.52/// then returns a test failure error.
...@@ -219,7 +199,7 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {...@@ -219,7 +199,7 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
219 }199 }
220}200}
221201
222test "expectEqual.union(enum)" {202test "expectEqual union(enum)" {
223 const T = union(enum) {203 const T = union(enum) {
224 a: i32,204 a: i32,
225 b: f32,205 b: f32,
...@@ -268,20 +248,6 @@ test "expectEqual null" {...@@ -268,20 +248,6 @@ test "expectEqual null" {
268 try expectEqual(a, b);248 try expectEqual(a, b);
269}249}
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
285/// This function is intended to be used only in tests. When the actual value is251/// This function is intended to be used only in tests. When the actual value is
286/// not approximately equal to the expected value, prints diagnostics to stderr252/// not approximately equal to the expected value, prints diagnostics to stderr
287/// to show exactly how they are not equal, then returns a test failure error.253/// to show exactly how they are not equal, then returns a test failure error.
...@@ -553,7 +519,7 @@ const BytesDiffer = struct {...@@ -553,7 +519,7 @@ const BytesDiffer = struct {
553 }519 }
554};520};
555521
556test {522test expectEqualSlices {
557 try expectEqualSlices(u8, "foo\x00", "foo\x00");523 try expectEqualSlices(u8, "foo\x00", "foo\x00");
558 try expectEqualSlices(u16, &[_]u16{ 100, 200, 300, 400 }, &[_]u16{ 100, 200, 300, 400 });524 try expectEqualSlices(u16, &[_]u16{ 100, 200, 300, 400 }, &[_]u16{ 100, 200, 300, 400 });
559 const E = enum { foo, bar };525 const E = enum { foo, bar };
...@@ -656,7 +622,47 @@ pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir {...@@ -656,7 +622,47 @@ pub fn tmpDir(opts: Io.Dir.OpenOptions) TmpDir {
656 };622 };
657}623}
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,
660/// it prints diagnostics to stderr to show how they are not equal, then returns an error.666/// it prints diagnostics to stderr to show how they are not equal, then returns an error.
661pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {667pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {
662 if (std.mem.findDiff(u8, actual, expected)) |diff_index| {668 if (std.mem.findDiff(u8, actual, expected)) |diff_index| {
...@@ -687,6 +693,10 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {...@@ -687,6 +693,10 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {
687 }693 }
688}694}
689695
696test expectEqualStrings {
697 try expectEqualStrings("foo", "foo");
698}
699
690/// This function is intended to be used only in test. When the start of `actual` and `expected_starts_with`700/// This function is intended to be used only in test. When the start of `actual` and `expected_starts_with`
691/// are not equal, it prints diagnostics to stderr to show how they are not equal, then returns an error.701/// are not equal, it prints diagnostics to stderr to show how they are not equal, then returns an error.
692pub fn expectStringStartsWith(actual: []const u8, expected_starts_with: []const u8) !void {702pub 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...@@ -709,6 +719,10 @@ pub fn expectStringStartsWith(actual: []const u8, expected_starts_with: []const
709 return error.TestExpectedStartsWith;719 return error.TestExpectedStartsWith;
710}720}
711721
722test expectStringStartsWith {
723 try expectStringStartsWith("foobar", "foo");
724}
725
712/// This function is intended to be used only in test. When the end of `actual` and `expected_ends_with`726/// This function is intended to be used only in test. When the end of `actual` and `expected_ends_with`
713/// are not equal, it prints diagnostics to stderr to show how they are not equal, then returns an error.727/// are not equal, it prints diagnostics to stderr to show how they are not equal, then returns an error.
714pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) !void {728pub 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)...@@ -731,6 +745,10 @@ pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8)
731 return error.TestExpectedEndsWith;745 return error.TestExpectedEndsWith;
732}746}
733747
748test expectStringEndsWith {
749 try expectStringEndsWith("foobar", "bar");
750}
751
734/// This function is intended to be used only in tests. When the two values are not752/// This function is intended to be used only in tests. When the two values are not
735/// deeply equal, prints diagnostics to stderr to show exactly how they are not equal,753/// deeply equal, prints diagnostics to stderr to show exactly how they are not equal,
736/// then returns a test failure error.754/// then returns a test failure error.
...@@ -1045,10 +1063,6 @@ pub fn failPrintLine(line: []const u8) void {...@@ -1045,10 +1063,6 @@ pub fn failPrintLine(line: []const u8) void {
1045 failPrint("{s}\n", .{line});1063 failPrint("{s}\n", .{line});
1046}1064}
10471065
1048test {
1049 try expectEqualStrings("foo", "foo");
1050}
1051
1052/// Exhaustively check that allocation failures within `test_fn` are handled without1066/// Exhaustively check that allocation failures within `test_fn` are handled without
1053/// introducing memory leaks. If used with the `testing.allocator` as the `backing_allocator`,1067/// introducing memory leaks. If used with the `testing.allocator` as the `backing_allocator`,
1054/// it will also be able to detect double frees, etc (when runtime safety is enabled).1068/// it will also be able to detect double frees, etc (when runtime safety is enabled).