diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/panes.zig | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/test/panes.zig b/test/panes.zig index a7e59923..a452bcfb 100644 --- a/test/panes.zig +++ b/test/panes.zig @@ -12,6 +12,184 @@ const image = pardes.image; const syntax = pardes.syntax; const filesystem = pardes.filesystem; +const TagNavigationTests = struct { + fn key(p: *Pardes, cp: u21) void { + p.update(.{ .key = .{ .cp = cp } }); + } + + fn enterNormal(p: *Pardes) *Pane { + key(p, ':'); + return p.panes[p.active].?; + } + + test "tag navigation retains each pane cursor and mouse placement overrides memory" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 20 }); + defer p.deinit(); + const first = try p.setTestFile("body\n"); + p.presentation.enabled = false; + try std.testing.expect(p.executeBuiltinLine(0, "New")); + const second_id = p.active; + const second = p.panes[second_id].?; + try std.testing.expect(layout.splitColumn(p, second_id, second_id, false)); + p.update(.tick); + p.active = 0; + key(p, ':'); + key(p, Key.home); + for (0..3) |_| key(p, Key.right); + const first_col = first.tag_col; + key(p, Key.escape); + p.active = second_id; + key(p, ':'); + key(p, Key.home); + for (0..5) |_| key(p, Key.right); + const second_col = second.tag_col; + key(p, Key.escape); + p.active = 0; + key(p, ':'); + try std.testing.expectEqual(first_col, first.tag_col); + key(p, Key.escape); + p.active = second_id; + key(p, ':'); + try std.testing.expectEqual(second_col, second.tag_col); + key(p, Key.escape); + var frame = std.heap.ArenaAllocator.init(p.gpa); + defer frame.deinit(); + _ = try p.render(frame.allocator()); + const rect = p.rects[0]; + const y = if (p.settings.tag_bottom) rect.y + rect.h - pardes.BOX_H else rect.y; + ClickCursorTests.click(p, .left, rect.x + config.GUTTER + 6, y); + try std.testing.expectEqual(@as(usize, 0), p.active); + try std.testing.expectEqual(@as(u16, 6), first.tag_col); + key(p, Key.escape); + p.startPrompt(first, .{ .search = config.search_marker }); + key(p, Key.escape); + key(p, ':'); + try std.testing.expectEqual(@as(u16, 6), first.tag_col); + key(p, Key.escape); + try std.testing.expectEqualStrings("body\n", first.file.?.content); + } + + test "tag navigation clamps remembered columns to renamed graphemes and shorter tags" { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 14 }); + defer p.deinit(); + const pane = try p.setTestFile("body\n"); + key(p, ':'); + key(p, Key.home); + for (0..3) |_| key(p, Key.right); + key(p, Key.escape); + p.gpa.free(pane.file.?.path); + pane.file.?.path = try p.gpa.dupe(u8, "/界.zig"); + key(p, ':'); + try std.testing.expectEqual(@as(u16, 1), pane.tag_col); + key(p, Key.end); + key(p, Key.escape); + p.gpa.free(pane.file.?.path); + pane.file.?.path = try p.gpa.dupe(u8, "/é"); + pane.tag_tail_len = 0; + key(p, ':'); + try std.testing.expectEqual(@as(u16, 3), pane.tag_col); + try std.testing.expectEqualStrings("body\n", pane.file.?.content); + } + + test "tag navigation J and K restore cursors in stacked panes" { + for ([_]bool{ false, true }) |bottom| { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 80, .rows = 24 }); + defer p.deinit(); + const first = try p.setTestFile("body\n"); + p.presentation.enabled = false; + p.settings.tag_bottom = bottom; + try std.testing.expect(p.executeBuiltinLine(0, "New")); + const second_id = p.active; + const second = p.panes[second_id].?; + p.update(.tick); + p.active = 0; + _ = enterNormal(p); + key(p, Key.home); + key(p, 'l'); + key(p, 'l'); + key(p, 'J'); + try std.testing.expectEqual(second_id, p.active); + try std.testing.expect(!first.tag_edit and second.tag_edit); + key(p, Key.home); + for (0..4) |_| key(p, 'l'); + key(p, 'K'); + try std.testing.expectEqual(@as(usize, 0), p.active); + try std.testing.expectEqual(@as(u16, 2), first.tag_col); + key(p, 'J'); + try std.testing.expectEqual(second_id, p.active); + try std.testing.expectEqual(@as(u16, 4), second.tag_col); + } + } + + test "tag navigation uses uppercase pane and header keys while lowercase stays local" { + for ([_]bool{ false, true }) |bottom| { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 100, .rows = 20 }); + defer p.deinit(); + _ = try p.setTestFile("body\n"); + p.presentation.enabled = false; + p.settings.tag_bottom = bottom; + p.settings.column_tags = true; + try std.testing.expect(p.executeBuiltinLine(0, "New")); + const right = p.active; + try std.testing.expect(layout.splitColumn(p, right, right, false)); + p.update(.tick); + p.active = 0; + const pane = enterNormal(p); + key(p, Key.home); + key(p, 'l'); + try std.testing.expectEqual(@as(u16, 1), pane.tag_col); + key(p, 'h'); + key(p, 'k'); + try std.testing.expectEqual(@as(u16, 0), pane.tag_col); + try std.testing.expectEqual(@as(usize, 0), p.active); + try std.testing.expect(pane.tag_edit and p.topbar_col == null); + key(p, 'L'); + try std.testing.expectEqual(right, p.active); + try std.testing.expect(!pane.tag_edit and p.panes[right].?.tag_edit); + key(p, 'H'); + try std.testing.expectEqual(@as(usize, 0), p.active); + key(p, 'K'); + try std.testing.expect(p.topbar_col != null and p.header_column != null); + try std.testing.expect(!pane.tag_edit); + key(p, 'l'); + const column_cursor = p.topbar_col.?; + key(p, 'K'); + try std.testing.expect(p.topbar_col != null and p.header_column == null); + key(p, 'l'); + key(p, 'l'); + const workspace_cursor = p.topbar_col.?; + key(p, 'J'); + try std.testing.expect(p.topbar_col != null and p.header_column != null); + try std.testing.expectEqual(column_cursor, p.topbar_col.?); + key(p, 'K'); + try std.testing.expectEqual(workspace_cursor, p.topbar_col.?); + key(p, 'J'); + key(p, 'J'); + try std.testing.expect(p.topbar_col == null and pane.tag_edit); + key(p, 'j'); + try std.testing.expect(!pane.tag_edit and p.topbar_col == null); + try std.testing.expectEqual(@as(usize, 0), p.active); + _ = enterNormal(p); + key(p, 'K'); + key(p, 'j'); + try std.testing.expect(p.topbar_col == null and !pane.tag_edit); + key(p, ':'); + key(p, 'i'); + key(p, Key.end); + const before = pane.tag_tail_len; + try std.testing.expect(pane.tag_edit and pane.mode == .insert); + for ("hjklHJKL") |letter| { + const text = [_]u8{letter}; + p.update(.{ .key = .{ .cp = letter, .text = &text } }); + try std.testing.expect(pane.tag_edit and pane.mode == .insert); + } + try std.testing.expectEqualStrings("hjklHJKL", pane.tag_tail[before..pane.tag_tail_len]); + try std.testing.expect(pane.tag_edit and pane.mode == .insert and p.topbar_col == null); + try std.testing.expectEqual(@as(usize, 0), p.active); + } + } +}; + const TreeContextTests = struct { const source = "const Box = struct {\n" ++ " pub fn work(\n" ++ @@ -3375,6 +3553,7 @@ const TerminalTests = struct { }; test { + _ = TagNavigationTests; _ = TagNameTintTests; _ = TreeContextTests; _ = TtySelectionTests; |
