Files
orca/config/scripts/node-server-policy-self-tests.test.mjs
T

193 lines
6.9 KiB
JavaScript

import { beforeAll, describe, expect, it } from 'vitest'
import { classifyNodeServerChanges, collectNodeServerInputs } from './node-server-change-scope.mjs'
import { NODE_SERVER_RUNNERS, nodeServerQualification } from './node-server-qualification.mjs'
import { discoverUnitFiles } from './ci-unit-files.mjs'
import { planUnitSelection } from './ci-unit-selection.mjs'
import { classifyPrJobs } from './pr-code-change-scope.mjs'
const policyTests = [
'config/scripts/node-server-change-scope.test.mjs',
'config/scripts/node-server-qualification.test.mjs'
]
const unavailableGraph = async () => {
throw new Error('graph unavailable')
}
describe('modified Node-server policy self-tests', () => {
let inputs
let unitFiles
beforeAll(async () => {
inputs = await collectNodeServerInputs()
unitFiles = discoverUnitFiles()
}, 60_000)
it.each(policyTests)(
'keeps %s in required root units without native qualification',
async (file) => {
expect(classifyPrJobs([file], { allowMobileCiTools: true })).toMatchObject({
test: true,
static_analysis: true,
typecheck: true,
mobile_ci_tools: false
})
expect(inputs.has(file)).toBe(false)
const scope = await classifyNodeServerChanges([file], async () => inputs, {
modifiedFiles: [file]
})
expect(scope).toMatchObject({ shouldRun: false, graphResolved: true, matchedFiles: [] })
const plan = planUnitSelection({
files: unitFiles,
changed: [file],
graph: () => {
throw new Error('config edits must select the full unit inventory')
},
timings: {},
event: { pull_request: { draft: true } },
mode: 'selected'
})
expect(plan.mode).toBe('shadow')
expect(plan.executionFiles).toEqual(unitFiles)
expect(plan.executionFiles).toContain(file)
}
)
it('keeps both modified policy self-tests in root units', async () => {
const scope = await classifyNodeServerChanges(policyTests, async () => inputs, {
modifiedFiles: policyTests
})
expect(scope.shouldRun).toBe(false)
expect(unitFiles).toEqual(expect.arrayContaining(policyTests))
})
it.each(policyTests)('requests the real graph before excluding %s', async (file) => {
const scope = await classifyNodeServerChanges([file], unavailableGraph, {
deferGraph: true,
modifiedFiles: [file]
})
expect(scope.graphRequired).toBe(true)
expect(scope.shouldRun).toBeUndefined()
})
it.each([
{ evidence: 'incomplete modified paths', changed: policyTests, modified: [policyTests[0]] },
{ evidence: 'missing modified paths', changed: policyTests },
{
evidence: 'duplicate modified paths',
changed: policyTests,
modified: [policyTests[0], policyTests[0]]
},
{
evidence: 'foreign modified path',
changed: policyTests,
modified: [policyTests[0], 'config/scripts/foreign.test.mjs']
},
{
evidence: 'unproven rename side',
changed: [...policyTests, 'config/scripts/node-server-renamed.test.mjs'],
modified: policyTests
},
{
evidence: 'duplicate changed paths',
changed: [policyTests[0], policyTests[0]],
modified: policyTests
}
])('retains full qualification with $evidence', async ({ changed, modified }) => {
const scope = await classifyNodeServerChanges(changed, unavailableGraph, {
modifiedFiles: modified
})
expect(scope.shouldRun).toBe(true)
expect(scope.graphUnavailable).toBeUndefined()
expect(nodeServerQualification(changed, scope)).toEqual({
qualification: true,
runners: NODE_SERVER_RUNNERS
})
})
it.each([
'config/scripts/node-server-change-scope.mjs',
'config/scripts/node-server-qualification.mjs',
'config/scripts/workspace-source-exports.test.mjs',
'.github/workflows/node-server-tests.yml',
'.github/actions/prepare-native-runtime/action.yml',
'pnpm-lock.yaml'
])('keeps full qualification for mixed edits including %s', async (file) => {
const changed = [...policyTests, file]
const scope = await classifyNodeServerChanges(changed, unavailableGraph, {
modifiedFiles: changed
})
expect(scope.shouldRun).toBe(true)
expect(scope.graphUnavailable).toBeUndefined()
expect(nodeServerQualification(changed, scope)).toEqual({
qualification: true,
runners: NODE_SERVER_RUNNERS
})
})
it.each([
'config/scripts/node-server-concurrency.test.mjs',
'config/scripts/node-server-packaged-chat-selection.test.mjs'
])(
'preserves unrelated %s routing with complete, absent, or non-modification evidence',
async (file) => {
expect(inputs.has(file)).toBe(false)
for (const modifiedFiles of [[file], undefined, []]) {
const scope = await classifyNodeServerChanges([file], async () => inputs, { modifiedFiles })
expect(scope.shouldRun).toBe(false)
expect(scope.graphUnavailable).toBeUndefined()
}
}
)
it.each([
'config/scripts/node-server-concurrency.test.mjs',
'config/scripts/node-server-packaged-chat-selection.test.mjs'
])('preserves both unmodified rename sides for unrelated %s', async (file) => {
const changed = [file, file.replace('.test.mjs', '-renamed.test.mjs')]
const scope = await classifyNodeServerChanges(changed, async () => inputs, {
modifiedFiles: []
})
expect(scope.shouldRun).toBe(false)
expect(scope.graphUnavailable).toBeUndefined()
})
it('preserves unrelated tests when only part of their changed vector is modified', async () => {
const changed = [
'config/scripts/node-server-concurrency.test.mjs',
'config/scripts/node-server-packaged-chat-selection.test.mjs'
]
const scope = await classifyNodeServerChanges(changed, async () => inputs, {
modifiedFiles: [changed[0]]
})
expect(scope.shouldRun).toBe(false)
expect(scope.graphUnavailable).toBeUndefined()
})
it.each(policyTests)(
'retains native qualification when %s becomes a real graph input',
async (file) => {
const reachable = await collectNodeServerInputs({ entryPoints: [file] })
expect(reachable.has(file)).toBe(true)
const scope = await classifyNodeServerChanges([file], async () => reachable, {
modifiedFiles: [file]
})
expect(scope).toMatchObject({ shouldRun: true, graphResolved: true, matchedFiles: [file] })
expect(nodeServerQualification([file], scope)).toEqual({
qualification: true,
runners: NODE_SERVER_RUNNERS
})
}
)
it('retains full qualification when graph collection fails', async () => {
const scope = await classifyNodeServerChanges(policyTests, unavailableGraph, {
modifiedFiles: policyTests
})
expect(scope).toMatchObject({ shouldRun: true, graphUnavailable: true })
expect(nodeServerQualification(policyTests, scope)).toEqual({
qualification: true,
runners: NODE_SERVER_RUNNERS
})
})
})