Skip to content

Commit 952ac82

Browse files
committed
test(fmt): group postprocess coverage in a suite
1 parent de0a6bd commit 952ac82

1 file changed

Lines changed: 101 additions & 99 deletions

File tree

‎packages/rstack/tests/fmt/swcNextPlugin.test.ts‎

Lines changed: 101 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
type Options,
55
type ParserOptions,
66
} from 'prettier';
7-
import { expect, test } from 'rstack/test';
7+
import { describe, expect, test } from 'rstack/test';
88
import { getPrettierPlugins } from '../../src/fmt/prettierPlugins.ts';
99
import { swcNextPlugin } from '../../src/fmt/swcNextPlugin.ts';
1010

@@ -107,85 +107,108 @@ test.each(['example.d.ts', 'example.d.mts', 'example.d.cts'])(
107107
},
108108
);
109109

110-
test.each([
111-
{
112-
name: 'hashbangs and unicode locations',
113-
parser: 'swc-next' as const,
114-
source: '#!/usr/bin/env node\n// 中文 😀\nconst 你好={值:"😀"}',
115-
expected: '#!/usr/bin/env node\n// 中文 😀\nconst 你好 = { 值: "😀" };\n',
116-
},
117-
{
118-
name: 'Closure-style type casts',
119-
parser: 'swc-next' as const,
120-
source: '/** @type {Foo} */ (value).method()',
121-
expected: '/** @type {Foo} */ (value).method();\n',
122-
},
123-
{
124-
name: 'comments before semicolons',
125-
parser: 'swc-next' as const,
126-
source: 'foo /* trailing */ ;',
127-
expected: 'foo; /* trailing */\n',
128-
},
129-
{
130-
name: 'adjacent multiline JSDoc comments',
131-
parser: 'swc-next' as const,
132-
source: '/**\n * outer\n *//**\n * inner\n */\nfoo()',
133-
expected: '/**\n * outer\n *//**\n * inner\n */\nfoo();\n',
134-
},
135-
{
136-
name: 'right-nested logical expressions',
137-
parser: 'swc-next' as const,
138-
source: 'const value = a || (b || c)',
139-
expected: 'const value = a || b || c;\n',
140-
},
141-
{
142-
name: 'parenthesized TypeScript types',
143-
parser: 'swc-next-ts' as const,
144-
source: 'type Value = (((string | number)));',
145-
expected: 'type Value = string | number;\n',
146-
},
147-
{
148-
name: 'single-member unions with comments',
149-
parser: 'swc-next-ts' as const,
150-
source: 'type Value = | // value\nstring;',
151-
expected: 'type Value =\n // value\n string;\n',
152-
},
153-
{
154-
name: 'TypeScript template expressions',
155-
parser: 'swc-next-ts' as const,
156-
source: 'const result = `value: ${foo satisfies string}`',
157-
expected: 'const result = `value: ${foo satisfies string}`;\n',
158-
},
159-
{
160-
name: 'TSX expressions',
161-
parser: 'swc-next-ts' as const,
162-
filepath: 'example.tsx',
163-
source: 'const view=(<Component value={{foo:1}}>{(item)}</Component>)',
164-
expected:
165-
'const view = <Component value={{ foo: 1 }}>{item}</Component>;\n',
166-
},
167-
])('normalizes $name for the ESTree printer', async (fixture) => {
168-
await expect(
169-
formatWithSwcNext(fixture.source, {
170-
filepath: fixture.filepath,
171-
parser: fixture.parser,
172-
}),
173-
).resolves.toBe(fixture.expected);
174-
});
110+
describe('postprocess', () => {
111+
test.each([
112+
{
113+
name: 'hashbangs and unicode locations',
114+
parser: 'swc-next' as const,
115+
source: '#!/usr/bin/env node\n// 中文 😀\nconst 你好={值:"😀"}',
116+
expected: '#!/usr/bin/env node\n// 中文 😀\nconst 你好 = { 值: "😀" };\n',
117+
},
118+
{
119+
name: 'Closure-style type casts',
120+
parser: 'swc-next' as const,
121+
source: '/** @type {Foo} */ (value).method()',
122+
expected: '/** @type {Foo} */ (value).method();\n',
123+
},
124+
{
125+
name: 'comments before semicolons',
126+
parser: 'swc-next' as const,
127+
source: 'foo /* trailing */ ;',
128+
expected: 'foo; /* trailing */\n',
129+
},
130+
{
131+
name: 'adjacent multiline JSDoc comments',
132+
parser: 'swc-next' as const,
133+
source: '/**\n * outer\n *//**\n * inner\n */\nfoo()',
134+
expected: '/**\n * outer\n *//**\n * inner\n */\nfoo();\n',
135+
},
136+
{
137+
name: 'right-nested logical expressions',
138+
parser: 'swc-next' as const,
139+
source: 'const value = a || (b || c)',
140+
expected: 'const value = a || b || c;\n',
141+
},
142+
{
143+
name: 'parenthesized TypeScript types',
144+
parser: 'swc-next-ts' as const,
145+
source: 'type Value = (((string | number)));',
146+
expected: 'type Value = string | number;\n',
147+
},
148+
{
149+
name: 'single-member unions with comments',
150+
parser: 'swc-next-ts' as const,
151+
source: 'type Value = | // value\nstring;',
152+
expected: 'type Value =\n // value\n string;\n',
153+
},
154+
{
155+
name: 'TypeScript template expressions',
156+
parser: 'swc-next-ts' as const,
157+
source: 'const result = `value: ${foo satisfies string}`',
158+
expected: 'const result = `value: ${foo satisfies string}`;\n',
159+
},
160+
{
161+
name: 'TSX expressions',
162+
parser: 'swc-next-ts' as const,
163+
filepath: 'example.tsx',
164+
source: 'const view=(<Component value={{foo:1}}>{(item)}</Component>)',
165+
expected:
166+
'const view = <Component value={{ foo: 1 }}>{item}</Component>;\n',
167+
},
168+
])('normalizes $name for the ESTree printer', async (fixture) => {
169+
await expect(
170+
formatWithSwcNext(fixture.source, {
171+
filepath: fixture.filepath,
172+
parser: fixture.parser,
173+
}),
174+
).resolves.toBe(fixture.expected);
175+
});
175176

176-
test.each(['swc-next', 'swc-next-ts'] as const)(
177-
'normalizes nested template expressions with %s',
178-
async (parser) => {
179-
const source =
180-
'const result=`outer ${(`inner ${(a || (b || c))}`)} ${/** @type {Foo} */ (value)}`';
181-
const formatted = await formatWithSwcNext(source, { parser });
177+
test.each(['swc-next', 'swc-next-ts'] as const)(
178+
'normalizes nested template expressions with %s',
179+
async (parser) => {
180+
const source =
181+
'const result=`outer ${(`inner ${(a || (b || c))}`)} ${/** @type {Foo} */ (value)}`';
182+
const formatted = await formatWithSwcNext(source, { parser });
183+
184+
expect(formatted).toBe(
185+
'const result = `outer ${`inner ${a || b || c}`} ${/** @type {Foo} */ (value)}`;\n',
186+
);
187+
expect(await formatWithSwcNext(formatted, { parser })).toBe(formatted);
188+
},
189+
);
182190

183-
expect(formatted).toBe(
184-
'const result = `outer ${`inner ${a || b || c}`} ${/** @type {Foo} */ (value)}`;\n',
185-
);
186-
expect(await formatWithSwcNext(formatted, { parser })).toBe(formatted);
187-
},
188-
);
191+
test('matches the official hashbang AST shape', async () => {
192+
const parser = swcNextPlugin.parsers?.['swc-next'];
193+
if (!parser) {
194+
throw new Error('The SWC Next parser is not registered.');
195+
}
196+
197+
const options = { filepath: 'example.js' } as ParserOptions;
198+
const astWithoutHashbang = (await parser.parse(
199+
'const value = 1',
200+
options,
201+
)) as Record<string, unknown>;
202+
const astWithHashbang = (await parser.parse(
203+
'#!/usr/bin/env node\nconst value = 1',
204+
options,
205+
)) as Record<string, unknown>;
206+
207+
expect(Object.hasOwn(astWithoutHashbang, 'hashbang')).toBe(true);
208+
expect(astWithoutHashbang.hashbang).toBeNull();
209+
expect(Object.hasOwn(astWithHashbang, 'hashbang')).toBe(false);
210+
});
211+
});
189212

190213
test('reuses Prettier options and pragma handling', async () => {
191214
await expect(
@@ -335,27 +358,6 @@ test('supports CommonJS source semantics for .cjs files', async () => {
335358
).resolves.toBe('return require("example");\n');
336359
});
337360

338-
test('matches the official hashbang AST shape', async () => {
339-
const parser = swcNextPlugin.parsers?.['swc-next'];
340-
if (!parser) {
341-
throw new Error('The SWC Next parser is not registered.');
342-
}
343-
344-
const options = { filepath: 'example.js' } as ParserOptions;
345-
const astWithoutHashbang = (await parser.parse(
346-
'const value = 1',
347-
options,
348-
)) as Record<string, unknown>;
349-
const astWithHashbang = (await parser.parse(
350-
'#!/usr/bin/env node\nconst value = 1',
351-
options,
352-
)) as Record<string, unknown>;
353-
354-
expect(Object.hasOwn(astWithoutHashbang, 'hashbang')).toBe(true);
355-
expect(astWithoutHashbang.hashbang).toBeNull();
356-
expect(Object.hasOwn(astWithHashbang, 'hashbang')).toBe(false);
357-
});
358-
359361
test('reports SWC Next diagnostics with Prettier locations', async () => {
360362
const error = await formatWithSwcNext('\n\nconst = 1', {
361363
parser: 'swc-next-ts',

0 commit comments

Comments
 (0)