| ... | @@ -114,7 +114,37 @@ pub const TestContext = struct { | ... | @@ -114,7 +114,37 @@ pub const TestContext = struct { |
| 114 | }) catch unreachable; | 114 | }) catch unreachable; |
| 115 | } | 115 | } |
| 116 | | 116 | |
| 117 | pub fn addError(self: *ZIRCase, src: [:0]const u8, errors: []const []const u8) void {} | 117 | pub fn addError(self: *ZIRCase, src: [:0]const u8, errors: []const []const u8) void { |
| | 118 | var array = self.updates.allocator.alloc(ErrorMsg, errors.len) catch unreachable; |
| | 119 | for (errors) |e, i| { |
| | 120 | var cur = e[1..]; |
| | 121 | var line_index = std.mem.indexOf(u8, cur, ":"); |
| | 122 | if (line_index == null) { |
| | 123 | std.debug.panic("Invalid test: error must be specified as ':line:column: error: msg', found '{}'", .{e}); |
| | 124 | } |
| | 125 | const line = std.fmt.parseInt(u32, cur[0..line_index.?], 10) catch @panic("Unable to parse line number"); |
| | 126 | cur = cur[line_index.? + 1 ..]; |
| | 127 | const column_index = std.mem.indexOf(u8, cur, ":"); |
| | 128 | if (column_index == null) { |
| | 129 | std.debug.panic("Invalid test: error must be specified as ':line:column: error: msg', found '{}'", .{e}); |
| | 130 | } |
| | 131 | const column = std.fmt.parseInt(u32, cur[0..column_index.?], 10) catch @panic("Unable to parse column number"); |
| | 132 | cur = cur[column_index.? + 2 ..]; |
| | 133 | std.debug.assert(std.mem.eql(u8, cur[0..7], "error: ")); |
| | 134 | const msg = cur[7..]; |
| | 135 | |
| | 136 | if (line == 0 or column == 0) { |
| | 137 | @panic("Invalid test: error line and column must be specified starting at one!"); |
| | 138 | } |
| | 139 | |
| | 140 | array[i] = .{ |
| | 141 | .msg = msg, |
| | 142 | .line = line - 1, |
| | 143 | .column = column - 1, |
| | 144 | }; |
| | 145 | } |
| | 146 | self.updates.append(.{ .src = src, .case = .{ .Error = array } }) catch unreachable; |
| | 147 | } |
| 118 | }; | 148 | }; |
| 119 | | 149 | |
| 120 | pub fn addZIRMulti( | 150 | pub fn addZIRMulti( |
| ... | @@ -161,42 +191,7 @@ pub const TestContext = struct { | ... | @@ -161,42 +191,7 @@ pub const TestContext = struct { |
| 161 | cross_target: std.zig.CrossTarget, | 191 | cross_target: std.zig.CrossTarget, |
| 162 | src: [:0]const u8, | 192 | src: [:0]const u8, |
| 163 | expected_errors: []const []const u8, | 193 | expected_errors: []const []const u8, |
| 164 | ) void { | 194 | ) void {} |
| 165 | var array = std.ArrayList(ErrorMsg).init(ctx.zir_error_cases.allocator); | | |
| 166 | for (expected_errors) |e| { | | |
| 167 | var cur = e; | | |
| 168 | var line_index = std.mem.indexOf(u8, cur, ":"); | | |
| 169 | if (line_index == null) { | | |
| 170 | std.debug.panic("Invalid test: error must be specified as 'line:column: error: msg', found '{}'", .{e}); | | |
| 171 | } | | |
| 172 | const line = std.fmt.parseInt(u32, cur[0..line_index.?], 10) catch @panic("Unable to parse line number"); | | |
| 173 | cur = cur[line_index.? + 1 ..]; | | |
| 174 | const column_index = std.mem.indexOf(u8, cur, ":"); | | |
| 175 | if (column_index == null) { | | |
| 176 | std.debug.panic("Invalid test: error must be specified as 'line:column: error: msg', found '{}'", .{e}); | | |
| 177 | } | | |
| 178 | const column = std.fmt.parseInt(u32, cur[0..column_index.?], 10) catch @panic("Unable to parse column number"); | | |
| 179 | cur = cur[column_index.? + 2 ..]; | | |
| 180 | std.debug.assert(std.mem.eql(u8, cur[0..7], "error: ")); | | |
| 181 | const msg = cur[7..]; | | |
| 182 | | | |
| 183 | if (line == 0 or column == 0) { | | |
| 184 | @panic("Invalid test: error line and column must be specified starting at one!"); | | |
| 185 | } | | |
| 186 | | | |
| 187 | array.append(.{ | | |
| 188 | .msg = msg, | | |
| 189 | .line = line - 1, | | |
| 190 | .column = column - 1, | | |
| 191 | }) catch unreachable; | | |
| 192 | } | | |
| 193 | ctx.zir_error_cases.append(.{ | | |
| 194 | .name = name, | | |
| 195 | .src = src, | | |
| 196 | .expected_errors = array.toOwnedSlice(), | | |
| 197 | .cross_target = cross_target, | | |
| 198 | }) catch unreachable; | | |
| 199 | } | | |
| 200 | | 195 | |
| 201 | fn init(self: *TestContext) !void { | 196 | fn init(self: *TestContext) !void { |
| 202 | const allocator = std.heap.page_allocator; | 197 | const allocator = std.heap.page_allocator; |
| ... | @@ -214,6 +209,11 @@ pub const TestContext = struct { | ... | @@ -214,6 +209,11 @@ pub const TestContext = struct { |
| 214 | } | 209 | } |
| 215 | self.zir_error_cases.deinit(); | 210 | self.zir_error_cases.deinit(); |
| 216 | for (self.zir_cases.items) |c| { | 211 | for (self.zir_cases.items) |c| { |
| | 212 | for (c.updates.items) |u| { |
| | 213 | if (u.case == .Error) { |
| | 214 | c.updates.allocator.free(u.case.Error); |
| | 215 | } |
| | 216 | } |
| 217 | c.updates.deinit(); | 217 | c.updates.deinit(); |
| 218 | } | 218 | } |
| 219 | self.zir_cases.deinit(); | 219 | self.zir_cases.deinit(); |
| ... | @@ -268,11 +268,11 @@ pub const TestContext = struct { | ... | @@ -268,11 +268,11 @@ pub const TestContext = struct { |
| 268 | // TODO: support tests for object file building, and library builds | 268 | // TODO: support tests for object file building, and library builds |
| 269 | // and linking. This will require a rework to support multi-file | 269 | // and linking. This will require a rework to support multi-file |
| 270 | // tests. | 270 | // tests. |
| 271 | .output_mode = .Exe, | 271 | .output_mode = .Obj, |
| 272 | // TODO: support testing optimizations | 272 | // TODO: support testing optimizations |
| 273 | .optimize_mode = .Debug, | 273 | .optimize_mode = .Debug, |
| 274 | .bin_file_dir = tmp.dir, | 274 | .bin_file_dir = tmp.dir, |
| 275 | .bin_file_path = "test_case", | 275 | .bin_file_path = "test_case.o", |
| 276 | .root_pkg = root_pkg, | 276 | .root_pkg = root_pkg, |
| 277 | }); | 277 | }); |
| 278 | defer module.deinit(); | 278 | defer module.deinit(); |
| ... | @@ -312,6 +312,35 @@ pub const TestContext = struct { | ... | @@ -312,6 +312,35 @@ pub const TestContext = struct { |
| 312 | | 312 | |
| 313 | std.testing.expectEqualSlices(u8, expected_output, out_zir.items); | 313 | std.testing.expectEqualSlices(u8, expected_output, out_zir.items); |
| 314 | }, | 314 | }, |
| | 315 | .Error => |e| { |
| | 316 | var handled_errors = try allocator.alloc(bool, e.len); |
| | 317 | defer allocator.free(handled_errors); |
| | 318 | for (handled_errors) |*h| { |
| | 319 | h.* = false; |
| | 320 | } |
| | 321 | var all_errors = try module.getAllErrorsAlloc(); |
| | 322 | defer all_errors.deinit(allocator); |
| | 323 | for (all_errors.list) |a| { |
| | 324 | for (e) |ex, i| { |
| | 325 | if (a.line == ex.line and a.column == ex.column and std.mem.eql(u8, ex.msg, a.msg)) { |
| | 326 | handled_errors[i] = true; |
| | 327 | break; |
| | 328 | } |
| | 329 | } else { |
| | 330 | std.debug.warn("{}\nUnexpected error:\n================\n{}:{}: {}\n================\nTest failed.\n", .{ case.name, a.line + 1, a.column + 1, a.msg }); |
| | 331 | std.process.exit(1); |
| | 332 | } |
| | 333 | } |
| | 334 | |
| | 335 | for (handled_errors) |h, i| { |
| | 336 | if (!h) { |
| | 337 | const er = e[i]; |
| | 338 | std.debug.warn("{}\nDid not receive error:\n================\n{}:{}: {}\n================\nTest failed.\n", .{ case.name, er.line, er.column, er.msg }); |
| | 339 | std.process.exit(1); |
| | 340 | } |
| | 341 | } |
| | 342 | }, |
| | 343 | |
| 315 | else => return error.unimplemented, | 344 | else => return error.unimplemented, |
| 316 | } | 345 | } |
| 317 | } | 346 | } |
| ... | @@ -423,10 +452,7 @@ pub const TestContext = struct { | ... | @@ -423,10 +452,7 @@ pub const TestContext = struct { |
| 423 | | 452 | |
| 424 | var module_node = prg_node.start("parse/analysis/codegen", null); | 453 | var module_node = prg_node.start("parse/analysis/codegen", null); |
| 425 | module_node.activate(); | 454 | module_node.activate(); |
| 426 | const failed = f: { | 455 | try module.update(); |
| 427 | module.update() catch break :f true; | | |
| 428 | break :f false; | | |
| 429 | }; | | |
| 430 | module_node.end(); | 456 | module_node.end(); |
| 431 | var err: ?anyerror = null; | 457 | var err: ?anyerror = null; |
| 432 | | 458 | |