// 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); } }