diff --git a/tests/assets.test.mjs b/tests/assets.test.mjs index 78b24ca..2292829 100644 --- a/tests/assets.test.mjs +++ b/tests/assets.test.mjs @@ -61,3 +61,44 @@ for (const [name, dataUrl] of Object.entries(alphaAssets)) { assert.ok(hasAlphaChunk || usesLosslessWebP, `${name} should preserve transparent background data`); }); } + +const webpDimensions = (name, dataUrl) => { + const match = /^data:image\/webp;base64,([A-Za-z0-9+/=]+)$/.exec(dataUrl); + assert.ok(match, `${name} must be a WebP data URL`); + const bytes = Buffer.from(match[1], 'base64'); + + let offset = 12; + while (offset + 18 <= bytes.length) { + const type = bytes.subarray(offset, offset + 4).toString('ascii'); + const size = bytes.readUInt32LE(offset + 4); + const dataOffset = offset + 8; + + if (type === 'VP8X') { + const width = + 1 + + bytes[dataOffset + 4] + + (bytes[dataOffset + 5] << 8) + + (bytes[dataOffset + 6] << 16); + const height = + 1 + + bytes[dataOffset + 7] + + (bytes[dataOffset + 8] << 8) + + (bytes[dataOffset + 9] << 16); + return { width, height }; + } + + offset = dataOffset + size + (size % 2); + } + + assert.fail(`${name} must expose VP8X dimensions`); +}; + +for (const [name, dataUrl] of Object.entries({ playerHealth, enemyHealth })) { + test(`${name} health sheet stays high resolution`, () => { + const { width, height } = webpDimensions(name, dataUrl); + assert.ok(width >= 1200, `${name} width must stay >= 1200px, got ${width}px`); + assert.ok(height >= 300, `${name} height must stay >= 300px, got ${height}px`); + assert.ok(width / 4 >= 300, `${name} frame width must stay >= 300px`); + assert.ok(height / 3 >= 100, `${name} frame height must stay >= 100px`); + }); +}