Skip to content

Commit 0c9b2d0

Browse files
committed
test(prompts): make Unicode symbol selection deterministic
1 parent 8ab780f commit 0c9b2d0

3 files changed

Lines changed: 71 additions & 2 deletions

File tree

‎packages/prompts/src/__tests__/output.spec.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { stripVTControlCharacters } from 'node:util';
33

44
import stringWidth from 'fast-string-width';
55
import color from 'picocolors';
6-
import { afterEach, describe, expect, it, vi } from 'vitest';
6+
import { afterEach, describe, expect, it, vi } from 'vite-plus/test';
77

88
import { box } from '../box.js';
99
import { settings, updateSettings } from '../index.js';
@@ -13,6 +13,9 @@ import { spinner } from '../spinner.js';
1313
import { stream } from '../stream.js';
1414
import { taskLog } from '../task-log.js';
1515

16+
// common.ts selects symbols at module load, before test hooks run.
17+
vi.mock('is-unicode-supported', () => ({ default: () => true }));
18+
1619
function capture(columns = 52, isTTY = false) {
1720
let content = '';
1821
const output = Object.assign(

‎packages/prompts/src/__tests__/render.spec.ts‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { beforeEach, describe, expect, it, vi } from 'vitest';
1+
import { beforeEach, describe, expect, it, vi } from 'vite-plus/test';
2+
3+
// Keep Unicode snapshots independent of the host terminal and platform.
4+
vi.mock('is-unicode-supported', () => ({ default: () => true }));
25

36
type PromptConfig = {
47
render: (this: Record<string, unknown>) => string;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Writable } from 'node:stream';
2+
import { stripVTControlCharacters } from 'node:util';
3+
4+
import { describe, expect, it, vi } from 'vite-plus/test';
5+
6+
import { promptTitle } from '../common.js';
7+
import { log } from '../log.js';
8+
import { spinner } from '../spinner.js';
9+
10+
// Select fallback symbols before common.ts and its consumers initialize.
11+
vi.mock('is-unicode-supported', () => ({ default: () => false }));
12+
13+
function capture() {
14+
let content = '';
15+
const output = Object.assign(
16+
new Writable({
17+
write(chunk, _, done) {
18+
content += chunk.toString();
19+
done();
20+
},
21+
}),
22+
{ columns: 52, isTTY: false },
23+
);
24+
return { output, text: () => stripVTControlCharacters(content) };
25+
}
26+
27+
describe('Unicode fallback output', () => {
28+
it('preserves log severity and guide alignment with fallback symbols', () => {
29+
const c = capture();
30+
log.info('Checking assets\nChecking config', { output: c.output, withGuide: true });
31+
log.success('Deployed', { output: c.output });
32+
log.warn('Missing optional setting', { output: c.output });
33+
log.error('Build failed', { output: c.output });
34+
35+
expect(c.text()).toBe(
36+
'• Checking assets\n| Checking config\n* Deployed\n! Missing optional setting\nx Build failed\n',
37+
);
38+
});
39+
40+
it('uses fallback frames and completion symbols in a static spinner', () => {
41+
const c = capture();
42+
const s = spinner({ output: c.output });
43+
s.start('Building');
44+
s.stop('Built');
45+
46+
expect(c.text()).toBe('• Building...\no Built\n');
47+
});
48+
49+
it.each([
50+
['active', '>'],
51+
['submit', 'o'],
52+
['cancel', 'x'],
53+
['error', 'x'],
54+
] as const)('renders a guided %s prompt title with fallback symbols', (state, marker) => {
55+
const c = capture();
56+
const title = promptTitle('Choose an option', state, {
57+
output: c.output,
58+
withGuide: true,
59+
});
60+
61+
expect(stripVTControlCharacters(title)).toBe(`|\n${marker} Choose an option\n`);
62+
});
63+
});

0 commit comments

Comments
 (0)