This commit is contained in:
Luke Boswell 2025-08-10 16:10:37 +10:00
parent 63ba3a1e0a
commit edbc7e7d28
No known key found for this signature in database
GPG key ID: 54A7324B1B975757
4 changed files with 118 additions and 33 deletions

View file

@ -225,12 +225,14 @@ fn addModuleTests(
for (module_configs, 0..) |config, i| {
const test_step = b.addTest(.{
.root_source_file = b.path(config.test_path),
.root_source_file = b.path(config.root_source_file),
.target = target,
.optimize = optimize,
.link_libc = true,
});
roc_modules.addAllToTest(test_step);
// Add only the required dependencies for this specific module
roc_modules.setupModuleTest(test_step, config.name);
const run_step = b.addRunArtifact(test_step);

View file

@ -131,20 +131,99 @@ pub const RocModules = struct {
step.root_module.addImport("build_options", self.build_options);
}
/// Returns the list of modules that have test files
/// Each entry contains the module name and the path to its test file
pub fn getTestableModules() []const struct { name: []const u8, test_path: []const u8 } {
return &.{
.{ .name = "collections", .test_path = "src/collections/mod.zig" },
.{ .name = "base", .test_path = "src/base/mod.zig" },
.{ .name = "builtins", .test_path = "src/builtins/mod.zig" },
// .{ .name = "cache", .test_path = "src/cache/mod.zig" },
// .{ .name = "canonicalize", .test_path = "src/canonicalize/Mod.zig" },
// .{ .name = "check", .test_path = "src/check/Mod.zig" },
// .{ .name = "compile", .test_path = "src/compile/mod.zig" },
// .{ .name = "eval", .test_path = "src/eval/mod.zig" },
// .{ .name = "types", .test_path = "src/types/mod.zig" },
// .{ .name = "parse", .test_path = "src/parse/test.zig" },
const ModuleInfo = struct {
name: []const u8,
root_source_file: []const u8,
};
pub fn getTestableModules() []const ModuleInfo {
return &[_]ModuleInfo{
.{ .name = "serialization", .root_source_file = "src/serialization/mod.zig" },
.{ .name = "collections", .root_source_file = "src/collections/mod.zig" },
.{ .name = "base", .root_source_file = "src/base/mod.zig" },
.{ .name = "types", .root_source_file = "src/types/mod.zig" },
.{ .name = "builtins", .root_source_file = "src/builtins/mod.zig" },
.{ .name = "compile", .root_source_file = "src/compile/mod.zig" },
.{ .name = "reporting", .root_source_file = "src/reporting/mod.zig" },
.{ .name = "parse", .root_source_file = "src/parse/mod.zig" },
.{ .name = "can", .root_source_file = "src/canonicalize/Mod.zig" },
.{ .name = "check", .root_source_file = "src/check/Mod.zig" },
.{ .name = "cache", .root_source_file = "src/cache/mod.zig" },
.{ .name = "fs", .root_source_file = "src/fs/mod.zig" },
};
}
pub fn setupModuleTest(self: RocModules, test_step: *Step.Compile, module_name: []const u8) void {
// Add build_options to all test steps
test_step.root_module.addImport("build_options", self.build_options);
// Add dependencies based on module name
if (std.mem.eql(u8, module_name, "serialization")) {
// serialization has no dependencies from other modules
} else if (std.mem.eql(u8, module_name, "collections")) {
test_step.root_module.addImport("serialization", self.serialization);
} else if (std.mem.eql(u8, module_name, "base")) {
test_step.root_module.addImport("serialization", self.serialization);
test_step.root_module.addImport("collections", self.collections);
} else if (std.mem.eql(u8, module_name, "types")) {
test_step.root_module.addImport("serialization", self.serialization);
test_step.root_module.addImport("base", self.base);
test_step.root_module.addImport("collections", self.collections);
} else if (std.mem.eql(u8, module_name, "builtins")) {
// builtins has no dependencies from other modules
} else if (std.mem.eql(u8, module_name, "reporting")) {
test_step.root_module.addImport("base", self.base);
} else if (std.mem.eql(u8, module_name, "compile")) {
test_step.root_module.addImport("base", self.base);
test_step.root_module.addImport("collections", self.collections);
test_step.root_module.addImport("types", self.types);
test_step.root_module.addImport("builtins", self.builtins);
test_step.root_module.addImport("reporting", self.reporting);
test_step.root_module.addImport("serialization", self.serialization);
test_step.root_module.addImport("parse", self.parse);
test_step.root_module.addImport("can", self.can);
test_step.root_module.addImport("check", self.check);
test_step.root_module.addImport("cache", self.cache);
} else if (std.mem.eql(u8, module_name, "parse")) {
test_step.root_module.addImport("base", self.base);
test_step.root_module.addImport("compile", self.compile);
test_step.root_module.addImport("collections", self.collections);
test_step.root_module.addImport("tracy", self.tracy);
test_step.root_module.addImport("reporting", self.reporting);
} else if (std.mem.eql(u8, module_name, "can")) {
test_step.root_module.addImport("base", self.base);
test_step.root_module.addImport("parse", self.parse);
test_step.root_module.addImport("collections", self.collections);
test_step.root_module.addImport("compile", self.compile);
test_step.root_module.addImport("types", self.types);
test_step.root_module.addImport("builtins", self.builtins);
test_step.root_module.addImport("tracy", self.tracy);
} else if (std.mem.eql(u8, module_name, "check")) {
test_step.root_module.addImport("base", self.base);
test_step.root_module.addImport("tracy", self.tracy);
test_step.root_module.addImport("collections", self.collections);
test_step.root_module.addImport("types", self.types);
test_step.root_module.addImport("can", self.can);
test_step.root_module.addImport("compile", self.compile);
test_step.root_module.addImport("builtins", self.builtins);
test_step.root_module.addImport("reporting", self.reporting);
} else if (std.mem.eql(u8, module_name, "cache")) {
test_step.root_module.addImport("compile", self.compile);
test_step.root_module.addImport("base", self.base);
test_step.root_module.addImport("collections", self.collections);
test_step.root_module.addImport("serialization", self.serialization);
test_step.root_module.addImport("reporting", self.reporting);
test_step.root_module.addImport("fs", self.fs);
} else if (std.mem.eql(u8, module_name, "fs")) {
// fs has no dependencies from other modules
}
// Add tracy and builtins imports for tests that might need them
if (!std.mem.eql(u8, module_name, "builtins")) {
test_step.root_module.addImport("builtins", self.builtins);
}
if (!std.mem.eql(u8, module_name, "tracy")) {
test_step.root_module.addImport("tracy", self.tracy);
}
}
};

View file

@ -98,3 +98,7 @@ test "collections tests" {
std.testing.refAllDecls(@import("safe_list.zig"));
std.testing.refAllDecls(@import("SortedArrayBuilder.zig"));
}
test "ASDF" {
@panic("ASDF");
}

View file

@ -1394,7 +1394,7 @@ test "SafeList(u32) CompactWriter roundtrip with file" {
}
// Create a temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("test.dat", .{ .read = true });
@ -1451,7 +1451,7 @@ test "SafeList(struct) CompactWriter roundtrip with file" {
_ = try original.append(gpa, .{ .x = 50, .y = 60 });
// Create a temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("test_struct.dat", .{ .read = true });
@ -1501,7 +1501,7 @@ test "SafeList empty list CompactWriter roundtrip" {
defer original.deinit(gpa);
// Create a temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("test_empty.dat", .{ .read = true });
@ -1541,7 +1541,7 @@ test "SafeList empty lists CompactWriter roundtrip multiple types" {
const gpa = testing.allocator;
// Test empty lists with different types to ensure alignment works correctly
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const test_types = .{
@ -1663,7 +1663,7 @@ test "SafeList CompactWriter complete roundtrip example" {
_ = try original.append(gpa, 400);
// Step 2: Create temp file and CompactWriter
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("example.dat", .{ .read = true });
@ -1752,7 +1752,7 @@ test "SafeList CompactWriter multiple lists with different alignments" {
_ = try list_struct.append(gpa, .{ .x = 99, .y = 9999, .z = 128 });
// Create temp file and CompactWriter
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("multi_list.dat", .{ .read = true });
@ -1863,7 +1863,7 @@ test "SafeList CompactWriter interleaved pattern with alignment tracking" {
defer offsets.deinit();
// Create temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("interleaved.dat", .{ .read = true });
defer file.close();
@ -1959,7 +1959,7 @@ test "SafeList CompactWriter brute-force alignment verification" {
// Test all combinations of slice lengths from 0 to 8 for different types
// This ensures our alignment padding works correctly for all cases
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
// Test different types with different alignments
@ -2089,7 +2089,7 @@ test "SafeMultiList CompactWriter roundtrip with file" {
_ = try original.append(gpa, .{ .id = 400, .value = 4000, .flag = false, .data = 40 });
// Create a temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("test_multi.dat", .{ .read = true });
@ -2156,7 +2156,7 @@ test "SafeMultiList empty list CompactWriter roundtrip" {
defer original.deinit(gpa);
// Create a temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("test_empty_multi.dat", .{ .read = true });
@ -2227,7 +2227,7 @@ test "SafeMultiList CompactWriter multiple lists different alignments" {
_ = try list3.append(gpa, .{ .id = 888, .data = 84, .flag = false });
// Create temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("multi_types.dat", .{ .read = true });
@ -2306,7 +2306,7 @@ test "SafeMultiList CompactWriter field access after deserialization" {
_ = try original.append(gpa, .{ .id = 777, .value = 888, .flag = true, .data = 99 });
// Create temp file
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("test_field_access.dat", .{ .read = true });
@ -2367,7 +2367,7 @@ test "SafeMultiList CompactWriter field access after deserialization" {
test "SafeMultiList CompactWriter brute-force alignment verification" {
const gpa = testing.allocator;
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
// Test with various struct configurations
@ -2465,7 +2465,7 @@ test "SafeMultiList CompactWriter brute-force alignment verification" {
test "SafeMultiList CompactWriter various field alignments and sizes" {
const gpa = testing.allocator;
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
// Test different field alignment combinations
@ -2602,7 +2602,7 @@ test "SafeMultiList CompactWriter verify exact memory layout" {
}
// Now serialize using our implementation
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("layout_test.dat", .{ .read = true });
@ -2693,7 +2693,7 @@ test "SafeMultiList CompactWriter stress test many field types" {
});
}
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("complex_test.dat", .{ .read = true });
@ -2762,7 +2762,7 @@ test "SafeMultiList CompactWriter empty with capacity" {
try testing.expect(list.items.capacity >= 50);
try testing.expectEqual(@as(usize, 0), list.len());
const tmp_dir = testing.tmpDir(.{});
var tmp_dir = testing.tmpDir(.{});
defer tmp_dir.cleanup();
const file = try tmp_dir.dir.createFile("empty_capacity.dat", .{ .read = true });