Skip to content

Commit 47d7080

Browse files
ciampoaduth
andauthored
Test: Run Vitest type graph validation in process (#83851)
Co-authored-by: ciampo <mciampini@git.wordpress.org> Co-authored-by: aduth <aduth@git.wordpress.org>
1 parent e1b6b62 commit 47d7080

1 file changed

Lines changed: 46 additions & 24 deletions

File tree

‎test/unit/scripts/validate-vitest-conventions.mjs‎

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { spawnSync } from 'node:child_process';
21
import {
32
existsSync,
43
mkdtempSync,
@@ -16,7 +15,6 @@ import {
1615
getVitestTestsByProject,
1716
VITEST_PROJECT_NAMES,
1817
} from './discover-test-files.mjs';
19-
import { resolvePackageBin } from './resolve-package-bin.mjs';
2018
import { resolveTypeRoots } from './resolve-type-roots.mjs';
2119
import {
2220
findVitestIsolationOptOuts,
@@ -221,6 +219,41 @@ function getTypecheckConfigPath( testFile ) {
221219
return path.join( ROOT_DIR, 'tools/monorepo/tsconfig/tsconfig.base.json' );
222220
}
223221

222+
const diagnosticsHost = {
223+
getCanonicalFileName: ( fileName ) => fileName,
224+
getCurrentDirectory: () => ROOT_DIR,
225+
getNewLine: () => '\n',
226+
};
227+
228+
function runTypecheck( configPath ) {
229+
const config = typescript.getParsedCommandLineOfConfigFile(
230+
configPath,
231+
{},
232+
{
233+
...typescript.sys,
234+
onUnRecoverableConfigFileDiagnostic: ( diagnostic ) => {
235+
throw new Error(
236+
typescript.formatDiagnostics(
237+
[ diagnostic ],
238+
diagnosticsHost
239+
)
240+
);
241+
},
242+
}
243+
);
244+
const host = typescript.createCompilerHost( config.options );
245+
// Match the CLI's parsing mode for a typecheck without editor tooling.
246+
host.jsDocParsingMode = typescript.JSDocParsingMode.ParseForTypeErrors;
247+
const program = typescript.createProgram( {
248+
rootNames: config.fileNames,
249+
options: config.options,
250+
projectReferences: config.projectReferences,
251+
configFileParsingDiagnostics: config.errors,
252+
host,
253+
} );
254+
return typescript.getPreEmitDiagnostics( program );
255+
}
256+
224257
let typescriptTestCount = 0;
225258

226259
for ( const projectName of VITEST_PROJECT_NAMES ) {
@@ -339,38 +372,27 @@ for ( const projectName of VITEST_PROJECT_NAMES ) {
339372
"declare module 'deep-freeze' { export default function deepFreeze<T>(value: T): T; }",
340373
].join( '\n' )
341374
);
342-
const typecheckArguments = [
343-
resolvePackageBin( 'typescript', 'tsc6' ),
344-
'--project',
345-
configPath,
346-
'--pretty',
347-
'false',
348-
];
349-
const runTypecheck = () =>
350-
spawnSync( process.execPath, typecheckArguments, {
351-
cwd: ROOT_DIR,
352-
encoding: 'utf8',
353-
} );
354375
writeFileSync( configPath, JSON.stringify( typecheckConfig ) );
355-
let result = runTypecheck();
376+
let diagnostics = runTypecheck( configPath );
356377

357-
const output = `${ result.stdout ?? '' }${ result.stderr ?? '' }`;
358-
if ( result.status !== 0 && /TS63(?:05|10)/.test( output ) ) {
378+
if (
379+
diagnostics.some(
380+
( { code } ) => code === 6305 || code === 6310
381+
)
382+
) {
359383
// A dependency cycle can make TypeScript treat routed tests as
360384
// source files owned by a referenced package project. The package
361385
// declarations were built before this check, so fall back to normal
362386
// module resolution when that project-ownership check fails.
363387
typecheckConfig.references = [];
364388
writeFileSync( configPath, JSON.stringify( typecheckConfig ) );
365-
result = runTypecheck();
389+
diagnostics = runTypecheck( configPath );
366390
}
367391

368-
if ( result.error ) {
369-
throw result.error;
370-
}
371-
if ( result.status !== 0 ) {
372-
process.stderr.write( result.stdout ?? '' );
373-
process.stderr.write( result.stderr ?? '' );
392+
if ( diagnostics.length ) {
393+
process.stderr.write(
394+
typescript.formatDiagnostics( diagnostics, diagnosticsHost )
395+
);
374396
throw new Error( 'TypeScript test graph validation failed.' );
375397
}
376398
} finally {

0 commit comments

Comments
 (0)