I reduced my solution to return Error.OutOfMemory just to fun:
pub fn transform(
_: std.mem.Allocator,
_: PointsToLettersMap,
) Error!LetterToPointsMap {
return Error.OutOfMemory;
}
And I got a funny message about a bunch of failed tests and a memory leak. I expected the tests to fail but I did not expect them to leak memory.
The offending line in every test is:
legacy.deinit();
It frees memory only on the happy path. actual.deinit() is similarly misplaced, but I did not care to trigger the memory leak there. We should use defer or errdefer to ensure that memory is freed even if there is an error:
test "single letter" {
var legacy = std.AutoHashMap(i5, []const u8).init(testing.allocator);
defer legacy.deinit(); // here
try legacy.put(1, "A");
var actual = try transform(testing.allocator, legacy);
defer actual.deinit(); // and also here
try testing.expectEqual(1, actual.count());
try testing.expectEqual(1, actual.get('a'));
}