Here is a revised version and with that, I am starting to like it (although I still prefer writing it manually for simple cases / where possible):
const std = @import("std");
pub fn Test(comptime args: anytype) type {
return struct {
const reference = args;
pub fn Impl(Def: type) type {
return struct {
const Self = @This();
test Self {
try Def.impl();
}
};
}
};
}
// This can be used in the args value so that the string value actually gets printed
// but using enum literals instead is better because those get printed more reliably
pub fn Literal(comptime str: []const u8) type {
return opaque {
const ref = str;
};
}
comptime {
const files = .{ "hay", "hey", "hooi", "needle" };
for (files) |file| {
_ = Test(file).Impl(struct {
fn impl() !void {
try std.testing.expect(std.mem.eql(u8, file, "needle"));
}
});
}
}
comptime {
for (.{ .alpha, .beta }) |kind| {
for (.{ 1, 2 }) |part| {
_ = Test(.{ .kind = kind, .part = part }).Impl(struct {
fn impl() !void {
try test_helper(@tagName(kind), part);
}
});
}
}
}
fn test_helper(kind: []const u8, part: i32) !void {
std.log.debug("test_helper({s}, {d})", .{ kind, part });
try std.testing.expect(false);
}
Some tips:
- use enum literals instead of strings and then convert them to strings when needed
(because the enum literals are printed when part of a compoundargsvalue, while the strings are elided) Literalcan be used to force that a string value will show up in the printing of a compoundargs
Output (names only):
1/8 testnames.Test("hay").Impl(testnames.comptime__struct_167).decltest.Self...FAIL (TestUnexpectedResult)
2/8 testnames.Test("hey").Impl(testnames.comptime__struct_175).decltest.Self...FAIL (TestUnexpectedResult)
3/8 testnames.Test("hooi").Impl(testnames.comptime__struct_184).decltest.Self...FAIL (TestUnexpectedResult)
5/8 testnames.Test(.{ .kind = .alpha, .part = 1 }).Impl(testnames.comptime__struct_211).decltest.Self...FAIL (TestUnexpectedResult)
6/8 testnames.Test(.{ .kind = .alpha, .part = 2 }).Impl(testnames.comptime__struct_221).decltest.Self...FAIL (TestUnexpectedResult)
7/8 testnames.Test(.{ .kind = .beta, .part = 1 }).Impl(testnames.comptime__struct_232).decltest.Self...FAIL (TestUnexpectedResult)
8/8 testnames.Test(.{ .kind = .beta, .part = 2 }).Impl(testnames.comptime__struct_242).decltest.Self...FAIL (TestUnexpectedResult)