| ... | ... | @@ -24,8 +24,6 @@ const ErrorMsg = struct { |
| 24 | 24 | pub const TestContext = struct { |
| 25 | 25 | // TODO: remove these. They are deprecated. |
| 26 | 26 | zir_cmp_output_cases: std.ArrayList(ZIRCompareOutputCase), |
| 27 | | // TODO: remove |
| 28 | | zir_error_cases: std.ArrayList(ZIRErrorCase), |
| 29 | 27 | |
| 30 | 28 | /// TODO: find a way to treat cases as individual tests (shouldn't show "1 test passed" if there are 200 cases) |
| 31 | 29 | zir_cases: std.ArrayList(ZIRCase), |
| ... | ... | @@ -37,14 +35,6 @@ pub const TestContext = struct { |
| 37 | 35 | expected_stdout_list: []const []const u8, |
| 38 | 36 | }; |
| 39 | 37 | |
| 40 | | // TODO: remove |
| 41 | | pub const ZIRErrorCase = struct { |
| 42 | | name: []const u8, |
| 43 | | src: [:0]const u8, |
| 44 | | expected_errors: []const ErrorMsg, |
| 45 | | cross_target: std.zig.CrossTarget, |
| 46 | | }; |
| 47 | | |
| 48 | 38 | pub const ZIRUpdateType = enum { |
| 49 | 39 | /// A transformation update transforms the input ZIR and tests against |
| 50 | 40 | /// the expected output |
| ... | ... | @@ -114,6 +104,9 @@ pub const TestContext = struct { |
| 114 | 104 | }) catch unreachable; |
| 115 | 105 | } |
| 116 | 106 | |
| 107 | /// TODO: document |
| 108 | /// |
| 109 | /// Errors must be specified in sequential order |
| 117 | 110 | pub fn addError(self: *ZIRCase, src: [:0]const u8, errors: []const []const u8) void { |
| 118 | 111 | var array = self.updates.allocator.alloc(ErrorMsg, errors.len) catch unreachable; |
| 119 | 112 | for (errors) |e, i| { |
| ... | ... | @@ -188,26 +181,24 @@ pub const TestContext = struct { |
| 188 | 181 | pub fn addZIRError( |
| 189 | 182 | ctx: *TestContext, |
| 190 | 183 | name: []const u8, |
| 191 | | cross_target: std.zig.CrossTarget, |
| 184 | target: std.zig.CrossTarget, |
| 192 | 185 | src: [:0]const u8, |
| 193 | 186 | expected_errors: []const []const u8, |
| 194 | | ) void {} |
| 187 | ) void { |
| 188 | var c = ctx.addZIRMulti(name, target); |
| 189 | c.addError(src, expected_errors); |
| 190 | } |
| 195 | 191 | |
| 196 | 192 | fn init(self: *TestContext) !void { |
| 197 | 193 | const allocator = std.heap.page_allocator; |
| 198 | 194 | self.* = .{ |
| 199 | 195 | .zir_cmp_output_cases = std.ArrayList(ZIRCompareOutputCase).init(allocator), |
| 200 | | .zir_error_cases = std.ArrayList(ZIRErrorCase).init(allocator), |
| 201 | 196 | .zir_cases = std.ArrayList(ZIRCase).init(allocator), |
| 202 | 197 | }; |
| 203 | 198 | } |
| 204 | 199 | |
| 205 | 200 | fn deinit(self: *TestContext) void { |
| 206 | 201 | self.zir_cmp_output_cases.deinit(); |
| 207 | | for (self.zir_error_cases.items) |e| { |
| 208 | | self.zir_error_cases.allocator.free(e.expected_errors); |
| 209 | | } |
| 210 | | self.zir_error_cases.deinit(); |
| 211 | 202 | for (self.zir_cases.items) |c| { |
| 212 | 203 | for (c.updates.items) |u| { |
| 213 | 204 | if (u.case == .Error) { |
| ... | ... | @@ -240,12 +231,6 @@ pub const TestContext = struct { |
| 240 | 231 | try self.runOneZIRCmpOutputCase(std.testing.allocator, root_node, case, native_info.target); |
| 241 | 232 | try std.testing.allocator_instance.validate(); |
| 242 | 233 | } |
| 243 | | for (self.zir_error_cases.items) |case| { |
| 244 | | std.testing.base_allocator_instance.reset(); |
| 245 | | const info = try std.zig.system.NativeTargetInfo.detect(std.testing.allocator, case.cross_target); |
| 246 | | try self.runOneZIRErrorCase(std.testing.allocator, root_node, case, info.target); |
| 247 | | try std.testing.allocator_instance.validate(); |
| 248 | | } |
| 249 | 234 | } |
| 250 | 235 | |
| 251 | 236 | fn runOneZIRCase(self: *TestContext, allocator: *Allocator, root_node: *std.Progress.Node, case: ZIRCase, target: std.Target) !void { |
| ... | ... | @@ -419,103 +404,4 @@ pub const TestContext = struct { |
| 419 | 404 | } |
| 420 | 405 | } |
| 421 | 406 | } |
| 422 | | |
| 423 | | fn runOneZIRErrorCase( |
| 424 | | self: *TestContext, |
| 425 | | allocator: *Allocator, |
| 426 | | root_node: *std.Progress.Node, |
| 427 | | case: ZIRErrorCase, |
| 428 | | target: std.Target, |
| 429 | | ) !void { |
| 430 | | var tmp = std.testing.tmpDir(.{}); |
| 431 | | defer tmp.cleanup(); |
| 432 | | |
| 433 | | var prg_node = root_node.start(case.name, 1); |
| 434 | | prg_node.activate(); |
| 435 | | defer prg_node.end(); |
| 436 | | |
| 437 | | const tmp_src_path = "test-case.zir"; |
| 438 | | try tmp.dir.writeFile(tmp_src_path, case.src); |
| 439 | | |
| 440 | | const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path); |
| 441 | | defer root_pkg.destroy(); |
| 442 | | |
| 443 | | var module = try Module.init(allocator, .{ |
| 444 | | .target = target, |
| 445 | | .output_mode = .Obj, |
| 446 | | .optimize_mode = .Debug, |
| 447 | | .bin_file_dir = tmp.dir, |
| 448 | | .bin_file_path = "test-case.o", |
| 449 | | .root_pkg = root_pkg, |
| 450 | | }); |
| 451 | | defer module.deinit(); |
| 452 | | |
| 453 | | var module_node = prg_node.start("parse/analysis/codegen", null); |
| 454 | | module_node.activate(); |
| 455 | | try module.update(); |
| 456 | | module_node.end(); |
| 457 | | var err: ?anyerror = null; |
| 458 | | |
| 459 | | var handled_errors = allocator.alloc(bool, case.expected_errors.len) catch unreachable; |
| 460 | | defer allocator.free(handled_errors); |
| 461 | | for (handled_errors) |*e| { |
| 462 | | e.* = false; |
| 463 | | } |
| 464 | | |
| 465 | | var all_errors = try module.getAllErrorsAlloc(); |
| 466 | | defer all_errors.deinit(allocator); |
| 467 | | for (all_errors.list) |e| { |
| 468 | | var handled = false; |
| 469 | | for (case.expected_errors) |ex, i| { |
| 470 | | if (e.line == ex.line and e.column == ex.column and std.mem.eql(u8, ex.msg, e.msg)) { |
| 471 | | if (handled_errors[i]) { |
| 472 | | err = error.ErrorReceivedMultipleTimes; |
| 473 | | std.debug.warn("Received error multiple times: {}\n", .{e.msg}); |
| 474 | | } else { |
| 475 | | handled_errors[i] = true; |
| 476 | | handled = true; |
| 477 | | } |
| 478 | | break; |
| 479 | | } |
| 480 | | } |
| 481 | | if (!handled) { |
| 482 | | err = error.ErrorNotExpected; |
| 483 | | std.debug.warn("Received an unexpected error: {}:{}: {}\n", .{ e.line, e.column, e.msg }); |
| 484 | | } |
| 485 | | } |
| 486 | | |
| 487 | | for (handled_errors) |e, i| { |
| 488 | | if (!e) { |
| 489 | | err = error.MissingExpectedError; |
| 490 | | const er = case.expected_errors[i]; |
| 491 | | std.debug.warn("Did not receive error: {}:{}: {}\n", .{ er.line, er.column, er.msg }); |
| 492 | | } |
| 493 | | } |
| 494 | | |
| 495 | | if (err) |e| { |
| 496 | | return e; |
| 497 | | } |
| 498 | | } |
| 499 | 407 | }; |
| 500 | | |
| 501 | | fn debugPrintErrors(src: []const u8, errors: var) void { |
| 502 | | std.debug.warn("\n", .{}); |
| 503 | | var nl = true; |
| 504 | | var line: usize = 1; |
| 505 | | for (src) |byte| { |
| 506 | | if (nl) { |
| 507 | | std.debug.warn("{: >3}| ", .{line}); |
| 508 | | nl = false; |
| 509 | | } |
| 510 | | if (byte == '\n') { |
| 511 | | nl = true; |
| 512 | | line += 1; |
| 513 | | } |
| 514 | | std.debug.warn("{c}", .{byte}); |
| 515 | | } |
| 516 | | std.debug.warn("\n", .{}); |
| 517 | | for (errors) |err_msg| { |
| 518 | | const loc = std.zig.findLineColumn(src, err_msg.byte_offset); |
| 519 | | std.debug.warn("{}:{}: error: {}\n", .{ loc.line + 1, loc.column + 1, err_msg.msg }); |
| 520 | | } |
| 521 | | } |