Files
jiapuapp/design-pipeline/tests/manifest-v2.test.mjs
T
2026-07-16 18:13:03 +08:00

73 lines
2.7 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { validateManifest } from '../scripts/manifest-v2.mjs'
const testDirectory = path.dirname(fileURLToPath(import.meta.url))
const workspace = path.resolve(testDirectory, '..', '..')
const validAsset = () => ({
id: 'a01-primary-button-v2',
assetClass: 'fixed-bitmap',
source: 'static/assets/foundation/opaque/a01-primary-button.png',
output: 'static/assets/foundation/transparent/a01-primary-button-v2.png',
logicalSlot: { widthRpx: 622, heightRpx: 92 },
outputPixels: { width: 1866, height: 276 },
render: { scalePolicy: 'uniform-only', uniMode: 'aspectFit', allowDistortion: false },
alpha: { required: true, transparentOuterPadding: 12, cornerMaxAlpha: 0 },
edge: { forbidChromaResidue: true, forbidLightFringe: true, premultipliedAlphaCheck: true },
quality: { maxBytes: 500000, symmetry: 'horizontal', colorSpace: 'sRGB' },
processing: { trim: 8, capWidth: 180 },
runtime: { selector: '.login-submit', imageSelector: '.button-skin img' },
consumers: ['pages/auth/a01-entry.vue']
})
const validManifest = () => ({
schemaVersion: 2,
page: 'A01',
runtime: { url: 'http://localhost:5173/#/pages/auth/a01-entry', chromePort: 9222 },
assets: [validAsset()]
})
test('accepts a complete manifest v2', () => {
const manifest = validManifest()
assert.equal(validateManifest(manifest, workspace), manifest)
})
test('rejects duplicate asset ids', () => {
const manifest = validManifest()
manifest.assets.push(validAsset())
assert.throws(() => validateManifest(manifest, workspace), /duplicate asset id/i)
})
test('rejects paths that escape the workspace', () => {
const manifest = validManifest()
manifest.assets[0].output = '../outside.png'
assert.throws(() => validateManifest(manifest, workspace), /escapes workspace/i)
})
test('rejects a fixed bitmap whose output ratio differs from its slot', () => {
const manifest = validManifest()
manifest.assets[0].outputPixels.height = 300
assert.throws(() => validateManifest(manifest, workspace), /ratio drift/i)
})
test('rejects scaleToFill for uniform-only assets', () => {
const manifest = validManifest()
manifest.assets[0].render.uniMode = 'scaleToFill'
assert.throws(() => validateManifest(manifest, workspace), /scaleToFill/i)
})
test('rejects unknown asset classes', () => {
const manifest = validManifest()
manifest.assets[0].assetClass = 'mystery'
assert.throws(() => validateManifest(manifest, workspace), /assetClass/i)
})
test('rejects assets without consumers', () => {
const manifest = validManifest()
manifest.assets[0].consumers = []
assert.throws(() => validateManifest(manifest, workspace), /consumers/i)
})