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) })