convert assemble and link tests to zig build system
This commit is contained in:
@@ -1,26 +1,6 @@
|
||||
const std = @import("std");
|
||||
const debug = std.debug;
|
||||
const build = std.build;
|
||||
const os = std.os;
|
||||
const StdIo = os.ChildProcess.StdIo;
|
||||
const Term = os.ChildProcess.Term;
|
||||
const Buffer0 = std.cstr.Buffer0;
|
||||
const io = std.io;
|
||||
const mem = std.mem;
|
||||
const fmt = std.fmt;
|
||||
const List = std.list.List;
|
||||
|
||||
error TestFailed;
|
||||
|
||||
pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {
|
||||
const cases = %%b.allocator.create(CompileErrorContext);
|
||||
*cases = CompileErrorContext {
|
||||
.b = b,
|
||||
.step = b.step("test-compile-errors", "Run the compile error tests"),
|
||||
.test_index = 0,
|
||||
.test_filter = test_filter,
|
||||
};
|
||||
const tests = @import("tests.zig");
|
||||
|
||||
pub fn addCases(cases: &tests.CompileErrorContext) {
|
||||
cases.add("implicit semicolon - block statement",
|
||||
\\export fn entry() {
|
||||
\\ {}
|
||||
@@ -1594,219 +1574,4 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui
|
||||
,
|
||||
"error: 'main' is private",
|
||||
".tmp_source.zig:1:1: note: declared here");
|
||||
|
||||
|
||||
|
||||
|
||||
return cases.step;
|
||||
}
|
||||
|
||||
const CompileErrorContext = struct {
|
||||
b: &build.Builder,
|
||||
step: &build.Step,
|
||||
test_index: usize,
|
||||
test_filter: ?[]const u8,
|
||||
|
||||
const TestCase = struct {
|
||||
name: []const u8,
|
||||
sources: List(SourceFile),
|
||||
expected_errors: List([]const u8),
|
||||
link_libc: bool,
|
||||
is_exe: bool,
|
||||
|
||||
const SourceFile = struct {
|
||||
filename: []const u8,
|
||||
source: []const u8,
|
||||
};
|
||||
|
||||
pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) {
|
||||
%%self.sources.append(SourceFile {
|
||||
.filename = filename,
|
||||
.source = source,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn addExpectedError(self: &TestCase, text: []const u8) {
|
||||
%%self.expected_errors.append(text);
|
||||
}
|
||||
};
|
||||
|
||||
const CompileCmpOutputStep = struct {
|
||||
step: build.Step,
|
||||
context: &CompileErrorContext,
|
||||
name: []const u8,
|
||||
test_index: usize,
|
||||
case: &const TestCase,
|
||||
release: bool,
|
||||
|
||||
pub fn create(context: &CompileErrorContext, name: []const u8,
|
||||
case: &const TestCase, release: bool) -> &CompileCmpOutputStep
|
||||
{
|
||||
const allocator = context.b.allocator;
|
||||
const ptr = %%allocator.create(CompileCmpOutputStep);
|
||||
*ptr = CompileCmpOutputStep {
|
||||
.step = build.Step.init("CompileCmpOutput", allocator, make),
|
||||
.context = context,
|
||||
.name = name,
|
||||
.test_index = context.test_index,
|
||||
.case = case,
|
||||
.release = release,
|
||||
};
|
||||
context.test_index += 1;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fn make(step: &build.Step) -> %void {
|
||||
const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
|
||||
const b = self.context.b;
|
||||
|
||||
const root_src = %%os.path.join(b.allocator, "test_artifacts", self.case.sources.items[0].filename);
|
||||
const obj_path = %%os.path.join(b.allocator, "test_artifacts", "test.o");
|
||||
|
||||
var zig_args = List([]const u8).init(b.allocator);
|
||||
%%zig_args.append(if (self.case.is_exe) "build_exe" else "build_obj");
|
||||
%%zig_args.append(b.pathFromRoot(root_src));
|
||||
|
||||
%%zig_args.append("--name");
|
||||
%%zig_args.append("test");
|
||||
|
||||
%%zig_args.append("--output");
|
||||
%%zig_args.append(b.pathFromRoot(obj_path));
|
||||
|
||||
if (self.release) {
|
||||
%%zig_args.append("--release");
|
||||
}
|
||||
|
||||
%%io.stderr.printf("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
|
||||
|
||||
if (b.verbose) {
|
||||
printInvocation(b.zig_exe, zig_args.toSliceConst());
|
||||
}
|
||||
|
||||
var child = os.ChildProcess.spawn(b.zig_exe, zig_args.toSliceConst(), &b.env_map,
|
||||
StdIo.Ignore, StdIo.Pipe, StdIo.Pipe, b.allocator) %% |err|
|
||||
{
|
||||
debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err));
|
||||
};
|
||||
|
||||
const term = child.wait() %% |err| {
|
||||
debug.panic("Unable to spawn {}: {}\n", b.zig_exe, @errorName(err));
|
||||
};
|
||||
switch (term) {
|
||||
Term.Clean => |code| {
|
||||
if (code == 0) {
|
||||
%%io.stderr.printf("Compilation incorrectly succeeded\n");
|
||||
return error.TestFailed;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
%%io.stderr.printf("Process {} terminated unexpectedly\n", b.zig_exe);
|
||||
return error.TestFailed;
|
||||
},
|
||||
};
|
||||
|
||||
var stdout_buf = %%Buffer0.initEmpty(b.allocator);
|
||||
var stderr_buf = %%Buffer0.initEmpty(b.allocator);
|
||||
|
||||
%%(??child.stdout).readAll(&stdout_buf);
|
||||
%%(??child.stderr).readAll(&stderr_buf);
|
||||
|
||||
const stdout = stdout_buf.toSliceConst();
|
||||
const stderr = stderr_buf.toSliceConst();
|
||||
|
||||
if (stdout.len != 0) {
|
||||
%%io.stderr.printf(
|
||||
\\
|
||||
\\Expected empty stdout, instead found:
|
||||
\\================================================
|
||||
\\{}
|
||||
\\================================================
|
||||
\\
|
||||
, stdout);
|
||||
return error.TestFailed;
|
||||
}
|
||||
|
||||
for (self.case.expected_errors.toSliceConst()) |expected_error| {
|
||||
if (mem.indexOf(u8, stderr, expected_error) == null) {
|
||||
%%io.stderr.printf(
|
||||
\\
|
||||
\\========= Expected this compile error: =========
|
||||
\\{}
|
||||
\\================================================
|
||||
\\{}
|
||||
\\
|
||||
, expected_error, stderr);
|
||||
return error.TestFailed;
|
||||
}
|
||||
}
|
||||
%%io.stderr.printf("OK\n");
|
||||
}
|
||||
};
|
||||
|
||||
fn printInvocation(exe_path: []const u8, args: []const []const u8) {
|
||||
%%io.stderr.printf("{}", exe_path);
|
||||
for (args) |arg| {
|
||||
%%io.stderr.printf(" {}", arg);
|
||||
}
|
||||
%%io.stderr.printf("\n");
|
||||
}
|
||||
|
||||
pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,
|
||||
expected_lines: ...) -> &TestCase
|
||||
{
|
||||
const tc = %%self.b.allocator.create(TestCase);
|
||||
*tc = TestCase {
|
||||
.name = name,
|
||||
.sources = List(TestCase.SourceFile).init(self.b.allocator),
|
||||
.expected_errors = List([]const u8).init(self.b.allocator),
|
||||
.link_libc = false,
|
||||
.is_exe = false,
|
||||
};
|
||||
tc.addSourceFile(".tmp_source.zig", source);
|
||||
comptime var arg_i = 0;
|
||||
inline while (arg_i < expected_lines.len; arg_i += 1) {
|
||||
// TODO mem.dupe is because of issue #336
|
||||
tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i]));
|
||||
}
|
||||
return tc;
|
||||
}
|
||||
|
||||
pub fn addC(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {
|
||||
var tc = self.create(name, source, expected_lines);
|
||||
tc.link_libc = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addExe(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {
|
||||
var tc = self.create(name, source, expected_lines);
|
||||
tc.is_exe = true;
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn add(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {
|
||||
const tc = self.create(name, source, expected_lines);
|
||||
self.addCase(tc);
|
||||
}
|
||||
|
||||
pub fn addCase(self: &CompileErrorContext, case: &const TestCase) {
|
||||
const b = self.b;
|
||||
|
||||
for ([]bool{false, true}) |release| {
|
||||
const annotated_case_name = %%fmt.allocPrint(self.b.allocator, "{} ({})",
|
||||
case.name, if (release) "release" else "debug");
|
||||
if (const filter ?= self.test_filter) {
|
||||
if (mem.indexOf(u8, annotated_case_name, filter) == null)
|
||||
continue;
|
||||
}
|
||||
|
||||
const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, release);
|
||||
self.step.dependOn(&compile_and_cmp_errors.step);
|
||||
|
||||
for (case.sources.toSliceConst()) |src_file| {
|
||||
const expanded_src_path = %%os.path.join(b.allocator, "test_artifacts", src_file.filename);
|
||||
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
|
||||
compile_and_cmp_errors.step.dependOn(&write_src.step);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user