Add test coverage for some module structures

This commit is contained in:
mlugg 2023-02-18 06:28:47 +00:00
parent b8a96baab8
commit f94cbab3ac
No known key found for this signature in database
GPG key ID: 58978E823BDE3EF9
23 changed files with 253 additions and 1 deletions

View file

@ -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",

View file

@ -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",
});
}
}

View file

@ -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

View file

@ -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", .{});
}

View file

@ -0,0 +1 @@
pub const shared = @import("shared");

View file

@ -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);
}

View file

@ -0,0 +1 @@
pub const shared = @import("shared");

View file

@ -0,0 +1 @@
// (empty)

View file

@ -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);
}

View file

@ -0,0 +1,6 @@
const assert = @import("std").debug.assert;
pub const foo = @import("foo");
comptime {
assert(foo.bar == @This());
}

View file

@ -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);
}

View file

@ -0,0 +1,6 @@
const assert = @import("std").debug.assert;
pub const bar = @import("bar");
comptime {
assert(bar.foo == @This());
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -0,0 +1,6 @@
const assert = @import("std").debug.assert;
pub const foo = @import("foo");
comptime {
assert(foo == @This());
}

View file

@ -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);
}

View file

@ -0,0 +1,19 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "test",
.root_source_file = .{ .path = "test.zig" },
.optimize = optimize,
});
exe.addAnonymousModule("foo", .{
.source_file = .{ .path = "foo.zig" },
});
const run = exe.run();
const test_step = b.step("test", "Test it");
test_step.dependOn(&run.step);
}

View file

@ -0,0 +1,3 @@
pub const std = @import("std");
pub const builtin = @import("builtin");
pub const root = @import("root");

View file

@ -0,0 +1,11 @@
const std = @import("std");
const builtin = @import("builtin");
const root = @import("root");
const foo = @import("foo");
pub fn main() void {
std.debug.assert(root == @This());
std.debug.assert(std == foo.std);
std.debug.assert(builtin == foo.builtin);
std.debug.assert(root == foo.root);
}

View file

@ -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);
}

View file

@ -0,0 +1 @@
pub const shared = @import("shared");

View file

@ -0,0 +1 @@
// (empty)

View file

@ -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);
}