Zig 54 lines
// Integration test: format the example programs end to end.
//
// Mirrors tests/lex_examples.zig, but drives `flashc fmt` over the real corpus.
// For every example it asserts the three formatter guarantees that hold at the
// string boundary: formatting succeeds, the result is idempotent
// (`fmt(fmt(s)) == fmt(s)`), and every comment in the input survives in the
// output exactly once (multiset equality). Transpile-equality — that formatting
// never changes the emitted Zig — is covered by the in-module unit tests in
// src/fmt.zig (it needs the parser and lowering on one module graph) and by the
// per-file shell gate the corpus reformat runs; here only strings cross the
// module boundary, so no cross-module AST types are involved.
const std = @import("std");
const fmt = @import("fmt");
const Lexer = fmt.Lexer;
const examples = @import("examples").all;
fn lessStr(_: void, a: []const u8, b: []const u8) bool {
return std.mem.lessThan(u8, a, b);
}
// The line-comment lexemes of `src`, sorted, for a multiset comparison.
fn sortedComments(arena: std.mem.Allocator, src: []const u8) ![]const []const u8 {
var list: std.ArrayList([]const u8) = .empty;
var lx = Lexer.init(src);
while (true) {
const t = lx.next();
if (t.kind == .eof) break;
if (t.kind == .line_comment) try list.append(arena, t.lexeme(src));
}
const slice = try list.toOwnedSlice(arena);
std.mem.sort([]const u8, slice, {}, lessStr);
return slice;
}
test "every example formats, is idempotent, and preserves its comments" {
for (examples) |src| {
var a = std.heap.ArenaAllocator.init(std.testing.allocator);
defer a.deinit();
const arena = a.allocator();
const formatted = try fmt.format(arena, src);
// Idempotence: a second pass changes nothing.
const formatted2 = try fmt.format(arena, formatted);
try std.testing.expectEqualStrings(formatted, formatted2);
// Comment multiset in == out.
const in_comments = try sortedComments(arena, src);
const out_comments = try sortedComments(arena, formatted);
try std.testing.expectEqual(in_comments.len, out_comments.len);
for (in_comments, out_comments) |ic, oc| try std.testing.expectEqualStrings(ic, oc);
}
}