| author | |
| committer | |
| log | e72f45475d05fb446e48d3e34e6c8e367916bd50 |
| tree | c8b12903027a506b533f34f4c78de3d739f2f5c2 |
| parent | 611bd8e9f49bd3532a23c49f6b675da03403b635 |
| parent | 87c9696121048fe9c14b898e26037f939d7959f0 |
| signature |
Add visible newlines to parser_test output when there's a failure.3 files changed, 83 insertions(+), 8 deletions(-)
lib/std/mem.zig+19| ... | @@ -514,6 +514,25 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { | ... | @@ -514,6 +514,25 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) bool { |
| 514 | return true; | 514 | return true; |
| 515 | } | 515 | } |
| 516 | 516 | ||
| 517 | /// Compares two slices and returns the index of the first inequality. | ||
| 518 | /// Returns null if the slices are equal. | ||
| 519 | pub fn indexOfDiff(comptime T: type, a: []const T, b: []const T) ?usize { | ||
| 520 | const shortest = math.min(a.len, b.len); | ||
| 521 | if (a.ptr == b.ptr) | ||
| 522 | return if (a.len == b.len) null else shortest; | ||
| 523 | var index: usize = 0; | ||
| 524 | while (index < shortest) : (index += 1) if (a[index] != b[index]) return index; | ||
| 525 | return if (a.len == b.len) null else shortest; | ||
| 526 | } | ||
| 527 | |||
| 528 | test "indexOfDiff" { | ||
| 529 | testing.expectEqual(indexOfDiff(u8, "one", "one"), null); | ||
| 530 | testing.expectEqual(indexOfDiff(u8, "one two", "one"), 3); | ||
| 531 | testing.expectEqual(indexOfDiff(u8, "one", "one two"), 3); | ||
| 532 | testing.expectEqual(indexOfDiff(u8, "one twx", "one two"), 6); | ||
| 533 | testing.expectEqual(indexOfDiff(u8, "xne", "one"), 0); | ||
| 534 | } | ||
| 535 | |||
| 517 | pub const toSliceConst = @compileError("deprecated; use std.mem.spanZ"); | 536 | pub const toSliceConst = @compileError("deprecated; use std.mem.spanZ"); |
| 518 | pub const toSlice = @compileError("deprecated; use std.mem.spanZ"); | 537 | pub const toSlice = @compileError("deprecated; use std.mem.spanZ"); |
| 519 | 538 |
lib/std/testing.zig+63| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std.zig"); | 1 | const std = @import("std.zig"); |
| 2 | const warn = std.debug.warn; | ||
| 2 | 3 | ||
| 3 | pub const LeakCountAllocator = @import("testing/leak_count_allocator.zig").LeakCountAllocator; | 4 | pub const LeakCountAllocator = @import("testing/leak_count_allocator.zig").LeakCountAllocator; |
| 4 | pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator; | 5 | pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator; |
| ... | @@ -212,3 +213,65 @@ test "expectEqual vector" { | ... | @@ -212,3 +213,65 @@ test "expectEqual vector" { |
| 212 | 213 | ||
| 213 | expectEqual(a, b); | 214 | expectEqual(a, b); |
| 214 | } | 215 | } |
| 216 | |||
| 217 | pub fn expectEqualStrings(expected: []const u8, actual: []const u8) void { | ||
| 218 | if (std.mem.indexOfDiff(u8, actual, expected)) |diff_index| { | ||
| 219 | warn("\n====== expected this output: =========\n", .{}); | ||
| 220 | printWithVisibleNewlines(expected); | ||
| 221 | warn("\n======== instead found this: =========\n", .{}); | ||
| 222 | printWithVisibleNewlines(actual); | ||
| 223 | warn("\n======================================\n", .{}); | ||
| 224 | |||
| 225 | var diff_line_number: usize = 1; | ||
| 226 | for (expected[0..diff_index]) |value| { | ||
| 227 | if (value == '\n') diff_line_number += 1; | ||
| 228 | } | ||
| 229 | warn("First difference occurs on line {}:\n", .{diff_line_number}); | ||
| 230 | |||
| 231 | warn("expected:\n", .{}); | ||
| 232 | printIndicatorLine(expected, diff_index); | ||
| 233 | |||
| 234 | warn("found:\n", .{}); | ||
| 235 | printIndicatorLine(actual, diff_index); | ||
| 236 | |||
| 237 | @panic("test failure"); | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | fn printIndicatorLine(source: []const u8, indicator_index: usize) void { | ||
| 242 | const line_begin_index = if (std.mem.lastIndexOfScalar(u8, source[0..indicator_index], '\n')) |line_begin| | ||
| 243 | line_begin + 1 | ||
| 244 | else | ||
| 245 | 0; | ||
| 246 | const line_end_index = if (std.mem.indexOfScalar(u8, source[indicator_index..], '\n')) |line_end| | ||
| 247 | (indicator_index + line_end) | ||
| 248 | else | ||
| 249 | source.len; | ||
| 250 | |||
| 251 | printLine(source[line_begin_index..line_end_index]); | ||
| 252 | { | ||
| 253 | var i: usize = line_begin_index; | ||
| 254 | while (i < indicator_index) : (i += 1) | ||
| 255 | warn(" ", .{}); | ||
| 256 | } | ||
| 257 | warn("^\n", .{}); | ||
| 258 | } | ||
| 259 | |||
| 260 | fn printWithVisibleNewlines(source: []const u8) void { | ||
| 261 | var i: usize = 0; | ||
| 262 | while (std.mem.indexOf(u8, source[i..], "\n")) |nl| : (i += nl + 1) { | ||
| 263 | printLine(source[i .. i + nl]); | ||
| 264 | } | ||
| 265 | warn("{}␃\n", .{source[i..]}); // End of Text symbol (ETX) | ||
| 266 | } | ||
| 267 | |||
| 268 | fn printLine(line: []const u8) void { | ||
| 269 | switch (line[line.len - 1]) { | ||
| 270 | ' ', '\t' => warn("{}⏎\n", .{line}), // Carriage return symbol, | ||
| 271 | else => warn("{}\n", .{line}), | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | test "" { | ||
| 276 | expectEqualStrings("foo", "foo"); | ||
| 277 | } |
lib/std/zig/parser_test.zig+1-8| ... | @@ -2971,14 +2971,7 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void { | ... | @@ -2971,14 +2971,7 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void { |
| 2971 | var failing_allocator = std.testing.FailingAllocator.init(&fixed_allocator.allocator, maxInt(usize)); | 2971 | var failing_allocator = std.testing.FailingAllocator.init(&fixed_allocator.allocator, maxInt(usize)); |
| 2972 | var anything_changed: bool = undefined; | 2972 | var anything_changed: bool = undefined; |
| 2973 | const result_source = try testParse(source, &failing_allocator.allocator, &anything_changed); | 2973 | const result_source = try testParse(source, &failing_allocator.allocator, &anything_changed); |
| 2974 | if (!mem.eql(u8, result_source, expected_source)) { | 2974 | std.testing.expectEqualStrings(expected_source, result_source); |
| 2975 | warn("\n====== expected this output: =========\n", .{}); | ||
| 2976 | warn("{}", .{expected_source}); | ||
| 2977 | warn("\n======== instead found this: =========\n", .{}); | ||
| 2978 | warn("{}", .{result_source}); | ||
| 2979 | warn("\n======================================\n", .{}); | ||
| 2980 | return error.TestFailed; | ||
| 2981 | } | ||
| 2982 | const changes_expected = source.ptr != expected_source.ptr; | 2975 | const changes_expected = source.ptr != expected_source.ptr; |
| 2983 | if (anything_changed != changes_expected) { | 2976 | if (anything_changed != changes_expected) { |
| 2984 | warn("std.zig.render returned {} instead of {}\n", .{ anything_changed, changes_expected }); | 2977 | warn("std.zig.render returned {} instead of {}\n", .{ anything_changed, changes_expected }); |