summaryrefslogtreecommitdiff
path: root/tests.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-07-02 18:10:28 -0300
committerGabriel Schneider <[email protected]>2026-08-01 15:02:07 -0300
commit62ef1882ab7878210f05f06504796849e412c318 (patch)
tree5c29cf9b3ef36bf09eb17469ecc7cc1c4246a583 /tests.zig
parentd9e394f92f0f2b91af2212ff0fef9e93dd9d42b1 (diff)
downloadpardes-62ef1882ab7878210f05f06504796849e412c318.tar.gz
pardes-62ef1882ab7878210f05f06504796849e412c318.zip
added middle+left mouse chord
Diffstat (limited to 'tests.zig')
-rw-r--r--tests.zig112
1 files changed, 104 insertions, 8 deletions
diff --git a/tests.zig b/tests.zig
index eb3ccf79..701b153a 100644
--- a/tests.zig
+++ b/tests.zig
@@ -275,7 +275,7 @@ pub fn main(init: std.process.Init) !void {
try hs.send("rm -rf /tmp/pardesE2E; mkdir -p /tmp/pardesE2E/ZZUNIQDIR; clear; echo /tmp/pardesE2E\r");
try hs.pump(2000); // let it run + settle
try hs.send("\x1b[<2;5;3M\x1b[<2;5;3m"); // right-click the path (+1 row: global tagbar)
- try hs.expectWaitFor("ZZUNIQDIR", 12000, "right-click on a directory did not open+ls it");
+ try hs.expectWaitFor("ZZUNIQDIR", 20000, "right-click on a directory did not open+ls it");
// 8. Right-click a "path:line" opens a line-numbered FILE pane SCROLLED to
// that line. Build a tall file whose deep marker (line 150) is only
@@ -299,7 +299,7 @@ pub fn main(init: std.process.Init) !void {
try hs.send("/tmp/pardesE2Efile.txt:150");
try hs.pump(800); // build the run
try hs.send("\x1b[<2;70;19M\x1b[<2;70;19m"); // right-click on the typed path (+1 row: global tagbar)
- try hs.expectWaitFor("ZZDEEPMARK", 12000, "right-click 'path:150' did not open the file scrolled to line 150");
+ try hs.expectWaitFor("ZZDEEPMARK", 20000, "right-click 'path:150' did not open the file scrolled to line 150");
try hs.expectContains("Save Del", "file pane tag did not include the default Save command");
try hs.expectNotContains("Delcol", "Delcol is still shown in the default pane tag");
@@ -401,7 +401,7 @@ pub fn main(init: std.process.Init) !void {
try hs_save.send("\x1b"); // -> normal
try hs_save.pump(400);
try hs_save.send("\x1b[<2;70;20M\x1b[<2;70;20m"); // right-click the path -> open file
- try hs_save.expectWaitFor("ZZORIG_SAVE_SHOULD_DISAPPEAR", 12000, "save regression file did not open");
+ try hs_save.expectWaitFor("ZZORIG_SAVE_SHOULD_DISAPPEAR", 20000, "save regression file did not open");
try hs_save.send("x"); // select the original line
try hs_save.pump(300);
try hs_save.send("c"); // clear it and enter insert
@@ -573,7 +573,7 @@ pub fn main(init: std.process.Init) !void {
try hs5.send("\x1b"); // -> normal
try hs5.pump(400);
try hs5.send("\x1b[<2;10;8M\x1b[<2;10;8m"); // right-click the typed path -> open image pane
- try hs5.expectWaitFor("Petscii", 10000, "right-click on an image path did not open an image pane with the Petscii toggle");
+ try hs5.expectWaitFor("Petscii", 16000, "right-click on an image path did not open an image pane with the Petscii toggle");
try hs5.pump(800); // let the petscii grid render across frames
// the diagonal split renders as real block glyphs — assert the full block
// shows (a blank body here would mean the grid didn't blit, e.g. a dangling
@@ -605,7 +605,7 @@ pub fn main(init: std.process.Init) !void {
try hs6.send("\x1b"); // -> normal
try hs6.pump(400);
try hs6.send("\x1b[<2;70;20M\x1b[<2;70;20m"); // right-click the path -> open file A
- try hs6.expectWaitFor("ZZFILEA", 12000, "right-click did not open file A");
+ try hs6.expectWaitFor("ZZFILEA", 20000, "right-click did not open file A");
// open file B likewise: a doc pane now exists, so B SPLITS it (lands below A).
try hs6.send("\x1b[<0;60;22M\x1b[<0;60;22m"); // pin another blank row, right column
try hs6.pump(400);
@@ -616,7 +616,7 @@ pub fn main(init: std.process.Init) !void {
try hs6.send("\x1b");
try hs6.pump(400);
try hs6.send("\x1b[<2;70;22M\x1b[<2;70;22m"); // right-click the path -> open file B
- try hs6.expectWaitFor("ZZFILEB", 12000, "right-click did not open file B");
+ try hs6.expectWaitFor("ZZFILEB", 20000, "right-click did not open file B");
// both markers sit on each file's TOP line (scroll 0). The split puts B
// under A -> A's row < B's row. Stack-at-top would invert this.
const text = try hs6.screenText();
@@ -644,7 +644,7 @@ pub fn main(init: std.process.Init) !void {
try hs7.pump(700);
// add a 3rd column via the global-tagbar "Newcol" (cols 5-10, 0-based).
try hs7.send("\x1b[<1;8;1M\x1b[<1;8;1m"); // middle-click "Newcol"
- try hs7.pump(1600); // let the new shell come up
+ try hs7.pump(2500); // let the new shell come up
// mark the rightmost column (now the active pane) with a unique token.
try hs7.send("\x02"); // normal -> tty
try hs7.pump(500);
@@ -653,7 +653,7 @@ pub fn main(init: std.process.Init) !void {
// split the token so it appears ONLY in the OUTPUT (at the pane's left edge),
// never in the command text — else colOf would match the prompt-relative echo.
try hs7.send("echo ZZFAR''COL\r");
- try hs7.expectWaitFor("ZZFARCOL", 8000, "new column's shell did not echo the marker");
+ try hs7.expectWaitFor("ZZFARCOL", 12000, "new column's shell did not echo the marker");
const before = try hs7.screenText();
const x1 = colOf(before, "ZZFARCOL") orelse {
gpa.free(before);
@@ -720,4 +720,100 @@ pub fn main(init: std.process.Init) !void {
try hs9.send("stty -icanon -echo min 1 time 0; printf '\\033[?u\\033[c'; read -r -d c -t 3 _r && printf 'ZZDA''OK\\n'; stty sane\r");
try hs9.expectWaitFor("ZZDAOK", 8000, "app blocked on its ESC[c device-attributes probe — pardes never answered primary DA (helix hangs on a blank pane)");
}
+
+ // 20. KEPT LEFT SELECTION + MIDDLE+LEFT CHORD. A left-drag selection now PERSISTS
+ // after release (it clears only on a plain left click or a new left drag). The
+ // middle+left chord: press middle (on a command word), press left BEFORE
+ // releasing middle -> the KEPT left selection's text is passed as the command's
+ // argument. Here a script echoes CHORDARG:"$1"; left-select ZZCHORDARG, then
+ // chord the script -> output "CHORDARG:ZZCHORDARG" only if the kept selection
+ // fed the arg. Top-left pane body row 0 = SGR row 3; body col 0 = SGR col 3.
+ {
+ var hsc = try Harness.init(gpa, exe.ptr, 24, 80);
+ defer hsc.deinit();
+ try hsc.expectWaitFor("build.zig", 8000, "chord test: fresh terminal never auto-ls'd");
+ try h.writeFile("/tmp/pardesE2Echord.sh", "#!/bin/sh\necho CHORDARG:\"$1\"\n");
+ try hsc.send("\x02"); // normal -> tty
+ try hsc.pump(500);
+ try hsc.send("chmod +x /tmp/pardesE2Echord.sh; clear; printf 'ZZCHORDARG\\n/tmp/pardesE2Echord.sh\\n'\r");
+ try hsc.expectWaitFor("/tmp/pardesE2Echord.sh", 8000, "chord test: command path not rendered");
+ // left-drag-select "ZZCHORDARG" (10 chars, body cols 0-9 = SGR cols 3-12) on
+ // body row 0 (SGR row 3) -> kept (.done) after release.
+ try hsc.send("\x1b[<0;3;3M\x1b[<32;12;3M\x1b[<0;12;3m");
+ try hsc.pump(400);
+ // middle+left chord: middle-press on the script path (body row 1 = SGR row 4),
+ // left-press (captures the kept selection as the arg), middle-release (runs it).
+ try hsc.send("\x1b[<1;8;4M\x1b[<0;8;4M\x1b[<1;8;4m");
+ try hsc.expectWaitFor("CHORDARG:ZZCHORDARG", 8000, "middle+left chord did not pass the kept left selection as the command argument");
+ }
+
+ // 21. A plain LEFT CLICK (no drag) clears the kept left selection, so a later
+ // middle+left chord passes NO argument. Left-select ZZCLRARG, left-click a
+ // blank cell (clears), then chord the script -> output "CHORDARG:" (empty),
+ // with no ZZCLRARG after it.
+ {
+ var hscl = try Harness.init(gpa, exe.ptr, 24, 80);
+ defer hscl.deinit();
+ try hscl.expectWaitFor("build.zig", 8000, "clear test: fresh terminal never auto-ls'd");
+ try h.writeFile("/tmp/pardesE2Echord.sh", "#!/bin/sh\necho CHORDARG:\"$1\"\n");
+ try hscl.send("\x02");
+ try hscl.pump(500);
+ try hscl.send("chmod +x /tmp/pardesE2Echord.sh; clear; printf 'ZZCLRARG\\n/tmp/pardesE2Echord.sh\\n'\r");
+ try hscl.expectWaitFor("/tmp/pardesE2Echord.sh", 8000, "clear test: command path not rendered");
+ // left-drag-select "ZZCLRARG" (8 chars, body cols 0-7 = SGR cols 3-10) -> kept.
+ try hscl.send("\x1b[<0;3;3M\x1b[<32;10;3M\x1b[<0;10;3m");
+ try hscl.pump(400);
+ // plain left click on a blank row (body row 3 = SGR row 6), no drag -> clears.
+ try hscl.send("\x1b[<0;3;6M\x1b[<0;3;6m");
+ try hscl.pump(400);
+ // chord the script; the kept selection is gone -> no arg -> "CHORDARG:" (empty).
+ try hscl.send("\x1b[<1;8;4M\x1b[<0;8;4M\x1b[<1;8;4m");
+ try hscl.pump(900);
+ try hscl.expectContains("CHORDARG:", "clear test: chord did not run the script");
+ try hscl.expectNotContains("CHORDARG:ZZCLRARG", "a plain left click did not clear the kept left selection (chord still passed it)");
+ }
+
+ // 22. A NEW left drag REPLACES the previous kept left selection. Left-select
+ // ZZTXTONE, then left-select ZZTXTTWO (replaces), then chord the script ->
+ // output "CHORDARG:ZZTXTTWO" (the NEW selection), NOT "CHORDARG:ZZTXTONE".
+ {
+ var hsr = try Harness.init(gpa, exe.ptr, 24, 80);
+ defer hsr.deinit();
+ try hsr.expectWaitFor("build.zig", 8000, "replace test: fresh terminal never auto-ls'd");
+ try h.writeFile("/tmp/pardesE2Echord.sh", "#!/bin/sh\necho CHORDARG:\"$1\"\n");
+ try hsr.send("\x02");
+ try hsr.pump(500);
+ try hsr.send("chmod +x /tmp/pardesE2Echord.sh; clear; printf 'ZZTXTONE\\nZZTXTTWO\\n/tmp/pardesE2Echord.sh\\n'\r");
+ try hsr.expectWaitFor("/tmp/pardesE2Echord.sh", 8000, "replace test: command path not rendered");
+ // left-drag-select "ZZTXTONE" on body row 0 (SGR row 3; 8 chars -> SGR cols 3-10).
+ try hsr.send("\x1b[<0;3;3M\x1b[<32;10;3M\x1b[<0;10;3m");
+ try hsr.pump(400);
+ // left-drag-select "ZZTXTTWO" on body row 1 (SGR row 4) -> REPLACES the kept one.
+ try hsr.send("\x1b[<0;3;4M\x1b[<32;10;4M\x1b[<0;10;4m");
+ try hsr.pump(400);
+ // chord the script on body row 2 (SGR row 5) -> arg is the NEW selection ZZTXTTWO.
+ try hsr.send("\x1b[<1;8;5M\x1b[<0;8;5M\x1b[<1;8;5m");
+ try hsr.expectWaitFor("CHORDARG:ZZTXTTWO", 8000, "a new left drag did not replace the old kept selection (chord used the wrong arg)");
+ try hsr.expectNotContains("CHORDARG:ZZTXTONE", "the old kept selection leaked into the chord arg (not replaced)");
+ }
+
+ // 23. A BUILTIN with a chord arg ignores the arg (each builtin decides; none use
+ // it yet). Left-select some text, then chord middle-click "Debug" in the body
+ // -> the Debug overlay toggles on (arg ignored), so "resizes=" appears.
+ {
+ var hsb = try Harness.init(gpa, exe.ptr, 24, 80);
+ defer hsb.deinit();
+ try hsb.expectWaitFor("build.zig", 8000, "builtin-chord test: fresh terminal never auto-ls'd");
+ try hsb.send("\x02");
+ try hsb.pump(500);
+ try hsb.send("clear; printf 'ZZBUILTARG\\nDebug\\n'\r");
+ try hsb.expectWaitFor("Debug", 8000, "builtin-chord test: 'Debug' word not rendered");
+ // left-select "ZZBUILTARG" (10 chars, SGR cols 3-12) on body row 0 -> kept.
+ try hsb.send("\x1b[<0;3;3M\x1b[<32;12;3M\x1b[<0;12;3m");
+ try hsb.pump(400);
+ // chord middle-click "Debug" on body row 1 (SGR row 4, body col 2 = SGR col 5).
+ try hsb.send("\x1b[<1;5;4M\x1b[<0;5;4M\x1b[<1;5;4m");
+ try hsb.pump(900);
+ try hsb.expectContains("resizes=", "builtin with a chord arg did not toggle (arg broke builtin dispatch)");
+ }
}