aboutsummaryrefslogtreecommitdiffstats
path: root/tools/image-thumbnails-test.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-22 10:12:49 -0700
committerAdam Soltys <[email protected]>2026-10-22 10:12:49 -0700
commitcc84dd0c6c852b46b309079a5a90a54080fc049c (patch)
treeaf524ce1d63d2d62b987cc456553c563391ebea5 /tools/image-thumbnails-test.js
parent7947be155d4cc4f43dd89d743c5e09bfac4b635b (diff)
downloadcoinosv3-cc84dd0c6c852b46b309079a5a90a54080fc049c.tar.gz
coinosv3-cc84dd0c6c852b46b309079a5a90a54080fc049c.zip
Images grid in justified rows too: tiles in each picture's own shape (the tile thumbnail is no longer a square crop: 360px tall, its middle cut to 1:2–2:1; vmedia pic.webp?s=row for hosts without CORS; tile cache v2)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'tools/image-thumbnails-test.js')
-rw-r--r--tools/image-thumbnails-test.js19
1 files changed, 12 insertions, 7 deletions
diff --git a/tools/image-thumbnails-test.js b/tools/image-thumbnails-test.js
index ede7e11..6ece275 100644
--- a/tools/image-thumbnails-test.js
+++ b/tools/image-thumbnails-test.js
@@ -1,4 +1,4 @@
-// Real minified blob worker: both thumbnail sizes, animated originals,
+// Real minified blob worker: both thumbnail sizes (the tile in the picture's own shape), animated originals,
// bounded concurrency and graceful fallback, with no page-thread encoding.
import assert from 'node:assert/strict';
import puppeteer from './puppeteer.js';
@@ -30,25 +30,30 @@ try {
thumbnails(new Blob(['broken'],{type:'image/jpeg'}),{width:1100}), thumbnails(blob,{width:1100}),
]);
const media = await decode(big.media), tile = await decode(big.tile);
- const square = new OffscreenCanvas(360,360);square.getContext('2d').drawImage(tile,0,0);
- const pixel=[...square.getContext('2d').getImageData(0,180,1,1).data];
+ const whole = new OffscreenCanvas(tile.width,tile.height);whole.getContext('2d').drawImage(tile,0,0);
+ const pixel=[...whole.getContext('2d').getImageData(tile.width>>1,180,1,1).data], edge=[...whole.getContext('2d').getImageData(2,180,1,1).data];
+ // a panorama past 2:1 keeps its middle, 2:1
+ const pano=new OffscreenCanvas(4000,1000);pano.getContext('2d').fillStyle='green';pano.getContext('2d').fillRect(0,0,4000,1000);
+ const panoTile=await decode((await thumbnails(await encode.call(pano,{type:'image/png'}),{tileSize:360})).tile);
const smallCanvas=new OffscreenCanvas(32,20);smallCanvas.getContext('2d');
const smallBlob=await encode.call(smallCanvas,{type:'image/png'});
const small=await thumbnails(smallBlob,{width:1100,tileSize:360});
const smallTile=await decode(small.tile);
const gif=new Blob([Uint8Array.from(atob('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'),c=>c.charCodeAt(0))],{type:'image/gif'});
const animated=await thumbnails(gif,{width:1100,tileSize:360});
- const out={mainCalls,maxPending,big:[big.width,big.height],media:[media.width,media.height],tile:[tile.width,tile.height],pixel,
+ const out={mainCalls,maxPending,big:[big.width,big.height],media:[media.width,media.height],tile:[tile.width,tile.height],pixel,edge,pano:[panoTile.width,panoTile.height],
tileOnly:!tiles.media&&!!tiles.tile,bad,recovered:!!recovered.media,smallOriginal:small.media===null,smallTile:[smallTile.width,smallTile.height],
animated: animated && [animated.width,animated.height,animated.media,animated.tile]};
media.close();tile.close();smallTile.close();return out;
});
console.log(result);
assert.equal(result.mainCalls,0);assert.equal(result.maxPending,1);
- assert.deepEqual(result.big,[3000,2000]);assert.deepEqual(result.media,[1100,733]);assert.deepEqual(result.tile,[360,360]);
- assert(result.pixel[2]>200&&result.pixel[0]<30,'tile crops the center');
+ assert.deepEqual(result.big,[3000,2000]);assert.deepEqual(result.media,[1100,733]);assert.deepEqual(result.tile,[540,360]);
+ // the grid's justified rows: a tile in the picture's own shape, 360 tall, uncut up to 2:1
+ assert(result.pixel[2]>200&&result.pixel[0]<30&&result.edge[0]>200,'tile keeps the whole picture');
+ assert.deepEqual(result.pano,[720,360]);
assert(result.tileOnly&&result.recovered&&result.smallOriginal);assert.equal(result.bad,null);
- assert.deepEqual(result.smallTile,[20,20]);assert.deepEqual(result.animated,[1,1,null,null]);
+ assert.deepEqual(result.smallTile,[32,20]);assert.deepEqual(result.animated,[1,1,null,null]);
const fallback=await browser.newPage();await fallback.goto(server.url.href);await fallback.waitForFunction(()=>window.thumbnails);
assert.equal(await fallback.evaluate(async()=>{window.Worker=class {constructor(){throw Error('blocked');}};return thumbnails(new Blob(['x']),{width:1100});}),null);
console.log('✓ thumbnails stay off the page thread; sizes, crop, originals, queue, bad-image recovery and worker fallback pass');