mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
137 lines
5.7 KiB
Zig
137 lines
5.7 KiB
Zig
const std = @import("std");
|
|
|
|
pub fn build(b: *std.Build) void {
|
|
const test_step = b.step("test", "Test it");
|
|
b.default_step = test_step;
|
|
|
|
const target = b.standardTargetOptions(.{});
|
|
const optimize = b.standardOptimizeOption(.{});
|
|
|
|
const exe = b.addExecutable(.{
|
|
.name = "create-file",
|
|
.root_module = b.createModule(.{
|
|
.root_source_file = b.path("main.zig"),
|
|
.target = target,
|
|
.optimize = optimize,
|
|
}),
|
|
});
|
|
|
|
{
|
|
const run_random_with_sideeffects_first = b.addRunArtifact(exe);
|
|
run_random_with_sideeffects_first.setName("run with side-effects (first)");
|
|
run_random_with_sideeffects_first.has_side_effects = true;
|
|
|
|
const run_random_with_sideeffects_second = b.addRunArtifact(exe);
|
|
run_random_with_sideeffects_second.setName("run with side-effects (second)");
|
|
run_random_with_sideeffects_second.has_side_effects = true;
|
|
|
|
// ensure that "second" runs after "first"
|
|
run_random_with_sideeffects_second.step.dependOn(&run_random_with_sideeffects_first.step);
|
|
|
|
const first_output = run_random_with_sideeffects_first.addOutputFileArg("a.txt");
|
|
const second_output = run_random_with_sideeffects_second.addOutputFileArg("a.txt");
|
|
|
|
const expect_uncached_dependencies = CheckOutputCaching.init(b, false, &.{ first_output, second_output });
|
|
test_step.dependOn(&expect_uncached_dependencies.step);
|
|
|
|
const expect_unequal_output = CheckPathEquality.init(b, true, &.{ first_output, second_output });
|
|
test_step.dependOn(&expect_unequal_output.step);
|
|
|
|
const check_first_output = b.addCheckFile(first_output, .{ .expected_matches = &.{"a.txt"} });
|
|
test_step.dependOn(&check_first_output.step);
|
|
const check_second_output = b.addCheckFile(second_output, .{ .expected_matches = &.{"a.txt"} });
|
|
test_step.dependOn(&check_second_output.step);
|
|
}
|
|
|
|
{
|
|
const run_random_without_sideeffects_1 = b.addRunArtifact(exe);
|
|
run_random_without_sideeffects_1.setName("run without side-effects (A)");
|
|
|
|
const run_random_without_sideeffects_2 = b.addRunArtifact(exe);
|
|
run_random_without_sideeffects_2.setName("run without side-effects (B)");
|
|
|
|
run_random_without_sideeffects_2.step.dependOn(&run_random_without_sideeffects_1.step);
|
|
|
|
const first_output = run_random_without_sideeffects_1.addOutputFileArg("a.txt");
|
|
const second_output = run_random_without_sideeffects_2.addOutputFileArg("a.txt");
|
|
|
|
const expect_cached_dependencies = CheckOutputCaching.init(b, true, &.{second_output});
|
|
test_step.dependOn(&expect_cached_dependencies.step);
|
|
|
|
const expect_equal_output = CheckPathEquality.init(b, true, &.{ first_output, second_output });
|
|
test_step.dependOn(&expect_equal_output.step);
|
|
|
|
const check_first_output = b.addCheckFile(first_output, .{ .expected_matches = &.{"a.txt"} });
|
|
test_step.dependOn(&check_first_output.step);
|
|
const check_second_output = b.addCheckFile(second_output, .{ .expected_matches = &.{"a.txt"} });
|
|
test_step.dependOn(&check_second_output.step);
|
|
}
|
|
}
|
|
|
|
const CheckOutputCaching = struct {
|
|
step: std.Build.Step,
|
|
expect_caching: bool,
|
|
|
|
pub fn init(owner: *std.Build, expect_caching: bool, output_paths: []const std.Build.LazyPath) *CheckOutputCaching {
|
|
const check = owner.allocator.create(CheckOutputCaching) catch @panic("OOM");
|
|
check.* = .{
|
|
.step = std.Build.Step.init(.{
|
|
.id = .custom,
|
|
.name = "check output caching",
|
|
.owner = owner,
|
|
.makeFn = make,
|
|
}),
|
|
.expect_caching = expect_caching,
|
|
};
|
|
for (output_paths) |output_path| {
|
|
output_path.addStepDependencies(&check.step);
|
|
}
|
|
return check;
|
|
}
|
|
|
|
fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
|
|
const check: *CheckOutputCaching = @fieldParentPtr("step", step);
|
|
|
|
for (step.dependencies.items) |dependency| {
|
|
if (check.expect_caching) {
|
|
if (dependency.result_cached) continue;
|
|
return step.fail("expected '{s}' step to be cached, but it was not", .{dependency.name});
|
|
} else {
|
|
if (!dependency.result_cached) continue;
|
|
return step.fail("expected '{s}' step to not be cached, but it was", .{dependency.name});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const CheckPathEquality = struct {
|
|
step: std.Build.Step,
|
|
expected_equality: bool,
|
|
output_paths: []const std.Build.LazyPath,
|
|
|
|
pub fn init(owner: *std.Build, expected_equality: bool, output_paths: []const std.Build.LazyPath) *CheckPathEquality {
|
|
const check = owner.allocator.create(CheckPathEquality) catch @panic("OOM");
|
|
check.* = .{
|
|
.step = std.Build.Step.init(.{
|
|
.id = .custom,
|
|
.name = "check output path equality",
|
|
.owner = owner,
|
|
.makeFn = make,
|
|
}),
|
|
.expected_equality = expected_equality,
|
|
.output_paths = owner.allocator.dupe(std.Build.LazyPath, output_paths) catch @panic("OOM"),
|
|
};
|
|
for (output_paths) |output_path| {
|
|
output_path.addStepDependencies(&check.step);
|
|
}
|
|
return check;
|
|
}
|
|
|
|
fn make(step: *std.Build.Step, _: std.Build.Step.MakeOptions) !void {
|
|
const check: *CheckPathEquality = @fieldParentPtr("step", step);
|
|
std.debug.assert(check.output_paths.len != 0);
|
|
for (check.output_paths[0 .. check.output_paths.len - 1], check.output_paths[1..]) |a, b| {
|
|
try std.testing.expectEqual(check.expected_equality, std.mem.eql(u8, a.getPath(step.owner), b.getPath(step.owner)));
|
|
}
|
|
}
|
|
};
|