| ... | @@ -96,6 +96,10 @@ pub const TestContext = struct { | ... | @@ -96,6 +96,10 @@ pub const TestContext = struct { |
| 96 | /// stdout against the expected results | 96 | /// stdout against the expected results |
| 97 | /// This is a slice containing the expected message. | 97 | /// This is a slice containing the expected message. |
| 98 | Execution: []const u8, | 98 | Execution: []const u8, |
| | 99 | /// A header update compiles the input with the equivalent of |
| | 100 | /// `-Demit_h=true` and tests the produced header against the |
| | 101 | /// expected result |
| | 102 | Header: []const u8, |
| 99 | }, | 103 | }, |
| 100 | }; | 104 | }; |
| 101 | | 105 | |
| ... | @@ -138,6 +142,15 @@ pub const TestContext = struct { | ... | @@ -138,6 +142,15 @@ pub const TestContext = struct { |
| 138 | }) catch unreachable; | 142 | }) catch unreachable; |
| 139 | } | 143 | } |
| 140 | | 144 | |
| | 145 | /// Adds a subcase in which the module is updated with `src`, and a C |
| | 146 | /// header is generated. |
| | 147 | pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void { |
| | 148 | self.updates.append(.{ |
| | 149 | .src = src, |
| | 150 | .case = .{ .Header = result }, |
| | 151 | }) catch unreachable; |
| | 152 | } |
| | 153 | |
| 141 | /// Adds a subcase in which the module is updated with `src`, compiled, | 154 | /// Adds a subcase in which the module is updated with `src`, compiled, |
| 142 | /// run, and the output is tested against `result`. | 155 | /// run, and the output is tested against `result`. |
| 143 | pub fn addCompareOutput(self: *Case, src: [:0]const u8, result: []const u8) void { | 156 | pub fn addCompareOutput(self: *Case, src: [:0]const u8, result: []const u8) void { |
| ... | @@ -269,6 +282,10 @@ pub const TestContext = struct { | ... | @@ -269,6 +282,10 @@ pub const TestContext = struct { |
| 269 | ctx.addC(name, target, .Zig).addTransform(src, cheader ++ out); | 282 | ctx.addC(name, target, .Zig).addTransform(src, cheader ++ out); |
| 270 | } | 283 | } |
| 271 | | 284 | |
| | 285 | pub fn h(ctx: *TestContext, name: []const u8, target: std.zig.CrossTarget, src: [:0]const u8, comptime out: [:0]const u8) void { |
| | 286 | ctx.addC(name, target, .Zig).addHeader(src, cheader ++ out); |
| | 287 | } |
| | 288 | |
| 272 | pub fn addCompareOutput( | 289 | pub fn addCompareOutput( |
| 273 | ctx: *TestContext, | 290 | ctx: *TestContext, |
| 274 | name: []const u8, | 291 | name: []const u8, |
| ... | @@ -547,6 +564,10 @@ pub const TestContext = struct { | ... | @@ -547,6 +564,10 @@ pub const TestContext = struct { |
| 547 | .directory = emit_directory, | 564 | .directory = emit_directory, |
| 548 | .basename = bin_name, | 565 | .basename = bin_name, |
| 549 | }; | 566 | }; |
| | 567 | const emit_h: Compilation.EmitLoc = .{ |
| | 568 | .directory = emit_directory, |
| | 569 | .basename = "test_case.h", |
| | 570 | }; |
| 550 | const comp = try Compilation.create(allocator, .{ | 571 | const comp = try Compilation.create(allocator, .{ |
| 551 | .local_cache_directory = zig_cache_directory, | 572 | .local_cache_directory = zig_cache_directory, |
| 552 | .global_cache_directory = zig_cache_directory, | 573 | .global_cache_directory = zig_cache_directory, |
| ... | @@ -561,6 +582,7 @@ pub const TestContext = struct { | ... | @@ -561,6 +582,7 @@ pub const TestContext = struct { |
| 561 | // TODO: support testing optimizations | 582 | // TODO: support testing optimizations |
| 562 | .optimize_mode = .Debug, | 583 | .optimize_mode = .Debug, |
| 563 | .emit_bin = emit_bin, | 584 | .emit_bin = emit_bin, |
| | 585 | .emit_h = emit_h, |
| 564 | .root_pkg = &root_pkg, | 586 | .root_pkg = &root_pkg, |
| 565 | .keep_source_files_loaded = true, | 587 | .keep_source_files_loaded = true, |
| 566 | .object_format = ofmt, | 588 | .object_format = ofmt, |
| ... | @@ -616,6 +638,22 @@ pub const TestContext = struct { | ... | @@ -616,6 +638,22 @@ pub const TestContext = struct { |
| 616 | } | 638 | } |
| 617 | | 639 | |
| 618 | switch (update.case) { | 640 | switch (update.case) { |
| | 641 | .Header => |expected_output| { |
| | 642 | var file = try tmp.dir.openFile("test_case.h", .{ .read = true }); |
| | 643 | defer file.close(); |
| | 644 | var out = file.reader().readAllAlloc(arena, 1024 * 1024) catch @panic("Unable to read headeroutput!"); |
| | 645 | |
| | 646 | if (expected_output.len != out.len) { |
| | 647 | std.debug.print("\nTransformed header length differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); |
| | 648 | std.process.exit(1); |
| | 649 | } |
| | 650 | for (expected_output) |e, i| { |
| | 651 | if (out[i] != e) { |
| | 652 | std.debug.print("\nTransformed header differs:\n================\nExpected:\n================\n{}\n================\nFound:\n================\n{}\n================\nTest failed.\n", .{ expected_output, out }); |
| | 653 | std.process.exit(1); |
| | 654 | } |
| | 655 | } |
| | 656 | }, |
| 619 | .Transformation => |expected_output| { | 657 | .Transformation => |expected_output| { |
| 620 | if (case.cbe) { | 658 | if (case.cbe) { |
| 621 | // The C file is always closed after an update, because we don't support | 659 | // The C file is always closed after an update, because we don't support |
| ... | @@ -670,8 +708,8 @@ pub const TestContext = struct { | ... | @@ -670,8 +708,8 @@ pub const TestContext = struct { |
| 670 | test_node.activate(); | 708 | test_node.activate(); |
| 671 | defer test_node.end(); | 709 | defer test_node.end(); |
| 672 | var handled_errors = try arena.alloc(bool, e.len); | 710 | var handled_errors = try arena.alloc(bool, e.len); |
| 673 | for (handled_errors) |*h| { | 711 | for (handled_errors) |*handled| { |
| 674 | h.* = false; | 712 | handled.* = false; |
| 675 | } | 713 | } |
| 676 | var all_errors = try comp.getAllErrorsAlloc(); | 714 | var all_errors = try comp.getAllErrorsAlloc(); |
| 677 | defer all_errors.deinit(allocator); | 715 | defer all_errors.deinit(allocator); |
| ... | @@ -709,8 +747,8 @@ pub const TestContext = struct { | ... | @@ -709,8 +747,8 @@ pub const TestContext = struct { |
| 709 | } | 747 | } |
| 710 | } | 748 | } |
| 711 | | 749 | |
| 712 | for (handled_errors) |h, i| { | 750 | for (handled_errors) |handled, i| { |
| 713 | if (!h) { | 751 | if (!handled) { |
| 714 | const er = e[i]; | 752 | const er = e[i]; |
| 715 | std.debug.print( | 753 | std.debug.print( |
| 716 | "{s}\nDid not receive error:\n================\n{}\n================\nTest failed.\n", | 754 | "{s}\nDid not receive error:\n================\n{}\n================\nTest failed.\n", |