diff options
Diffstat (limited to 'test/panes.zig')
| -rw-r--r-- | test/panes.zig | 154 |
1 files changed, 36 insertions, 118 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); } } |
