summaryrefslogtreecommitdiff
path: root/src/ninep/ctl.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-29 07:05:46 -0300
committerGabriel Schneider <[email protected]>2026-10-01 00:12:16 -0300
commit1b513045336b3c7381c447ffa8c9167f8b1a5a0a (patch)
treebf9377e7178f367c3ad0b35446f4aa9eaf9600d2 /src/ninep/ctl.zig
parent96383331f09e8af3fa24f767b3c56863309723b8 (diff)
downloadpardes-1b513045336b3c7381c447ffa8c9167f8b1a5a0a.tar.gz
pardes-1b513045336b3c7381c447ffa8c9167f8b1a5a0a.zip
A builtin's Verbose announcement is logged only when it succeeds
A failure said while it ran (Exit's refusal, a Del refused) or later by the host (a Save's write, a Dump's) left `msg N Save` in the log as if it had worked. The announcement's record is remembered and taken back out on either, unless a follower read it already. A refused pane/new logs its err alone, and a failed Dump says its reason in words (`file not found`, not `FileNotFound`) so its msg goes and the err is the one record. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src/ninep/ctl.zig')
-rw-r--r--src/ninep/ctl.zig32
1 files changed, 31 insertions, 1 deletions
diff --git a/src/ninep/ctl.zig b/src/ninep/ctl.zig
index de63c6aa..b6fefa01 100644
--- a/src/ninep/ctl.zig
+++ b/src/ninep/ctl.zig
@@ -1486,6 +1486,36 @@ test "look and exec read back what the last command touched, a ctl write's too"
try testing.expectEqualStrings("", rd(p, @intFromEnum(tree.TopFile.look), 0, 64).bytes);
}
+test "a builtin's Verbose announcement is logged only when it succeeds, its failure said now or by the host later" {
+ const gpa = testing.allocator;
+ const p = try withFile(gpa, "x\n");
+ defer p.deinit();
+ const serial = serialOf(p);
+ var want: [64]u8 = undefined;
+ const said_exit = try std.fmt.bufPrint(&want, "msg {d} Exit\n", .{serial});
+ // Refused as it runs, through a click: the write fails, and no Exit.
+ const f = &p.panes[0].?.file.?;
+ f.saved_revision = f.revision -% 1;
+ f.saved_hash = 0;
+ try testing.expect(wr(p, Node.of(serial, .exec), "Exit\n").errno() != 0);
+ try testing.expect(!th.logHas(p, said_exit));
+ // Refused at the keyboard (no write to fail), edited since: the same.
+ f.revision +%= 1;
+ _ = p.executeBuiltinLine(p.active, "Exit");
+ try testing.expect(!th.logHas(p, said_exit));
+ try testing.expect(!p.quit);
+ // A Save the host could not do, told a step later: the Save goes too.
+ var save_buf: [64]u8 = undefined;
+ const said_save = try std.fmt.bufPrint(&save_buf, "msg {d} Save\n", .{serial});
+ _ = wr(p, Node.of(serial, .exec), "Save\n");
+ p.saveFailed(@intCast(p.paneBySerial(serial).?), "/test.txt", error.AccessDenied);
+ try testing.expect(!th.logHas(p, said_save));
+ // One that does what it says keeps its announcement.
+ _ = wr(p, Node.of(serial, .exec), "Undo\n");
+ var undo_buf: [64]u8 = undefined;
+ try testing.expect(th.logHas(p, try std.fmt.bufPrint(&undo_buf, "msg {d} Undo", .{serial})));
+}
+
test "an error's words give the errno a mount reads: EINVAL for what is malformed, EIO for what failed" {
// 9ns (cloud9's 9ns/src/nine.zig) maps an error to an errno by its
// words, and EIO when none of them match: these words must not.
@@ -1574,7 +1604,7 @@ test "a Restore of a file that is no dump fails the write before any warning, an
p.fs.late_failure_len = 0;
p.dumpFailed("/nowhere/pardes.dump.zon", error.FileNotFound);
- try testing.expectEqualStrings("Dump /nowhere/pardes.dump.zon: FileNotFound", p.fs.late_failure[0..p.fs.late_failure_len]);
+ try testing.expectEqualStrings("Dump /nowhere/pardes.dump.zon: file not found", p.fs.late_failure[0..p.fs.late_failure_len]);
}
test "a setting this frontend cannot show says GUI-only, and DumpDir reads back the directory in effect" {