authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-02-18 06:28:47+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-02-21 02:05:36+00:00
logf94cbab3acc3b31464f45872c1f700874eecb23e
treed56da0b14670acdc562ea2574d170731cd9e1cf8
parentb8a96baab887e4dcd54d49fb1bbc8294af47392e
signaturelock-open Commit is signed but in an unrecognized format.

Add test coverage for some module structures


23 files changed, 253 insertions(+), 1 deletions(-)

src/test.zig+38-1
...@@ -583,6 +583,11 @@ pub const TestContext = struct {...@@ -583,6 +583,11 @@ pub const TestContext = struct {
583 path: []const u8,583 path: []const u8,
584 };584 };
585585
586 pub const DepModule = struct {
587 name: []const u8,
588 path: []const u8,
589 };
590
586 pub const Backend = enum {591 pub const Backend = enum {
587 stage1,592 stage1,
588 stage2,593 stage2,
...@@ -611,6 +616,7 @@ pub const TestContext = struct {...@@ -611,6 +616,7 @@ pub const TestContext = struct {
611 link_libc: bool = false,616 link_libc: bool = false,
612617
613 files: std.ArrayList(File),618 files: std.ArrayList(File),
619 deps: std.ArrayList(DepModule),
614620
615 result: anyerror!void = {},621 result: anyerror!void = {},
616622
...@@ -618,6 +624,13 @@ pub const TestContext = struct {...@@ -618,6 +624,13 @@ pub const TestContext = struct {
618 case.files.append(.{ .path = name, .src = src }) catch @panic("out of memory");624 case.files.append(.{ .path = name, .src = src }) catch @panic("out of memory");
619 }625 }
620626
627 pub fn addDepModule(case: *Case, name: []const u8, path: []const u8) void {
628 case.deps.append(.{
629 .name = name,
630 .path = path,
631 }) catch @panic("out of memory");
632 }
633
621 /// Adds a subcase in which the module is updated with `src`, and a C634 /// Adds a subcase in which the module is updated with `src`, and a C
622 /// header is generated.635 /// header is generated.
623 pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {636 pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {
...@@ -767,6 +780,7 @@ pub const TestContext = struct {...@@ -767,6 +780,7 @@ pub const TestContext = struct {
767 .updates = std.ArrayList(Update).init(ctx.cases.allocator),780 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
768 .output_mode = .Exe,781 .output_mode = .Exe,
769 .files = std.ArrayList(File).init(ctx.arena),782 .files = std.ArrayList(File).init(ctx.arena),
783 .deps = std.ArrayList(DepModule).init(ctx.arena),
770 }) catch @panic("out of memory");784 }) catch @panic("out of memory");
771 return &ctx.cases.items[ctx.cases.items.len - 1];785 return &ctx.cases.items[ctx.cases.items.len - 1];
772 }786 }
...@@ -787,6 +801,7 @@ pub const TestContext = struct {...@@ -787,6 +801,7 @@ pub const TestContext = struct {
787 .updates = std.ArrayList(Update).init(ctx.cases.allocator),801 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
788 .output_mode = .Exe,802 .output_mode = .Exe,
789 .files = std.ArrayList(File).init(ctx.arena),803 .files = std.ArrayList(File).init(ctx.arena),
804 .deps = std.ArrayList(DepModule).init(ctx.arena),
790 .link_libc = true,805 .link_libc = true,
791 }) catch @panic("out of memory");806 }) catch @panic("out of memory");
792 return &ctx.cases.items[ctx.cases.items.len - 1];807 return &ctx.cases.items[ctx.cases.items.len - 1];
...@@ -801,6 +816,7 @@ pub const TestContext = struct {...@@ -801,6 +816,7 @@ pub const TestContext = struct {
801 .updates = std.ArrayList(Update).init(ctx.cases.allocator),816 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
802 .output_mode = .Exe,817 .output_mode = .Exe,
803 .files = std.ArrayList(File).init(ctx.arena),818 .files = std.ArrayList(File).init(ctx.arena),
819 .deps = std.ArrayList(DepModule).init(ctx.arena),
804 .backend = .llvm,820 .backend = .llvm,
805 .link_libc = true,821 .link_libc = true,
806 }) catch @panic("out of memory");822 }) catch @panic("out of memory");
...@@ -818,6 +834,7 @@ pub const TestContext = struct {...@@ -818,6 +834,7 @@ pub const TestContext = struct {
818 .updates = std.ArrayList(Update).init(ctx.cases.allocator),834 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
819 .output_mode = .Obj,835 .output_mode = .Obj,
820 .files = std.ArrayList(File).init(ctx.arena),836 .files = std.ArrayList(File).init(ctx.arena),
837 .deps = std.ArrayList(DepModule).init(ctx.arena),
821 }) catch @panic("out of memory");838 }) catch @panic("out of memory");
822 return &ctx.cases.items[ctx.cases.items.len - 1];839 return &ctx.cases.items[ctx.cases.items.len - 1];
823 }840 }
...@@ -834,6 +851,7 @@ pub const TestContext = struct {...@@ -834,6 +851,7 @@ pub const TestContext = struct {
834 .output_mode = .Exe,851 .output_mode = .Exe,
835 .is_test = true,852 .is_test = true,
836 .files = std.ArrayList(File).init(ctx.arena),853 .files = std.ArrayList(File).init(ctx.arena),
854 .deps = std.ArrayList(DepModule).init(ctx.arena),
837 }) catch @panic("out of memory");855 }) catch @panic("out of memory");
838 return &ctx.cases.items[ctx.cases.items.len - 1];856 return &ctx.cases.items[ctx.cases.items.len - 1];
839 }857 }
...@@ -858,6 +876,7 @@ pub const TestContext = struct {...@@ -858,6 +876,7 @@ pub const TestContext = struct {
858 .updates = std.ArrayList(Update).init(ctx.cases.allocator),876 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
859 .output_mode = .Obj,877 .output_mode = .Obj,
860 .files = std.ArrayList(File).init(ctx.arena),878 .files = std.ArrayList(File).init(ctx.arena),
879 .deps = std.ArrayList(DepModule).init(ctx.arena),
861 }) catch @panic("out of memory");880 }) catch @panic("out of memory");
862 return &ctx.cases.items[ctx.cases.items.len - 1];881 return &ctx.cases.items[ctx.cases.items.len - 1];
863 }882 }
...@@ -1145,6 +1164,7 @@ pub const TestContext = struct {...@@ -1145,6 +1164,7 @@ pub const TestContext = struct {
1145 .output_mode = output_mode,1164 .output_mode = output_mode,
1146 .link_libc = backend == .llvm,1165 .link_libc = backend == .llvm,
1147 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),1166 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
1167 .deps = std.ArrayList(DepModule).init(ctx.cases.allocator),
1148 });1168 });
1149 try cases.append(next);1169 try cases.append(next);
1150 }1170 }
...@@ -1498,7 +1518,24 @@ pub const TestContext = struct {...@@ -1498,7 +1518,24 @@ pub const TestContext = struct {
1498 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },1518 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
1499 .root_src_path = tmp_src_path,1519 .root_src_path = tmp_src_path,
1500 };1520 };
1501 defer main_pkg.table.deinit(allocator);1521 defer {
1522 var it = main_pkg.table.iterator();
1523 while (it.next()) |kv| {
1524 allocator.free(kv.key_ptr.*);
1525 kv.value_ptr.*.destroy(allocator);
1526 }
1527 main_pkg.table.deinit(allocator);
1528 }
1529
1530 for (case.deps.items) |dep| {
1531 var pkg = try Package.create(
1532 allocator,
1533 tmp_dir_path,
1534 dep.path,
1535 );
1536 errdefer pkg.destroy(allocator);
1537 try main_pkg.add(allocator, dep.name, pkg);
1538 }
15021539
1503 const bin_name = try std.zig.binNameAlloc(arena, .{1540 const bin_name = try std.zig.binNameAlloc(arena, .{
1504 .root_name = "test_case",1541 .root_name = "test_case",
test/compile_errors.zig+22
...@@ -288,4 +288,26 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -288,4 +288,26 @@ pub fn addCases(ctx: *TestContext) !void {
288 //, &[_][]const u8{288 //, &[_][]const u8{
289 // "tmp.zig:4:1: error: unable to inline function",289 // "tmp.zig:4:1: error: unable to inline function",
290 //});290 //});
291
292 {
293 const case = ctx.obj("file in multiple modules", .{});
294 case.backend = .stage2;
295
296 case.addSourceFile("foo.zig",
297 \\const dummy = 0;
298 );
299
300 case.addDepModule("foo", "foo.zig");
301
302 case.addError(
303 \\comptime {
304 \\ _ = @import("foo");
305 \\ _ = @import("foo.zig");
306 \\}
307 , &[_][]const u8{
308 ":1:1: error: file exists in multiple modules",
309 ":1:1: note: root of module root.foo",
310 ":3:17: note: imported from module root",
311 });
312 }
291}313}
test/stage2/nvptx.zig+1
...@@ -97,6 +97,7 @@ pub fn addPtx(...@@ -97,6 +97,7 @@ pub fn addPtx(
97 .updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator),97 .updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator),
98 .output_mode = .Obj,98 .output_mode = .Obj,
99 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),99 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
100 .deps = std.ArrayList(TestContext.DepModule).init(ctx.cases.allocator),
100 .link_libc = false,101 .link_libc = false,
101 .backend = .llvm,102 .backend = .llvm,
102 // Bug in Debug mode103 // Bug in Debug mode
test/standalone.zig+6
...@@ -107,4 +107,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void {...@@ -107,4 +107,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
107 cases.addBuildFile("test/standalone/emit_asm_and_bin/build.zig", .{});107 cases.addBuildFile("test/standalone/emit_asm_and_bin/build.zig", .{});
108 cases.addBuildFile("test/standalone/issue_12588/build.zig", .{});108 cases.addBuildFile("test/standalone/issue_12588/build.zig", .{});
109 cases.addBuildFile("test/standalone/embed_generated_file/build.zig", .{});109 cases.addBuildFile("test/standalone/embed_generated_file/build.zig", .{});
110
111 cases.addBuildFile("test/standalone/dep_diamond/build.zig", .{});
112 cases.addBuildFile("test/standalone/dep_triangle/build.zig", .{});
113 cases.addBuildFile("test/standalone/dep_recursive/build.zig", .{});
114 cases.addBuildFile("test/standalone/dep_mutually_recursive/build.zig", .{});
115 cases.addBuildFile("test/standalone/dep_shared_builtin/build.zig", .{});
110}116}
test/standalone/dep_diamond/bar.zig created+1
...@@ -0,0 +1 @@
1pub const shared = @import("shared");
test/standalone/dep_diamond/build.zig created+28
...@@ -0,0 +1,28 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5
6 const shared = b.createModule(.{
7 .source_file = .{ .path = "shared.zig" },
8 });
9
10 const exe = b.addExecutable(.{
11 .name = "test",
12 .root_source_file = .{ .path = "test.zig" },
13 .optimize = optimize,
14 });
15 exe.addAnonymousModule("foo", .{
16 .source_file = .{ .path = "foo.zig" },
17 .dependencies = &.{.{ .name = "shared", .module = shared }},
18 });
19 exe.addAnonymousModule("bar", .{
20 .source_file = .{ .path = "bar.zig" },
21 .dependencies = &.{.{ .name = "shared", .module = shared }},
22 });
23
24 const run = exe.run();
25
26 const test_step = b.step("test", "Test it");
27 test_step.dependOn(&run.step);
28}
test/standalone/dep_diamond/foo.zig created+1
...@@ -0,0 +1 @@
1pub const shared = @import("shared");
test/standalone/dep_diamond/shared.zig created+1
...@@ -0,0 +1 @@
1// (empty)
test/standalone/dep_diamond/test.zig created+7
...@@ -0,0 +1,7 @@
1const foo = @import("foo");
2const bar = @import("bar");
3const assert = @import("std").debug.assert;
4
5pub fn main() void {
6 assert(foo.shared == bar.shared);
7}
test/standalone/dep_mutually_recursive/bar.zig created+6
...@@ -0,0 +1,6 @@
1const assert = @import("std").debug.assert;
2pub const foo = @import("foo");
3
4comptime {
5 assert(foo.bar == @This());
6}
test/standalone/dep_mutually_recursive/build.zig created+26
...@@ -0,0 +1,26 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5
6 const foo = b.createModule(.{
7 .source_file = .{ .path = "foo.zig" },
8 });
9 const bar = b.createModule(.{
10 .source_file = .{ .path = "bar.zig" },
11 });
12 foo.dependencies.put("bar", bar) catch @panic("OOM");
13 bar.dependencies.put("foo", foo) catch @panic("OOM");
14
15 const exe = b.addExecutable(.{
16 .name = "test",
17 .root_source_file = .{ .path = "test.zig" },
18 .optimize = optimize,
19 });
20 exe.addModule("foo", foo);
21
22 const run = exe.run();
23
24 const test_step = b.step("test", "Test it");
25 test_step.dependOn(&run.step);
26}
test/standalone/dep_mutually_recursive/foo.zig created+6
...@@ -0,0 +1,6 @@
1const assert = @import("std").debug.assert;
2pub const bar = @import("bar");
3
4comptime {
5 assert(bar.foo == @This());
6}
test/standalone/dep_mutually_recursive/test.zig created+7
...@@ -0,0 +1,7 @@
1const foo = @import("foo");
2const assert = @import("std").debug.assert;
3
4pub fn main() void {
5 assert(foo == foo.bar.foo);
6 assert(foo == foo.bar.foo.bar.foo);
7}
test/standalone/dep_recursive/build.zig created+22
...@@ -0,0 +1,22 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5
6 const foo = b.createModule(.{
7 .source_file = .{ .path = "foo.zig" },
8 });
9 foo.dependencies.put("foo", foo) catch @panic("OOM");
10
11 const exe = b.addExecutable(.{
12 .name = "test",
13 .root_source_file = .{ .path = "test.zig" },
14 .optimize = optimize,
15 });
16 exe.addModule("foo", foo);
17
18 const run = exe.run();
19
20 const test_step = b.step("test", "Test it");
21 test_step.dependOn(&run.step);
22}
test/standalone/dep_recursive/foo.zig created+6
...@@ -0,0 +1,6 @@
1const assert = @import("std").debug.assert;
2pub const foo = @import("foo");
3
4comptime {
5 assert(foo == @This());
6}
test/standalone/dep_recursive/test.zig created+8
...@@ -0,0 +1,8 @@
1const foo = @import("foo");
2const shared = @import("shared");
3const assert = @import("std").debug.assert;
4
5pub fn main() void {
6 assert(foo == foo.foo);
7 assert(foo == foo.foo.foo);
8}
test/standalone/dep_shared_builtin/build.zig created+19
...@@ -0,0 +1,19 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5
6 const exe = b.addExecutable(.{
7 .name = "test",
8 .root_source_file = .{ .path = "test.zig" },
9 .optimize = optimize,
10 });
11 exe.addAnonymousModule("foo", .{
12 .source_file = .{ .path = "foo.zig" },
13 });
14
15 const run = exe.run();
16
17 const test_step = b.step("test", "Test it");
18 test_step.dependOn(&run.step);
19}
test/standalone/dep_shared_builtin/foo.zig created+3
...@@ -0,0 +1,3 @@
1pub const std = @import("std");
2pub const builtin = @import("builtin");
3pub const root = @import("root");
test/standalone/dep_shared_builtin/test.zig created+11
...@@ -0,0 +1,11 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const root = @import("root");
4const foo = @import("foo");
5
6pub fn main() void {
7 std.debug.assert(root == @This());
8 std.debug.assert(std == foo.std);
9 std.debug.assert(builtin == foo.builtin);
10 std.debug.assert(root == foo.root);
11}
test/standalone/dep_triangle/build.zig created+25
...@@ -0,0 +1,25 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});
5
6 const shared = b.createModule(.{
7 .source_file = .{ .path = "shared.zig" },
8 });
9
10 const exe = b.addExecutable(.{
11 .name = "test",
12 .root_source_file = .{ .path = "test.zig" },
13 .optimize = optimize,
14 });
15 exe.addAnonymousModule("foo", .{
16 .source_file = .{ .path = "foo.zig" },
17 .dependencies = &.{.{ .name = "shared", .module = shared }},
18 });
19 exe.addModule("shared", shared);
20
21 const run = exe.run();
22
23 const test_step = b.step("test", "Test it");
24 test_step.dependOn(&run.step);
25}
test/standalone/dep_triangle/foo.zig created+1
...@@ -0,0 +1 @@
1pub const shared = @import("shared");
test/standalone/dep_triangle/shared.zig created+1
...@@ -0,0 +1 @@
1// (empty)
test/standalone/dep_triangle/test.zig created+7
...@@ -0,0 +1,7 @@
1const foo = @import("foo");
2const shared = @import("shared");
3const assert = @import("std").debug.assert;
4
5pub fn main() void {
6 assert(foo.shared == shared);
7}