test: don't run heal during configuration phase
In order to simplify the code, the heal function is called during the configuration phase, thus resulting in the function being always called when the build.zig file is run. This behavior unfortunately causes a serious issue when the user fix a broken exercise and, during the next step, the heal function tries to heal the fixed exercise resulting in GNU patch assuming an attempt to reverse a patch, waiting for input from the terminal. Run the heal function from the new HealStep step, so that it is called only during tests. Rename the outdir constant to work_path, for consistency with build.zig. Fixes #272
This commit is contained in:
parent
f9aec283c8
commit
74b48192e4
1 changed files with 48 additions and 11 deletions
|
@ -20,15 +20,14 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
|
|
||||||
// We should use a temporary path, but it will make the implementation of
|
// We should use a temporary path, but it will make the implementation of
|
||||||
// `build.zig` more complex.
|
// `build.zig` more complex.
|
||||||
const outdir = "patches/healed";
|
const work_path = "patches/healed";
|
||||||
|
|
||||||
fs.cwd().makePath(outdir) catch |err| {
|
fs.cwd().makePath(work_path) catch |err| {
|
||||||
return fail(step, "unable to make '{s}': {s}\n", .{ outdir, @errorName(err) });
|
return fail(step, "unable to make '{s}': {s}\n", .{ work_path, @errorName(err) });
|
||||||
};
|
|
||||||
heal(b.allocator, exercises, outdir) catch |err| {
|
|
||||||
return fail(step, "unable to heal exercises: {s}\n", .{@errorName(err)});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const heal_step = HealStep.create(b, exercises, work_path);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Test that `zig build -Dhealed -Dn=n test` selects the nth exercise.
|
// Test that `zig build -Dhealed -Dn=n test` selects the nth exercise.
|
||||||
const case_step = createCase(b, "case-1");
|
const case_step = createCase(b, "case-1");
|
||||||
|
@ -49,6 +48,8 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
else
|
else
|
||||||
expectStdErrMatch(cmd, ex.output);
|
expectStdErrMatch(cmd, ex.output);
|
||||||
|
|
||||||
|
cmd.step.dependOn(&heal_step.step);
|
||||||
|
|
||||||
case_step.dependOn(&cmd.step);
|
case_step.dependOn(&cmd.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +73,8 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
cmd.expectStdOutEqual("");
|
cmd.expectStdOutEqual("");
|
||||||
expectStdErrMatch(cmd, b.fmt("{s} skipped", .{ex.main_file}));
|
expectStdErrMatch(cmd, b.fmt("{s} skipped", .{ex.main_file}));
|
||||||
|
|
||||||
|
cmd.step.dependOn(&heal_step.step);
|
||||||
|
|
||||||
case_step.dependOn(&cmd.step);
|
case_step.dependOn(&cmd.step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +89,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
const cmd = b.addSystemCommand(&.{ b.zig_exe, "build", "-Dhealed" });
|
const cmd = b.addSystemCommand(&.{ b.zig_exe, "build", "-Dhealed" });
|
||||||
cmd.setName("zig build -Dhealed");
|
cmd.setName("zig build -Dhealed");
|
||||||
cmd.expectExitCode(0);
|
cmd.expectExitCode(0);
|
||||||
|
cmd.step.dependOn(&heal_step.step);
|
||||||
|
|
||||||
const stderr = cmd.captureStdErr();
|
const stderr = cmd.captureStdErr();
|
||||||
const verify = CheckStep.create(b, exercises, stderr, true);
|
const verify = CheckStep.create(b, exercises, stderr, true);
|
||||||
|
@ -107,6 +111,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
);
|
);
|
||||||
cmd.setName("zig build -Dhealed -Dn=1 start");
|
cmd.setName("zig build -Dhealed -Dn=1 start");
|
||||||
cmd.expectExitCode(0);
|
cmd.expectExitCode(0);
|
||||||
|
cmd.step.dependOn(&heal_step.step);
|
||||||
|
|
||||||
const stderr = cmd.captureStdErr();
|
const stderr = cmd.captureStdErr();
|
||||||
const verify = CheckStep.create(b, exercises, stderr, false);
|
const verify = CheckStep.create(b, exercises, stderr, false);
|
||||||
|
@ -126,14 +131,16 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
|
||||||
cmd.expectExitCode(1);
|
cmd.expectExitCode(1);
|
||||||
expectStdErrMatch(cmd, exercises[0].hint);
|
expectStdErrMatch(cmd, exercises[0].hint);
|
||||||
|
|
||||||
|
cmd.step.dependOn(&heal_step.step);
|
||||||
|
|
||||||
case_step.dependOn(&cmd.step);
|
case_step.dependOn(&cmd.step);
|
||||||
|
|
||||||
step.dependOn(case_step);
|
step.dependOn(case_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't add the cleanup step, since it may delete outdir while a test case
|
// Don't add the cleanup step, since it may delete work_path while a test
|
||||||
// is running.
|
// case is running.
|
||||||
//const cleanup = b.addRemoveDirTree(outdir);
|
//const cleanup = b.addRemoveDirTree(work_path);
|
||||||
//step.dependOn(&cleanup.step);
|
//step.dependOn(&cleanup.step);
|
||||||
|
|
||||||
return step;
|
return step;
|
||||||
|
@ -315,8 +322,38 @@ fn fail(step: *Step, comptime format: []const u8, args: anytype) *Step {
|
||||||
return step;
|
return step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A step that heals exercises.
|
||||||
|
const HealStep = struct {
|
||||||
|
step: Step,
|
||||||
|
exercises: []const Exercise,
|
||||||
|
work_path: []const u8,
|
||||||
|
|
||||||
|
pub fn create(owner: *Build, exercises: []const Exercise, work_path: []const u8) *HealStep {
|
||||||
|
const self = owner.allocator.create(HealStep) catch @panic("OOM");
|
||||||
|
self.* = .{
|
||||||
|
.step = Step.init(.{
|
||||||
|
.id = .custom,
|
||||||
|
.name = "heal",
|
||||||
|
.owner = owner,
|
||||||
|
.makeFn = make,
|
||||||
|
}),
|
||||||
|
.exercises = exercises,
|
||||||
|
.work_path = work_path,
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make(step: *Step, _: *std.Progress.Node) !void {
|
||||||
|
const b = step.owner;
|
||||||
|
const self = @fieldParentPtr(HealStep, "step", step);
|
||||||
|
|
||||||
|
return heal(b.allocator, self.exercises, self.work_path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Heals all the exercises.
|
// Heals all the exercises.
|
||||||
fn heal(allocator: Allocator, exercises: []const Exercise, outdir: []const u8) !void {
|
fn heal(allocator: Allocator, exercises: []const Exercise, work_path: []const u8) !void {
|
||||||
const join = fs.path.join;
|
const join = fs.path.join;
|
||||||
|
|
||||||
const exercises_path = "exercises";
|
const exercises_path = "exercises";
|
||||||
|
@ -331,7 +368,7 @@ fn heal(allocator: Allocator, exercises: []const Exercise, outdir: []const u8) !
|
||||||
const patch_name = try fmt.allocPrint(allocator, "{s}.patch", .{name});
|
const patch_name = try fmt.allocPrint(allocator, "{s}.patch", .{name});
|
||||||
break :b try join(allocator, &.{ patches_path, patch_name });
|
break :b try join(allocator, &.{ patches_path, patch_name });
|
||||||
};
|
};
|
||||||
const output = try join(allocator, &.{ outdir, ex.main_file });
|
const output = try join(allocator, &.{ work_path, ex.main_file });
|
||||||
|
|
||||||
const argv = &.{ "patch", "-i", patch, "-o", output, "-s", file };
|
const argv = &.{ "patch", "-i", patch, "-o", output, "-s", file };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue