Merge PR #8806: fix(tests): isolate TUI scrollback tests from terminal multiplexers (@Huang-404-Q)
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { afterEach, beforeEach } from "bun:test";
|
||||
|
||||
/**
|
||||
* Neutralize every terminal-multiplexer signal for the calling test file.
|
||||
*
|
||||
* `isInsideTerminalMultiplexer()` treats `TMUX`, `STY`, `ZELLIJ`,
|
||||
* `HERDR_ENV=1`, the `CMUX_*` markers and a `tmux`/`screen` `TERM` as
|
||||
* authoritative, and `isMultiplexerSession()` then routes rendering down the
|
||||
* path that cannot rebuild scrollback. Tests that assert the destructive
|
||||
* full-paint behavior otherwise fail for anyone running the suite inside tmux,
|
||||
* screen, Zellij or CMUX. Restores whatever was set afterwards.
|
||||
*/
|
||||
export function withoutTerminalMultiplexer(): void {
|
||||
const KEYS = [
|
||||
"TMUX",
|
||||
"STY",
|
||||
"ZELLIJ",
|
||||
"HERDR_ENV",
|
||||
"CMUX_WORKSPACE_ID",
|
||||
"CMUX_SURFACE_ID",
|
||||
"CMUX_REMOTE_TRANSPORT",
|
||||
"TERM",
|
||||
] as const;
|
||||
const previous = new Map<string, string | undefined>();
|
||||
|
||||
beforeEach(() => {
|
||||
for (const key of KEYS) {
|
||||
previous.set(key, Bun.env[key]);
|
||||
delete Bun.env[key];
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
for (const [key, value] of previous) {
|
||||
if (value === undefined) delete Bun.env[key];
|
||||
else Bun.env[key] = value;
|
||||
}
|
||||
previous.clear();
|
||||
});
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { previewWindowRows } from "@oh-my-pi/pi-coding-agent/tools/render-utils"
|
||||
import { TUI, visibleWidth } from "@oh-my-pi/pi-tui";
|
||||
import { removeWithRetries } from "@oh-my-pi/pi-utils";
|
||||
import { VirtualTerminal } from "../../tui/test/virtual-terminal";
|
||||
import { withoutTerminalMultiplexer } from "./helpers/terminal-multiplexer";
|
||||
|
||||
// The streaming edit preview is a fixed-height tail window ("cursor"): the last
|
||||
// EDIT_STREAMING_PREVIEW_LINES rows of the recomputed diff are pinned to the
|
||||
@@ -21,6 +22,8 @@ import { VirtualTerminal } from "../../tui/test/virtual-terminal";
|
||||
// whole change segments grew and shrank tick to tick (the stutter), and the
|
||||
// earlier high-water fix padded the deficit with blank rows (the "large
|
||||
// rectangle that is half empty" regression). The tail window has neither.
|
||||
withoutTerminalMultiplexer();
|
||||
|
||||
describe("streaming edit preview height (stable, full tail window)", () => {
|
||||
const oldBlock = ["function foo() {", " const x = 1;", " return x;", "}"].join("\n");
|
||||
const tail = ["", "function bar() {", " return 2;", "}", "", "function baz() {", " return 3;", "}", ""].join("\n");
|
||||
|
||||
@@ -4,6 +4,7 @@ import { initTheme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
||||
import { type Component, TUI } from "@oh-my-pi/pi-tui";
|
||||
import { StressRenderScheduler } from "../../tui/test/render-stress-scheduler";
|
||||
import { VirtualTerminal } from "../../tui/test/virtual-terminal";
|
||||
import { withoutTerminalMultiplexer } from "./helpers/terminal-multiplexer";
|
||||
|
||||
function writeArgs(lineCount: number) {
|
||||
return {
|
||||
@@ -31,6 +32,8 @@ function plainBuffer(term: VirtualTerminal): string[] {
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
withoutTerminalMultiplexer();
|
||||
|
||||
describe("ToolExecutionComponent write repaint seam", () => {
|
||||
const components: ToolExecutionComponent[] = [];
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import {
|
||||
type Component,
|
||||
Container,
|
||||
@@ -10,20 +10,12 @@ import {
|
||||
type NativeScrollbackReplay,
|
||||
TUI,
|
||||
} from "@oh-my-pi/pi-tui";
|
||||
import { withoutTerminalMultiplexer } from "./helpers/terminal-multiplexer";
|
||||
import { StressRenderScheduler } from "./render-stress-scheduler";
|
||||
import { defaultEditorTheme } from "./test-themes";
|
||||
import { VirtualTerminal } from "./virtual-terminal";
|
||||
|
||||
const ORIGINAL_HERDR_ENV = Bun.env.HERDR_ENV;
|
||||
|
||||
beforeEach(() => {
|
||||
delete Bun.env.HERDR_ENV;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
if (ORIGINAL_HERDR_ENV === undefined) delete Bun.env.HERDR_ENV;
|
||||
else Bun.env.HERDR_ENV = ORIGINAL_HERDR_ENV;
|
||||
});
|
||||
withoutTerminalMultiplexer();
|
||||
|
||||
// Behavioral tests for TUI.requestComponentRender: a component whose own
|
||||
// content changed (spinner frame, blink) asks for a component-scoped frame.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { afterEach, beforeEach } from "bun:test";
|
||||
|
||||
/**
|
||||
* Neutralize every terminal-multiplexer signal for the calling test file.
|
||||
*
|
||||
* `isInsideTerminalMultiplexer()` treats `TMUX`, `STY`, `ZELLIJ`,
|
||||
* `HERDR_ENV=1`, the `CMUX_*` markers and a `tmux`/`screen` `TERM` as
|
||||
* authoritative, and `isMultiplexerSession()` then routes rendering down the
|
||||
* path that cannot rebuild scrollback. Tests that assert the destructive
|
||||
* full-paint behavior otherwise fail for anyone running the suite inside tmux,
|
||||
* screen, Zellij or CMUX. Restores whatever was set afterwards.
|
||||
*/
|
||||
export function withoutTerminalMultiplexer(): void {
|
||||
const KEYS = [
|
||||
"TMUX",
|
||||
"STY",
|
||||
"ZELLIJ",
|
||||
"HERDR_ENV",
|
||||
"CMUX_WORKSPACE_ID",
|
||||
"CMUX_SURFACE_ID",
|
||||
"CMUX_REMOTE_TRANSPORT",
|
||||
"TERM",
|
||||
] as const;
|
||||
const previous = new Map<string, string | undefined>();
|
||||
|
||||
beforeEach(() => {
|
||||
for (const key of KEYS) {
|
||||
previous.set(key, Bun.env[key]);
|
||||
delete Bun.env[key];
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
for (const [key, value] of previous) {
|
||||
if (value === undefined) delete Bun.env[key];
|
||||
else Bun.env[key] = value;
|
||||
}
|
||||
previous.clear();
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "bun:test";
|
||||
import { type Component, CURSOR_MARKER, type Focusable, type OverlayFocusOwner, TUI } from "@oh-my-pi/pi-tui";
|
||||
import { withoutTerminalMultiplexer } from "./helpers/terminal-multiplexer";
|
||||
import { VirtualTerminal } from "./virtual-terminal";
|
||||
|
||||
class LineComponent implements Component {
|
||||
@@ -167,6 +168,8 @@ async function settleResize(term: VirtualTerminal): Promise<void> {
|
||||
await flushRender(term);
|
||||
}
|
||||
|
||||
withoutTerminalMultiplexer();
|
||||
|
||||
describe("TUI overlays", () => {
|
||||
let savedTerminalEnv: Record<string, string | undefined> = {};
|
||||
beforeEach(() => {
|
||||
|
||||
Reference in New Issue
Block a user