2026-07-19 22:13:50 +08:00
import { mkdirSync , mkdtempSync , rmSync , writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach , describe , expect , it } from 'vitest'
import {
collectPackageInvariantViolations ,
2026-08-28 12:37:29 +08:00
packageInvariantOwners ,
2026-07-19 22:13:50 +08:00
} from './package-invariants.ts'
const roots : string [ ] = [ ]
afterEach ( ( ) = > {
for ( const root of roots . splice ( 0 ) ) rmSync ( root , { recursive : true , force : true } )
} )
2026-07-20 00:38:37 +08:00
function handwrittenInvariant ( packageName : string ) : string {
return `
export const name = 'probe-invariant'
export const inject = [ 'invariants' ]
2026-07-20 19:34:19 +08:00
const install = ( ctx : { on ( name : string , listener : ( value : number ) = > void ) : void } , fail : ( message : string ) = > never ) = > {
ctx . on ( 'probe/value' , ( value ) = > {
if ( value < 0 ) fail ( 'observed values must be non-negative' )
} )
2026-07-20 00:38:37 +08:00
}
export const apply = ( ctx : { invariants : { register ( name : string , install : typeof install ) : ( ) = > void } } ) = >
Promise . resolve ( ctx . invariants . register ( $ { JSON . stringify ( packageName ) } , install ) )
`
}
2026-07-19 22:13:50 +08:00
function fixture ( options : {
2026-08-28 12:37:29 +08:00
companion? : boolean
2026-07-19 22:13:50 +08:00
packageName? : string
source? : string
invariantExport? : boolean
2026-08-28 12:37:29 +08:00
invariantFile? : boolean
2026-07-19 22:13:50 +08:00
invariantDependency? : boolean
invariantReference? : boolean
buildEntry? : boolean
2026-08-28 12:37:29 +08:00
omissionReason? : boolean
2026-07-19 22:13:50 +08:00
} = { } ) : string {
const root = mkdtempSync ( join ( tmpdir ( ) , 'dsh-package-invariants-' ) )
roots . push ( root )
const dir = join ( root , 'packages/core/probe' )
mkdirSync ( join ( dir , 'src' ) , { recursive : true } )
const packageName = options . packageName ? ? '@deepseek-ai/dsh-probe'
2026-08-28 12:37:29 +08:00
const companion = options . companion ? ? true
const invariantExport = options . invariantExport ? ? companion
const invariantFile = options . invariantFile ? ? companion
const invariantDependency = options . invariantDependency ? ? companion
const invariantReference = options . invariantReference ? ? companion
const buildEntry = options . buildEntry ? ? companion
2026-07-19 22:13:50 +08:00
const manifest = {
name : packageName ,
2026-08-28 12:37:29 +08:00
exports : invariantExport ? {
2026-07-19 22:13:50 +08:00
'./invariant' : {
types : './lib/types/invariant.d.ts' ,
default : './lib/invariant.js' ,
} ,
2026-08-28 12:37:29 +08:00
} : { } ,
files : [ 'lib/index.js' , . . . invariantFile ? [ 'lib/invariant.js' ] : [ ] ] ,
peerDependencies : ! invariantDependency ? { } : {
2026-08-11 01:01:40 +08:00
'@deepseek-ai/dsh-invariants' : 'workspace:^' ,
2026-07-19 22:13:50 +08:00
} ,
2026-08-28 12:37:29 +08:00
devDependencies : ! invariantDependency ? { } : {
2026-07-19 22:13:50 +08:00
'@deepseek-ai/dsh-invariants' : 'workspace:^' ,
} ,
}
writeFileSync ( join ( dir , 'package.json' ) , ` ${ JSON . stringify ( manifest , null , 2 ) } \ n ` )
writeFileSync ( join ( dir , 'tsconfig.json' ) , ` ${ JSON . stringify ( {
2026-08-28 12:37:29 +08:00
references : invariantReference ? [ { path : '../../runtime-diagnostics/invariants' } ] : [ ] ,
2026-07-19 22:13:50 +08:00
} , null , 2 ) } \ n ` )
2026-08-28 12:37:29 +08:00
if ( companion ) {
writeFileSync ( join ( dir , 'src/invariant.ts' ) , options . source ? ? handwrittenInvariant ( packageName ) )
}
2026-07-19 22:13:50 +08:00
writeFileSync (
join ( dir , 'tsdown.config.ts' ) ,
2026-08-28 12:37:29 +08:00
buildEntry ? "export default { entry: ['lib/types/index.js', 'lib/types/invariant.js'] }\n" : "export default { entry: ['lib/types/index.js'] }\n" ,
)
writeFileSync (
join ( dir , 'README.md' ) ,
options . omissionReason === false ? '# Probe\n' : '# Probe\n\nNo runtime invariant companion is published because this fixture owns no diverging observations.\n' ,
2026-07-19 22:13:50 +08:00
)
return root
}
describe ( 'package invariant gate' , ( ) = > {
2026-07-20 00:38:37 +08:00
it ( 'accepts a hand-owned checking companion with publication metadata' , ( ) = > {
2026-07-19 22:13:50 +08:00
expect ( collectPackageInvariantViolations ( fixture ( ) ) ) . toEqual ( [ ] )
} )
2026-08-28 12:37:29 +08:00
it ( 'accepts a package that cleanly omits an invariant companion' , ( ) = > {
const root = fixture ( { companion : false } )
expect ( collectPackageInvariantViolations ( root ) ) . toEqual ( [ ] )
expect ( packageInvariantOwners ( root ) ) . toEqual ( [ ] )
} )
it ( 'requires an omitted companion to have a package-specific README reason' , ( ) = > {
const violations = collectPackageInvariantViolations ( fixture ( {
companion : false ,
omissionReason : false ,
} ) )
expect ( violations ) . toContainEqual ( {
path : 'packages/core/probe/README.md' ,
message : 'omitted companion requires a package-specific "No ... companion is published" reason' ,
} )
} )
2026-08-08 03:29:12 +08:00
it ( 'accepts an invariant reference owned by a package-local leaf project' , ( ) = > {
const root = fixture ( { invariantReference : false } )
const dir = join ( root , 'packages/core/probe' )
writeFileSync ( join ( dir , 'tsconfig.json' ) , ` ${ JSON . stringify ( {
files : [ ] ,
references : [ { path : './tsconfig.host.json' } ] ,
} , null , 2 ) } \ n ` )
writeFileSync ( join ( dir , 'tsconfig.host.json' ) , ` ${ JSON . stringify ( {
2026-08-13 00:36:22 +08:00
references : [ { path : '../../runtime-diagnostics/invariants' } ] ,
2026-08-08 03:29:12 +08:00
} , null , 2 ) } \ n ` )
expect ( collectPackageInvariantViolations ( root ) ) . toEqual ( [ ] )
} )
2026-07-19 22:13:50 +08:00
it ( 'rejects missing publication metadata and build output' , ( ) = > {
const violations = collectPackageInvariantViolations ( fixture ( {
invariantExport : false ,
2026-08-28 12:37:29 +08:00
invariantFile : false ,
2026-07-19 22:13:50 +08:00
invariantDependency : false ,
invariantReference : false ,
buildEntry : false ,
} ) )
expect ( violations . map ( violation = > violation . message ) ) . toEqual ( expect . arrayContaining ( [
expect . stringContaining ( 'exports["./invariant"]' ) ,
expect . stringContaining ( 'peerDependency' ) ,
expect . stringContaining ( 'devDependency' ) ,
expect . stringContaining ( 'TypeScript project references' ) ,
expect . stringContaining ( 'must bundle lib/types/invariant.js' ) ,
] ) )
} )
2026-08-28 12:37:29 +08:00
it ( 'rejects publication and build wiring left behind after omission' , ( ) = > {
const violations = collectPackageInvariantViolations ( fixture ( {
companion : false ,
invariantExport : true ,
invariantFile : true ,
buildEntry : true ,
} ) )
expect ( violations . map ( violation = > violation . message ) ) . toEqual ( expect . arrayContaining ( [
expect . stringContaining ( 'exports["./invariant"] must be omitted' ) ,
expect . stringContaining ( 'files must omit lib/invariant.js' ) ,
expect . stringContaining ( 'build override must omit lib/types/invariant.js' ) ,
] ) )
} )
2026-07-19 22:13:50 +08:00
it ( 'rejects foreign, duplicate, and unresolved registrations' , ( ) = > {
const source = `
export const name = 'probe-invariant'
export const inject = [ 'invariants' ]
const selected = process . env . PACKAGE_NAME
2026-07-20 00:38:37 +08:00
const install = ( _ctx : unknown , fail : ( message : string ) = > never ) = > { fail ( 'probe' ) }
export const apply = ( ctx : { invariants : { register ( name : string , install : typeof install ) : ( ) = > void } } ) = > {
ctx . invariants . register ( '@deepseek-ai/dsh-foreign' , install )
return ctx . invariants . register ( selected ! , install )
2026-07-19 22:13:50 +08:00
}
`
const violations = collectPackageInvariantViolations ( fixture ( { source } ) )
expect ( violations . map ( violation = > violation . message ) ) . toEqual ( expect . arrayContaining ( [
expect . stringContaining ( 'must resolve to a local string constant' ) ,
expect . stringContaining ( 'must register exactly its own package name' ) ,
] ) )
} )
2026-07-20 19:34:19 +08:00
it ( 'rejects generated markers and reporter-free executable installers' , ( ) = > {
2026-07-20 00:38:37 +08:00
const generated = fixture ( {
2026-07-20 00:54:28 +08:00
source : ` /** @generated */ \ n ${ handwrittenInvariant ( '@deepseek-ai/dsh-probe' ) } ` ,
2026-07-20 00:38:37 +08:00
} )
expect ( collectPackageInvariantViolations ( generated ) . map ( violation = > violation . message ) )
. toContain ( 'invariant companions must be hand-owned and may not carry @generated markers' )
2026-07-20 19:34:19 +08:00
const reporterFree = fixture ( {
2026-07-20 00:38:37 +08:00
source : `
export const name = 'probe-invariant'
export const inject = [ 'invariants' ]
2026-07-20 19:34:19 +08:00
const install = ( ) = > { void 0 }
2026-07-20 00:38:37 +08:00
export const apply = ( ctx : { invariants : { register ( name : string , install : typeof install ) : ( ) = > void } } ) = >
Promise . resolve ( ctx . invariants . register ( '@deepseek-ai/dsh-probe' , install ) )
` ,
} )
2026-07-20 19:34:19 +08:00
expect ( collectPackageInvariantViolations ( reporterFree ) . map ( violation = > violation . message ) )
. toContain ( 'install function must accept the bound failure reporter as its second parameter' )
2026-07-20 00:38:37 +08:00
const unused = fixture ( {
source : `
export const name = 'probe-invariant'
export const inject = [ 'invariants' ]
const install = ( _ctx : unknown , _fail : ( message : string ) = > never ) = > { void 0 }
export const apply = ( ctx : { invariants : { register ( name : string , install : typeof install ) : ( ) = > void } } ) = >
Promise . resolve ( ctx . invariants . register ( '@deepseek-ai/dsh-probe' , install ) )
` ,
} )
expect ( collectPackageInvariantViolations ( unused ) . map ( violation = > violation . message ) )
. toContain ( 'install function must use its bound failure reporter' )
} )
2026-07-20 23:16:08 +08:00
it ( 'rejects registering a different installer than the checked local function' , ( ) = > {
const decoy = fixture ( {
source : `
export const name = 'probe-invariant'
export const inject = [ 'invariants' ]
const install = ( _ctx : unknown , fail : ( message : string ) = > never ) = > { fail ( 'checked decoy' ) }
export const apply = ( ctx : { invariants : { register ( name : string , install : ( ) = > void ) : ( ) = > void } } ) = >
ctx . invariants . register ( '@deepseek-ai/dsh-probe' , ( ) = > { } )
` ,
} )
expect ( collectPackageInvariantViolations ( decoy ) . map ( violation = > violation . message ) )
. toContain ( 'line 6: ctx.invariants.register must use the checked local install function' )
} )
2026-07-21 00:25:38 +08:00
it . each ( [
'export default { name, inject, apply }' ,
"export * as default from './probe.ts'" ,
] ) ( 'rejects a default export that would collapse the Loader namespace' , ( defaultExport ) = > {
const source = ` ${ handwrittenInvariant ( '@deepseek-ai/dsh-probe' ) } \ n ${ defaultExport } \ n `
expect ( collectPackageInvariantViolations ( fixture ( { source } ) ) . map ( violation = > violation . message ) )
. toContain ( 'must not default-export; Loader must retain the companion namespace' )
} )
2026-08-28 12:37:29 +08:00
it ( 'rejects empty installers because packages without a check omit the companion' , ( ) = > {
const source = `
2026-07-20 19:34:19 +08:00
export const name = 'probe-invariant'
export const inject = [ 'invariants' ]
const PACKAGE_NAME = '@deepseek-ai/dsh-probe'
/** No runtime invariant: this pure package owns no events or mutable data. */
const install = ( ) = > { }
export const apply = ( ctx : { invariants : { register ( name : string , install : ( ) = > void ) : ( ) = > void } } ) = >
ctx . invariants . register ( PACKAGE_NAME , install )
`
2026-08-28 12:37:29 +08:00
expect ( collectPackageInvariantViolations ( fixture ( { source } ) ) . map ( violation = > violation . message ) )
. toContain ( 'empty install function is unnecessary; omit the companion and its publication wiring' )
2026-07-20 18:39:37 +08:00
} )
2026-07-19 22:13:50 +08:00
} )