diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 22:59:43 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:17 -0300 |
| commit | 6d148bb9c433814835935ead30020e43781b7f03 (patch) | |
| tree | 49e42dbbbff64119ead447598a896a69e638e061 /test/output.zig | |
| parent | b1485c97b493f7eaf65c6afdfb82e3065306b8fe (diff) | |
| parent | d4960472375ea68f709c56a677d8a37571419ff7 (diff) | |
| download | pardes-6d148bb9c433814835935ead30020e43781b7f03.tar.gz pardes-6d148bb9c433814835935ead30020e43781b7f03.zip | |
Release Pardes 0.6
Merge: audit top-five cuts + tag sweeps + Config/DumpConfig (on the audit bug fixes C9, C2).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'test/output.zig')
| -rw-r--r-- | test/output.zig | 98 |
1 files changed, 88 insertions, 10 deletions
diff --git a/test/output.zig b/test/output.zig index 3a11b101..c67c021e 100644 --- a/test/output.zig +++ b/test/output.zig @@ -89,7 +89,7 @@ fn resultId(p: *Pardes) !usize { } test "output callers opt into location highlighting instead of matching prose colons" { - for ([_]panes.Output.Origin{ .{ .cmd = .LocationsConfig }, .{ .cmd = .Config }, .{ .query = .hover } }) |origin| { + for ([_]panes.Output.Origin{ .{ .cmd = .LocationsConfig }, .{ .cmd = .DumpConfig }, .{ .query = .hover } }) |origin| { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 140, .rows = 30 }); defer p.deinit(); p.locations_config.layout = .@"inline"; @@ -533,12 +533,12 @@ test "Mini failures leave its existing snapshot and focus unchanged" { try std.testing.expectEqual(next, p.freeSlot()); } -test "Config prints the startup path and refreshes its one output" { +test "DumpConfig prints the startup path and refreshes its one output" { const path = "/home/pardes-test/.config/pardes/init"; const p = try Pardes.init(std.testing.allocator, .{ .startup_config_path = path }); defer p.deinit(); - try std.testing.expect(p.executeBuiltinLine(0, "Config")); + try std.testing.expect(p.executeBuiltinLine(0, "DumpConfig")); const opened = p.active; const out = p.panes[opened].?.file.?; for ([_][]const u8{ @@ -549,28 +549,106 @@ test "Config prints the startup path and refreshes its one output" { }) |line| try std.testing.expect(std.mem.indexOf(u8, out.content, line) != null); var default_line: [256]u8 = undefined; try std.testing.expect(std.mem.indexOf(u8, out.content, try std.fmt.bufPrint(&default_line, "Shell requested (new panes) {s} (default)\n", .{config.defaultShell()})) != null); - try std.testing.expectEqualStrings(config.config_buffer, std.fs.path.basename(out.path)); - try std.testing.expectEqual(panes.Output.Origin{ .cmd = .Config }, out.output.?.from); + try std.testing.expectEqualStrings(config.dump_config_buffer, std.fs.path.basename(out.path)); + try std.testing.expectEqual(panes.Output.Origin{ .cmd = .DumpConfig }, out.output.?.from); - try std.testing.expect(p.executeBuiltinLine(0, "Config")); + try std.testing.expect(p.executeBuiltinLine(0, "DumpConfig")); try std.testing.expectEqual(opened, p.active); var buffers: usize = 0; for (p.panes) |slot| { const f = (slot orelse continue).file orelse continue; const origin = (f.output orelse continue).from; - buffers += @intFromBool(std.meta.eql(origin, panes.Output.Origin{ .cmd = .Config })); + buffers += @intFromBool(std.meta.eql(origin, panes.Output.Origin{ .cmd = .DumpConfig })); } try std.testing.expectEqual(@as(usize, 1), buffers); } -test "Config reports the absence of a per-user config path" { +test "DumpConfig reports the absence of a per-user config path" { const p = try Pardes.init(std.testing.allocator, .{}); defer p.deinit(); - try std.testing.expect(p.executeBuiltinLine(0, "Config")); + try std.testing.expect(p.executeBuiltinLine(0, "DumpConfig")); const report = p.panes[p.active].?.file.?.content; try std.testing.expect(std.mem.indexOf(u8, report, "no per-user config path") != null); } +/// The file Config names, in a fresh temporary directory: `pardes/init` +/// under it, written with `content` unless that is null. +fn configFixture(tmp: *std.testing.TmpDir, content: ?[]const u8, buf: *[4096]u8) ![]const u8 { + if (content) |text| { + try tmp.dir.createDirPath(std.testing.io, "pardes"); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "pardes/init", .data = text }); + } + const len = try tmp.dir.realPath(std.testing.io, buf); + return std.fmt.bufPrint(buf[len..], "{s}/pardes/init", .{buf[0..len]}) catch unreachable; +} + +test "Config opens the startup file, and a second Config goes back to its pane" { + if (comptime !pardes.hosted) return; + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + var buf: [4096]u8 = undefined; + const path = try configFixture(&tmp, "Theme orchard\n", &buf); + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .startup_config_path = path }); + defer p.deinit(); + const first = p.active; + + try std.testing.expect(p.executeBuiltinLine(first, "Config")); + const opened = p.active; + try std.testing.expect(opened != first); + const f = p.panes[opened].?.file.?; + try std.testing.expectEqualStrings(path, f.path); + try std.testing.expectEqualStrings("Theme orchard\n", f.content); + try std.testing.expect(f.output == null); + + p.active = first; + try std.testing.expect(p.executeBuiltinLine(first, "Config")); + try std.testing.expectEqual(opened, p.active); + var named: usize = 0; + for (p.panes) |slot| if (slot) |pane| if (pane.file) |file| { + named += @intFromBool(std.mem.eql(u8, file.path, path)); + }; + try std.testing.expectEqual(@as(usize, 1), named); +} + +test "Config with no startup file opens a pane of its name, and Save makes its directory" { + if (comptime !pardes.hosted) return; + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + var buf: [4096]u8 = undefined; + const path = try configFixture(&tmp, null, &buf); + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .startup_config_path = path }); + defer p.deinit(); + const first = p.active; + + try std.testing.expect(p.executeBuiltinLine(first, "Config")); + const opened = p.active; + try std.testing.expect(opened != first); + const f = p.panes[opened].?.file.?; + try std.testing.expectEqualStrings(path, f.path); + try std.testing.expectEqualStrings("", f.content); + try std.testing.expect(f.output == null); + + // Again: the same pane, not a second one. + p.active = first; + try std.testing.expect(p.executeBuiltinLine(first, "Config")); + try std.testing.expectEqual(opened, p.active); + + try std.testing.expectError(error.FileNotFound, tmp.dir.statFile(std.testing.io, "pardes", .{})); + // Save's effect, as a host performs it. + try std.testing.expect(p.executeBuiltinLine(opened, "Save")); + p.perform(.{ .save_file = .{ .pane = @intCast(opened) } }); + const made = try tmp.dir.statFile(std.testing.io, "pardes", .{}); + try std.testing.expectEqual(std.Io.File.Kind.directory, made.kind); +} + +test "Config without a configuration directory says so and opens nothing" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const before = p.freeSlot(); + try std.testing.expect(p.executeBuiltinLine(p.active, "Config")); + try std.testing.expectEqual(before, p.freeSlot()); +} + test "EffectCode lists readable virtual sources used by this backend" { if (comptime !builtins.EffectCode.enabled) return; const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); @@ -648,7 +726,7 @@ test "every enabled setting builtin mutates the State Config reports" { } } - try std.testing.expect(p.executeBuiltinLine(p.active, "Config")); + try std.testing.expect(p.executeBuiltinLine(p.active, "DumpConfig")); const report = p.panes[p.active].?.file.?.content; for ([_][]const u8{ "Colors off\n", |
