Commit f94cbab3ac
Changed files (23)
src
src/test.zig
@@ -583,6 +583,11 @@ pub const TestContext = struct {
path: []const u8,
};
+ pub const DepModule = struct {
+ name: []const u8,
+ path: []const u8,
+ };
+
pub const Backend = enum {
stage1,
stage2,
@@ -611,6 +616,7 @@ pub const TestContext = struct {
link_libc: bool = false,
files: std.ArrayList(File),
+ deps: std.ArrayList(DepModule),
result: anyerror!void = {},
@@ -618,6 +624,13 @@ pub const TestContext = struct {
case.files.append(.{ .path = name, .src = src }) catch @panic("out of memory");
}
+ pub fn addDepModule(case: *Case, name: []const u8, path: []const u8) void {
+ case.deps.append(.{
+ .name = name,
+ .path = path,
+ }) catch @panic("out of memory");
+ }
+
/// Adds a subcase in which the module is updated with `src`, and a C
/// header is generated.
pub fn addHeader(self: *Case, src: [:0]const u8, result: [:0]const u8) void {
@@ -767,6 +780,7 @@ pub const TestContext = struct {
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Exe,
.files = std.ArrayList(File).init(ctx.arena),
+ .deps = std.ArrayList(DepModule).init(ctx.arena),
}) catch @panic("out of memory");
return &ctx.cases.items[ctx.cases.items.len - 1];
}
@@ -787,6 +801,7 @@ pub const TestContext = struct {
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Exe,
.files = std.ArrayList(File).init(ctx.arena),
+ .deps = std.ArrayList(DepModule).init(ctx.arena),
.link_libc = true,
}) catch @panic("out of memory");
return &ctx.cases.items[ctx.cases.items.len - 1];
@@ -801,6 +816,7 @@ pub const TestContext = struct {
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Exe,
.files = std.ArrayList(File).init(ctx.arena),
+ .deps = std.ArrayList(DepModule).init(ctx.arena),
.backend = .llvm,
.link_libc = true,
}) catch @panic("out of memory");
@@ -818,6 +834,7 @@ pub const TestContext = struct {
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Obj,
.files = std.ArrayList(File).init(ctx.arena),
+ .deps = std.ArrayList(DepModule).init(ctx.arena),
}) catch @panic("out of memory");
return &ctx.cases.items[ctx.cases.items.len - 1];
}
@@ -834,6 +851,7 @@ pub const TestContext = struct {
.output_mode = .Exe,
.is_test = true,
.files = std.ArrayList(File).init(ctx.arena),
+ .deps = std.ArrayList(DepModule).init(ctx.arena),
}) catch @panic("out of memory");
return &ctx.cases.items[ctx.cases.items.len - 1];
}
@@ -858,6 +876,7 @@ pub const TestContext = struct {
.updates = std.ArrayList(Update).init(ctx.cases.allocator),
.output_mode = .Obj,
.files = std.ArrayList(File).init(ctx.arena),
+ .deps = std.ArrayList(DepModule).init(ctx.arena),
}) catch @panic("out of memory");
return &ctx.cases.items[ctx.cases.items.len - 1];
}
@@ -1145,6 +1164,7 @@ pub const TestContext = struct {
.output_mode = output_mode,
.link_libc = backend == .llvm,
.files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
+ .deps = std.ArrayList(DepModule).init(ctx.cases.allocator),
});
try cases.append(next);
}
@@ -1498,7 +1518,24 @@ pub const TestContext = struct {
.root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
.root_src_path = tmp_src_path,
};
- defer main_pkg.table.deinit(allocator);
+ defer {
+ var it = main_pkg.table.iterator();
+ while (it.next()) |kv| {
+ allocator.free(kv.key_ptr.*);
+ kv.value_ptr.*.destroy(allocator);
+ }
+ main_pkg.table.deinit(allocator);
+ }
+
+ for (case.deps.items) |dep| {
+ var pkg = try Package.create(
+ allocator,
+ tmp_dir_path,
+ dep.path,
+ );
+ errdefer pkg.destroy(allocator);
+ try main_pkg.add(allocator, dep.name, pkg);
+ }
const bin_name = try std.zig.binNameAlloc(arena, .{
.root_name = "test_case",
test/stage2/nvptx.zig
@@ -97,6 +97,7 @@ pub fn addPtx(
.updates = std.ArrayList(TestContext.Update).init(ctx.cases.allocator),
.output_mode = .Obj,
.files = std.ArrayList(TestContext.File).init(ctx.cases.allocator),
+ .deps = std.ArrayList(TestContext.DepModule).init(ctx.cases.allocator),
.link_libc = false,
.backend = .llvm,
// Bug in Debug mode
test/standalone/dep_diamond/bar.zig
@@ -0,0 +1,1 @@
+pub const shared = @import("shared");
test/standalone/dep_diamond/build.zig
@@ -0,0 +1,28 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const optimize = b.standardOptimizeOption(.{});
+
+ const shared = b.createModule(.{
+ .source_file = .{ .path = "shared.zig" },
+ });
+
+ const exe = b.addExecutable(.{
+ .name = "test",
+ .root_source_file = .{ .path = "test.zig" },
+ .optimize = optimize,
+ });
+ exe.addAnonymousModule("foo", .{
+ .source_file = .{ .path = "foo.zig" },
+ .dependencies = &.{.{ .name = "shared", .module = shared }},
+ });
+ exe.addAnonymousModule("bar", .{
+ .source_file = .{ .path = "bar.zig" },
+ .dependencies = &.{.{ .name = "shared", .module = shared }},
+ });
+
+ const run = exe.run();
+
+ const test_step = b.step("test", "Test it");
+ test_step.dependOn(&run.step);
+}
test/standalone/dep_diamond/foo.zig
@@ -0,0 +1,1 @@
+pub const shared = @import("shared");
test/standalone/dep_diamond/test.zig
@@ -0,0 +1,7 @@
+const foo = @import("foo");
+const bar = @import("bar");
+const assert = @import("std").debug.assert;
+
+pub fn main() void {
+ assert(foo.shared == bar.shared);
+}
test/standalone/dep_mutually_recursive/bar.zig
@@ -0,0 +1,6 @@
+const assert = @import("std").debug.assert;
+pub const foo = @import("foo");
+
+comptime {
+ assert(foo.bar == @This());
+}
test/standalone/dep_mutually_recursive/build.zig
@@ -0,0 +1,26 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const optimize = b.standardOptimizeOption(.{});
+
+ const foo = b.createModule(.{
+ .source_file = .{ .path = "foo.zig" },
+ });
+ const bar = b.createModule(.{
+ .source_file = .{ .path = "bar.zig" },
+ });
+ foo.dependencies.put("bar", bar) catch @panic("OOM");
+ bar.dependencies.put("foo", foo) catch @panic("OOM");
+
+ const exe = b.addExecutable(.{
+ .name = "test",
+ .root_source_file = .{ .path = "test.zig" },
+ .optimize = optimize,
+ });
+ exe.addModule("foo", foo);
+
+ const run = exe.run();
+
+ const test_step = b.step("test", "Test it");
+ test_step.dependOn(&run.step);
+}
test/standalone/dep_mutually_recursive/foo.zig
@@ -0,0 +1,6 @@
+const assert = @import("std").debug.assert;
+pub const bar = @import("bar");
+
+comptime {
+ assert(bar.foo == @This());
+}
test/standalone/dep_mutually_recursive/test.zig
@@ -0,0 +1,7 @@
+const foo = @import("foo");
+const assert = @import("std").debug.assert;
+
+pub fn main() void {
+ assert(foo == foo.bar.foo);
+ assert(foo == foo.bar.foo.bar.foo);
+}
test/standalone/dep_recursive/build.zig
@@ -0,0 +1,22 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const optimize = b.standardOptimizeOption(.{});
+
+ const foo = b.createModule(.{
+ .source_file = .{ .path = "foo.zig" },
+ });
+ foo.dependencies.put("foo", foo) catch @panic("OOM");
+
+ const exe = b.addExecutable(.{
+ .name = "test",
+ .root_source_file = .{ .path = "test.zig" },
+ .optimize = optimize,
+ });
+ exe.addModule("foo", foo);
+
+ const run = exe.run();
+
+ const test_step = b.step("test", "Test it");
+ test_step.dependOn(&run.step);
+}
test/standalone/dep_recursive/foo.zig
@@ -0,0 +1,6 @@
+const assert = @import("std").debug.assert;
+pub const foo = @import("foo");
+
+comptime {
+ assert(foo == @This());
+}
test/standalone/dep_recursive/test.zig
@@ -0,0 +1,8 @@
+const foo = @import("foo");
+const shared = @import("shared");
+const assert = @import("std").debug.assert;
+
+pub fn main() void {
+ assert(foo == foo.foo);
+ assert(foo == foo.foo.foo);
+}
test/standalone/dep_triangle/build.zig
@@ -0,0 +1,25 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const optimize = b.standardOptimizeOption(.{});
+
+ const shared = b.createModule(.{
+ .source_file = .{ .path = "shared.zig" },
+ });
+
+ const exe = b.addExecutable(.{
+ .name = "test",
+ .root_source_file = .{ .path = "test.zig" },
+ .optimize = optimize,
+ });
+ exe.addAnonymousModule("foo", .{
+ .source_file = .{ .path = "foo.zig" },
+ .dependencies = &.{.{ .name = "shared", .module = shared }},
+ });
+ exe.addModule("shared", shared);
+
+ const run = exe.run();
+
+ const test_step = b.step("test", "Test it");
+ test_step.dependOn(&run.step);
+}
test/standalone/dep_triangle/foo.zig
@@ -0,0 +1,1 @@
+pub const shared = @import("shared");
test/standalone/dep_triangle/test.zig
@@ -0,0 +1,7 @@
+const foo = @import("foo");
+const shared = @import("shared");
+const assert = @import("std").debug.assert;
+
+pub fn main() void {
+ assert(foo.shared == shared);
+}
test/compile_errors.zig
@@ -288,4 +288,26 @@ pub fn addCases(ctx: *TestContext) !void {
//, &[_][]const u8{
// "tmp.zig:4:1: error: unable to inline function",
//});
+
+ {
+ const case = ctx.obj("file in multiple modules", .{});
+ case.backend = .stage2;
+
+ case.addSourceFile("foo.zig",
+ \\const dummy = 0;
+ );
+
+ case.addDepModule("foo", "foo.zig");
+
+ case.addError(
+ \\comptime {
+ \\ _ = @import("foo");
+ \\ _ = @import("foo.zig");
+ \\}
+ , &[_][]const u8{
+ ":1:1: error: file exists in multiple modules",
+ ":1:1: note: root of module root.foo",
+ ":3:17: note: imported from module root",
+ });
+ }
}
test/standalone.zig
@@ -107,4 +107,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
cases.addBuildFile("test/standalone/emit_asm_and_bin/build.zig", .{});
cases.addBuildFile("test/standalone/issue_12588/build.zig", .{});
cases.addBuildFile("test/standalone/embed_generated_file/build.zig", .{});
+
+ cases.addBuildFile("test/standalone/dep_diamond/build.zig", .{});
+ cases.addBuildFile("test/standalone/dep_triangle/build.zig", .{});
+ cases.addBuildFile("test/standalone/dep_recursive/build.zig", .{});
+ cases.addBuildFile("test/standalone/dep_mutually_recursive/build.zig", .{});
+ cases.addBuildFile("test/standalone/dep_shared_builtin/build.zig", .{});
}