Comptime test names

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 compound args value, while the strings are elided)
  • Literal can be used to force that a string value will show up in the printing of a compound args

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)