authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-05-04 19:36:59+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-05-08 15:15:23+03:00
log59f9253d94331cedd4d0518250c8094a064f6cd2
treee87664a007e91a1af83240eb46b7890f35c418ab
parent530e67cb868fbd24900d48eee891efa1aa135096

allow tests to fail


2 files changed, 72 insertions(+), 51 deletions(-)

lib/std/special/test_runner.zig+9-6
...@@ -23,6 +23,7 @@ pub fn main() anyerror!void {...@@ -23,6 +23,7 @@ pub fn main() anyerror!void {
23 const test_fn_list = builtin.test_functions;23 const test_fn_list = builtin.test_functions;
24 var ok_count: usize = 0;24 var ok_count: usize = 0;
25 var skip_count: usize = 0;25 var skip_count: usize = 0;
26 var fail_count: usize = 0;
26 var progress = std.Progress{};27 var progress = std.Progress{};
27 const root_node = progress.start("Test", test_fn_list.len) catch |err| switch (err) {28 const root_node = progress.start("Test", test_fn_list.len) catch |err| switch (err) {
28 // TODO still run tests in this case29 // TODO still run tests in this case
...@@ -62,7 +63,7 @@ pub fn main() anyerror!void {...@@ -62,7 +63,7 @@ pub fn main() anyerror!void {
62 .blocking => {63 .blocking => {
63 skip_count += 1;64 skip_count += 1;
64 test_node.end();65 test_node.end();
65 progress.log("{s}...SKIP (async test)\n", .{test_fn.name});66 progress.log("{s}... SKIP (async test)\n", .{test_fn.name});
66 if (progress.terminal == null) std.debug.print("SKIP (async test)\n", .{});67 if (progress.terminal == null) std.debug.print("SKIP (async test)\n", .{});
67 continue;68 continue;
68 },69 },
...@@ -75,12 +76,14 @@ pub fn main() anyerror!void {...@@ -75,12 +76,14 @@ pub fn main() anyerror!void {
75 error.SkipZigTest => {76 error.SkipZigTest => {
76 skip_count += 1;77 skip_count += 1;
77 test_node.end();78 test_node.end();
78 progress.log("{s}...SKIP\n", .{test_fn.name});79 progress.log("{s}... SKIP\n", .{test_fn.name});
79 if (progress.terminal == null) std.debug.print("SKIP\n", .{});80 if (progress.terminal == null) std.debug.print("SKIP\n", .{});
80 },81 },
81 else => {82 else => {
82 progress.log("", .{});83 fail_count += 1;
83 return err;84 test_node.end();
85 progress.log("{s}... FAIL ({s})\n", .{ test_fn.name, @errorName(err) });
86 if (progress.terminal == null) std.debug.print("FAIL ({s})\n", .{@errorName(err)});
84 },87 },
85 }88 }
86 }89 }
...@@ -88,7 +91,7 @@ pub fn main() anyerror!void {...@@ -88,7 +91,7 @@ pub fn main() anyerror!void {
88 if (ok_count == test_fn_list.len) {91 if (ok_count == test_fn_list.len) {
89 std.debug.print("All {d} tests passed.\n", .{ok_count});92 std.debug.print("All {d} tests passed.\n", .{ok_count});
90 } else {93 } else {
91 std.debug.print("{d} passed; {d} skipped.\n", .{ ok_count, skip_count });94 std.debug.print("{d} passed; {d} skipped; {d} failed.\n", .{ ok_count, skip_count, fail_count });
92 }95 }
93 if (log_err_count != 0) {96 if (log_err_count != 0) {
94 std.debug.print("{d} errors were logged.\n", .{log_err_count});97 std.debug.print("{d} errors were logged.\n", .{log_err_count});
...@@ -96,7 +99,7 @@ pub fn main() anyerror!void {...@@ -96,7 +99,7 @@ pub fn main() anyerror!void {
96 if (leaks != 0) {99 if (leaks != 0) {
97 std.debug.print("{d} tests leaked memory.\n", .{leaks});100 std.debug.print("{d} tests leaked memory.\n", .{leaks});
98 }101 }
99 if (leaks != 0 or log_err_count != 0) {102 if (leaks != 0 or log_err_count != 0 or fail_count != 0) {
100 std.process.exit(1);103 std.process.exit(1);
101 }104 }
102}105}
lib/std/testing.zig+63-45
...@@ -27,15 +27,17 @@ pub var zig_exe_path: []const u8 = undefined;...@@ -27,15 +27,17 @@ pub var zig_exe_path: []const u8 = undefined;
2727
28/// This function is intended to be used only in tests. It prints diagnostics to stderr28/// This function is intended to be used only in tests. It prints diagnostics to stderr
29/// and then aborts when actual_error_union is not expected_error.29/// and then aborts when actual_error_union is not expected_error.
30pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void {30pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void {
31 if (actual_error_union) |actual_payload| {31 if (actual_error_union) |actual_payload| {
32 std.debug.panic("expected error.{s}, found {any}", .{ @errorName(expected_error), actual_payload });32 std.debug.print("expected error.{s}, found {any}", .{ @errorName(expected_error), actual_payload });
33 return error.TestUnexpectedError;
33 } else |actual_error| {34 } else |actual_error| {
34 if (expected_error != actual_error) {35 if (expected_error != actual_error) {
35 std.debug.panic("expected error.{s}, found error.{s}", .{36 std.debug.print("expected error.{s}, found error.{s}", .{
36 @errorName(expected_error),37 @errorName(expected_error),
37 @errorName(actual_error),38 @errorName(actual_error),
38 });39 });
40 return error.TestExpectedError;
39 }41 }
40 }42 }
41}43}
...@@ -44,7 +46,7 @@ pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void {...@@ -44,7 +46,7 @@ pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void {
44/// equal, prints diagnostics to stderr to show exactly how they are not equal,46/// equal, prints diagnostics to stderr to show exactly how they are not equal,
45/// then aborts.47/// then aborts.
46/// `actual` is casted to the type of `expected`.48/// `actual` is casted to the type of `expected`.
47pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {49pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void {
48 switch (@typeInfo(@TypeOf(actual))) {50 switch (@typeInfo(@TypeOf(actual))) {
49 .NoReturn,51 .NoReturn,
50 .BoundFn,52 .BoundFn,
...@@ -60,7 +62,8 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {...@@ -60,7 +62,8 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
6062
61 .Type => {63 .Type => {
62 if (actual != expected) {64 if (actual != expected) {
63 std.debug.panic("expected type {s}, found type {s}", .{ @typeName(expected), @typeName(actual) });65 std.debug.print("expected type {s}, found type {s}", .{ @typeName(expected), @typeName(actual) });
66 return error.TestExpectedEqual;
64 }67 }
65 },68 },
6669
...@@ -75,7 +78,8 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {...@@ -75,7 +78,8 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
75 .ErrorSet,78 .ErrorSet,
76 => {79 => {
77 if (actual != expected) {80 if (actual != expected) {
78 std.debug.panic("expected {}, found {}", .{ expected, actual });81 std.debug.print("expected {}, found {}", .{ expected, actual });
82 return error.TestExpectedEqual;
79 }83 }
80 },84 },
8185
...@@ -83,34 +87,38 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {...@@ -83,34 +87,38 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
83 switch (pointer.size) {87 switch (pointer.size) {
84 .One, .Many, .C => {88 .One, .Many, .C => {
85 if (actual != expected) {89 if (actual != expected) {
86 std.debug.panic("expected {*}, found {*}", .{ expected, actual });90 std.debug.print("expected {*}, found {*}", .{ expected, actual });
91 return error.TestExpectedEqual;
87 }92 }
88 },93 },
89 .Slice => {94 .Slice => {
90 if (actual.ptr != expected.ptr) {95 if (actual.ptr != expected.ptr) {
91 std.debug.panic("expected slice ptr {*}, found {*}", .{ expected.ptr, actual.ptr });96 std.debug.print("expected slice ptr {*}, found {*}", .{ expected.ptr, actual.ptr });
97 return error.TestExpectedEqual;
92 }98 }
93 if (actual.len != expected.len) {99 if (actual.len != expected.len) {
94 std.debug.panic("expected slice len {}, found {}", .{ expected.len, actual.len });100 std.debug.print("expected slice len {}, found {}", .{ expected.len, actual.len });
101 return error.TestExpectedEqual;
95 }102 }
96 },103 },
97 }104 }
98 },105 },
99106
100 .Array => |array| expectEqualSlices(array.child, &expected, &actual),107 .Array => |array| try expectEqualSlices(array.child, &expected, &actual),
101108
102 .Vector => |vectorType| {109 .Vector => |vectorType| {
103 var i: usize = 0;110 var i: usize = 0;
104 while (i < vectorType.len) : (i += 1) {111 while (i < vectorType.len) : (i += 1) {
105 if (!std.meta.eql(expected[i], actual[i])) {112 if (!std.meta.eql(expected[i], actual[i])) {
106 std.debug.panic("index {} incorrect. expected {}, found {}", .{ i, expected[i], actual[i] });113 std.debug.print("index {} incorrect. expected {}, found {}", .{ i, expected[i], actual[i] });
114 return error.TestExpectedEqual;
107 }115 }
108 }116 }
109 },117 },
110118
111 .Struct => |structType| {119 .Struct => |structType| {
112 inline for (structType.fields) |field| {120 inline for (structType.fields) |field| {
113 expectEqual(@field(expected, field.name), @field(actual, field.name));121 try expectEqual(@field(expected, field.name), @field(actual, field.name));
114 }122 }
115 },123 },
116124
...@@ -124,12 +132,12 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {...@@ -124,12 +132,12 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
124 const expectedTag = @as(Tag, expected);132 const expectedTag = @as(Tag, expected);
125 const actualTag = @as(Tag, actual);133 const actualTag = @as(Tag, actual);
126134
127 expectEqual(expectedTag, actualTag);135 try expectEqual(expectedTag, actualTag);
128136
129 // we only reach this loop if the tags are equal137 // we only reach this loop if the tags are equal
130 inline for (std.meta.fields(@TypeOf(actual))) |fld| {138 inline for (std.meta.fields(@TypeOf(actual))) |fld| {
131 if (std.mem.eql(u8, fld.name, @tagName(actualTag))) {139 if (std.mem.eql(u8, fld.name, @tagName(actualTag))) {
132 expectEqual(@field(expected, fld.name), @field(actual, fld.name));140 try expectEqual(@field(expected, fld.name), @field(actual, fld.name));
133 return;141 return;
134 }142 }
135 }143 }
...@@ -143,13 +151,15 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {...@@ -143,13 +151,15 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
143 .Optional => {151 .Optional => {
144 if (expected) |expected_payload| {152 if (expected) |expected_payload| {
145 if (actual) |actual_payload| {153 if (actual) |actual_payload| {
146 expectEqual(expected_payload, actual_payload);154 try expectEqual(expected_payload, actual_payload);
147 } else {155 } else {
148 std.debug.panic("expected {any}, found null", .{expected_payload});156 std.debug.print("expected {any}, found null", .{expected_payload});
157 return error.TestExpectedEqual;
149 }158 }
150 } else {159 } else {
151 if (actual) |actual_payload| {160 if (actual) |actual_payload| {
152 std.debug.panic("expected null, found {any}", .{actual_payload});161 std.debug.print("expected null, found {any}", .{actual_payload});
162 return error.TestExpectedEqual;
153 }163 }
154 }164 }
155 },165 },
...@@ -157,15 +167,17 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {...@@ -157,15 +167,17 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
157 .ErrorUnion => {167 .ErrorUnion => {
158 if (expected) |expected_payload| {168 if (expected) |expected_payload| {
159 if (actual) |actual_payload| {169 if (actual) |actual_payload| {
160 expectEqual(expected_payload, actual_payload);170 try expectEqual(expected_payload, actual_payload);
161 } else |actual_err| {171 } else |actual_err| {
162 std.debug.panic("expected {any}, found {}", .{ expected_payload, actual_err });172 std.debug.print("expected {any}, found {}", .{ expected_payload, actual_err });
173 return error.TestExpectedEqual;
163 }174 }
164 } else |expected_err| {175 } else |expected_err| {
165 if (actual) |actual_payload| {176 if (actual) |actual_payload| {
166 std.debug.panic("expected {}, found {any}", .{ expected_err, actual_payload });177 std.debug.print("expected {}, found {any}", .{ expected_err, actual_payload });
178 return error.TestExpectedEqual;
167 } else |actual_err| {179 } else |actual_err| {
168 expectEqual(expected_err, actual_err);180 try expectEqual(expected_err, actual_err);
169 }181 }
170 }182 }
171 },183 },
...@@ -181,7 +193,7 @@ test "expectEqual.union(enum)" {...@@ -181,7 +193,7 @@ test "expectEqual.union(enum)" {
181 const a10 = T{ .a = 10 };193 const a10 = T{ .a = 10 };
182 const a20 = T{ .a = 20 };194 const a20 = T{ .a = 20 };
183195
184 expectEqual(a10, a10);196 try expectEqual(a10, a10);
185}197}
186198
187/// This function is intended to be used only in tests. When the formatted result of the template199/// This function is intended to be used only in tests. When the formatted result of the template
...@@ -197,7 +209,7 @@ pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anyt...@@ -197,7 +209,7 @@ pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anyt
197 print("\n======== instead found this: =========\n", .{});209 print("\n======== instead found this: =========\n", .{});
198 print("{s}", .{result});210 print("{s}", .{result});
199 print("\n======================================\n", .{});211 print("\n======================================\n", .{});
200 return error.TestFailed;212 return error.TestExpectedFmt;
201}213}
202214
203pub const expectWithinMargin = @compileError("expectWithinMargin is deprecated, use expectApproxEqAbs or expectApproxEqRel");215pub const expectWithinMargin = @compileError("expectWithinMargin is deprecated, use expectApproxEqAbs or expectApproxEqRel");
...@@ -208,12 +220,14 @@ pub const expectWithinEpsilon = @compileError("expectWithinEpsilon is deprecated...@@ -208,12 +220,14 @@ pub const expectWithinEpsilon = @compileError("expectWithinEpsilon is deprecated
208/// to show exactly how they are not equal, then aborts.220/// to show exactly how they are not equal, then aborts.
209/// See `math.approxEqAbs` for more informations on the tolerance parameter.221/// See `math.approxEqAbs` for more informations on the tolerance parameter.
210/// The types must be floating point222/// The types must be floating point
211pub fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) void {223pub fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void {
212 const T = @TypeOf(expected);224 const T = @TypeOf(expected);
213225
214 switch (@typeInfo(T)) {226 switch (@typeInfo(T)) {
215 .Float => if (!math.approxEqAbs(T, expected, actual, tolerance))227 .Float => if (!math.approxEqAbs(T, expected, actual, tolerance)) {
216 std.debug.panic("actual {}, not within absolute tolerance {} of expected {}", .{ actual, tolerance, expected }),228 std.debug.print("actual {}, not within absolute tolerance {} of expected {}", .{ actual, tolerance, expected });
229 return error.TestExpectedApproxEqAbs;
230 },
217231
218 .ComptimeFloat => @compileError("Cannot approximately compare two comptime_float values"),232 .ComptimeFloat => @compileError("Cannot approximately compare two comptime_float values"),
219233
...@@ -228,8 +242,8 @@ test "expectApproxEqAbs" {...@@ -228,8 +242,8 @@ test "expectApproxEqAbs" {
228 const neg_x: T = -12.0;242 const neg_x: T = -12.0;
229 const neg_y: T = -12.06;243 const neg_y: T = -12.06;
230244
231 expectApproxEqAbs(pos_x, pos_y, 0.1);245 try expectApproxEqAbs(pos_x, pos_y, 0.1);
232 expectApproxEqAbs(neg_x, neg_y, 0.1);246 try expectApproxEqAbs(neg_x, neg_y, 0.1);
233 }247 }
234}248}
235249
...@@ -238,12 +252,14 @@ test "expectApproxEqAbs" {...@@ -238,12 +252,14 @@ test "expectApproxEqAbs" {
238/// to show exactly how they are not equal, then aborts.252/// to show exactly how they are not equal, then aborts.
239/// See `math.approxEqRel` for more informations on the tolerance parameter.253/// See `math.approxEqRel` for more informations on the tolerance parameter.
240/// The types must be floating point254/// The types must be floating point
241pub fn expectApproxEqRel(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) void {255pub fn expectApproxEqRel(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void {
242 const T = @TypeOf(expected);256 const T = @TypeOf(expected);
243257
244 switch (@typeInfo(T)) {258 switch (@typeInfo(T)) {
245 .Float => if (!math.approxEqRel(T, expected, actual, tolerance))259 .Float => if (!math.approxEqRel(T, expected, actual, tolerance)) {
246 std.debug.panic("actual {}, not within relative tolerance {} of expected {}", .{ actual, tolerance, expected }),260 std.debug.print("actual {}, not within relative tolerance {} of expected {}", .{ actual, tolerance, expected });
261 return error.TestExpectedApproxEqRel;
262 },
247263
248 .ComptimeFloat => @compileError("Cannot approximately compare two comptime_float values"),264 .ComptimeFloat => @compileError("Cannot approximately compare two comptime_float values"),
249265
...@@ -261,8 +277,8 @@ test "expectApproxEqRel" {...@@ -261,8 +277,8 @@ test "expectApproxEqRel" {
261 const neg_x: T = -12.0;277 const neg_x: T = -12.0;
262 const neg_y: T = neg_x - 2 * eps_value;278 const neg_y: T = neg_x - 2 * eps_value;
263279
264 expectApproxEqRel(pos_x, pos_y, sqrt_eps_value);280 try expectApproxEqRel(pos_x, pos_y, sqrt_eps_value);
265 expectApproxEqRel(neg_x, neg_y, sqrt_eps_value);281 try expectApproxEqRel(neg_x, neg_y, sqrt_eps_value);
266 }282 }
267}283}
268284
...@@ -270,26 +286,28 @@ test "expectApproxEqRel" {...@@ -270,26 +286,28 @@ test "expectApproxEqRel" {
270/// equal, prints diagnostics to stderr to show exactly how they are not equal,286/// equal, prints diagnostics to stderr to show exactly how they are not equal,
271/// then aborts.287/// then aborts.
272/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.288/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
273pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) void {289pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
274 // TODO better printing of the difference290 // TODO better printing of the difference
275 // If the arrays are small enough we could print the whole thing291 // If the arrays are small enough we could print the whole thing
276 // If the child type is u8 and no weird bytes, we could print it as strings292 // If the child type is u8 and no weird bytes, we could print it as strings
277 // Even for the length difference, it would be useful to see the values of the slices probably.293 // Even for the length difference, it would be useful to see the values of the slices probably.
278 if (expected.len != actual.len) {294 if (expected.len != actual.len) {
279 std.debug.panic("slice lengths differ. expected {d}, found {d}", .{ expected.len, actual.len });295 std.debug.print("slice lengths differ. expected {d}, found {d}", .{ expected.len, actual.len });
296 return error.TestExpectedEqual;
280 }297 }
281 var i: usize = 0;298 var i: usize = 0;
282 while (i < expected.len) : (i += 1) {299 while (i < expected.len) : (i += 1) {
283 if (!std.meta.eql(expected[i], actual[i])) {300 if (!std.meta.eql(expected[i], actual[i])) {
284 std.debug.panic("index {} incorrect. expected {any}, found {any}", .{ i, expected[i], actual[i] });301 std.debug.print("index {} incorrect. expected {any}, found {any}", .{ i, expected[i], actual[i] });
302 return error.TestExpectedEqual;
285 }303 }
286 }304 }
287}305}
288306
289/// This function is intended to be used only in tests. When `ok` is false, the test fails.307/// This function is intended to be used only in tests. When `ok` is false, the test fails.
290/// A message is printed to stderr and then abort is called.308/// A message is printed to stderr and then abort is called.
291pub fn expect(ok: bool) void {309pub fn expect(ok: bool) !void {
292 if (!ok) @panic("test failure");310 if (!ok) return error.TestUnexpectedResult;
293}311}
294312
295pub const TmpDir = struct {313pub const TmpDir = struct {
...@@ -356,17 +374,17 @@ test "expectEqual nested array" {...@@ -356,17 +374,17 @@ test "expectEqual nested array" {
356 [_]f32{ 0.0, 1.0 },374 [_]f32{ 0.0, 1.0 },
357 };375 };
358376
359 expectEqual(a, b);377 try expectEqual(a, b);
360}378}
361379
362test "expectEqual vector" {380test "expectEqual vector" {
363 var a = @splat(4, @as(u32, 4));381 var a = @splat(4, @as(u32, 4));
364 var b = @splat(4, @as(u32, 4));382 var b = @splat(4, @as(u32, 4));
365383
366 expectEqual(a, b);384 try expectEqual(a, b);
367}385}
368386
369pub fn expectEqualStrings(expected: []const u8, actual: []const u8) void {387pub fn expectEqualStrings(expected: []const u8, actual: []const u8) !void {
370 if (std.mem.indexOfDiff(u8, actual, expected)) |diff_index| {388 if (std.mem.indexOfDiff(u8, actual, expected)) |diff_index| {
371 print("\n====== expected this output: =========\n", .{});389 print("\n====== expected this output: =========\n", .{});
372 printWithVisibleNewlines(expected);390 printWithVisibleNewlines(expected);
...@@ -386,11 +404,11 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) void {...@@ -386,11 +404,11 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) void {
386 print("found:\n", .{});404 print("found:\n", .{});
387 printIndicatorLine(actual, diff_index);405 printIndicatorLine(actual, diff_index);
388406
389 @panic("test failure");407 return error.TestExpectedEqual;
390 }408 }
391}409}
392410
393pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) void {411pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) !void {
394 if (std.mem.endsWith(u8, actual, expected_ends_with))412 if (std.mem.endsWith(u8, actual, expected_ends_with))
395 return;413 return;
396414
...@@ -407,7 +425,7 @@ pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8)...@@ -407,7 +425,7 @@ pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8)
407 printWithVisibleNewlines(actual);425 printWithVisibleNewlines(actual);
408 print("\n======================================\n", .{});426 print("\n======================================\n", .{});
409427
410 @panic("test failure");428 return error.TestExpectedEndsWith;
411}429}
412430
413fn printIndicatorLine(source: []const u8, indicator_index: usize) void {431fn printIndicatorLine(source: []const u8, indicator_index: usize) void {
...@@ -446,7 +464,7 @@ fn printLine(line: []const u8) void {...@@ -446,7 +464,7 @@ fn printLine(line: []const u8) void {
446}464}
447465
448test {466test {
449 expectEqualStrings("foo", "foo");467 try expectEqualStrings("foo", "foo");
450}468}
451469
452/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.470/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.