86 lines
3.5 KiB
JavaScript
86 lines
3.5 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const { applyThumbnailTargets, orderCurrentTargetLast } = require('../js/spine-group-thumbnails');
|
|
|
|
(async () => {
|
|
const targets = ['json', 'skel', 'atlas'].map((id) => ({ sourcePath: '/library/' + id }));
|
|
assert.deepEqual(
|
|
orderCurrentTargetLast(targets, '/library/json').map((target) => target.sourcePath),
|
|
['/library/skel', '/library/atlas', '/library/json'],
|
|
'the preview-owning item must be processed last because Eagle tears down its viewer after updating it'
|
|
);
|
|
const applied = new Set();
|
|
const inputPaths = [];
|
|
const result = await applyThumbnailTargets({
|
|
targets,
|
|
initialSkipped: 1,
|
|
settleDelayMs: 0,
|
|
cleanupDelayMs: 0,
|
|
rendered: { buffer: Buffer.from('thumbnail'), extension: '.webp' },
|
|
getItem: async (sourcePath) => ({ id: sourcePath.split('/').pop(), data: { customThumbnail: false } }),
|
|
setThumbnail: async (id, thumbnailPath) => {
|
|
assert(fs.existsSync(thumbnailPath));
|
|
assert.equal(fs.readFileSync(thumbnailPath, 'utf8'), 'thumbnail');
|
|
inputPaths.push(thumbnailPath);
|
|
// Simulate Eagle consuming the supplied file. Reusing one file would make
|
|
// every call after the first fail, which was the original regression.
|
|
fs.unlinkSync(thumbnailPath);
|
|
applied.add(id);
|
|
return true;
|
|
},
|
|
waitForApplied: async (sourcePath) => applied.has(sourcePath.split('/').pop()),
|
|
});
|
|
assert.deepEqual(result, { success: 3, skipped: 1, failed: 0 });
|
|
assert.equal(new Set(inputPaths).size, 3);
|
|
const overwritten = await applyThumbnailTargets({
|
|
targets: [{ sourcePath: '/library/custom', allowOverwrite: true }],
|
|
settleDelayMs: 0,
|
|
cleanupDelayMs: 0,
|
|
rendered: { buffer: Buffer.from('replacement'), extension: '.webp' },
|
|
getItem: async () => ({ id: 'custom', data: { customThumbnail: true } }),
|
|
setThumbnail: async (_id, thumbnailPath) => { assert(fs.existsSync(thumbnailPath)); return true; },
|
|
waitForApplied: async () => true,
|
|
});
|
|
assert.deepEqual(overwritten, { success: 1, skipped: 0, failed: 0 });
|
|
|
|
const deferredReads = [];
|
|
const deferred = await applyThumbnailTargets({
|
|
targets,
|
|
settleDelayMs: 15,
|
|
cleanupDelayMs: 25,
|
|
rendered: { buffer: Buffer.from('deferred-thumbnail'), extension: '.webp' },
|
|
getItem: async (sourcePath) => ({ id: sourcePath.split('/').pop(), data: { customThumbnail: false } }),
|
|
setThumbnail: async (id, thumbnailPath) => {
|
|
setTimeout(() => {
|
|
deferredReads.push({ id, content: fs.readFileSync(thumbnailPath, 'utf8') });
|
|
}, 10);
|
|
return true;
|
|
},
|
|
// Simulate the Web API exposing customThumbnail before its background file
|
|
// copy has completed.
|
|
waitForApplied: async () => true,
|
|
});
|
|
assert.deepEqual(deferred, { success: 3, skipped: 0, failed: 0 });
|
|
assert.deepEqual(deferredReads.map((entry) => entry.id), ['json', 'skel', 'atlas']);
|
|
assert(deferredReads.every((entry) => entry.content === 'deferred-thumbnail'));
|
|
|
|
let rejectedCalls = 0;
|
|
const retried = await applyThumbnailTargets({
|
|
targets: [{ sourcePath: '/library/retry' }],
|
|
settleDelayMs: 0,
|
|
cleanupDelayMs: 0,
|
|
rendered: { buffer: Buffer.from('retry-thumbnail'), extension: '.png' },
|
|
getItem: async () => ({ id: 'retry', data: { customThumbnail: false } }),
|
|
setThumbnail: async () => ++rejectedCalls === 1 ? false : true,
|
|
waitForApplied: async () => true,
|
|
});
|
|
assert.equal(rejectedCalls, 2);
|
|
assert.deepEqual(retried, { success: 1, skipped: 0, failed: 0 });
|
|
console.log('PASS: first batch applies every selected item using an independent temporary file');
|
|
})().catch((error) => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
});
|