summaryrefslogtreecommitdiff
path: root/test/output.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 22:59:43 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:17 -0300
commit6d148bb9c433814835935ead30020e43781b7f03 (patch)
tree49e42dbbbff64119ead447598a896a69e638e061 /test/output.zig
parentb1485c97b493f7eaf65c6afdfb82e3065306b8fe (diff)
parentd4960472375ea68f709c56a677d8a37571419ff7 (diff)
downloadpardes-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.zig98
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",