linecraft 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +313 -64
- package/lib/api/color.d.ts +6 -0
- package/lib/api/color.d.ts.map +1 -0
- package/lib/api/color.js +9 -0
- package/lib/api/color.js.map +1 -0
- package/lib/api/color.test.d.ts +2 -0
- package/lib/api/color.test.d.ts.map +1 -0
- package/lib/api/color.test.js +23 -0
- package/lib/api/color.test.js.map +1 -0
- package/lib/api/flex.d.ts +55 -0
- package/lib/api/flex.d.ts.map +1 -0
- package/lib/api/flex.js +86 -0
- package/lib/api/flex.js.map +1 -0
- package/lib/api/flex.test.d.ts +2 -0
- package/lib/api/flex.test.d.ts.map +1 -0
- package/lib/api/flex.test.js +82 -0
- package/lib/api/flex.test.js.map +1 -0
- package/lib/api/grid.d.ts +22 -0
- package/lib/api/grid.d.ts.map +1 -0
- package/lib/api/grid.js +65 -0
- package/lib/api/grid.js.map +1 -0
- package/lib/api/grid.test.d.ts +2 -0
- package/lib/api/grid.test.d.ts.map +1 -0
- package/lib/api/grid.test.js +48 -0
- package/lib/api/grid.test.js.map +1 -0
- package/lib/components/base.d.ts +53 -0
- package/lib/components/base.d.ts.map +1 -0
- package/lib/components/base.js +47 -0
- package/lib/components/base.js.map +1 -0
- package/lib/components/col.d.ts +35 -0
- package/lib/components/col.d.ts.map +1 -0
- package/lib/components/col.js +168 -0
- package/lib/components/col.js.map +1 -0
- package/lib/components/col.test.d.ts +2 -0
- package/lib/components/col.test.d.ts.map +1 -0
- package/lib/components/col.test.js +96 -0
- package/lib/components/col.test.js.map +1 -0
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/index.js +5 -0
- package/lib/components/index.js.map +1 -0
- package/lib/components/progress-bar-grid.d.ts +20 -0
- package/lib/components/progress-bar-grid.d.ts.map +1 -0
- package/lib/components/progress-bar-grid.js +44 -0
- package/lib/components/progress-bar-grid.js.map +1 -0
- package/lib/components/progress-bar-grid.test.d.ts +2 -0
- package/lib/components/progress-bar-grid.test.d.ts.map +1 -0
- package/lib/components/progress-bar-grid.test.js +101 -0
- package/lib/components/progress-bar-grid.test.js.map +1 -0
- package/lib/components/progress-bar.d.ts +26 -3
- package/lib/components/progress-bar.d.ts.map +1 -1
- package/lib/components/progress-bar.js +62 -6
- package/lib/components/progress-bar.js.map +1 -1
- package/lib/components/progress-bar.test.d.ts +2 -0
- package/lib/components/progress-bar.test.d.ts.map +1 -0
- package/lib/components/progress-bar.test.js +153 -0
- package/lib/components/progress-bar.test.js.map +1 -0
- package/lib/components/prompt.d.ts +14 -0
- package/lib/components/prompt.d.ts.map +1 -0
- package/lib/components/prompt.js +77 -0
- package/lib/components/prompt.js.map +1 -0
- package/lib/components/renderable.d.ts +42 -0
- package/lib/components/renderable.d.ts.map +1 -0
- package/lib/components/renderable.js +225 -0
- package/lib/components/renderable.js.map +1 -0
- package/lib/components/spinner.d.ts +2 -2
- package/lib/components/spinner.d.ts.map +1 -1
- package/lib/components/spinner.js +3 -1
- package/lib/components/spinner.js.map +1 -1
- package/lib/components/spinner.test.d.ts +2 -0
- package/lib/components/spinner.test.d.ts.map +1 -0
- package/lib/components/spinner.test.js +168 -0
- package/lib/components/spinner.test.js.map +1 -0
- package/lib/components/style.d.ts +16 -0
- package/lib/components/style.d.ts.map +1 -0
- package/lib/components/style.js +72 -0
- package/lib/components/style.js.map +1 -0
- package/lib/components/style.test.d.ts +2 -0
- package/lib/components/style.test.d.ts.map +1 -0
- package/lib/components/style.test.js +135 -0
- package/lib/components/style.test.js.map +1 -0
- package/lib/components/text.d.ts +24 -0
- package/lib/components/text.d.ts.map +1 -0
- package/lib/components/text.js +65 -0
- package/lib/components/text.js.map +1 -0
- package/lib/drawing/boxes.d.ts +33 -0
- package/lib/drawing/boxes.d.ts.map +1 -0
- package/lib/drawing/boxes.js +76 -0
- package/lib/drawing/boxes.js.map +1 -0
- package/lib/index.d.ts +18 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +21 -10
- package/lib/index.js.map +1 -1
- package/lib/index.test.d.ts +2 -0
- package/lib/index.test.d.ts.map +1 -0
- package/lib/index.test.js +80 -0
- package/lib/index.test.js.map +1 -0
- package/lib/layout/flex.d.ts +39 -0
- package/lib/layout/flex.d.ts.map +1 -0
- package/lib/layout/flex.js +300 -0
- package/lib/layout/flex.js.map +1 -0
- package/lib/layout/flex.test.d.ts +2 -0
- package/lib/layout/flex.test.d.ts.map +1 -0
- package/lib/layout/flex.test.js +206 -0
- package/lib/layout/flex.test.js.map +1 -0
- package/lib/layout/grid.d.ts +53 -0
- package/lib/layout/grid.d.ts.map +1 -0
- package/lib/layout/grid.js +421 -0
- package/lib/layout/grid.js.map +1 -0
- package/lib/layout/grid.test.d.ts +2 -0
- package/lib/layout/grid.test.d.ts.map +1 -0
- package/lib/layout/grid.test.js +139 -0
- package/lib/layout/grid.test.js.map +1 -0
- package/lib/native/ansi.d.ts +104 -0
- package/lib/native/ansi.d.ts.map +1 -0
- package/lib/native/ansi.js +120 -0
- package/lib/native/ansi.js.map +1 -0
- package/lib/native/ansi.test.d.ts +2 -0
- package/lib/native/ansi.test.d.ts.map +1 -0
- package/lib/native/ansi.test.js +57 -0
- package/lib/native/ansi.test.js.map +1 -0
- package/lib/native/buffer.d.ts +32 -0
- package/lib/native/buffer.d.ts.map +1 -0
- package/lib/native/buffer.js +49 -0
- package/lib/native/buffer.js.map +1 -0
- package/lib/native/buffer.test.d.ts +2 -0
- package/lib/native/buffer.test.d.ts.map +1 -0
- package/lib/native/buffer.test.js +64 -0
- package/lib/native/buffer.test.js.map +1 -0
- package/lib/native/diff.d.ts +20 -0
- package/lib/native/diff.d.ts.map +1 -0
- package/lib/native/diff.js +33 -0
- package/lib/native/diff.js.map +1 -0
- package/lib/native/diff.test.d.ts +2 -0
- package/lib/native/diff.test.d.ts.map +1 -0
- package/lib/native/diff.test.js +106 -0
- package/lib/native/diff.test.js.map +1 -0
- package/lib/native/region-old.d.ts +117 -0
- package/lib/native/region-old.d.ts.map +1 -0
- package/lib/native/region-old.js +539 -0
- package/lib/native/region-old.js.map +1 -0
- package/lib/native/region-renderer.d.ts +167 -0
- package/lib/native/region-renderer.d.ts.map +1 -0
- package/lib/native/region-renderer.js +1238 -0
- package/lib/native/region-renderer.js.map +1 -0
- package/lib/native/region-simple.d.ts +44 -0
- package/lib/native/region-simple.d.ts.map +1 -0
- package/lib/native/region-simple.js +290 -0
- package/lib/native/region-simple.js.map +1 -0
- package/lib/native/region.d.ts +53 -0
- package/lib/native/region.d.ts.map +1 -0
- package/lib/native/region.js +426 -0
- package/lib/native/region.js.map +1 -0
- package/lib/native/region.test.d.ts +2 -0
- package/lib/native/region.test.d.ts.map +1 -0
- package/lib/native/region.test.js +248 -0
- package/lib/native/region.test.js.map +1 -0
- package/lib/native/throttle.d.ts +29 -0
- package/lib/native/throttle.d.ts.map +1 -0
- package/lib/native/throttle.js +57 -0
- package/lib/native/throttle.js.map +1 -0
- package/lib/native/throttle.test.d.ts +2 -0
- package/lib/native/throttle.test.d.ts.map +1 -0
- package/lib/native/throttle.test.js +86 -0
- package/lib/native/throttle.test.js.map +1 -0
- package/lib/native.d.ts +5 -11
- package/lib/native.d.ts.map +1 -1
- package/lib/native.js +8 -64
- package/lib/native.js.map +1 -1
- package/lib/region.d.ts +48 -5
- package/lib/region.d.ts.map +1 -1
- package/lib/region.js +474 -36
- package/lib/region.js.map +1 -1
- package/lib/region.test.d.ts +2 -0
- package/lib/region.test.d.ts.map +1 -0
- package/lib/region.test.js +227 -0
- package/lib/region.test.js.map +1 -0
- package/lib/region.visual.test.d.ts +2 -0
- package/lib/region.visual.test.d.ts.map +1 -0
- package/lib/region.visual.test.js +55 -0
- package/lib/region.visual.test.js.map +1 -0
- package/lib/test-helpers/capturable-terminal.d.ts +61 -0
- package/lib/test-helpers/capturable-terminal.d.ts.map +1 -0
- package/lib/test-helpers/capturable-terminal.js +113 -0
- package/lib/test-helpers/capturable-terminal.js.map +1 -0
- package/lib/test-helpers/capturable-terminal.test.d.ts +2 -0
- package/lib/test-helpers/capturable-terminal.test.d.ts.map +1 -0
- package/lib/test-helpers/capturable-terminal.test.js +45 -0
- package/lib/test-helpers/capturable-terminal.test.js.map +1 -0
- package/lib/test-helpers/mock-region.d.ts +21 -0
- package/lib/test-helpers/mock-region.d.ts.map +1 -0
- package/lib/test-helpers/mock-region.js +37 -0
- package/lib/test-helpers/mock-region.js.map +1 -0
- package/lib/test-helpers/virtual-terminal-diff-reflow.test.d.ts +2 -0
- package/lib/test-helpers/virtual-terminal-diff-reflow.test.d.ts.map +1 -0
- package/lib/test-helpers/virtual-terminal-diff-reflow.test.js +256 -0
- package/lib/test-helpers/virtual-terminal-diff-reflow.test.js.map +1 -0
- package/lib/test-helpers/virtual-terminal-flex-resize.test.d.ts +2 -0
- package/lib/test-helpers/virtual-terminal-flex-resize.test.d.ts.map +1 -0
- package/lib/test-helpers/virtual-terminal-flex-resize.test.js +438 -0
- package/lib/test-helpers/virtual-terminal-flex-resize.test.js.map +1 -0
- package/lib/test-helpers/virtual-terminal.d.ts +176 -0
- package/lib/test-helpers/virtual-terminal.d.ts.map +1 -0
- package/lib/test-helpers/virtual-terminal.js +492 -0
- package/lib/test-helpers/virtual-terminal.js.map +1 -0
- package/lib/test-helpers/virtual-terminal.test.d.ts +2 -0
- package/lib/test-helpers/virtual-terminal.test.d.ts.map +1 -0
- package/lib/test-helpers/virtual-terminal.test.js +219 -0
- package/lib/test-helpers/virtual-terminal.test.js.map +1 -0
- package/lib/ts/components/spinner.test.d.ts +2 -0
- package/lib/ts/components/spinner.test.d.ts.map +1 -0
- package/lib/ts/components/spinner.test.js +168 -0
- package/lib/ts/components/spinner.test.js.map +1 -0
- package/lib/ts/utils/colors.test.d.ts +2 -0
- package/lib/ts/utils/colors.test.d.ts.map +1 -0
- package/lib/ts/utils/colors.test.js +87 -0
- package/lib/ts/utils/colors.test.js.map +1 -0
- package/lib/types.d.ts +8 -2
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js.map +1 -1
- package/lib/utils/colors-simple.d.ts +51 -0
- package/lib/utils/colors-simple.d.ts.map +1 -0
- package/lib/utils/colors-simple.js +59 -0
- package/lib/utils/colors-simple.js.map +1 -0
- package/lib/utils/colors.d.ts +1 -1
- package/lib/utils/colors.d.ts.map +1 -1
- package/lib/utils/colors.js.map +1 -1
- package/lib/utils/colors.test.d.ts +2 -0
- package/lib/utils/colors.test.d.ts.map +1 -0
- package/lib/utils/colors.test.js +87 -0
- package/lib/utils/colors.test.js.map +1 -0
- package/lib/utils/cursor-position.d.ts +22 -0
- package/lib/utils/cursor-position.d.ts.map +1 -0
- package/lib/utils/cursor-position.js +139 -0
- package/lib/utils/cursor-position.js.map +1 -0
- package/lib/utils/debug-log.d.ts +2 -0
- package/lib/utils/debug-log.d.ts.map +1 -0
- package/lib/utils/debug-log.js +36 -0
- package/lib/utils/debug-log.js.map +1 -0
- package/lib/utils/terminal.d.ts +27 -0
- package/lib/utils/terminal.d.ts.map +1 -0
- package/lib/utils/terminal.js +116 -0
- package/lib/utils/terminal.js.map +1 -0
- package/lib/utils/text.d.ts +21 -0
- package/lib/utils/text.d.ts.map +1 -0
- package/lib/utils/text.js +82 -0
- package/lib/utils/text.js.map +1 -0
- package/lib/utils/wait-for-spacebar.d.ts +10 -0
- package/lib/utils/wait-for-spacebar.d.ts.map +1 -0
- package/lib/utils/wait-for-spacebar.js +71 -0
- package/lib/utils/wait-for-spacebar.js.map +1 -0
- package/package.json +31 -28
- package/.cursor/plan.md +0 -952
- package/TESTING.md +0 -102
- package/build.zig +0 -100
- package/examples/basic-progress.ts +0 -21
- package/examples/multi-lane.ts +0 -29
- package/examples/spinner.ts +0 -20
- package/examples/test-basic.ts +0 -23
- package/src/ts/components/progress-bar.ts +0 -53
- package/src/ts/components/spinner.ts +0 -56
- package/src/ts/index.ts +0 -37
- package/src/ts/native.ts +0 -86
- package/src/ts/region.ts +0 -89
- package/src/ts/types/ffi-napi.d.ts +0 -11
- package/src/ts/types/ref-napi.d.ts +0 -5
- package/src/ts/types.ts +0 -53
- package/src/ts/utils/colors.ts +0 -72
- package/src/zig/ansi.zig +0 -21
- package/src/zig/buffer.zig +0 -37
- package/src/zig/diff.zig +0 -43
- package/src/zig/region.zig +0 -292
- package/src/zig/renderer.zig +0 -92
- package/src/zig/test_ansi.zig +0 -66
- package/src/zig/test_buffer.zig +0 -82
- package/src/zig/test_diff.zig +0 -220
- package/src/zig/test_integration.zig +0 -76
- package/src/zig/test_region.zig +0 -191
- package/src/zig/test_runner.zig +0 -27
- package/src/zig/test_throttle.zig +0 -59
- package/src/zig/throttle.zig +0 -38
- package/tsconfig.json +0 -21
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive tests for flex component resize behavior using VirtualTerminal
|
|
3
|
+
*
|
|
4
|
+
* These tests validate:
|
|
5
|
+
* 1. What happens when flex components that fill up the line get resized
|
|
6
|
+
* 2. Whether we can update flex components correctly after they've been reflowed
|
|
7
|
+
* 3. Terminal-like wrapping behavior
|
|
8
|
+
* 4. Flex distribution on resize
|
|
9
|
+
* 5. Edge cases and real-world scenarios
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
12
|
+
import { VirtualTerminal } from './virtual-terminal.js';
|
|
13
|
+
import { flex, col } from '../api/flex.js';
|
|
14
|
+
import { TerminalRegion } from '../region.js';
|
|
15
|
+
describe('VirtualTerminal - Flex Resize Behavior', () => {
|
|
16
|
+
let terminal;
|
|
17
|
+
let region;
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
terminal = new VirtualTerminal({ width: 80, height: 24 });
|
|
20
|
+
const writeStream = terminal.createWriteStream();
|
|
21
|
+
region = new TerminalRegion({
|
|
22
|
+
height: 10,
|
|
23
|
+
stdout: writeStream,
|
|
24
|
+
disableRendering: false, // Actually render to virtual terminal
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('Basic resize behavior', () => {
|
|
28
|
+
it('should update region width when terminal resizes (auto-resize enabled)', () => {
|
|
29
|
+
expect(region.width).toBe(80);
|
|
30
|
+
terminal.simulateResize(40, 24);
|
|
31
|
+
// Region should detect resize and update width
|
|
32
|
+
expect(region.width).toBe(40);
|
|
33
|
+
expect(terminal.width).toBe(40);
|
|
34
|
+
});
|
|
35
|
+
it('should NOT update region width when explicitly set', () => {
|
|
36
|
+
const fixedRegion = new TerminalRegion({
|
|
37
|
+
width: 80, // Explicitly set
|
|
38
|
+
height: 10,
|
|
39
|
+
stdout: terminal.createWriteStream(),
|
|
40
|
+
disableRendering: false,
|
|
41
|
+
});
|
|
42
|
+
expect(fixedRegion.width).toBe(80);
|
|
43
|
+
terminal.simulateResize(40, 24);
|
|
44
|
+
// Width should NOT change (explicitly set)
|
|
45
|
+
expect(fixedRegion.width).toBe(80);
|
|
46
|
+
fixedRegion.destroy();
|
|
47
|
+
});
|
|
48
|
+
it('should render flex layout with correct width after resize', () => {
|
|
49
|
+
// Initial render
|
|
50
|
+
region.set(flex({ gap: 2 }, col({ min: 10, max: 10 }, 'Label:'), col({ flex: 1 }, 'Value')));
|
|
51
|
+
region.flush();
|
|
52
|
+
const initialLine1 = terminal.getLine(1);
|
|
53
|
+
expect(initialLine1).toContain('Label:');
|
|
54
|
+
expect(initialLine1).toContain('Value');
|
|
55
|
+
// Resize narrower
|
|
56
|
+
terminal.simulateResize(40, 24);
|
|
57
|
+
expect(region.width).toBe(40);
|
|
58
|
+
// Re-render with new width
|
|
59
|
+
region.set(flex({ gap: 2 }, col({ min: 10, max: 10 }, 'Label:'), col({ flex: 1 }, 'Value')));
|
|
60
|
+
region.flush();
|
|
61
|
+
// Should still render correctly
|
|
62
|
+
const afterLine1 = terminal.getLine(1);
|
|
63
|
+
expect(afterLine1).toContain('Label:');
|
|
64
|
+
expect(afterLine1).toContain('Value');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('Text wrapping on resize', () => {
|
|
68
|
+
it('should wrap long text when col has wrap overflow', () => {
|
|
69
|
+
const longText = 'This is a very long line of text that should wrap when the terminal is resized. '.repeat(2);
|
|
70
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'wrap' }, longText)));
|
|
71
|
+
region.flush();
|
|
72
|
+
// Initially, should be on multiple lines (if text is long enough)
|
|
73
|
+
const initialLines = terminal.getAllLines();
|
|
74
|
+
const initialNonEmpty = initialLines.filter(line => line.trim().length > 0);
|
|
75
|
+
// Resize narrower
|
|
76
|
+
terminal.simulateResize(30, 24);
|
|
77
|
+
expect(region.width).toBe(30);
|
|
78
|
+
// Re-render
|
|
79
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'wrap' }, longText)));
|
|
80
|
+
region.flush();
|
|
81
|
+
// Should have more lines after resize (narrower = more wrapping)
|
|
82
|
+
const afterLines = terminal.getAllLines();
|
|
83
|
+
const afterNonEmpty = afterLines.filter(line => line.trim().length > 0);
|
|
84
|
+
expect(afterNonEmpty.length).toBeGreaterThanOrEqual(initialNonEmpty.length);
|
|
85
|
+
});
|
|
86
|
+
it('should handle ellipsis when text is too long', () => {
|
|
87
|
+
const longText = 'A'.repeat(100);
|
|
88
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'ellipsis-end', max: 50 }, longText)));
|
|
89
|
+
region.flush();
|
|
90
|
+
const initialLine1 = terminal.getLine(1);
|
|
91
|
+
expect(initialLine1.length).toBeLessThanOrEqual(50);
|
|
92
|
+
expect(initialLine1).toContain('...');
|
|
93
|
+
// Resize narrower
|
|
94
|
+
terminal.simulateResize(30, 24);
|
|
95
|
+
expect(region.width).toBe(30);
|
|
96
|
+
// Re-render
|
|
97
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'ellipsis-end', max: 25 }, longText)));
|
|
98
|
+
region.flush();
|
|
99
|
+
const afterLine1 = terminal.getLine(1);
|
|
100
|
+
expect(afterLine1.length).toBeLessThanOrEqual(25);
|
|
101
|
+
expect(afterLine1).toContain('...');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('Flex distribution on resize', () => {
|
|
105
|
+
it('should redistribute flex columns when terminal resizes', () => {
|
|
106
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Col1'), col({ flex: 1 }, 'Col2'), col({ flex: 1 }, 'Col3')));
|
|
107
|
+
region.flush();
|
|
108
|
+
const initialLine1 = terminal.getLine(1);
|
|
109
|
+
const initialCol1Pos = initialLine1.indexOf('Col1');
|
|
110
|
+
const initialCol2Pos = initialLine1.indexOf('Col2');
|
|
111
|
+
const initialCol3Pos = initialLine1.indexOf('Col3');
|
|
112
|
+
// All should be on same line initially
|
|
113
|
+
expect(initialCol1Pos).toBeGreaterThan(-1);
|
|
114
|
+
expect(initialCol2Pos).toBeGreaterThan(initialCol1Pos);
|
|
115
|
+
expect(initialCol3Pos).toBeGreaterThan(initialCol2Pos);
|
|
116
|
+
// Resize narrower
|
|
117
|
+
terminal.simulateResize(40, 24);
|
|
118
|
+
expect(region.width).toBe(40);
|
|
119
|
+
// Re-render
|
|
120
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Col1'), col({ flex: 1 }, 'Col2'), col({ flex: 1 }, 'Col3')));
|
|
121
|
+
region.flush();
|
|
122
|
+
// Should still be on same line, but positions may have changed
|
|
123
|
+
const afterLine1 = terminal.getLine(1);
|
|
124
|
+
expect(afterLine1).toContain('Col1');
|
|
125
|
+
expect(afterLine1).toContain('Col2');
|
|
126
|
+
expect(afterLine1).toContain('Col3');
|
|
127
|
+
});
|
|
128
|
+
it('should handle proportional flex ratios on resize', () => {
|
|
129
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Small'), col({ flex: 2 }, 'Large')));
|
|
130
|
+
region.flush();
|
|
131
|
+
const initialLine1 = terminal.getLine(1);
|
|
132
|
+
const initialSmallPos = initialLine1.indexOf('Small');
|
|
133
|
+
const initialLargePos = initialLine1.indexOf('Large');
|
|
134
|
+
const initialRatio = (initialLargePos - initialSmallPos) / (initialSmallPos || 1);
|
|
135
|
+
// Resize
|
|
136
|
+
terminal.simulateResize(40, 24);
|
|
137
|
+
expect(region.width).toBe(40);
|
|
138
|
+
// Re-render
|
|
139
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Small'), col({ flex: 2 }, 'Large')));
|
|
140
|
+
region.flush();
|
|
141
|
+
const afterLine1 = terminal.getLine(1);
|
|
142
|
+
const afterSmallPos = afterLine1.indexOf('Small');
|
|
143
|
+
const afterLargePos = afterLine1.indexOf('Large');
|
|
144
|
+
const afterRatio = (afterLargePos - afterSmallPos) / (afterSmallPos || 1);
|
|
145
|
+
// Ratio should be approximately maintained (2:1)
|
|
146
|
+
// Large should take roughly 2x the space of Small
|
|
147
|
+
expect(afterRatio).toBeGreaterThan(1);
|
|
148
|
+
});
|
|
149
|
+
it('should respect min/max constraints on resize', () => {
|
|
150
|
+
region.set(flex({ gap: 2 }, col({ min: 10, max: 20 }, 'Fixed'), col({ flex: 1 }, 'Flexible')));
|
|
151
|
+
region.flush();
|
|
152
|
+
const initialLine1 = terminal.getLine(1);
|
|
153
|
+
expect(initialLine1).toContain('Fixed');
|
|
154
|
+
expect(initialLine1).toContain('Flexible');
|
|
155
|
+
// Resize narrower
|
|
156
|
+
terminal.simulateResize(30, 24);
|
|
157
|
+
expect(region.width).toBe(30);
|
|
158
|
+
// Re-render
|
|
159
|
+
region.set(flex({ gap: 2 }, col({ min: 10, max: 20 }, 'Fixed'), col({ flex: 1 }, 'Flexible')));
|
|
160
|
+
region.flush();
|
|
161
|
+
// Fixed column should still respect min/max
|
|
162
|
+
const afterLine1 = terminal.getLine(1);
|
|
163
|
+
expect(afterLine1).toContain('Fixed');
|
|
164
|
+
expect(afterLine1).toContain('Flexible');
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe('Multiple columns and complex layouts', () => {
|
|
168
|
+
it('should handle multiple flex columns that fill the line on resize', () => {
|
|
169
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Column 1: ' + 'A'.repeat(20)), col({ flex: 1 }, 'Column 2: ' + 'B'.repeat(20)), col({ flex: 1 }, 'Column 3: ' + 'C'.repeat(20))));
|
|
170
|
+
region.flush();
|
|
171
|
+
// Initially, all columns should be on the same line
|
|
172
|
+
const initialLine1 = terminal.getLine(1);
|
|
173
|
+
expect(initialLine1).toContain('Column 1');
|
|
174
|
+
expect(initialLine1).toContain('Column 2');
|
|
175
|
+
expect(initialLine1).toContain('Column 3');
|
|
176
|
+
// Resize terminal to 40 columns (much narrower)
|
|
177
|
+
terminal.simulateResize(40, 24);
|
|
178
|
+
expect(region.width).toBe(40);
|
|
179
|
+
// Re-render with new width
|
|
180
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Column 1: ' + 'A'.repeat(20)), col({ flex: 1 }, 'Column 2: ' + 'B'.repeat(20)), col({ flex: 1 }, 'Column 3: ' + 'C'.repeat(20))));
|
|
181
|
+
region.flush();
|
|
182
|
+
// After resize, columns should still be on same line (flex distributes space)
|
|
183
|
+
// But if content is too long, it might wrap
|
|
184
|
+
const afterLine1 = terminal.getLine(1);
|
|
185
|
+
// Check all lines to see if content wrapped
|
|
186
|
+
const allLines = terminal.getAllLines();
|
|
187
|
+
const allContent = allLines.join(' ');
|
|
188
|
+
// All three columns should still be present somewhere
|
|
189
|
+
expect(allContent).toContain('Column 1');
|
|
190
|
+
expect(allContent).toContain('Column 2');
|
|
191
|
+
expect(allContent).toContain('Column 3');
|
|
192
|
+
});
|
|
193
|
+
it('should handle nested flex layouts on resize', () => {
|
|
194
|
+
region.set(flex({ gap: 2, direction: 'column' }, flex({ gap: 1 }, col({ flex: 1 }, 'Row1-Col1'), col({ flex: 1 }, 'Row1-Col2')), flex({ gap: 1 }, col({ flex: 1 }, 'Row2-Col1'), col({ flex: 1 }, 'Row2-Col2'))));
|
|
195
|
+
region.flush();
|
|
196
|
+
// Should be on multiple lines (column direction)
|
|
197
|
+
const line1 = terminal.getLine(1);
|
|
198
|
+
const line2 = terminal.getLine(2);
|
|
199
|
+
expect(line1).toContain('Row1');
|
|
200
|
+
expect(line2).toContain('Row2');
|
|
201
|
+
// Resize
|
|
202
|
+
terminal.simulateResize(40, 24);
|
|
203
|
+
expect(region.width).toBe(40);
|
|
204
|
+
// Re-render
|
|
205
|
+
region.set(flex({ gap: 2, direction: 'column' }, flex({ gap: 1 }, col({ flex: 1 }, 'Row1-Col1'), col({ flex: 1 }, 'Row1-Col2')), flex({ gap: 1 }, col({ flex: 1 }, 'Row2-Col1'), col({ flex: 1 }, 'Row2-Col2'))));
|
|
206
|
+
region.flush();
|
|
207
|
+
// Should still be on multiple lines
|
|
208
|
+
const afterLine1 = terminal.getLine(1);
|
|
209
|
+
const afterLine2 = terminal.getLine(2);
|
|
210
|
+
expect(afterLine1).toContain('Row1');
|
|
211
|
+
expect(afterLine2).toContain('Row2');
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe('Updating flex components after resize reflow', () => {
|
|
215
|
+
it('should correctly update flex components after they have been reflowed to multiple lines', () => {
|
|
216
|
+
// Initial setup: content that fills the line
|
|
217
|
+
const initialText = 'Initial: ' + 'A'.repeat(50);
|
|
218
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'wrap' }, initialText)));
|
|
219
|
+
region.flush();
|
|
220
|
+
// Resize to narrow terminal
|
|
221
|
+
terminal.simulateResize(30, 24);
|
|
222
|
+
expect(region.width).toBe(30);
|
|
223
|
+
// Re-render (this should cause reflow)
|
|
224
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'wrap' }, initialText)));
|
|
225
|
+
region.flush();
|
|
226
|
+
// Verify content is on multiple lines
|
|
227
|
+
const linesBeforeUpdate = terminal.getAllLines();
|
|
228
|
+
const nonEmptyBefore = linesBeforeUpdate.filter(line => line.trim().length > 0);
|
|
229
|
+
expect(nonEmptyBefore.length).toBeGreaterThan(0);
|
|
230
|
+
// Now update the content
|
|
231
|
+
const updatedText = 'Updated: ' + 'B'.repeat(50);
|
|
232
|
+
region.set(flex({ gap: 0 }, col({ overflow: 'wrap' }, updatedText)));
|
|
233
|
+
region.flush();
|
|
234
|
+
// Verify the update worked correctly
|
|
235
|
+
const linesAfterUpdate = terminal.getAllLines();
|
|
236
|
+
const allContentAfter = linesAfterUpdate.join(' ');
|
|
237
|
+
// Should contain the updated text
|
|
238
|
+
expect(allContentAfter).toContain('Updated');
|
|
239
|
+
expect(allContentAfter).toContain('B');
|
|
240
|
+
// Should not contain old text
|
|
241
|
+
expect(allContentAfter).not.toContain('Initial');
|
|
242
|
+
});
|
|
243
|
+
it('should update multiple flex columns correctly after resize', () => {
|
|
244
|
+
// Setup with multiple columns
|
|
245
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Col1: ' + 'A'.repeat(15)), col({ flex: 1 }, 'Col2: ' + 'B'.repeat(15)), col({ flex: 1 }, 'Col3: ' + 'C'.repeat(15))));
|
|
246
|
+
region.flush();
|
|
247
|
+
// Resize narrower
|
|
248
|
+
terminal.simulateResize(40, 24);
|
|
249
|
+
expect(region.width).toBe(40);
|
|
250
|
+
// Re-render
|
|
251
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Col1: ' + 'A'.repeat(15)), col({ flex: 1 }, 'Col2: ' + 'B'.repeat(15)), col({ flex: 1 }, 'Col3: ' + 'C'.repeat(15))));
|
|
252
|
+
region.flush();
|
|
253
|
+
// Update all columns
|
|
254
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'New1: ' + 'X'.repeat(15)), col({ flex: 1 }, 'New2: ' + 'Y'.repeat(15)), col({ flex: 1 }, 'New3: ' + 'Z'.repeat(15))));
|
|
255
|
+
region.flush();
|
|
256
|
+
// Verify all updates are present
|
|
257
|
+
const allLines = terminal.getAllLines();
|
|
258
|
+
const allContent = allLines.join(' ');
|
|
259
|
+
expect(allContent).toContain('New1');
|
|
260
|
+
expect(allContent).toContain('New2');
|
|
261
|
+
expect(allContent).toContain('New3');
|
|
262
|
+
expect(allContent).toContain('X');
|
|
263
|
+
expect(allContent).toContain('Y');
|
|
264
|
+
expect(allContent).toContain('Z');
|
|
265
|
+
// Old content should be gone
|
|
266
|
+
expect(allContent).not.toContain('Col1');
|
|
267
|
+
expect(allContent).not.toContain('Col2');
|
|
268
|
+
expect(allContent).not.toContain('Col3');
|
|
269
|
+
});
|
|
270
|
+
it('should handle progressive updates after resize (simulating real-time updates)', () => {
|
|
271
|
+
// Start with narrow terminal
|
|
272
|
+
terminal.simulateResize(30, 24);
|
|
273
|
+
expect(region.width).toBe(30);
|
|
274
|
+
// Initial render
|
|
275
|
+
let progress = 0;
|
|
276
|
+
region.set(flex({ gap: 2 }, col({ min: 10, max: 10 }, 'Progress:'), col({ flex: 1 }, `${progress}%`)));
|
|
277
|
+
region.flush();
|
|
278
|
+
// Simulate multiple updates (like a progress bar)
|
|
279
|
+
for (let i = 1; i <= 5; i++) {
|
|
280
|
+
progress = i * 20;
|
|
281
|
+
region.set(flex({ gap: 2 }, col({ min: 10, max: 10 }, 'Progress:'), col({ flex: 1 }, `${progress}%`)));
|
|
282
|
+
region.flush();
|
|
283
|
+
// Verify each update
|
|
284
|
+
const allLines = terminal.getAllLines();
|
|
285
|
+
const allContent = allLines.join(' ');
|
|
286
|
+
expect(allContent).toContain(`${progress}%`);
|
|
287
|
+
}
|
|
288
|
+
// Final state should show 100%
|
|
289
|
+
const finalLines = terminal.getAllLines();
|
|
290
|
+
const finalContent = finalLines.join(' ');
|
|
291
|
+
expect(finalContent).toContain('100%');
|
|
292
|
+
});
|
|
293
|
+
it('should correctly clear and re-render flex layout after resize', () => {
|
|
294
|
+
// Initial content
|
|
295
|
+
region.set(flex({ gap: 0 }, col({}, 'Initial content that is quite long and should wrap')));
|
|
296
|
+
region.flush();
|
|
297
|
+
// Resize
|
|
298
|
+
terminal.simulateResize(20, 24);
|
|
299
|
+
expect(region.width).toBe(20);
|
|
300
|
+
// Clear the region
|
|
301
|
+
region.set(''); // Clear
|
|
302
|
+
region.flush();
|
|
303
|
+
// Re-render with new content
|
|
304
|
+
region.set(flex({ gap: 0 }, col({}, 'New content after clear and resize')));
|
|
305
|
+
region.flush();
|
|
306
|
+
// Verify new content is present
|
|
307
|
+
const allLines = terminal.getAllLines();
|
|
308
|
+
const allContent = allLines.join(' ');
|
|
309
|
+
expect(allContent).toContain('New content');
|
|
310
|
+
expect(allContent).not.toContain('Initial content');
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
describe('Edge cases and stress tests', () => {
|
|
314
|
+
it('should handle rapid resize events', () => {
|
|
315
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Content')));
|
|
316
|
+
region.flush();
|
|
317
|
+
// Rapid resize
|
|
318
|
+
terminal.simulateResize(40, 24);
|
|
319
|
+
expect(region.width).toBe(40);
|
|
320
|
+
terminal.simulateResize(60, 24);
|
|
321
|
+
expect(region.width).toBe(60);
|
|
322
|
+
terminal.simulateResize(20, 24);
|
|
323
|
+
expect(region.width).toBe(20);
|
|
324
|
+
// Should still render correctly
|
|
325
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Content')));
|
|
326
|
+
region.flush();
|
|
327
|
+
const line1 = terminal.getLine(1);
|
|
328
|
+
expect(line1).toContain('Content');
|
|
329
|
+
});
|
|
330
|
+
it('should handle resize to very narrow terminal', () => {
|
|
331
|
+
region.set(flex({ gap: 1 }, col({ min: 5 }, 'Label'), col({ flex: 1 }, 'Value')));
|
|
332
|
+
region.flush();
|
|
333
|
+
// Resize to very narrow
|
|
334
|
+
terminal.simulateResize(10, 24);
|
|
335
|
+
expect(region.width).toBe(10);
|
|
336
|
+
// Re-render
|
|
337
|
+
region.set(flex({ gap: 1 }, col({ min: 5 }, 'Label'), col({ flex: 1 }, 'Value')));
|
|
338
|
+
region.flush();
|
|
339
|
+
// Should still work (may wrap or truncate)
|
|
340
|
+
const allLines = terminal.getAllLines();
|
|
341
|
+
const allContent = allLines.join(' ');
|
|
342
|
+
expect(allContent).toContain('Label');
|
|
343
|
+
});
|
|
344
|
+
it('should handle resize to very wide terminal', () => {
|
|
345
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Col1'), col({ flex: 1 }, 'Col2')));
|
|
346
|
+
region.flush();
|
|
347
|
+
// Resize to very wide
|
|
348
|
+
terminal.simulateResize(200, 24);
|
|
349
|
+
expect(region.width).toBe(200);
|
|
350
|
+
// Re-render
|
|
351
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, 'Col1'), col({ flex: 1 }, 'Col2')));
|
|
352
|
+
region.flush();
|
|
353
|
+
// Should still work
|
|
354
|
+
const line1 = terminal.getLine(1);
|
|
355
|
+
expect(line1).toContain('Col1');
|
|
356
|
+
expect(line1).toContain('Col2');
|
|
357
|
+
});
|
|
358
|
+
it('should handle empty columns on resize', () => {
|
|
359
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, ''), col({ flex: 1 }, 'Content'), col({ flex: 1 }, '')));
|
|
360
|
+
region.flush();
|
|
361
|
+
terminal.simulateResize(40, 24);
|
|
362
|
+
expect(region.width).toBe(40);
|
|
363
|
+
// Re-render
|
|
364
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, ''), col({ flex: 1 }, 'Content'), col({ flex: 1 }, '')));
|
|
365
|
+
region.flush();
|
|
366
|
+
const line1 = terminal.getLine(1);
|
|
367
|
+
expect(line1).toContain('Content');
|
|
368
|
+
});
|
|
369
|
+
it('should handle columns with only spaces on resize', () => {
|
|
370
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, ' '), col({ flex: 1 }, 'Content')));
|
|
371
|
+
region.flush();
|
|
372
|
+
terminal.simulateResize(40, 24);
|
|
373
|
+
expect(region.width).toBe(40);
|
|
374
|
+
// Re-render
|
|
375
|
+
region.set(flex({ gap: 2 }, col({ flex: 1 }, ' '), col({ flex: 1 }, 'Content')));
|
|
376
|
+
region.flush();
|
|
377
|
+
const line1 = terminal.getLine(1);
|
|
378
|
+
expect(line1).toContain('Content');
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
describe('Real terminal-like behavior validation', () => {
|
|
382
|
+
it('should demonstrate that characters wrap to next line when terminal resizes', () => {
|
|
383
|
+
// Create a single long line of text
|
|
384
|
+
const longLine = 'This is a very long line of text that should wrap when the terminal is resized to be narrower than its original width. '.repeat(2);
|
|
385
|
+
// Set initial width to 80
|
|
386
|
+
terminal = new VirtualTerminal({ width: 80, height: 24 });
|
|
387
|
+
const writeStream = terminal.createWriteStream();
|
|
388
|
+
region = new TerminalRegion({
|
|
389
|
+
height: 10,
|
|
390
|
+
stdout: writeStream,
|
|
391
|
+
disableRendering: false,
|
|
392
|
+
});
|
|
393
|
+
// Write the long line directly (bypassing flex for this test)
|
|
394
|
+
region.setLine(1, longLine);
|
|
395
|
+
region.flush();
|
|
396
|
+
// Check initial state
|
|
397
|
+
const initialLine1 = terminal.getLine(1);
|
|
398
|
+
expect(initialLine1.length).toBeGreaterThan(0);
|
|
399
|
+
// Now resize to 40 columns
|
|
400
|
+
terminal.simulateResize(40, 24);
|
|
401
|
+
expect(region.width).toBe(40);
|
|
402
|
+
// The virtual terminal should have reflowed the content
|
|
403
|
+
// Read all lines to see where characters went
|
|
404
|
+
const allLines = terminal.getAllLines();
|
|
405
|
+
const nonEmptyLines = allLines.filter(line => line.trim().length > 0);
|
|
406
|
+
// With a narrower terminal, content should be on more lines
|
|
407
|
+
// (This tests the virtual terminal's resize reflow behavior)
|
|
408
|
+
expect(nonEmptyLines.length).toBeGreaterThan(0);
|
|
409
|
+
// All content should still be present
|
|
410
|
+
const allContent = allLines.join(' ');
|
|
411
|
+
expect(allContent.length).toBeGreaterThan(0);
|
|
412
|
+
});
|
|
413
|
+
it('should show terminal-like behavior: content wraps, then updates correctly', () => {
|
|
414
|
+
// Simulate a real scenario: progress bar that updates while terminal resizes
|
|
415
|
+
terminal.simulateResize(60, 24);
|
|
416
|
+
expect(region.width).toBe(60);
|
|
417
|
+
// Initial render
|
|
418
|
+
region.set(flex({ gap: 2 }, col({ min: 12, max: 12 }, 'Downloading'), col({ flex: 1 }, '50%')));
|
|
419
|
+
region.flush();
|
|
420
|
+
const initialLine1 = terminal.getLine(1);
|
|
421
|
+
expect(initialLine1).toContain('Downloading');
|
|
422
|
+
expect(initialLine1).toContain('50%');
|
|
423
|
+
// Resize narrower (simulating user resizing terminal)
|
|
424
|
+
terminal.simulateResize(30, 24);
|
|
425
|
+
expect(region.width).toBe(30);
|
|
426
|
+
// Update progress
|
|
427
|
+
region.set(flex({ gap: 2 }, col({ min: 12, max: 12 }, 'Downloading'), col({ flex: 1 }, '75%')));
|
|
428
|
+
region.flush();
|
|
429
|
+
// Should still show correctly
|
|
430
|
+
const allLines = terminal.getAllLines();
|
|
431
|
+
const allContent = allLines.join(' ');
|
|
432
|
+
expect(allContent).toContain('Downloading');
|
|
433
|
+
expect(allContent).toContain('75%');
|
|
434
|
+
expect(allContent).not.toContain('50%');
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
//# sourceMappingURL=virtual-terminal-flex-resize.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual-terminal-flex-resize.test.js","sourceRoot":"","sources":["../../src/ts/test-helpers/virtual-terminal-flex-resize.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virtual Terminal for Testing
|
|
3
|
+
*
|
|
4
|
+
* A complete terminal simulator that:
|
|
5
|
+
* - Implements TerminalRegion interface (drop-in replacement for tests)
|
|
6
|
+
* - Tracks character positions in a 2D grid
|
|
7
|
+
* - Handles ANSI escape codes (colors, cursor movement)
|
|
8
|
+
* - Simulates text wrapping when width changes
|
|
9
|
+
* - Allows resizing to test flex layouts and reflow
|
|
10
|
+
* - Emits resize events that native TerminalRegion can listen to
|
|
11
|
+
* - Provides readback of actual displayed content
|
|
12
|
+
*
|
|
13
|
+
* Use this instead of CapturableTerminal for comprehensive testing of:
|
|
14
|
+
* - Resize behavior
|
|
15
|
+
* - Text wrapping
|
|
16
|
+
* - Flex layout calculations
|
|
17
|
+
* - ANSI code handling
|
|
18
|
+
*/
|
|
19
|
+
import { EventEmitter } from 'events';
|
|
20
|
+
export interface TerminalCell {
|
|
21
|
+
char: string;
|
|
22
|
+
fgColor?: string;
|
|
23
|
+
bgColor?: string;
|
|
24
|
+
bold?: boolean;
|
|
25
|
+
italic?: boolean;
|
|
26
|
+
underline?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface VirtualTerminalOptions {
|
|
29
|
+
width?: number;
|
|
30
|
+
height?: number;
|
|
31
|
+
autoWrap?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A virtual terminal that simulates real terminal behavior for testing
|
|
35
|
+
* Has the same API as TerminalRegion so it can be used as a drop-in replacement
|
|
36
|
+
*/
|
|
37
|
+
export declare class VirtualTerminal extends EventEmitter {
|
|
38
|
+
private grid;
|
|
39
|
+
private autoWrap;
|
|
40
|
+
private cursorX;
|
|
41
|
+
private cursorY;
|
|
42
|
+
private currentStyle;
|
|
43
|
+
private writeHistory;
|
|
44
|
+
private setLineCalls;
|
|
45
|
+
private _width;
|
|
46
|
+
private _height;
|
|
47
|
+
private writeStream;
|
|
48
|
+
constructor(options?: VirtualTerminalOptions);
|
|
49
|
+
get width(): number;
|
|
50
|
+
get height(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Set a line (1-based line numbers) - implements TerminalRegion interface
|
|
53
|
+
* This simulates what happens when col.render() calls setLine
|
|
54
|
+
*
|
|
55
|
+
* Note: col.render() already handles merging at the x position, so setLine
|
|
56
|
+
* receives the final merged line content. We just need to store it.
|
|
57
|
+
*/
|
|
58
|
+
setLine(lineNumber: number, content: string | {
|
|
59
|
+
text: string;
|
|
60
|
+
style?: any;
|
|
61
|
+
}): void;
|
|
62
|
+
/**
|
|
63
|
+
* Get a line (1-based line numbers) - implements TerminalRegion interface
|
|
64
|
+
* Returns the actual content that would be displayed
|
|
65
|
+
*/
|
|
66
|
+
getLine(lineNumber: number): string;
|
|
67
|
+
/**
|
|
68
|
+
* Clear a line (1-based)
|
|
69
|
+
*/
|
|
70
|
+
clearLine(lineNumber: number): void;
|
|
71
|
+
/**
|
|
72
|
+
* Set entire content (multiple lines)
|
|
73
|
+
*/
|
|
74
|
+
set(content: string | Array<{
|
|
75
|
+
text: string;
|
|
76
|
+
style?: any;
|
|
77
|
+
}> | any): void;
|
|
78
|
+
/**
|
|
79
|
+
* Flush - no-op for simulator
|
|
80
|
+
*/
|
|
81
|
+
flush(): void;
|
|
82
|
+
/**
|
|
83
|
+
* Set throttle - no-op for simulator
|
|
84
|
+
*/
|
|
85
|
+
setThrottle(fps: number): void;
|
|
86
|
+
/**
|
|
87
|
+
* Destroy - clears simulator
|
|
88
|
+
*/
|
|
89
|
+
destroy(clearFirst?: boolean): void;
|
|
90
|
+
/**
|
|
91
|
+
* Get width (for TerminalRegion interface)
|
|
92
|
+
*/
|
|
93
|
+
getWidth(): number;
|
|
94
|
+
/**
|
|
95
|
+
* Get height (for TerminalRegion interface)
|
|
96
|
+
*/
|
|
97
|
+
getHeight(): number;
|
|
98
|
+
/**
|
|
99
|
+
* Resize the terminal - this simulates what happens when a terminal is resized
|
|
100
|
+
* Text that no longer fits will wrap or be truncated
|
|
101
|
+
*
|
|
102
|
+
* This method reflows existing content and emits a 'resize' event
|
|
103
|
+
* that native TerminalRegion can listen to (via process.stdout.on('resize'))
|
|
104
|
+
*/
|
|
105
|
+
resize(newWidth: number, newHeight: number): void;
|
|
106
|
+
/**
|
|
107
|
+
* Expand terminal height
|
|
108
|
+
*/
|
|
109
|
+
private expandTo;
|
|
110
|
+
/**
|
|
111
|
+
* Write data to the terminal (simulating stdout.write)
|
|
112
|
+
* Handles ANSI escape codes and updates the grid
|
|
113
|
+
*/
|
|
114
|
+
private write;
|
|
115
|
+
/**
|
|
116
|
+
* Handle ANSI escape codes
|
|
117
|
+
*/
|
|
118
|
+
private handleAnsiCode;
|
|
119
|
+
/**
|
|
120
|
+
* Apply ANSI escape code to current style
|
|
121
|
+
*/
|
|
122
|
+
private applyAnsiCode;
|
|
123
|
+
/**
|
|
124
|
+
* Get the character at a specific position
|
|
125
|
+
*/
|
|
126
|
+
getCell(x: number, y: number): TerminalCell | null;
|
|
127
|
+
/**
|
|
128
|
+
* Get a line as a string (strips ANSI for plain text, or includes ANSI)
|
|
129
|
+
* Returns only the actual content, trimming trailing spaces
|
|
130
|
+
*/
|
|
131
|
+
private getLineAt;
|
|
132
|
+
/**
|
|
133
|
+
* Get all lines as an array
|
|
134
|
+
*/
|
|
135
|
+
getAllLines(includeAnsi?: boolean): string[];
|
|
136
|
+
/**
|
|
137
|
+
* Get a snapshot of the terminal as a string
|
|
138
|
+
*/
|
|
139
|
+
snapshot(includeAnsi?: boolean): string;
|
|
140
|
+
/**
|
|
141
|
+
* Clear the terminal
|
|
142
|
+
*/
|
|
143
|
+
clear(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Get write history (for debugging)
|
|
146
|
+
*/
|
|
147
|
+
getWriteHistory(): Array<{
|
|
148
|
+
data: string;
|
|
149
|
+
timestamp: number;
|
|
150
|
+
}>;
|
|
151
|
+
/**
|
|
152
|
+
* Get setLine call history
|
|
153
|
+
*/
|
|
154
|
+
getSetLineCalls(): Array<{
|
|
155
|
+
line: number;
|
|
156
|
+
content: string;
|
|
157
|
+
}>;
|
|
158
|
+
/**
|
|
159
|
+
* Create a NodeJS.WriteStream-like object that writes to this simulator
|
|
160
|
+
* Useful for passing to native TerminalRegion
|
|
161
|
+
*
|
|
162
|
+
* This stream emits 'resize' events that native TerminalRegion listens to
|
|
163
|
+
*/
|
|
164
|
+
createWriteStream(): NodeJS.WriteStream;
|
|
165
|
+
/**
|
|
166
|
+
* Simulate a resize event
|
|
167
|
+
* This is the key feature for testing resize behavior!
|
|
168
|
+
*
|
|
169
|
+
* This will:
|
|
170
|
+
* 1. Resize the terminal grid and reflow content
|
|
171
|
+
* 2. Update the writeStream's columns/rows (via getters)
|
|
172
|
+
* 3. Emit 'resize' events that native TerminalRegion listens to
|
|
173
|
+
*/
|
|
174
|
+
simulateResize(newWidth: number, newHeight: number): void;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=virtual-terminal.d.ts.map
|