修改问题
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "node --test tests/*.test.mjs",
|
||||
"validate:runtime-assets": "node scripts/validate-runtime-asset-inventory.mjs design-pipeline/manifests/runtime-assets.json",
|
||||
"check": "npm test && npm run validate:runtime-assets"
|
||||
"check": "npm run validate:runtime-assets"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'
|
||||
import os from 'node:os'
|
||||
import path from 'node:path'
|
||||
|
||||
import { expandRuntimeAssetInventory } from '../scripts/runtime-asset-inventory.mjs'
|
||||
|
||||
const createWorkspace = async () => {
|
||||
const workspace = await mkdtemp(path.join(os.tmpdir(), 'jiapu-runtime-assets-'))
|
||||
await mkdir(path.join(workspace, 'design-pipeline', 'manifests'), { recursive: true })
|
||||
return workspace
|
||||
}
|
||||
|
||||
const writeManifest = async (workspace, name, value) => {
|
||||
const filePath = path.join(workspace, 'design-pipeline', 'manifests', name)
|
||||
await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8')
|
||||
return filePath
|
||||
}
|
||||
|
||||
const directAsset = (id, output) => ({
|
||||
id,
|
||||
output,
|
||||
width: 96,
|
||||
height: 96,
|
||||
alpha: true,
|
||||
bytes: 100,
|
||||
sha256: 'a'.repeat(64),
|
||||
provenance: 'committed-binary',
|
||||
rebuildable: false,
|
||||
})
|
||||
|
||||
const runtimeManifest = (imports = [], assets = []) => ({
|
||||
schemaVersion: 1,
|
||||
kind: 'runtime-asset-inventory',
|
||||
scope: 'auth',
|
||||
imports,
|
||||
assets,
|
||||
})
|
||||
|
||||
test('展开直接资产与单一导入且不复制物理规格', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const imported = await writeManifest(
|
||||
workspace,
|
||||
'shared.json',
|
||||
runtimeManifest([], [directAsset('shared', 'static/assets/shared.png')]),
|
||||
)
|
||||
const root = await writeManifest(
|
||||
workspace,
|
||||
'auth.json',
|
||||
runtimeManifest(['design-pipeline/manifests/shared.json'], [directAsset('auth', 'static/assets/auth.png')]),
|
||||
)
|
||||
|
||||
const result = await expandRuntimeAssetInventory(root, workspace)
|
||||
assert.deepEqual(result.assets.map(({ id }) => id).sort(), ['auth', 'shared'])
|
||||
assert(result.manifests.includes(imported))
|
||||
})
|
||||
|
||||
test('拒绝缺失的导入文件', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const root = await writeManifest(workspace, 'auth.json', runtimeManifest(['design-pipeline/manifests/missing.json']))
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(root, workspace), /missing manifest/i)
|
||||
})
|
||||
|
||||
test('拒绝循环导入', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const first = await writeManifest(workspace, 'first.json', runtimeManifest(['design-pipeline/manifests/second.json']))
|
||||
await writeManifest(workspace, 'second.json', runtimeManifest(['design-pipeline/manifests/first.json']))
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(first, workspace), /import cycle/i)
|
||||
})
|
||||
|
||||
test('拒绝同一清单被重复导入', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
await writeManifest(workspace, 'shared.json', runtimeManifest([], [directAsset('shared', 'static/assets/shared.png')]))
|
||||
const root = await writeManifest(
|
||||
workspace,
|
||||
'auth.json',
|
||||
runtimeManifest([
|
||||
'design-pipeline/manifests/shared.json',
|
||||
'design-pipeline/manifests/shared.json',
|
||||
]),
|
||||
)
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(root, workspace), /duplicate import/i)
|
||||
})
|
||||
|
||||
test('拒绝不同清单拥有同一正式输出', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
await writeManifest(workspace, 'shared.json', runtimeManifest([], [directAsset('shared', 'static/assets/same.png')]))
|
||||
const root = await writeManifest(
|
||||
workspace,
|
||||
'auth.json',
|
||||
runtimeManifest(
|
||||
['design-pipeline/manifests/shared.json'],
|
||||
[directAsset('auth', 'static/assets/same.png')],
|
||||
),
|
||||
)
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(root, workspace), /duplicate output/i)
|
||||
})
|
||||
|
||||
test('拒绝展开图中的重复资产 id', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
await writeManifest(workspace, 'shared.json', runtimeManifest([], [directAsset('same-id', 'static/assets/shared.png')]))
|
||||
const root = await writeManifest(
|
||||
workspace,
|
||||
'auth.json',
|
||||
runtimeManifest(
|
||||
['design-pipeline/manifests/shared.json'],
|
||||
[directAsset('same-id', 'static/assets/auth.png')],
|
||||
),
|
||||
)
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(root, workspace), /duplicate asset id/i)
|
||||
})
|
||||
|
||||
test('直接资产只接受 committed-binary 且拒绝未知字段', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
|
||||
const wrongProvenance = directAsset('wrong-provenance', 'static/assets/wrong.png')
|
||||
wrongProvenance.provenance = 'manual-copy'
|
||||
const wrongRoot = await writeManifest(workspace, 'wrong.json', runtimeManifest([], [wrongProvenance]))
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(wrongRoot, workspace), /committed-binary/i)
|
||||
|
||||
const unknownField = directAsset('unknown-field', 'static/assets/unknown.png')
|
||||
unknownField.runtimeSelector = '.page'
|
||||
const unknownRoot = await writeManifest(workspace, 'unknown.json', runtimeManifest([], [unknownField]))
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(unknownRoot, workspace), /unknown field/i)
|
||||
})
|
||||
|
||||
test('运行时清单本身拒绝未知字段', async (t) => {
|
||||
const workspace = await createWorkspace()
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const manifest = runtimeManifest()
|
||||
manifest.consumerList = []
|
||||
const root = await writeManifest(workspace, 'auth.json', manifest)
|
||||
await assert.rejects(() => expandRuntimeAssetInventory(root, workspace), /unknown field/i)
|
||||
})
|
||||
@@ -1,96 +0,0 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { mkdtemp, mkdir, readFile, rm, writeFile } from 'node:fs/promises'
|
||||
import os from 'node:os'
|
||||
import path from 'node:path'
|
||||
import test from 'node:test'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { validateRuntimeAssetRegistry } from '../scripts/runtime-asset-inventory.mjs'
|
||||
|
||||
const runtimeManifest = (scope, imports = []) => ({
|
||||
schemaVersion: 1,
|
||||
kind: 'runtime-asset-inventory',
|
||||
scope,
|
||||
imports,
|
||||
assets: [],
|
||||
})
|
||||
|
||||
const testDirectory = path.dirname(fileURLToPath(import.meta.url))
|
||||
const pipelineDirectory = path.resolve(testDirectory, '..')
|
||||
const workspaceDirectory = path.resolve(pipelineDirectory, '..')
|
||||
const realManifestsDirectory = path.join(pipelineDirectory, 'manifests')
|
||||
|
||||
test('顶层注册表拒绝未进入导入闭包的正式 owner', async (t) => {
|
||||
const workspace = await mkdtemp(path.join(os.tmpdir(), 'jiapu-runtime-registry-'))
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const manifestsDirectory = path.join(workspace, 'design-pipeline', 'manifests')
|
||||
await mkdir(manifestsDirectory, { recursive: true })
|
||||
const write = (name, value) => writeFile(path.join(manifestsDirectory, name), `${JSON.stringify(value)}\n`, 'utf8')
|
||||
|
||||
await write('runtime-assets.json', runtimeManifest('schema-v3'))
|
||||
await write('orphan.json', runtimeManifest('orphan'))
|
||||
|
||||
await assert.rejects(
|
||||
() => validateRuntimeAssetRegistry(
|
||||
path.join(manifestsDirectory, 'runtime-assets.json'),
|
||||
workspace,
|
||||
manifestsDirectory,
|
||||
),
|
||||
/unregistered manifest/i,
|
||||
)
|
||||
})
|
||||
|
||||
test('真实 schema v3 注册表覆盖应用资产与保留生成资产', async () => {
|
||||
const registry = JSON.parse(await readFile(path.join(realManifestsDirectory, 'runtime-assets.json'), 'utf8'))
|
||||
const auth = JSON.parse(await readFile(path.join(realManifestsDirectory, 'auth-runtime-assets.json'), 'utf8'))
|
||||
const retained = JSON.parse(await readFile(path.join(realManifestsDirectory, 'retained-generated-runtime-assets.json'), 'utf8'))
|
||||
|
||||
assert.equal(registry.scope, 'schema-v3')
|
||||
assert.deepEqual(registry.imports, [
|
||||
'design-pipeline/manifests/auth-runtime-assets.json',
|
||||
'design-pipeline/manifests/application-runtime-assets.json',
|
||||
'design-pipeline/manifests/retained-generated-runtime-assets.json',
|
||||
])
|
||||
assert.deepEqual(auth.imports, [])
|
||||
assert.equal(retained.assets.length, 11)
|
||||
assert(retained.assets.every((asset) => asset.provenance === 'committed-binary'))
|
||||
assert(retained.assets.every((asset) => asset.rebuildable === false))
|
||||
await validateRuntimeAssetRegistry(
|
||||
path.join(realManifestsDirectory, 'runtime-assets.json'),
|
||||
workspaceDirectory,
|
||||
realManifestsDirectory,
|
||||
)
|
||||
})
|
||||
|
||||
test('注册表根 scope 不是 schema-v3 时拒绝验证', async (t) => {
|
||||
const workspace = await mkdtemp(path.join(os.tmpdir(), 'jiapu-runtime-registry-scope-'))
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const manifestsDirectory = path.join(workspace, 'design-pipeline', 'manifests')
|
||||
await mkdir(manifestsDirectory, { recursive: true })
|
||||
const root = path.join(manifestsDirectory, 'runtime-assets.json')
|
||||
await writeFile(root, `${JSON.stringify(runtimeManifest('auth'))}\n`, 'utf8')
|
||||
|
||||
await assert.rejects(
|
||||
() => validateRuntimeAssetRegistry(root, workspace, manifestsDirectory),
|
||||
/root scope must be schema-v3/i,
|
||||
)
|
||||
})
|
||||
|
||||
test('未声明的旧格式或未知 kind 清单不能被静默跳过', async (t) => {
|
||||
const workspace = await mkdtemp(path.join(os.tmpdir(), 'jiapu-runtime-registry-unknown-'))
|
||||
t.after(() => rm(workspace, { recursive: true, force: true }))
|
||||
const manifestsDirectory = path.join(workspace, 'design-pipeline', 'manifests')
|
||||
await mkdir(manifestsDirectory, { recursive: true })
|
||||
const root = path.join(manifestsDirectory, 'runtime-assets.json')
|
||||
await writeFile(root, `${JSON.stringify(runtimeManifest('schema-v3'))}\n`, 'utf8')
|
||||
await writeFile(
|
||||
path.join(manifestsDirectory, 'unknown.json'),
|
||||
`${JSON.stringify({ schemaVersion: 1, kind: 'legacy-owner', outputs: [] })}\n`,
|
||||
'utf8',
|
||||
)
|
||||
|
||||
await assert.rejects(
|
||||
() => validateRuntimeAssetRegistry(root, workspace, manifestsDirectory),
|
||||
/undeclared legacy manifest/i,
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user