78 lines
2.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
/**
|
|
* The variable form, on a terminal that reports no size.
|
|
*
|
|
* This is the one case that cannot be tested from inside a vitest worker: there
|
|
* is no TTY there for enquirer to misread, so the mocked tests in
|
|
* `prompts.test.ts` prove only that `rows` is *passed*, never that passing it
|
|
* matters. Here a real pty is opened at 0x0 — `pty.fork()`'s own default, and
|
|
* what `script -q` and some CI terminals report — and a real form is answered
|
|
* through it.
|
|
*
|
|
* Measured both ways while writing this: with `terminalSize()` removed from
|
|
* `nopy.prompts.ts`, the form never renders and the driver times out with
|
|
* nothing on the wire.
|
|
*
|
|
* Needs `python3` for the pty; skipped, loudly, where there is none.
|
|
*/
|
|
|
|
import { execFileSync, spawnSync } from 'node:child_process';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
|
|
const EXPECT_PY = fileURLToPath(new URL('../../../scripts/expect.py', import.meta.url));
|
|
const TSX = fileURLToPath(new URL('../node_modules/.bin/tsx', import.meta.url));
|
|
const PROBE = fileURLToPath(new URL('./fixtures/form-probe.ts', import.meta.url));
|
|
|
|
const hasPython = spawnSync('python3', ['--version']).status === 0;
|
|
|
|
/** Down arrow — how the form moves from one field to the next. */
|
|
const DOWN = '\u001b[B';
|
|
|
|
const STEPS = [
|
|
{ expect: 'ALPHA', send: 'alpha-typed', settle: 0.6 },
|
|
{ send: DOWN, settle: 0.4 },
|
|
{ send: 'beta-typed', settle: 0.4 },
|
|
{ send: '\r', settle: 1.2 },
|
|
];
|
|
|
|
describe.skipIf(!hasPython)('variable form over a pty', () => {
|
|
let tmpDir: string;
|
|
|
|
beforeEach(() => {
|
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'nopy-pty-'));
|
|
});
|
|
|
|
afterEach(() => {
|
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
});
|
|
|
|
/** Answers the probe form on a pty of the given size; returns what it assigned. */
|
|
const answerForm = (rows: number, cols: number) => {
|
|
const stepsPath = path.join(tmpDir, 'steps.json');
|
|
const logPath = path.join(tmpDir, 'session.log');
|
|
fs.writeFileSync(stepsPath, JSON.stringify(STEPS));
|
|
|
|
execFileSync('python3', [EXPECT_PY, stepsPath, '--', TSX, PROBE], {
|
|
env: {
|
|
...process.env,
|
|
PTY_ROWS: String(rows),
|
|
PTY_COLS: String(cols),
|
|
EXPECT_TIMEOUT: '60',
|
|
EXPECT_LOG: logPath,
|
|
},
|
|
stdio: 'pipe',
|
|
});
|
|
|
|
const transcript = fs.readFileSync(logPath, 'utf-8').replace(/\r/g, '');
|
|
const line = transcript.split('\n').find((l) => l.startsWith('NOPY_PROBE '));
|
|
return line ? JSON.parse(line.slice('NOPY_PROBE '.length)) : undefined;
|
|
};
|
|
|
|
it('collects every field on a terminal reporting 0x0', () => {
|
|
expect(answerForm(0, 0)).toEqual({ ALPHA: 'alpha-typed', BETA: 'beta-typed' });
|
|
}, 90_000);
|
|
});
|