Skip to content

Commit d62c91e

Browse files
committed
refactor: use expect.toMatchSnapshot to test conplex frames
1 parent 10664f5 commit d62c91e

File tree

11 files changed

+198
-197
lines changed

11 files changed

+198
-197
lines changed

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ export default {
99
moduleNameMapper: {
1010
'^(\\.{1,2}/.*)\\.js$': '$1',
1111
},
12-
testRegex: ['__tests__/.+(spec|test).ts'],
12+
testRegex: ['__tests__/.+(spec|test).ts$'],
1313
setupFiles: ['<rootDir>/setup.tests.ts'],
1414
};

packages/core/__tests__/index.spec.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ import { readdirSync } from 'node:fs';
22
import { join } from 'node:path';
33
import * as packageExports from '../src/index';
44

5-
function pascalCase(input: string): string {
6-
const words = input.split('-');
7-
const pascalCaseWords = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1));
8-
return pascalCaseWords.join('');
9-
}
10-
115
describe('Package', () => {
126
const exportedKeys = Object.keys(packageExports);
137

packages/prompts/__tests__/index.spec.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ function camelCase(input: string): string {
66
return input.replace(/[-_]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''));
77
}
88

9-
function pascalCase(input: string): string {
10-
const words = input.split('-');
11-
const pascalCaseWords = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1));
12-
return pascalCaseWords.join('');
13-
}
14-
159
describe('Package', () => {
1610
const exportedKeys = Object.keys(packageExports);
1711

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`groupMultiselect should render error 1`] = `
4+
"│
5+
▲ test message
6+
│ ◻ changed packages
7+
│ │ ◻ @scope/a
8+
│ │ ◻ @scope/b
9+
│ └ ◻ @scope/c
10+
│ ◻ unchanged packages
11+
│ │ ◻ @scope/x
12+
│ │ ◻ @scope/y
13+
│ └ ◻ @scope/z
14+
└ Please select at least one option.
15+
- Press  space  to select,  enter  to submit
16+
"
17+
`;
18+
19+
exports[`groupMultiselect should render initial state 1`] = `
20+
"│
21+
◆ test message
22+
│ ◻ changed packages
23+
│ │ ◻ @scope/a
24+
│ │ ◻ @scope/b
25+
│ └ ◻ @scope/c
26+
│ ◻ unchanged packages
27+
│ │ ◻ @scope/x
28+
│ │ ◻ @scope/y
29+
│ └ ◻ @scope/z
30+
└
31+
"
32+
`;
33+
34+
exports[`groupMultiselect should render initial state with option active 1`] = `
35+
"│
36+
◆ test message
37+
│ ◻ changed packages
38+
│ │ ◻ @scope/a
39+
│ │ ◻ @scope/b
40+
│ └ ◻ @scope/c
41+
│ ◻ unchanged packages
42+
│ │ ◻ @scope/x
43+
│ │ ◻ @scope/y
44+
│ └ ◻ @scope/z
45+
└
46+
"
47+
`;
48+
49+
exports[`groupMultiselect should render initial state with option active and selected 1`] = `
50+
"│
51+
◆ test message
52+
│ ◻ changed packages
53+
│ │ ◼ @scope/a
54+
│ │ ◻ @scope/b
55+
│ └ ◻ @scope/c
56+
│ ◻ unchanged packages
57+
│ │ ◻ @scope/x
58+
│ │ ◻ @scope/y
59+
│ └ ◻ @scope/z
60+
└
61+
"
62+
`;
63+
64+
exports[`groupMultiselect should render initial state with option not active and selected 1`] = `
65+
"│
66+
◆ test message
67+
│ ◻ changed packages
68+
│ │ ◼ @scope/a
69+
│ │ ◻ @scope/b
70+
│ └ ◻ @scope/c
71+
│ ◻ unchanged packages
72+
│ │ ◻ @scope/x
73+
│ │ ◻ @scope/y
74+
│ └ ◻ @scope/z
75+
└
76+
"
77+
`;
78+
79+
exports[`groupMultiselect should render initial with group active 1`] = `
80+
"│
81+
◆ test message
82+
│ ◻ changed packages
83+
│ │ ◻ @scope/a
84+
│ │ ◻ @scope/b
85+
│ └ ◻ @scope/c
86+
│ ◻ unchanged packages
87+
│ │ ◻ @scope/x
88+
│ │ ◻ @scope/y
89+
│ └ ◻ @scope/z
90+
└
91+
"
92+
`;
93+
94+
exports[`groupMultiselect should render initial with group selected 1`] = `
95+
"│
96+
◆ test message
97+
│ ◼ changed packages
98+
│ │ ◼ @scope/a
99+
│ │ ◼ @scope/b
100+
│ └ ◼ @scope/c
101+
│ ◻ unchanged packages
102+
│ │ ◻ @scope/x
103+
│ │ ◻ @scope/y
104+
│ └ ◻ @scope/z
105+
└
106+
"
107+
`;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`multiselect should render error 1`] = `
4+
"│
5+
▲ test message
6+
│ ◻ foo
7+
│ ◻ bar
8+
│ ◻ baz
9+
└ Please select at least one option.
10+
- Press  space  to select,  enter  to submit
11+
"
12+
`;
13+
14+
exports[`multiselect should render initial state 1`] = `
15+
"│
16+
◆ test message
17+
│ ◻ foo
18+
│ ◻ bar
19+
│ ◻ baz
20+
└
21+
"
22+
`;
23+
24+
exports[`multiselect should render initial state with initialValue 1`] = `
25+
"│
26+
◆ test message
27+
│ ◼ foo
28+
│ ◼ bar
29+
│ ◻ baz
30+
└
31+
"
32+
`;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`selectKey should render initial state 1`] = `
4+
"│
5+
◆ test message
6+
│  a  a
7+
│  b  b
8+
│  c  c
9+
└
10+
"
11+
`;
12+
13+
exports[`selectKey should render initial state with initialValue 1`] = `
14+
"│
15+
◆ test message
16+
│  a  a
17+
│  b  b
18+
│  c  c
19+
└
20+
"
21+
`;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`select should render initial state 1`] = `
4+
"│
5+
◆ test message
6+
│ ● foo
7+
│ ○ bar
8+
│ ○ baz
9+
└
10+
"
11+
`;
12+
13+
exports[`select should render initial state with initialValue 1`] = `
14+
"│
15+
◆ test message
16+
│ ○ foo
17+
│ ● bar
18+
│ ○ baz
19+
└
20+
"
21+
`;

packages/prompts/__tests__/prompts/group-multiselect.spec.ts

Lines changed: 8 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mockPrompt, SelectPrompt, State } from '@clack/core';
1+
import { mockPrompt, SelectPrompt } from '@clack/core';
22
import color from 'picocolors';
33
import { groupMultiselect } from '../../src';
44
import { opt } from '../../src/prompts/group-multiselect';
@@ -17,51 +17,6 @@ const options = {
1717
'unchanged packages': [{ value: '@scope/x' }, { value: '@scope/y' }, { value: '@scope/z' }],
1818
} satisfies Record<string, Option<string>[]>;
1919

20-
const formatOptions = (
21-
opts: Record<string, Option<string>[]> = options,
22-
value: string[] = [],
23-
cursor: number = 0,
24-
state: State = 'initial'
25-
): string => {
26-
const stateColor = state === 'error' ? color.yellow : color.cyan;
27-
return `${stateColor(S_BAR)} ${Object.entries(opts)
28-
.map(([group, children], i, tuples) => {
29-
const skip = tuples.slice(0, i).flat(3).length;
30-
const isGroupActive = i + skip === cursor;
31-
const isGroupSelected = !tuples[i][1]
32-
.map((option) => value.includes(option.value))
33-
.includes(false);
34-
const CHECKBOX = isGroupSelected
35-
? color.green(S_CHECKBOX_SELECTED)
36-
: isGroupActive
37-
? color.cyan(S_CHECKBOX_ACTIVE)
38-
: color.dim(S_CHECKBOX_INACTIVE);
39-
const label = isGroupActive ? group : color.dim(group);
40-
return [
41-
`${color.dim('')}${CHECKBOX} ${label}`,
42-
children.map((child, j, ar) => {
43-
const isActive = i + j + skip + 1 === cursor;
44-
const isSelected = value.includes(child.value);
45-
const isLast = j === ar.length - 1;
46-
const BAR = isLast ? S_BAR_END : S_BAR;
47-
const CHECKBOX = isSelected
48-
? color.green(S_CHECKBOX_SELECTED)
49-
: isGroupActive || isActive
50-
? color.cyan(S_CHECKBOX_ACTIVE)
51-
: color.dim(S_CHECKBOX_INACTIVE);
52-
const prefix = isGroupActive ? `${BAR} ` : color.dim(`${BAR} `);
53-
const label = child.label ?? child.value;
54-
return `${stateColor(S_BAR)} ${prefix}${CHECKBOX} ${
55-
isActive ? label : color.dim(label)
56-
}`;
57-
}),
58-
]
59-
.flat(2)
60-
.join('\n');
61-
})
62-
.join(`\n${stateColor(S_BAR)} `)}`;
63-
};
64-
6520
describe('groupMultiselect', () => {
6621
const mock = mockPrompt<SelectPrompt<{ value: string }>>();
6722
const message = 'test message';
@@ -178,52 +133,38 @@ describe('groupMultiselect', () => {
178133
});
179134

180135
it('should render initial state', () => {
181-
const title = `${color.gray(S_BAR)}\n${symbol('initial')} ${message}`;
182-
183136
groupMultiselect({ message, options });
184137

185138
expect(mock.state).toBe('initial');
186-
expect(mock.frame).toBe(`${title}\n${formatOptions()}\n${color.cyan(S_BAR_END)}\n`);
139+
expect(mock.frame).toMatchSnapshot();
187140
});
188141

189142
it('should render initial with group active', () => {
190-
const title = `${color.gray(S_BAR)}\n${symbol('initial')} ${message}`;
191-
192143
groupMultiselect({ message, options });
193144

194145
expect(mock.state).toBe('initial');
195-
expect(mock.frame).toBe(`${title}\n${formatOptions()}\n${color.cyan(S_BAR_END)}\n`);
146+
expect(mock.frame).toMatchSnapshot();
196147
});
197148

198149
it('should render initial with group selected', () => {
199-
const title = `${color.gray(S_BAR)}\n${symbol('initial')} ${message}`;
200-
201150
groupMultiselect({ message, options, initialValues: ['changed packages'] });
202151

203152
expect(mock.state).toBe('initial');
204-
expect(mock.frame).toBe(
205-
`${title}\n${formatOptions(options, mock.value)}\n${color.cyan(S_BAR_END)}\n`
206-
);
153+
expect(mock.frame).toMatchSnapshot();
207154
});
208155

209156
it('should render initial state with option active', () => {
210-
const title = `${color.gray(S_BAR)}\n${symbol('initial')} ${message}\n`;
211-
212157
groupMultiselect({
213158
message,
214159
options,
215160
cursorAt: options['changed packages'][0].value,
216161
});
217162

218163
expect(mock.state).toBe('initial');
219-
expect(mock.frame).toBe(
220-
`${title}${formatOptions(options, mock.value, 1)}\n${color.cyan(S_BAR_END)}\n`
221-
);
164+
expect(mock.frame).toMatchSnapshot();
222165
});
223166

224167
it('should render initial state with option active and selected', () => {
225-
const title = `${color.gray(S_BAR)}\n${symbol('initial')} ${message}\n`;
226-
227168
groupMultiselect({
228169
message,
229170
options,
@@ -232,14 +173,10 @@ describe('groupMultiselect', () => {
232173
});
233174

234175
expect(mock.state).toBe('initial');
235-
expect(mock.frame).toBe(
236-
`${title}${formatOptions(options, mock.value, 1)}\n${color.cyan(S_BAR_END)}\n`
237-
);
176+
expect(mock.frame).toMatchSnapshot();
238177
});
239178

240179
it('should render initial state with option not active and selected', () => {
241-
const title = `${color.gray(S_BAR)}\n${symbol('initial')} ${message}\n`;
242-
243180
groupMultiselect({
244181
message,
245182
options,
@@ -248,28 +185,15 @@ describe('groupMultiselect', () => {
248185
});
249186

250187
expect(mock.state).toBe('initial');
251-
expect(mock.frame).toBe(
252-
`${title}${formatOptions(options, mock.value, 2)}\n${color.cyan(S_BAR_END)}\n`
253-
);
188+
expect(mock.frame).toMatchSnapshot();
254189
});
255190

256191
it('should render error', () => {
257-
const title = `${color.gray(S_BAR)}\n${symbol('error')} ${message}`;
258-
259192
groupMultiselect({ message, options });
260193
mock.submit();
261-
const errorLines = mock.error.split('\n');
262194

263195
expect(mock.state).toBe('error');
264-
expect(mock.frame).toBe(
265-
[
266-
title,
267-
formatOptions(options, mock.value, 0, 'error'),
268-
`${color.yellow(S_BAR_END)} ${color.yellow(errorLines[0])}`,
269-
`${color.hidden('-')} ${errorLines[1]}`,
270-
'',
271-
].join('\n')
272-
);
196+
expect(mock.frame).toMatchSnapshot();
273197
});
274198

275199
// Implement when `groupMultiselect.validate` be exposed

0 commit comments

Comments
 (0)