summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/panes.zig154
-rw-r--r--test/pdf.zig4
-rw-r--r--test/snapshots/find.golden1
-rw-r--r--test/snapshots/find.snap3
-rw-r--r--test/snapshots/tagbottomshort.golden2
-rw-r--r--test/snapshots/tagbottomshort.snap9
6 files changed, 45 insertions, 128 deletions
diff --git a/test/panes.zig b/test/panes.zig
index 4c969ab5..f1adafee 100644
--- a/test/panes.zig
+++ b/test/panes.zig
@@ -1353,8 +1353,9 @@ test "paste into pane commands and prompts never inserts into the body" {
try std.testing.expect(std.mem.endsWith(u8, pane.tagSlice(), " CustomCommand"));
p.update(.{ .key = .{ .cp = Key.escape } });
p.startPrompt(pane, .{ .search = config.search_marker });
- p.update(.{ .paste = "two" });
- try std.testing.expect(std.mem.endsWith(u8, pane.tagSlice(), "two"));
+ p.update(.{ .paste = "t\r\nwo" });
+ try std.testing.expectEqualStrings(config.search_marker ++ "two", pane.promptText().?);
+ try std.testing.expect(std.mem.endsWith(u8, pane.tagSlice(), " CustomCommand"));
try std.testing.expectEqualStrings("one two one\n", pane.file.?.content);
p.update(.{ .key = .{ .cp = Key.escape } });
try std.testing.expect(std.mem.endsWith(u8, pane.tagSlice(), " CustomCommand"));
@@ -1646,7 +1647,7 @@ test "terminal eviction and lower-region scrolling in one read preserve a surviv
try std.testing.expectEqualStrings("kept edit", pane.ovl.?.text);
}
-test "tag prompt entry and cancellation preserve exact text and cursor state" {
+test "a prompt's entry and cancellation leave the tag, the body and its cursor as they were" {
const Case = struct { key: ?Key = null, save: bool = false, marker: []const u8 };
const cases = [_]Case{
.{ .marker = config.search_marker },
@@ -1665,8 +1666,6 @@ test "tag prompt entry and cancellation preserve exact text and cursor state" {
@memcpy(pane.tag_tail[0..tail.len], tail);
pane.tag_tail_len = tail.len;
pane.tag_init = true;
- pane.tag_sel = true;
- pane.tag_col = 1;
pane.body.cur_row = 1;
pane.body.cur_col = 2;
pane.body.cur_pinned = true;
@@ -1677,16 +1676,16 @@ test "tag prompt entry and cancellation preserve exact text and cursor state" {
} else {
p.startPrompt(pane, .{ .search = config.search_marker });
}
- try std.testing.expect(pane.tag_edit);
- try std.testing.expect(!pane.tag_sel);
- try std.testing.expectEqual(.insert, pane.body.mode);
+ // The answer is typed into the prompt's own line, never the tag.
+ try std.testing.expect(!pane.tag_edit);
+ try std.testing.expectEqual(.insert, pane.input.mode);
+ try std.testing.expectEqualStrings(case.marker, pane.promptText().?);
+ try std.testing.expectEqual(@as(i32, @intCast(case.marker.len)), pane.input.cur_col);
+ try std.testing.expectEqualStrings(tail, pane.tag_tail[0..pane.tag_tail_len]);
try std.testing.expectEqualDeep(modal.Normal.State{}, pane.body.normal);
- try std.testing.expectEqualStrings(tail, pane.tag_tail[0..tail.len]);
- try std.testing.expectEqualStrings(case.marker, pane.tag_tail[tail.len..pane.tag_tail_len]);
- try std.testing.expectEqual(pane.file.?.path.len + pane.tag_tail_len, pane.tag_col);
p.update(.{ .key = .{ .cp = Key.escape } });
try std.testing.expect(pane.prompt == .none);
- try std.testing.expect(!pane.tag_edit);
+ try std.testing.expect(pane.input.own == null);
try std.testing.expectEqual(.normal, pane.body.mode);
try std.testing.expectEqualStrings(tail, pane.tag_tail[0..pane.tag_tail_len]);
try std.testing.expectEqual(@as(i32, 1), pane.body.cur_row);
@@ -1695,28 +1694,23 @@ test "tag prompt entry and cancellation preserve exact text and cursor state" {
}
}
-test "tag prompt capacity refusal leaves the existing tail and input state untouched" {
+test "a prompt opens whatever the tag already holds" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one\n");
@memset(&pane.tag_tail, 'x');
- pane.tag_tail_len = pane.tag_tail.len - 1;
+ pane.tag_tail_len = pane.tag_tail.len;
pane.tag_init = true;
- pane.tag_col = 17;
- pane.tag_sel = true;
for (0..3) |case| {
switch (case) {
0 => p.startPrompt(pane, .{ .search = config.search_marker }),
1 => p.startPrompt(pane, .save),
else => p.update(.{ .key = .{ .cp = '|' } }),
}
- try std.testing.expect(pane.prompt == .none);
- try std.testing.expect(!pane.tag_edit);
- try std.testing.expect(pane.tag_sel);
- try std.testing.expectEqual(.normal, pane.body.mode);
- try std.testing.expectEqual(@as(u16, 17), pane.tag_col);
- try std.testing.expectEqual(pane.tag_tail.len - 1, pane.tag_tail_len);
+ try std.testing.expect(pane.prompt != .none);
+ try std.testing.expectEqual(pane.tag_tail.len, pane.tag_tail_len);
for (pane.tag_tail) |byte| try std.testing.expectEqual(@as(u8, 'x'), byte);
+ p.update(.{ .key = .{ .cp = Key.escape } });
}
}
@@ -1735,7 +1729,7 @@ test "generated output refuses every pipe prompt before seeding the tag" {
}
}
-test "tag prompt owns the pipe behavior through cancellation and submission" {
+test "a prompt owns the pipe behavior through cancellation and submission" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one\ntwo\n");
@@ -1746,7 +1740,7 @@ test "tag prompt owns the pipe behavior through cancellation and submission" {
p.startPrompt(pane, .{ .pipe = .append });
p.update(.{ .key = .{ .cp = Key.escape } });
p.startPrompt(pane, .{ .pipe = how });
- try std.testing.expectEqual(how, pane.prompt.pipe.how);
+ try std.testing.expectEqual(how, pane.prompt.pipe);
p.update(.{ .key = .{ .cp = 'c', .text = "cat" } });
p.update(.{ .key = .{ .cp = Key.enter } });
const pending = p.pipe.wait orelse return error.MissingPipe;
@@ -1758,7 +1752,7 @@ test "tag prompt owns the pipe behavior through cancellation and submission" {
}
}
-test "tag prompt cancellation restores the selection before regex previews" {
+test "prompt cancellation restores the selection before regex previews" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one two one");
@@ -1786,133 +1780,57 @@ test "tag prompt cancellation restores the selection before regex previews" {
}
}
-test "tag prompt prefix allocation failure preserves an already seeded prompt" {
+test "a prompt that cannot be opened leaves the open one as it was" {
const Request = @typeInfo(@TypeOf(Pardes.startPrompt)).@"fn".params[2].type.?;
for ([_]Request{ .{ .search = config.search_marker }, .save, .{ .pipe = .replace }, .{ .pipe = .ignore }, .{ .pipe = .insert }, .{ .pipe = .append } }) |request| {
var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{});
const p = try Pardes.init(failing.allocator(), .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one\n");
- const tail = " keep /prior";
- @memcpy(pane.tag_tail[0..tail.len], tail);
- pane.tag_tail_len = tail.len;
- pane.tag_init = true;
- pane.prompt = .{ .search = 5 };
- pane.tag_edit = true;
- pane.tag_sel = true;
- pane.tag_col = 14;
- pane.tag_anchor = 7;
+ p.startPrompt(pane, .{ .search = config.search_marker });
+ p.update(.{ .key = .{ .cp = 'p', .text = "prior" } });
pane.body.normal = .{ .count = 9, .prefix = .goto };
- const previous_prompt = pane.prompt;
const previous_normal = pane.body.normal;
_ = p.scratch.reset(.free_all);
failing.fail_index = failing.alloc_index;
p.startPrompt(pane, request);
try std.testing.expect(failing.has_induced_failure);
- try std.testing.expectEqualDeep(previous_prompt, pane.prompt);
+ try std.testing.expect(pane.prompt == .search);
+ try std.testing.expectEqualStrings(config.search_marker ++ "prior", pane.promptText().?);
try std.testing.expectEqualDeep(previous_normal, pane.body.normal);
- try std.testing.expectEqualStrings(tail, pane.tag_tail[0..pane.tag_tail_len]);
- try std.testing.expect(pane.tag_edit and pane.tag_sel);
- try std.testing.expectEqual(.normal, pane.body.mode);
- try std.testing.expectEqual(@as(u16, 14), pane.tag_col);
- try std.testing.expectEqual(@as(u16, 7), pane.tag_anchor);
+ try std.testing.expect(!pane.tag_init and !pane.tag_edit);
}
}
-test "tag prompt Save requires room for its complete directory prefix" {
+test "Save's prompt starts from the pane's directory" {
const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one\n");
for ([_][]const u8{ "/dír space", "/dír space/", "" }) |dir| {
try pane.setOwnedCwd(dir);
- const slash: usize = @intFromBool(dir.len == 0 or dir[dir.len - 1] != '/');
- const needed = config.save_marker.len + dir.len + slash;
- for ([_]usize{ 1, 0 }) |shortfall| {
- @memset(&pane.tag_tail, 'x');
- pane.tag_tail_len = pane.tag_tail.len - needed + shortfall;
- pane.tag_init = true;
- pane.tag_edit = false;
- pane.tag_sel = true;
- pane.tag_col = 17;
- const start = pane.tag_tail_len;
- p.startPrompt(pane, .save);
- if (shortfall != 0) {
- try std.testing.expect(pane.prompt == .none);
- try std.testing.expectEqual(start, pane.tag_tail_len);
- try std.testing.expect(!pane.tag_edit and pane.tag_sel);
- try std.testing.expectEqual(@as(u16, 17), pane.tag_col);
- for (pane.tag_tail) |byte| try std.testing.expectEqual(@as(u8, 'x'), byte);
- } else {
- try std.testing.expect(pane.prompt == .save);
- try std.testing.expectEqual(pane.tag_tail.len, pane.tag_tail_len);
- try std.testing.expectEqualStrings(config.save_marker, pane.tag_tail[start..][0..config.save_marker.len]);
- try std.testing.expectEqualStrings(dir, pane.tag_tail[start + config.save_marker.len ..][0..dir.len]);
- try std.testing.expectEqual(@as(u8, '/'), pane.tag_tail[pane.tag_tail_len - 1]);
- p.update(.{ .key = .{ .cp = Key.escape } });
- }
- }
+ const slash = if (dir.len == 0 or dir[dir.len - 1] != '/') "/" else "";
+ p.startPrompt(pane, .save);
+ try std.testing.expect(pane.prompt == .save);
+ const answer = pane.promptText().?;
+ try std.testing.expect(std.mem.startsWith(u8, answer, config.save_marker));
+ try std.testing.expectEqualStrings(dir, answer[config.save_marker.len..][0..dir.len]);
+ try std.testing.expectEqualStrings(slash, answer[config.save_marker.len + dir.len ..]);
+ p.update(.{ .key = .{ .cp = Key.escape } });
}
}
-test "tag prompt successful seeded entry needs one scratch allocation" {
+test "a prompt opens with one allocation" {
const Request = @typeInfo(@TypeOf(Pardes.startPrompt)).@"fn".params[2].type.?;
for ([_]Request{ .{ .search = config.search_marker }, .save, .{ .pipe = .replace }, .{ .pipe = .ignore }, .{ .pipe = .insert }, .{ .pipe = .append } }) |request| {
var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{});
const p = try Pardes.init(failing.allocator(), .{ .tty_only = true });
defer p.deinit();
const pane = try p.setTestFile("one\n");
- pane.tag_tail_len = 0;
- pane.tag_init = true;
_ = p.scratch.reset(.free_all);
const before = failing.alloc_index;
p.startPrompt(pane, request);
try std.testing.expectEqual(before + 1, failing.alloc_index);
- try std.testing.expect(pane.tag_edit and pane.body.mode == .insert);
- }
-}
-
-test "tag prompt failure may initialize only the default tail" {
- const Request = @typeInfo(@TypeOf(Pardes.startPrompt)).@"fn".params[2].type.?;
- for ([_]Request{ .{ .search = config.search_marker }, .save, .{ .pipe = .replace }, .{ .pipe = .ignore }, .{ .pipe = .insert }, .{ .pipe = .append } }) |request| {
- var saw_seeded_failure = false;
- var succeeded = false;
- for (0..16) |failure| {
- var failing = std.testing.FailingAllocator.init(std.testing.allocator, .{});
- const p = try Pardes.init(failing.allocator(), .{ .tty_only = true });
- defer p.deinit();
- const pane = try p.setTestFile("one\n");
- const path = try p.gpa.dupe(u8, "/" ++ "a" ** 2048 ++ ".zig");
- p.gpa.free(pane.file.?.path);
- pane.file.?.path = path;
- p.seedTail(pane);
- try std.testing.expect(pane.tag_init);
- const default_tail = pane.tag_tail;
- const default_len = pane.tag_tail_len;
- pane.tag_init = false;
- pane.tag_tail_len = 0;
- pane.tag_col = 17;
- pane.tag_sel = true;
- pane.body.normal = .{ .count = 9, .prefix = .goto };
- const previous_normal = pane.body.normal;
- _ = p.scratch.reset(.free_all);
- failing.fail_index = failing.alloc_index + failure;
- p.startPrompt(pane, request);
- if (!failing.has_induced_failure) {
- try std.testing.expect(pane.tag_edit and pane.body.mode == .insert);
- succeeded = true;
- break;
- }
- try std.testing.expect(pane.prompt == .none);
- try std.testing.expect(!pane.tag_edit and pane.tag_sel);
- try std.testing.expectEqual(.normal, pane.body.mode);
- try std.testing.expectEqualDeep(previous_normal, pane.body.normal);
- try std.testing.expectEqual(@as(u16, 17), pane.tag_col);
- if (pane.tag_init) {
- saw_seeded_failure = true;
- try std.testing.expectEqualStrings(default_tail[0..default_len], pane.tag_tail[0..pane.tag_tail_len]);
- } else try std.testing.expectEqual(@as(usize, 0), pane.tag_tail_len);
- }
- try std.testing.expect(succeeded and saw_seeded_failure);
+ try std.testing.expect(!pane.tag_edit and pane.input.mode == .insert);
}
}
diff --git a/test/pdf.zig b/test/pdf.zig
index 52fb62aa..5bc271d4 100644
--- a/test/pdf.zig
+++ b/test/pdf.zig
@@ -1113,9 +1113,9 @@ test "PDF normal adapter consumes unsupported actions and navigates page fallbac
p.update(.{ .key = .{ .cp = '!' } });
try std.testing.expect(!p.leader_on);
p.update(.{ .key = .{ .cp = '/' } });
- try std.testing.expect(pane.tag_edit);
+ try std.testing.expect(pane.prompt == .search and !pane.tag_edit);
p.update(.{ .key = .{ .cp = Key.escape } });
- try std.testing.expect(!pane.tag_edit);
+ try std.testing.expect(pane.prompt == .none);
}
test "Escape cancels PDF chrome in place and Shift-Escape leaves the pane" {
diff --git a/test/snapshots/find.golden b/test/snapshots/find.golden
index 12dac242..b6b7b322 100644
--- a/test/snapshots/find.golden
+++ b/test/snapshots/find.golden
@@ -81,7 +81,6 @@
|4:
|30: 1 gamma body Last
== snap nomatch grid=120x41 cursor=7,39
-|2: /tmp/pardes-snap/find/cwd/here.txt Save Tty Collapse Del Find /
|3: 1 Find
|18: /tmp/pardes-snap/find/cwd/+Search Save Tty Collapse Del
|19: 1
diff --git a/test/snapshots/find.snap b/test/snapshots/find.snap
index fbd585f7..fe1ecad3 100644
--- a/test/snapshots/find.snap
+++ b/test/snapshots/find.snap
@@ -64,7 +64,8 @@ key enter
stable 700 15000
snap back
# executing the WORD Find (middle-click in a body) arms the same input — the
-# enum IS the dispatch — and Esc abandons it, restoring the tag tail
+# enum IS the dispatch — and Esc abandons it. The input is its own line, so an
+# abandoned one leaves nothing behind in the tag
press middle 8 4
release middle 8 4
stable 700 10000
diff --git a/test/snapshots/tagbottomshort.golden b/test/snapshots/tagbottomshort.golden
index a5d53fe2..c11fe4ac 100644
--- a/test/snapshots/tagbottomshort.golden
+++ b/test/snapshots/tagbottomshort.golden
@@ -21,7 +21,7 @@
| New Tty Find Grep Joincol Delcol
| 1 one /ZZ
| /tmp/pardes-snap/tagbottomshort/cwd/s.txt Save Tty Collapse Del
-== snap tag-only grid=80x2 cursor=70,1
+== snap tag-only grid=80x2 cursor=79,1
|Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor Debug Kill
| /tmp/pardes-snap/tagbottomshort/cwd/s.txt Save Tty Collapse Del
== snap regrown grid=80x11 cursor=79,2
diff --git a/test/snapshots/tagbottomshort.snap b/test/snapshots/tagbottomshort.snap
index 2574df36..58da6a87 100644
--- a/test/snapshots/tagbottomshort.snap
+++ b/test/snapshots/tagbottomshort.snap
@@ -10,8 +10,8 @@ wait 8000 s.txt
stable 700 20000
key space t b
stable 700 15000
-# `/` with room to spare: the prompt is cut off the tagline (grid 9) and drawn
-# on grid 8, the last body row, with the cursor.
+# `/` with room to spare: the prompt is its own line, drawn on grid 8, the last
+# body row, with the cursor; the tagline (grid 9) never holds any of it.
key /
send ZZ
stable 600 8000
@@ -27,9 +27,8 @@ resize 4 80
stable 700 10000
snap one-body
# the tagline alone. No body row, so nothing of the prompt is drawn anywhere —
-# not over the tag, not on the row above the pane. The tagline itself is
-# untouched: the marker sits after the builtins, so cutting the tail there
-# leaves every column of it exactly as `tag-only` would look unarmed.
+# not over the tag, not on the row above the pane, and its caret with it. The
+# tagline itself is untouched, exactly as `tag-only` would look unarmed.
resize 2 80
stable 700 10000
snap tag-only