Skip to content

Commit cfa3a99

Browse files
committed
feat: add transformWin32RelativePath
1 parent 7e69bbd commit cfa3a99

File tree

6 files changed

+96
-51
lines changed

6 files changed

+96
-51
lines changed

e2e/features.test.ts

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'node:path';
2-
import { expect } from 'vitest';
3-
import { test } from 'vitest';
42
import { createSnapshotSerializer } from 'path-serializer';
3+
import { describe, expect } from 'vitest';
4+
import { test } from 'vitest';
55

66
expect.addSnapshotSerializer(
77
createSnapshotSerializer({
@@ -13,44 +13,39 @@ expect.addSnapshotSerializer(
1313
}),
1414
);
1515

16-
test('should serialize file content without escaping \\"', () => {
17-
const fileContent = `"use strict";
18-
const a = "${require.resolve('@rslib/core')}";
19-
`;
16+
test('transformWin32Path', () => {
17+
const fileContent = `{
18+
loader: 'D:\\Users\\user\\Documents\\code\\user\\fe-dev-scripts\\src\\utils.ts',
19+
}`;
2020

2121
expect(fileContent).toMatchInlineSnapshot(`
22-
"use strict";
23-
const a = "<ROOT>/node_modules/<PNPM_INNER>/@rslib/core/dist/index.js";
22+
{
23+
loader: '/d/Users/user/Documents/code/user/fe-dev-scripts/src/utils.ts',
24+
}
2425
`);
2526
});
2627

27-
test('should serialize webpack output content', () => {
28-
const fileContent = `;// CONCATENATED MODULE: ../../../../node_modules/.pnpm/@[email protected]/node_modules/@swc/helpers/esm/_class_private_method_get.js
29-
function _class_private_method_get(receiver, privateSet, fn) {
30-
if (!privateSet.has(receiver)) throw new TypeError("attempted to get private field on non-instance");
28+
test('transformWin32RelativePath', () => {
29+
const case1 = `Cannot find file "..\\..\\getting-started\\next"`;
3130

32-
return fn;
33-
}
34-
`;
35-
36-
expect(fileContent).toMatchInlineSnapshot(`
37-
;// CONCATENATED MODULE: ../../../../node_modules/<PNPM_INNER>/@swc/helpers/esm/_class_private_method_get.js
38-
function _class_private_method_get(receiver, privateSet, fn) {
39-
if (!privateSet.has(receiver)) throw new TypeError("attempted to get private field on non-instance");
31+
expect(case1).toMatchInlineSnapshot(
32+
`Cannot find file "../../getting-started/next"`,
33+
);
4034

41-
return fn;
42-
}
43-
`);
35+
const case2 = `Cannot find file "..\\getting-started\\next"`;
36+
expect(case2).toMatchInlineSnapshot(
37+
`Cannot find file "../getting-started/next"`,
38+
);
4439
});
4540

46-
test('should serialize the Win32 path', () => {
47-
const fileContent = `{
48-
loader: 'D:\\Users\\user\\Documents\\code\\user\\fe-dev-scripts\\src\\utils.ts',
49-
}`;
41+
describe('transformCLR', () => {
42+
test('should transform the color', () => {
43+
const input = '\u001b[1mBold Text\u001b[0m';
44+
expect(input).toMatchInlineSnapshot('<CLR=BOLD>Bold Text<CLR=0>');
45+
});
5046

51-
expect(fileContent).toMatchInlineSnapshot(`
52-
{
53-
loader: '/d/Users/user/Documents/code/user/fe-dev-scripts/src/utils.ts',
54-
}
55-
`);
47+
test('bad case 1', () => {
48+
const input = 'static/react.svg'; // bad case: 'static/reactXsvg'
49+
expect(input).toMatchInlineSnapshot('static/react.svg');
50+
});
5651
});

e2e/realworld.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import path from 'node:path';
2+
import { createSnapshotSerializer } from 'path-serializer';
3+
import { expect } from 'vitest';
4+
import { test } from 'vitest';
5+
6+
expect.addSnapshotSerializer(
7+
createSnapshotSerializer({
8+
root: path.resolve(__dirname, '..'),
9+
features: {
10+
escapeDoubleQuotes: false,
11+
addDoubleQuotes: false,
12+
},
13+
}),
14+
);
15+
16+
test('should serialize file content without escaping \\"', () => {
17+
const fileContent = `"use strict";
18+
const a = "${require.resolve('@rslib/core')}";
19+
`;
20+
21+
expect(fileContent).toMatchInlineSnapshot(`
22+
"use strict";
23+
const a = "<ROOT>/node_modules/<PNPM_INNER>/@rslib/core/dist/index.js";
24+
`);
25+
});
26+
27+
test('should serialize webpack output content', () => {
28+
const fileContent = `;// CONCATENATED MODULE: ../../../../node_modules/.pnpm/@[email protected]/node_modules/@swc/helpers/esm/_class_private_method_get.js
29+
function _class_private_method_get(receiver, privateSet, fn) {
30+
if (!privateSet.has(receiver)) throw new TypeError("attempted to get private field on non-instance");
31+
32+
return fn;
33+
}
34+
`;
35+
36+
expect(fileContent).toMatchInlineSnapshot(`
37+
;// CONCATENATED MODULE: ../../../../node_modules/<PNPM_INNER>/@swc/helpers/esm/_class_private_method_get.js
38+
function _class_private_method_get(receiver, privateSet, fn) {
39+
if (!privateSet.has(receiver)) throw new TypeError("attempted to get private field on non-instance");
40+
41+
return fn;
42+
}
43+
`);
44+
});

e2e/transformCLR.test.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/createSnapshotSerializer.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
normalizeCLR,
99
normalizeCodeToPosix,
1010
normalizePathToPosix,
11+
normalizeWin32RelativePath,
1112
} from './normalize';
1213
import type { PathMatcher, SnapshotSerializerOptions } from './types';
1314

@@ -37,6 +38,7 @@ export function createSnapshotSerializer(
3738
replaceHomeDir = true,
3839
addDoubleQuotes = true,
3940
transformWin32Path = true,
41+
transformWin32RelativePath = true,
4042
escapeDoubleQuotes = true,
4143
escapeEOL = true,
4244
transformCLR = true,
@@ -87,6 +89,10 @@ export function createSnapshotSerializer(
8789
replaced = normalizeCodeToPosix(replaced);
8890
}
8991

92+
if (transformWin32RelativePath) {
93+
replaced = normalizeWin32RelativePath(replaced);
94+
}
95+
9096
replaced = applyMatcherReplacement(pathMatchers, replaced);
9197

9298
if (transformCLR) {

src/normalize.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,25 @@ export const normalizeCodeToPosix = (code: string): string => {
1919
);
2020
};
2121

22+
export function normalizeWin32RelativePath(p: string): string {
23+
return p.replace(
24+
/(['"`])(\.\.([\\/]))+([\w-]+\3)+[^\\/]*\1/g,
25+
(match: string) => {
26+
return match.replace(/\\/g, '/');
27+
},
28+
);
29+
}
30+
2231
export const normalizeCLR = (str: string): string => {
2332
return (
2433
str
34+
// biome-ignore lint/suspicious/noControlCharactersInRegex: copied code
2535
.replace(/\u001b\[1m\u001b\[([0-9;]*)m/g, '<CLR=$1,BOLD>')
36+
// biome-ignore lint/suspicious/noControlCharactersInRegex: copied code
2637
.replace(/\u001b\[1m/g, '<CLR=BOLD>')
38+
// biome-ignore lint/suspicious/noControlCharactersInRegex: copied code
2739
.replace(/\u001b\[39m\u001b\[22m/g, '</CLR>')
40+
// biome-ignore lint/suspicious/noControlCharactersInRegex: copied code
2841
.replace(/\u001b\[([0-9;]*)m/g, '<CLR=$1>')
2942
// CHANGE: The time unit display in Rspack is second
3043
// CHANGE2: avoid a bad case "./react/assets.svg" -> "./react/assetsXsvg"

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ export interface Features {
4343
* @default true
4444
*/
4545
transformWin32Path?: boolean;
46+
/**
47+
* `..\..\getting-started\next`
48+
* -> `../../getting-started/next`
49+
* @default true
50+
*/
51+
transformWin32RelativePath?: boolean;
4652
/**
4753
* "" -> \"\"
4854
* @default true

0 commit comments

Comments
 (0)