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'
2026-08-26 15:49:42 +08:00
import { usesFlattenedPackageDependencies } from './package-dependency-policy.ts'
2026-07-19 22:13:50 +08:00
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
2026-08-26 15:49:42 +08:00
packageDirectory? : string
2026-07-19 22:13:50 +08:00
source? : string
2026-08-26 15:49:42 +08:00
clientDeclaration? : boolean
clientExport? : boolean
2026-07-19 22:13:50 +08:00
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 )
2026-08-26 15:49:42 +08:00
const packageDirectory = options . packageDirectory ? ? 'packages/core/probe'
const dir = join ( root , packageDirectory )
2026-07-19 22:13:50 +08:00
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-08-31 14:38:55 +08:00
const exports = {
. . . ( invariantExport ? { './invariant' : {
2026-08-26 15:49:42 +08:00
types : './lib/types/invariant.d.ts' ,
default : './lib/invariant.js' ,
2026-08-31 14:38:55 +08:00
} } : { } ) ,
2026-08-26 15:49:42 +08:00
. . . ( options . clientExport === true ? {
'./client' : {
types : './lib/types/client/index.d.ts' ,
default : './lib/client.js' ,
} ,
} : { } ) ,
}
const dsh = options . clientDeclaration === true ? { client : { } } : undefined
const developmentOnlyInvariant = usesFlattenedPackageDependencies (
` ${ packageDirectory } /package.json ` ,
packageName ,
dsh ,
)
2026-07-19 22:13:50 +08:00
const manifest = {
name : packageName ,
2026-08-26 15:49:42 +08:00
. . . ( dsh === undefined ? { } : { dsh } ) ,
exports ,
2026-08-28 12:37:29 +08:00
files : [ 'lib/index.js' , . . . invariantFile ? [ 'lib/invariant.js' ] : [ ] ] ,
2026-08-31 14:38:55 +08:00
peerDependencies : ! invariantDependency || developmentOnlyInvariant ? { } : {
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 ( [ ] )
} )
2026-08-31 17:10:19 +08:00
it ( 'requires an omitted companion to have a README reason sentence' , ( ) = > {
2026-08-28 12:37:29 +08:00
const violations = collectPackageInvariantViolations ( fixture ( {
companion : false ,
omissionReason : false ,
} ) )
expect ( violations ) . toContainEqual ( {
path : 'packages/core/probe/README.md' ,
2026-08-31 17:10:19 +08:00
message : 'omitted companion requires a README "No ... companion is published" reason sentence' ,
2026-08-28 12:37:29 +08:00
} )
} )
2026-08-26 15:49:42 +08:00
it ( 'accepts development-only invariants for configured Host dependencies' , ( ) = > {
expect ( collectPackageInvariantViolations ( fixture ( { packageName : '@deepseek-ai/dsh-llm' } ) ) ) . toEqual ( [ ] )
} )
it ( 'accepts development-only invariants for client packages' , ( ) = > {
expect ( collectPackageInvariantViolations ( fixture ( {
packageName : '@deepseek-ai/dsh-client-probe' ,
packageDirectory : 'packages/client/probe' ,
} ) ) ) . toEqual ( [ ] )
} )
it ( 'accepts development-only invariants for packages with a dsh.client entry' , ( ) = > {
expect ( collectPackageInvariantViolations ( fixture ( { clientDeclaration : true , clientExport : true } ) ) ) . toEqual ( [ ] )
} )
it ( 'keeps invariant peers for packages that only export a Client API' , ( ) = > {
expect ( collectPackageInvariantViolations ( fixture ( { clientExport : true } ) ) ) . toEqual ( [ ] )
} )
it ( 'keeps invariant peers for experimental packages with a dsh.client entry' , ( ) = > {
expect ( collectPackageInvariantViolations ( fixture ( {
packageDirectory : 'packages/experimental/probe' ,
clientDeclaration : true ,
clientExport : true ,
} ) ) ) . toEqual ( [ ] )
} )
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 ,
2026-08-31 17:10:19 +08:00
invariantReference : true ,
2026-08-28 12:37:29 +08:00
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' ) ,
2026-08-31 17:10:19 +08:00
expect . stringContaining ( 'TypeScript project references must omit ../../runtime-diagnostics/invariants' ) ,
2026-08-28 12:37:29 +08:00
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'
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
} )