diff --git a/parser_test.zig b/parser_test.zig index 051c3fc2ec..de26b011f2 100644 --- a/parser_test.zig +++ b/parser_test.zig @@ -4566,6 +4566,250 @@ test "zig fmt: decimal float literals with underscore separators" { ); } +test "zig fmt: remove newlines surrounding doc comment between members within container decl (1)" { + try testTransform( + \\const Foo = struct { + \\ fn foo() void {} + \\ + \\ + \\ /// doc comment + \\ + \\ + \\ fn bar() void {} + \\}; + \\ + , + \\const Foo = struct { + \\ fn foo() void {} + \\ + \\ /// doc comment + \\ fn bar() void {} + \\}; + \\ + ); +} +test "zig fmt: remove newlines surrounding doc comment between members within container decl (2)" { + try testTransform( + \\const Foo = struct { + \\ fn foo() void {} + \\ /// doc comment 1 + \\ + \\ /// doc comment 2 + \\ + \\ fn bar() void {} + \\}; + \\ + , + \\const Foo = struct { + \\ fn foo() void {} + \\ /// doc comment 1 + \\ /// doc comment 2 + \\ fn bar() void {} + \\}; + \\ + ); +} +test "zig fmt: remove newlines surrounding doc comment within container decl" { + try testTransform( + \\const Foo = struct { + \\ + \\ + \\ /// doc comment + \\ + \\ fn foo() void {} + \\}; + \\ + , + \\const Foo = struct { + \\ /// doc comment + \\ fn foo() void {} + \\}; + \\ + ); +} +test "zig fmt: comments with CRLF line endings" { + try testTransform("" ++ + "//! Top-level doc comment\r\n" ++ + "//! Continuing to another line\r\n" ++ + "\r\n" ++ + "/// Regular doc comment\r\n" ++ + "const S = struct {\r\n" ++ + " // Regular comment\r\n" ++ + " // More content\r\n" ++ + "};\r\n", + \\//! Top-level doc comment + \\//! Continuing to another line + \\ + \\/// Regular doc comment + \\const S = struct { + \\ // Regular comment + \\ // More content + \\}; + \\ + ); +} +test "zig fmt: else comptime expr" { + try testCanonical( + \\comptime { + \\ if (true) {} else comptime foo(); + \\} + \\comptime { + \\ while (true) {} else comptime foo(); + \\} + \\comptime { + \\ for ("") |_| {} else comptime foo(); + \\} + \\ + ); +} +test "zig fmt: integer literals with underscore separators" { + try testTransform( + \\const + \\ x = + \\ 1_234_567 + \\ + (0b0_1-0o7_0+0xff_FF ) + 1_0; + , + \\const x = + \\ 1_234_567 + (0b0_1 - 0o7_0 + 0xff_FF) + 1_0; + \\ + ); +} +test "zig fmt: hex literals with underscore separators" { + try testTransform( + \\pub fn orMask(a: [ 1_000 ]u64, b: [ 1_000] u64) [1_000]u64 { + \\ var c: [1_000]u64 = [1]u64{ 0xFFFF_FFFF_FFFF_FFFF}**1_000; + \\ for (c [ 1_0 .. ], 0..) |_, i| { + \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA; + \\ } + \\ return c; + \\} + \\ + \\ + , + \\pub fn orMask(a: [1_000]u64, b: [1_000]u64) [1_000]u64 { + \\ var c: [1_000]u64 = [1]u64{0xFFFF_FFFF_FFFF_FFFF} ** 1_000; + \\ for (c[1_0..], 0..) |_, i| { + \\ c[i] = (a[i] | b[i]) & 0xCCAA_CCAA_CCAA_CCAA; + \\ } + \\ return c; + \\} + \\ + ); +} +test "zig fmt: hexadecimal float literals with underscore separators" { + try testTransform( + \\pub fn main() void { + \\ const a: f64 = (0x10.0p-0+(0x10.0p+0))+0x10_00.00_00p-8+0x00_00.00_10p+16; + \\ const b: f64 = 0x0010.0--0x00_10.0+0x10.00+0x1p4; + \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); + \\} + , + \\pub fn main() void { + \\ const a: f64 = (0x10.0p-0 + (0x10.0p+0)) + 0x10_00.00_00p-8 + 0x00_00.00_10p+16; + \\ const b: f64 = 0x0010.0 - -0x00_10.0 + 0x10.00 + 0x1p4; + \\ std.debug.warn("a: {}, b: {} -> a+b: {}\n", .{ a, b, a + b }); + \\} + \\ + ); +} +test "zig fmt: C var args" { + try testCanonical( + \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; + \\ + ); +} +test "zig fmt: Only indent multiline string literals in function calls" { + try testCanonical( + \\test "zig fmt:" { + \\ try testTransform( + \\ \\const X = struct { + \\ \\ foo: i32, bar: i8 }; + \\ , + \\ \\const X = struct { + \\ \\ foo: i32, bar: i8 + \\ \\}; + \\ \\ + \\ ); + \\} + \\ + ); +} +test "zig fmt: Don't add extra newline after if" { + try testCanonical( + \\pub fn atomicSymLink(allocator: Allocator, existing_path: []const u8, new_path: []const u8) !void { + \\ if (cwd().symLink(existing_path, new_path, .{})) { + \\ return; + \\ } + \\} + \\ + ); +} +test "zig fmt: comments in ternary ifs" { + try testCanonical( + \\const x = if (true) { + \\ 1; + \\} else if (false) + \\ // Comment + \\ 0; + \\const y = if (true) + \\ // Comment + \\ 1 + \\else + \\ // Comment + \\ 0; + \\ + \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; + \\ + ); +} +test "zig fmt: while statement in blockless if" { + try testCanonical( + \\pub fn main() void { + \\ const zoom_node = if (focused_node == layout_first) + \\ while (it.next()) |node| { + \\ if (!node.view.pending.float and !node.view.pending.fullscreen) break node; + \\ } else null + \\ else + \\ focused_node; + \\} + \\ + ); +} +test "zig fmt: test comments in field access chain" { + try testCanonical( + \\pub const str = struct { + \\ pub const Thing = more.more // + \\ .more() // + \\ .more().more() // + \\ .more() // + \\ // .more() // + \\ .more() // + \\ .more(); + \\ data: Data, + \\}; + \\ + \\pub const str = struct { + \\ pub const Thing = more.more // + \\ .more() // + \\ // .more() // + \\ // .more() // + \\ // .more() // + \\ .more() // + \\ .more(); + \\ data: Data, + \\}; + \\ + \\pub const str = struct { + \\ pub const Thing = more // + \\ .more // + \\ .more() // + \\ .more(); + \\ data: Data, + \\}; + \\ + ); +} + test "Ast header smoke test" { try std.testing.expectEqual(zigNode(c.AST_NODE_IF), Ast.Node.Tag.@"if"); }