import {test} from 'node:test'; import assert from 'node:assert/strict'; import {mkdtemp,mkdir,writeFile,readFile,rm,symlink,cp,realpath} from 'node:fs/promises'; import {join} from 'node:path'; import {tmpdir} from 'node:os'; import {fileURLToPath} from 'node:url'; import {checkLockSync,packageLockVersions,pnpmLockVersions,LOCKED_RUNTIME} from '../scripts/check-lock-sync.mjs'; const projectRoot=fileURLToPath(new URL('../',import.meta.url)); test('repository npm and pnpm locks agree with the installed runtime packages',()=>{ const result=checkLockSync(projectRoot); assert.equal(result.expected.next,result.installed.next); assert.ok(result.pnpm); assert.equal(result.pnpm.next,result.expected.next); for(const name of LOCKED_RUNTIME)assert.match(result.expected[name],/^\d+\.\d+\.\d+/); }); test('lock sync rejects an installed next that drifts from package-lock.json',async t=>{ const root=await mkdtemp(join(tmpdir(),'91-lock-sync-'));t.after(()=>rm(root,{recursive:true,force:true})); await writeFile(join(root,'package.json'),JSON.stringify({name:'fixture',type:'module',dependencies:{next:'16.4.3'}})); await writeFile(join(root,'package-lock.json'),JSON.stringify({ lockfileVersion:3, packages:{ 'node_modules/next':{version:'16.4.3'}, 'node_modules/react':{version:'19.3.1'}, 'node_modules/react-dom':{version:'19.3.1'}, 'node_modules/dotenv':{version:'17.2.3'}, 'node_modules/hls.js':{version:'1.7.3'}, 'node_modules/qrcode':{version:'1.5.4'}, }, })); for(const [name,version] of Object.entries(packageLockVersions(root))){ const dir=join(root,'node_modules',name); await mkdir(dir,{recursive:true}); await writeFile(join(dir,'package.json'),JSON.stringify({name,version:name==='next'?'16.4.2':version})); } assert.throws(()=>checkLockSync(root),/已安装 16\.4\.2[\s\S]*package-lock\.json 为 16\.4\.3/); }); test('lock sync rejects pnpm-lock next that drifts from package-lock.json',async t=>{ const root=await mkdtemp(join(tmpdir(),'91-lock-pnpm-'));t.after(()=>rm(root,{recursive:true,force:true})); const expected=packageLockVersions(projectRoot); await writeFile(join(root,'package.json'),JSON.stringify({name:'fixture',type:'module'})); await writeFile(join(root,'package-lock.json'),JSON.stringify({ lockfileVersion:3, packages:Object.fromEntries(LOCKED_RUNTIME.map(name=>[`node_modules/${name}`,{version:expected[name]}])), })); for(const name of LOCKED_RUNTIME){ const dir=join(root,'node_modules',name); await mkdir(dir,{recursive:true}); await writeFile(join(dir,'package.json'),JSON.stringify({name,version:expected[name]})); } const pnpm=[ 'lockfileVersion: \'9.0\'','','importers:','', ' .:',' dependencies:', ...LOCKED_RUNTIME.flatMap(name=>[ ` ${name}:`, ` specifier: ${expected[name]}`, ` version: ${name==='next'?'16.0.0':expected[name]}`, ]), '', ].join('\n'); await writeFile(join(root,'pnpm-lock.yaml'),pnpm); assert.equal(pnpmLockVersions(root).next,'16.0.0'); assert.throws(()=>checkLockSync(root),/pnpm-lock\.yaml 为 16\.0\.0/); }); test('dotenv copy source resolves under both real directories and pnpm links',async t=>{ const root=await mkdtemp(join(tmpdir(),'91-dotenv-'));t.after(()=>rm(root,{recursive:true,force:true})); const real=join(root,'.store/dotenv'); await mkdir(real,{recursive:true}); await writeFile(join(real,'package.json'),JSON.stringify({name:'dotenv',version:'17.2.3'})); await mkdir(join(root,'node_modules'),{recursive:true}); await symlink(real,join(root,'node_modules/dotenv')); const destination=join(root,'out/node_modules/dotenv'); await mkdir(join(root,'out/node_modules'),{recursive:true}); await cp(await realpath(join(root,'node_modules/dotenv')),destination,{recursive:true,dereference:true}); assert.equal(JSON.parse(await readFile(join(destination,'package.json'),'utf8')).version,'17.2.3'); });