-
Notifications
You must be signed in to change notification settings - Fork 175
Expand file tree
/
Copy pathutils.spec.ts
More file actions
289 lines (255 loc) · 11 KB
/
utils.spec.ts
File metadata and controls
289 lines (255 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
import { randomUUID } from 'node:crypto';
import fs from 'node:fs';
import { homedir, tmpdir } from 'node:os';
import path from 'node:path';
import { describe, expect, test } from '@voidzero-dev/vite-plus-test';
import { isPassThroughEnv, replaceUnstableOutput } from '../utils.js';
describe('replaceUnstableOutput()', () => {
test('strip ANSI escape sequences', () => {
const output = '\u001b[1m\u001b[2mnote:\u001b[0m\u001b[0m yarn@2+ uses upgrade-interactive';
expect(replaceUnstableOutput(output)).toBe('note: yarn@2+ uses upgrade-interactive');
});
test('normalize CRLF line endings', () => {
const output = 'line 1\r\nline 2\r\nline 3\r';
expect(replaceUnstableOutput(output)).toBe('line 1\nline 2\nline 3');
});
test('replace unstable semver version', () => {
const output = `
foo v1.0.0
v1.0.0-beta.1
v1.0.0-beta.1+build.1
1.0.0
1.0.0-beta.1
1.0.0-beta.1+build.1
tsdown/0.15.1
vitest/3.2.4
foo/v100.1.1000
foo@1.0.0
bar@v1.0.0
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace date', () => {
const output = `
Start at 15:01:23
15:01:23
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace full datetime (YYYY-MM-DD HH:MM:SS)', () => {
const output = `
Installed: 2026-02-04 15:30:45
Created: 2024-01-15 10:30:00
Updated: 1999-12-31 23:59:59
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace parenthesized thread counts', () => {
const output = `
pass: All 3 files are correctly formatted (88ms, 2 threads)
pass: Found no warnings or lint errors in 1 file (<variable>ms, 16 threads)
`;
expect(replaceUnstableOutput(output.trim())).toBe(
[
'pass: All 3 files are correctly formatted (<variable>ms, <variable> threads)',
'pass: Found no warnings or lint errors in 1 file (<variable>ms, <variable> threads)',
].join('\n'),
);
});
test('replace unstable pnpm install output', () => {
const outputs = [
`
Scope: all 6 workspace projects
Packages: +312
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 1, reused 0, downloaded 0, added 0
Progress: resolved 316, reused 316, downloaded 0, added 315
WARN Skip adding vite to the default catalog because it already exists as npm:vite-plus. Please use \`pnpm update\` to update the catalogs.
WARN Skip adding vitest to the default catalog because it already exists as beta. Please use \`pnpm update\` to update the catalogs.
Progress: resolved 316, reused 316, downloaded 0, added 316, done
devDependencies:
+ vite-plus 0.0.0-8a4f4936e0eca32dd57e1a503c2b09745953344d
+ vitest 3.2.4
`,
`
Scope: all 2 workspace projects
Lockfile is up to date, resolution step is skipped
Already up to date
╭ Warning ───────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Ignored build scripts: esbuild. │
│ Run "pnpm approve-builds" to pick which dependencies should be allowed to run scripts. │
│ │
╰────────────────────────────────────────────────────────────────────────────────────────────╯
Done in 171ms using pnpm v10.16.1
`,
];
for (const output of outputs) {
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
}
});
test.skipIf(process.platform === 'win32')('replace unstable cwd', () => {
const cwd = tmpdir();
const output = path.join(cwd, 'foo.txt');
expect(replaceUnstableOutput(output.trim(), cwd)).toMatchSnapshot();
});
test.skipIf(process.platform === 'win32')('replace unstable tmpdir with realpath', () => {
const tmp = fs.realpathSync(tmpdir());
const cwd = path.join(tmp, `vite-plus-unittest-${randomUUID()}`);
const output = `${path.join(cwd, 'foo.txt')}\n${path.join(cwd, '../other/bar.txt')}`;
expect(replaceUnstableOutput(output.trim(), cwd)).toMatchSnapshot();
});
describe.skipIf(process.platform !== 'win32')('Windows cwd replacement', () => {
test('mixed-separator cwd matches all-backslash output', () => {
// Simulates the CI failure: cwd has mixed separators (template literal),
// but Vite outputs all-backslash paths (path.resolve)
const cwd =
'C:\\Users\\RUNNER~1\\AppData\\Local\\Temp/vite-plus-test-abc/command-staged-broken-config';
const output =
'failed to load config from C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\vite-plus-test-abc\\command-staged-broken-config\\vite.config.ts';
expect(replaceUnstableOutput(output, cwd)).toBe(
'failed to load config from <cwd>/vite.config.ts',
);
});
test('all-backslash cwd matches all-backslash output', () => {
const cwd = 'C:\\Users\\runner\\project';
const output = 'error in C:\\Users\\runner\\project\\src\\main.ts';
expect(replaceUnstableOutput(output, cwd)).toBe('error in <cwd>/src/main.ts');
});
test('cwd at end of string without trailing separator', () => {
const cwd = 'C:\\Users\\runner\\project';
const output = 'path is C:\\Users\\runner\\project';
expect(replaceUnstableOutput(output, cwd)).toBe('path is <cwd>');
});
test('parent directory replacement with backslash paths', () => {
const cwd = 'C:\\Users\\RUNNER~1\\Temp/vite-plus-test/my-test';
const output = 'found C:\\Users\\RUNNER~1\\Temp\\vite-plus-test\\other\\file.ts';
expect(replaceUnstableOutput(output, cwd)).toBe('found <cwd>/../other/file.ts');
});
});
test('replace tsdown output', () => {
const output = `
ℹ tsdown v0.15.1 powered by rolldown v0.15.1
ℹ entry: src/index.ts
ℹ Build start
ℹ dist/index.js 0.15 kB │ gzip: 0.12 kB
ℹ 1 files, total: 0.15 kB
✔ Build complete in 100ms
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace yarn YN0013', () => {
const output = `
➤ YN0000: ┌ Fetch step
➤ YN0013: │ A package was added to the project (+ 0.7 KiB).
➤ YN0000: └ Completed
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace yarn YN0000: └ Completed with duration to empty string', () => {
const output = `
➤ YN0000: └ Completed in 100ms
➤ YN0000: └ Completed in 100ms 200ms
➤ YN0000: └ Completed
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace ignore pnpm request warning log', () => {
const output = `
Foo bar
WARN Request took <variable>ms: https://registry.npmjs.org/testnpm2
Packages:
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace ignore npm audited packages log', () => {
const output = `
removed 1 package, and audited 3 packages in 700ms
up to date, audited 4 packages in 11ms
added 1 package, and audited 3 packages in 700ms
added 3 packages, and audited 4 packages in 100ms
found 0 vulnerabilities
Done in 1000ms
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace ignore npm registry domain', () => {
const output = `
https://registry.npmjs.org/testnpm2
https://registry.yarnpkg.com/debug
https://registry.yarnpkg.com/testnpm2/-/testnpm2-1.0.0.tgz
"resolved": "https://registry.yarnpkg.com/testnpm2/-/testnpm2-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/testnpm2/-/testnpm2-1.0.0.tgz",
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace pnpm registry request error warning log', () => {
const output = `
WARN GET https://registry.npmjs.org/test-vite-plus-install error (ECONNRESET). Will retry in 10 seconds. 2 retries left.
Progress: resolved
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace ignore tarball download average speed warning log', () => {
const output = `
WARN Tarball download average speed 29 KiB/s (size 56 KiB) is below 50 KiB/s: https://registry.npmjs.org/qs/-/qs-6.14.0.tgz (GET)
WARN Tarball download average speed 34 KiB/s (size 347 KiB) is below 50 KiB/s: https://registry.npmjs.org/undici/-/undici-7.16.0.tgz (GET)
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace hash values', () => {
const output = `
npm notice shasum: 65c35f9599054722ecde040abd4a19682a723cdc
npm notice integrity: sha512-qugLL42iCblSD[...]Gfk6HJodp2ZOQ==
"shasum": "65c35f9599054722ecde040abd4a19682a723cdc",
"integrity": "sha512-qugLL42iCblSDO0Vwic9xYkKYNtf+MwPW4cQSppKbGtQ/xswl1gXyu/DF5b7I/WbsVi02DJIHGfk6HJodp2ZOQ==",
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace ignore npm notice access token expired or revoked warning log', () => {
const output = `
line 1
npm notice Access token expired or revoked. Please try logging in again.
npm notice Access token expired or revoked. Please try logging in again.
line 2
npm notice Access token expired or revoked. Please try logging in again.
line 3
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test('replace unstable vite-plus hash version', () => {
const output = `
"vite-plus": "^0.0.0-aa9f90fe23216b8ad85b0ba4fc1bccb0614afaf0"
"vite-plus-core": "^0.0.0-43b91ac4e4bc63ba78dee8a813806bdbaa7a4378"
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
test.skipIf(process.platform === 'win32')('replace vite-plus home paths', () => {
const home = homedir();
const output = [
`${home}/.vite-plus/js_runtime/node/v20.18.0/bin/node`,
`${home}/.vite-plus/packages/cowsay/lib/node_modules/cowsay/./cli.js`,
`${home}/.vite-plus`,
`${home}/.vite-plus/bin`,
].join('\n');
expect(replaceUnstableOutput(output)).toMatchSnapshot();
});
test('replace ignore npm warn exec The following package was not found and will be installed: cowsay@<semver> warning log', () => {
const output = `
npm warn exec The following package was not found and will be installed: cowsay@<semver>
npm warn exec The following package was not found and will be installed: cowsay@1.6.0
hello world
`;
expect(replaceUnstableOutput(output.trim())).toMatchSnapshot();
});
});
describe('isPassThroughEnv()', () => {
test('should return true if env is pass-through', () => {
expect(isPassThroughEnv('NPM_AUTH_TOKEN')).toBe(true);
expect(isPassThroughEnv('PATH')).toBe(true);
});
test('should return false if env is not pass-through', () => {
expect(isPassThroughEnv('NODE_ENV')).toBe(false);
expect(isPassThroughEnv('API_URL')).toBe(false);
});
});