Files
orca/config/scripts/static-module-specifiers.test.mjs
T
Neil 71733ccc04 Speed up process-host import enforcement in CI (#27124)
Reduce import-scanner work by omitting unused AST parents and the duplicate traversal. Run the mandatory process-host import check alongside static work and explicitly join it before CI can succeed.

Update both workflow phase/enforcement contracts and migrate the newer benchmark to the public subprocess package API. Keep the original package build path, manifests, runtime, test selection, and shard count. Independent native review is clean; validation and timing evidence are in the PR.
2026-10-09 22:12:37 -07:00

218 lines
8.4 KiB
JavaScript

import { describe, expect, it } from 'vitest'
import { assessProcessHostImports } from './check-process-host-imports.mjs'
import { collectModuleSpecifiers } from './static-module-specifiers.mjs'
function specifiers(contents) {
return collectModuleSpecifiers('file.ts', contents)
}
describe('static module specifiers', () => {
it.each([
[
'a direct createRequire call',
"import { createRequire } from 'node:module'\ncreateRequire(import.meta.url)('child_process')"
],
[
'an assigned createRequire loader',
"import { createRequire } from 'node:module'\nconst load = createRequire(__filename)\nload('node:child_process')"
],
[
'a renamed createRequire import',
"import { createRequire as make } from 'module'\nconst load = make(__filename)\nload.resolve('child_process')"
],
[
'a namespace createRequire',
"import * as nodeModule from 'node:module'\nnodeModule.createRequire(__filename)('child_process')"
],
[
'a default-import createRequire',
"import Module from 'module'\nconst load = Module.createRequire(__filename)\nload('child_process')"
],
[
'a named default-import createRequire',
"import { default as Module } from 'node:module'\nModule.createRequire(__filename)('child_process')"
],
[
'a named Module constructor',
"import { Module } from 'node:module'\nModule.createRequire(__filename)('child_process')"
],
[
'a renamed Module constructor',
"import { Module as HostModule } from 'module'\nHostModule.createRequire(__filename)('node:child_process')"
],
[
'an import-equals createRequire',
"import Module = require('node:module')\nconst load = Module.createRequire(__filename)\nload('node:child_process')"
],
[
'a literal-property createRequire',
"import * as Module from 'node:module'\nModule['createRequire'](__filename)('child_process')"
],
[
'a required createRequire',
"const { createRequire: make } = require('node:module')\nmake(__filename)('child_process')"
],
[
'a quoted destructured createRequire',
"const { 'createRequire': make } = require('node:module')\nmake(__filename)('child_process')"
],
[
'a chained module alias',
"const nodeModule = require('module')\nconst load = nodeModule.createRequire(__filename)\nload('child_process')"
],
[
'an awaited module import',
"const { createRequire } = await import('node:module')\ncreateRequire(import.meta.url)('child_process')"
],
['a reassigned require', "const load = require\nload('child_process')"],
['module.require', "module.require('child_process')"],
['a literal-property module.require', "module['require']('child_process')"],
['a literal-property require.resolve', "require['resolve']('child_process')"],
['process.getBuiltinModule', "process.getBuiltinModule('node:child_process')"],
['a literal-property getBuiltinModule', "process['getBuiltinModule']('node:child_process')"],
['a template-property getBuiltinModule', 'process[`getBuiltinModule`]("child_process")'],
['globalThis.process.getBuiltinModule', "globalThis.process.getBuiltinModule('child_process')"],
[
'literal properties on globalThis.process',
"globalThis['process']['getBuiltinModule']('child_process')"
],
[
'an imported process',
"import nodeProcess from 'node:process'\nnodeProcess.getBuiltinModule('child_process')"
],
[
'a named default-import process',
"import { default as nodeProcess } from 'node:process'\nnodeProcess.getBuiltinModule('child_process')"
],
[
'an import-equals process',
"import nodeProcess = require('node:process')\nnodeProcess.getBuiltinModule('child_process')"
],
[
'a destructured getBuiltinModule',
"const { getBuiltinModule } = process\ngetBuiltinModule('child_process')"
],
[
'a quoted destructured getBuiltinModule',
"const { 'getBuiltinModule': load } = process\nload('child_process')"
],
[
'a builtin module with a literal-property factory',
"process['getBuiltinModule']('node:module')['createRequire'](__filename)('child_process')"
],
[
'an imported getBuiltinModule',
"import { getBuiltinModule as load } from 'process'\nload('child_process')"
],
[
'a const specifier',
"const CHILD_PROCESS = 'node:child_process' as const\nrequire(CHILD_PROCESS)"
],
[
'a const template specifier',
'const CHILD_PROCESS = `child_process`\nprocess.getBuiltinModule(CHILD_PROCESS)'
]
])('resolves child_process loaded through %s', (_label, contents) => {
expect(
specifiers(contents).filter((specifier) => specifier.endsWith('child_process'))
).toHaveLength(1)
})
it('resolves escaped loader names and literals after parsing', () => {
expect(
specifiers(String.raw`
const load = \u0072equire
const CHILD_PROCESS = '\u0063hild_process'
load(CHILD_PROCESS)
process['get\u0042uiltinModule']('node:\u0063hild_process')
`)
).toEqual(['child_process', 'node:child_process'])
})
it('preserves const binding order across nested declaration lists', () => {
expect(
specifiers(`
const nested = (() => { const NAME = 'first'; return NAME })(), NAME = 'second'
require(NAME)
`)
).toEqual(['first', 'second'])
})
it('rejects invalid syntax even without imports or loader names', () => {
expect(() => specifiers('const broken = (')).toThrow('Cannot parse file.ts')
})
it('ignores unrelated objects, computed property values, and non-constant specifiers', () => {
expect(
specifiers(
[
'const registry = { getBuiltinModule: (name) => name, createRequire: () => () => null }',
"registry.getBuiltinModule('child_process')",
"registry.createRequire(__filename)('child_process')",
"registry['getBuiltinModule']('child_process')",
"registry['createRequire'](__filename)('child_process')",
"const method = 'getBuiltinModule'",
"process[method]('child_process')",
"let mutable = 'child_process'",
'require(mutable)',
"require('child' + '_process')",
"const name = 'child'",
'require(`${name}_process`)'
].join('\n')
)
).toEqual([])
})
it('flags a new production file that bypasses the import form', () => {
expect(
assessProcessHostImports(
new Map([
[
'src/main/bypass.ts',
"import { createRequire } from 'node:module'\nconst load = createRequire(import.meta.url)\nload('child_process')"
],
['src/main/builtin.ts', "process['getBuiltinModule']('node:child_process')"],
[
'src/main/import-equals.ts',
"import Module = require('node:module')\nconst load = Module.createRequire(__filename)\nload('node:child_process')"
],
[
'src/main/named-default-module.ts',
"import { default as Module } from 'node:module'\nModule.createRequire(__filename)('child_process')"
],
[
'src/main/named-default-process.ts',
"import { default as nodeProcess } from 'node:process'\nnodeProcess.getBuiltinModule('child_process')"
]
]),
{ exports: {} },
[]
).added
).toEqual([
'src/main/builtin.ts',
'src/main/bypass.ts',
'src/main/import-equals.ts',
'src/main/named-default-module.ts',
'src/main/named-default-process.ts'
])
})
it.each([
"import { createRequire } from 'node:module'\nconst ELECTRON = 'electron'\ncreateRequire(__filename)(ELECTRON)",
"import Module = require('node:module')\nModule.createRequire(__filename)('electron')",
"import { Module as HostModule } from 'module'\nHostModule.createRequire(__filename)('electron')",
"import * as Module from 'node:module'\nModule['createRequire'](__filename)('electron')",
"const { 'createRequire': make } = require('node:module')\nmake(__filename)('electron')"
])('applies package dependency rules to dynamically loaded specifiers: %s', (contents) => {
expect(
assessProcessHostImports(
new Map([['src/packages/process-host/src/runner.ts', contents]]),
{ exports: {} },
[]
).violations
).toEqual([
'src/packages/process-host/src/runner.ts: undeclared process-host dependency: electron'
])
})
})