All tests in the Twelve Days exercise on Zig track are currently generous with the buffer they give. Some solutions overuse the buffer but pass the tests nevertheless. For example, I have seen a solution that prints an '\n' at the end of the output and then deletes it. This raises the requirement for buffer size by one and makes it impossible for the user to allocate a buffer of the exact size needed for the output. This is an example of a test that could be added to cover this edge case:
test "a buffer of exact size does not trigger an error" {
var buffer: [4000]u8 = undefined;
const expected: []const u8 =
\\On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree.
;
const actual = try recite(buffer[0..expected.len], 1, 1);
try std.testing.expectEqualStrings(expected, actual);
}
There are a few other exercises that use a buffer for the output. They may need a similar test.
The other two edge cases are comptime function parameters abuse and failing to use the actual buffer. I talked about them earlier. Example tests:
fn testRecite(expected: []const u8, start_verse: u8, end_verse: u8) !void {
var buffer: [4000]u8 = undefined;
const actual = try recite(&buffer, start_verse, end_verse);
try std.testing.expectEqualStrings(expected, actual);
}
test "arguments are run-time known" {
const expected: []const u8 =
\\On the first day of Christmas my true love gave to me: a Partridge in a Pear Tree.
;
try testRecite(expected, 1, 1);
}
test "returned slice refers to the buffer" {
var buffer: [4000]u8 = undefined;
const actual = try recite(&buffer, 1, 1);
try std.testing.expect((&buffer).ptr == actual.ptr);
}