Merge pull request #11952 from ziglang/test-harness-improvements

Test harness improvements
This commit is contained in:
Andrew Kelley 2022-06-28 14:15:30 -04:00 committed by GitHub
commit aa1f9556d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 19 deletions

View File

@ -235,9 +235,9 @@ const TestManifest = struct {
inner: std.mem.SplitIterator(u8), inner: std.mem.SplitIterator(u8),
parse_fn: ParseFn(T), parse_fn: ParseFn(T),
fn next(self: *@This()) ?T { fn next(self: *@This()) !?T {
const next_raw = self.inner.next() orelse return null; const next_raw = self.inner.next() orelse return null;
return self.parse_fn(next_raw); return try self.parse_fn(next_raw);
} }
}; };
} }
@ -339,20 +339,20 @@ const TestManifest = struct {
allocator: Allocator, allocator: Allocator,
key: []const u8, key: []const u8,
comptime T: type, comptime T: type,
) error{OutOfMemory}![]const T { ) ![]const T {
var out = std.ArrayList(T).init(allocator); var out = std.ArrayList(T).init(allocator);
defer out.deinit(); defer out.deinit();
var it = self.getConfigForKey(key, T); var it = self.getConfigForKey(key, T);
while (it.next()) |item| { while (try it.next()) |item| {
try out.append(item); try out.append(item);
} }
return out.toOwnedSlice(); return out.toOwnedSlice();
} }
fn getConfigForKeyAssertSingle(self: TestManifest, key: []const u8, comptime T: type) T { fn getConfigForKeyAssertSingle(self: TestManifest, key: []const u8, comptime T: type) !T {
var it = self.getConfigForKey(key, T); var it = self.getConfigForKey(key, T);
const res = it.next().?; const res = (try it.next()) orelse unreachable;
assert(it.next() == null); assert((try it.next()) == null);
return res; return res;
} }
@ -373,33 +373,36 @@ const TestManifest = struct {
} }
fn ParseFn(comptime T: type) type { fn ParseFn(comptime T: type) type {
return fn ([]const u8) ?T; return fn ([]const u8) anyerror!T;
} }
fn getDefaultParser(comptime T: type) ParseFn(T) { fn getDefaultParser(comptime T: type) ParseFn(T) {
switch (@typeInfo(T)) { switch (@typeInfo(T)) {
.Int => return struct { .Int => return struct {
fn parse(str: []const u8) ?T { fn parse(str: []const u8) anyerror!T {
return std.fmt.parseInt(T, str, 0) catch null; return try std.fmt.parseInt(T, str, 0);
} }
}.parse, }.parse,
.Bool => return struct { .Bool => return struct {
fn parse(str: []const u8) ?T { fn parse(str: []const u8) anyerror!T {
const as_int = std.fmt.parseInt(u1, str, 0) catch return null; const as_int = try std.fmt.parseInt(u1, str, 0);
return as_int > 0; return as_int > 0;
} }
}.parse, }.parse,
.Enum => return struct { .Enum => return struct {
fn parse(str: []const u8) ?T { fn parse(str: []const u8) anyerror!T {
return std.meta.stringToEnum(T, str); return std.meta.stringToEnum(T, str) orelse {
std.log.err("unknown enum variant for {s}: {s}", .{ @typeName(T), str });
return error.UnknownEnumVariant;
};
} }
}.parse, }.parse,
.Struct => if (comptime std.mem.eql(u8, @typeName(T), "CrossTarget")) return struct { .Struct => if (comptime std.mem.eql(u8, @typeName(T), "CrossTarget")) return struct {
fn parse(str: []const u8) ?T { fn parse(str: []const u8) anyerror!T {
var opts = CrossTarget.ParseOptions{ var opts = CrossTarget.ParseOptions{
.arch_os_abi = str, .arch_os_abi = str,
}; };
return CrossTarget.parse(opts) catch null; return try CrossTarget.parse(opts);
} }
}.parse else @compileError("no default parser for " ++ @typeName(T)), }.parse else @compileError("no default parser for " ++ @typeName(T)),
else => @compileError("no default parser for " ++ @typeName(T)), else => @compileError("no default parser for " ++ @typeName(T)),
@ -1128,8 +1131,8 @@ pub const TestContext = struct {
if (cases.items.len == 0) { if (cases.items.len == 0) {
const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend); const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend);
const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", CrossTarget); const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", CrossTarget);
const is_test = manifest.getConfigForKeyAssertSingle("is_test", bool); const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
const output_mode = manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode); const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode);
const name_prefix = blk: { const name_prefix = blk: {
const ext_index = std.mem.lastIndexOfScalar(u8, current_file.*, '.') orelse const ext_index = std.mem.lastIndexOfScalar(u8, current_file.*, '.') orelse

View File

@ -19,6 +19,6 @@ pub fn main() void {
} }
// run // run
// backend=stage2, llvm // backend=stage2,llvm
// target=x86_64-linux,x86_64-macos // target=x86_64-linux,x86_64-macos
// //

View File

@ -9,4 +9,5 @@ inline fn fibonacci(n: usize) usize {
} }
// run // run
// target=x86_64-linux,arm-linux,x86_64-macos,wasm32-wasi
// //