import test from 'node:test'; import assert from 'node:assert/strict'; import {createRequire} from 'node:module'; const require=createRequire(import.meta.url),{PNG}=require('pngjs'),{decodePNG,fingerprintPNG}=require('../packages/core/visual-image.cjs'); function image(){const png=new PNG({width:64,height:64});for(let y=0;y<64;y++)for(let x=0;x<64;x++){const i=(y*64+x)*4;png.data.set([x<32?30:240,y<20?10:180,x+y,255],i);}return PNG.sync.write(png);} test('bounded PNG returns deterministic derived features without source pixels',()=>{const source=image(),decoded=decodePNG(source),feature=fingerprintPNG(source);assert.equal(decoded.rgba.length,64*64*4);assert.equal(feature.usable,true);assert.match(feature.hash,/^[a-f0-9]{16}$/);assert.equal(feature.rgba,undefined);assert.deepEqual(feature,fingerprintPNG(source));}); test('malformed, oversized, animated/interlaced and oversized output PNG are refused',()=>{ assert.throws(()=>decodePNG(Buffer.alloc(11*1024*1024)));assert.throws(()=>decodePNG(image().subarray(0,40))); for(const mutate of [bytes=>bytes.writeUInt32BE(0xffffffff,16),bytes=>{bytes[28]=1;},bytes=>{bytes[24]=16;},bytes=>{bytes[bytes.length-5]^=1;}]){const bytes=image();mutate(bytes);assert.throws(()=>decodePNG(bytes));} assert.throws(()=>decodePNG(Buffer.concat([image(),Buffer.from('trailing-data')]))); });