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 {
583583 path: []const u8,
584584 };
585585
586 pub const DepModule = struct {
587 name: []const u8,
588 path: []const u8,
589 };
590
586591 pub const Backend = enum {
587592 stage1,
588593 stage2,
......@@ -611,6 +616,7 @@ pub const TestContext = struct {
611616 link_libc: bool = false,
612617
613618 files: std.ArrayList(File),
619 deps: std.ArrayList(DepModule),
614620
615621 result: anyerror!void = {},
616622
......@@ -618,6 +624,13 @@ pub const TestContext = struct {
618624 case.files.append(.{ .path = name, .src = src }) catch @panic("out of memory");
619625 }
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
621634 /// Adds a subcase in which the module is updated with `src`, and a C
622635 /// header is generated.
623636 pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {
......@@ -767,6 +780,7 @@ pub const TestContext = struct {
767780 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
768781 .output_mode = .Exe,
769782 .files = std.ArrayList(File).init(ctx.arena),
783 .deps = std.ArrayList(DepModule).init(ctx.arena),
770784 }) catch @panic("out of memory");
771785 return &ctx.cases.items[ctx.cases.items.len - 1];
772786 }
......@@ -787,6 +801,7 @@ pub const TestContext = struct {
787801 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
788802 .output_mode = .Exe,
789803 .files = std.ArrayList(File).init(ctx.arena),
804 .deps = std.ArrayList(DepModule).init(ctx.arena),
790805 .link_libc = true,
791806 }) catch @panic("out of memory");
792807 return &ctx.cases.items[ctx.cases.items.len - 1];
......@@ -801,6 +816,7 @@ pub const TestContext = struct {
801816 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
802817 .output_mode = .Exe,
803818 .files = std.ArrayList(File).init(ctx.arena),
819 .deps = std.ArrayList(DepModule).init(ctx.arena),
804820 .backend = .llvm,
805821 .link_libc = true,
806822 }) catch @panic("out of memory");
......@@ -818,6 +834,7 @@ pub const TestContext = struct {
818834 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
819835 .output_mode = .Obj,
820836 .files = std.ArrayList(File).init(ctx.arena),
837 .deps = std.ArrayList(DepModule).init(ctx.arena),
821838 }) catch @panic("out of memory");
822839 return &ctx.cases.items[ctx.cases.items.len - 1];
823840 }
......@@ -834,6 +851,7 @@ pub const TestContext = struct {
834851 .output_mode = .Exe,
835852 .is_test = true,
836853 .files = std.ArrayList(File).init(ctx.arena),
854 .deps = std.ArrayList(DepModule).init(ctx.arena),
837855 }) catch @panic("out of memory");
838856 return &ctx.cases.items[ctx.cases.items.len - 1];
839857 }
......@@ -858,6 +876,7 @@ pub const TestContext = struct {
858876 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
859877 .output_mode = .Obj,
860878 .files = std.ArrayList(File).init(ctx.arena),
879 .deps = std.ArrayList(DepModule).init(ctx.arena),
861880 }) catch @panic("out of memory");
862881 return &ctx.cases.items[ctx.cases.items.len - 1];
863882 }
......@@ -1145,6 +1164,7 @@ pub const TestContext = struct {
11451164 .output_mode = output_mode,
11461165 .link_libc = backend == .llvm,
11471166 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
1167 .deps = std.ArrayList(DepModule).init(ctx.cases.allocator),
11481168 });
11491169 try cases.append(next);
11501170 }
......@@ -1498,7 +1518,24 @@ pub const TestContext = struct {
14981518 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
14991519 .root_src_path = tmp_src_path,
15001520 };
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
15031540 const bin_name = try std.zig.binNameAlloc(arena, .{
15041541 .root_name = "test_case",
test/compile_errors.zig+22
......@@ -288,4 +288,26 @@ pub fn addCases(ctx: *TestContext) !void {
288288 //, &[_][]const u8{
289289 // "tmp.zig:4:1: error: unable to inline function",
290290 //});
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 }
291313}
test/stage2/nvptx.zig+1
......@@ -97,6 +97,7 @@ pub fn addPtx(
9797 .updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator),
9898 .output_mode = .Obj,
9999 .files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
100 .deps = std.ArrayList(TestContext.DepModule).init(ctx.cases.allocator),
100101 .link_libc = false,
101102 .backend = .llvm,
102103 // Bug in Debug mode
test/standalone.zig+6
......@@ -107,4 +107,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
107107 cases.addBuildFile("test/standalone/emit_asm_and_bin/build.zig", .{});
108108 cases.addBuildFile("test/standalone/issue_12588/build.zig", .{});
109109 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", .{});
110116}
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}