56 行
4.8 KiB
JavaScript
56 行
4.8 KiB
JavaScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import {fileURLToPath} from 'node:url'
|
|
import assert from 'node:assert/strict'
|
|
import {syncInput,checkInput,watchInput} from '../scripts/install.mjs'
|
|
const parent=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'../.glyphix-work')
|
|
fs.mkdirSync(parent,{recursive:true})
|
|
const scratch=fs.mkdtempSync(path.join(parent,'sync-test-')),source=path.join(scratch,'source'),host=path.join(scratch,'host')
|
|
function write(root,name,body){const file=path.join(root,name);fs.mkdirSync(path.dirname(file),{recursive:true});fs.writeFileSync(file,body)}
|
|
function fixture(root){
|
|
write(root,'src/manifest.json',JSON.stringify({versionName:'fixture',router:{pages:{}}}))
|
|
for(const name of ['keyboard/index.ux','components/CrabInput/index.ux','assets/ime-icons/icon.png',...['engine','theme','lifecycle'].map(n=>'common/ime-'+n+'.js')])write(root,'src/'+name,'first')
|
|
write(root,'src/assets/ime-dict/meta.json',JSON.stringify({shards:['2222']}));write(root,'src/assets/ime-dict/2222.json','{}');write(root,'src/assets/ime-dict/runtime.json','{"version":1}')
|
|
for(const name of ['crabKeyboard','jieba','remix-icon'])write(root,'third_party/'+name+'/LICENSE','MIT')
|
|
write(root,'LICENSE','MIT');write(root,'NOTICE.md','third party notices')
|
|
}
|
|
let stop
|
|
try{
|
|
fixture(source);write(host,'src/manifest.json',JSON.stringify({router:{pages:{}}}));write(host,'src/assets/host-data.txt','preserve')
|
|
write(host,'src/assets/ime-dict/meta.json',JSON.stringify({shards:['1111']}));write(host,'src/assets/ime-dict/1111.json','old format')
|
|
const first=syncInput(host,source);assert.equal(first.copied,14);assert.equal(first.removed,1);checkInput(host,source)
|
|
assert.equal(fs.readFileSync(path.join(host,'src/assets/ime-dict/runtime.json'),'utf8'),'{"version":1}','Compact runtime index is included in host synchronization')
|
|
const timestamp=fs.statSync(path.join(host,'src/components/CrabInput/index.ux')).mtimeMs
|
|
assert.equal(syncInput(host,source).copied,0);assert.equal(fs.statSync(path.join(host,'src/components/CrabInput/index.ux')).mtimeMs,timestamp)
|
|
write(host,'src/common/ime-theme.js','stale');assert.throws(()=>checkInput(host,source),/differs/);assert.equal(syncInput(host,source).copied,1)
|
|
write(source,'src/common/ime-engine.js','second');assert.throws(()=>checkInput(host,source),/changed/)
|
|
write(host,'input-component.json',JSON.stringify({schema:1,integration:'component'}));syncInput(host,source)
|
|
assert.ok(!JSON.parse(fs.readFileSync(path.join(host,'src/manifest.json'),'utf8')).router.pages.keyboard)
|
|
assert.ok(!fs.existsSync(path.join(host,'src/keyboard/index.ux')))
|
|
write(source,'src/keyboard/index.ux','unused compatibility route update');checkInput(host,source)
|
|
const events=[];stop=watchInput(host,source,event=>events.push(event))
|
|
const initial=events.length
|
|
write(source,'src/components/CrabInput/index.ux','component update')
|
|
write(source,'src/common/ime-theme.js','theme update')
|
|
write(source,'src/assets/ime-icons/new-icon.png','new icon')
|
|
write(source,'src/common/ime-layout.js','new related module')
|
|
write(source,'src/assets/ime-dict/meta.json',JSON.stringify({shards:['3333'],association_shards:['a0f'],completion_shards:['c01']}));write(source,'src/assets/ime-dict/3333.json','{"changed":true}');write(source,'src/assets/ime-dict/a0f.json','{}');write(source,'src/assets/ime-dict/c01.json','{}')
|
|
const deadline=Date.now()+8000
|
|
while(Date.now()<deadline){await new Promise(resolve=>setTimeout(resolve,50));try{checkInput(host,source);break}catch{}}
|
|
const current=checkInput(host,source)
|
|
assert.ok(fs.existsSync(path.join(host,'src/assets/ime-dict/a0f.json'))&&fs.existsSync(path.join(host,'src/assets/ime-dict/c01.json')),'prediction shards synchronize')
|
|
assert.notEqual(current.sourceHash,first.sourceHash);assert.ok(events.length>initial)
|
|
assert.equal(fs.readFileSync(path.join(host,'src/common/ime-layout.js'),'utf8'),'new related module')
|
|
assert.ok(!fs.existsSync(path.join(host,'src/assets/ime-dict/2222.json')))
|
|
assert.equal(fs.readFileSync(path.join(host,'src/assets/host-data.txt'),'utf8'),'preserve')
|
|
const receipt=JSON.parse(fs.readFileSync(path.join(host,'src/assets/crab-input-source.json'),'utf8'))
|
|
receipt.files['../outside']={};write(host,'src/assets/crab-input-source.json',JSON.stringify(receipt))
|
|
assert.throws(()=>syncInput(host,source),/Invalid managed/)
|
|
assert.ok(!fs.existsSync(path.join(host,'src/assets/crab-input-source.json')),'failed sync invalidates receipt')
|
|
console.log(JSON.stringify({suite:'input-sync',status:'passed',watchEvents:events.length,checks:['incremental','tamper rejection','source drift rejection','watch component engine theme icon dictionary update','obsolete shard removal','host isolation','invalid receipt rejection']}))
|
|
}finally{
|
|
if(stop)stop()
|
|
if(!scratch.startsWith(parent+path.sep+'sync-test-'))throw Error('Unexpected test directory')
|
|
fs.rmSync(scratch,{recursive:true,force:true})
|
|
}
|