资源组更新缩略图
This commit is contained in:
1 parent
05c4fc4b90
commit
2a5fe0ce1f
27 files changed
+562
-161
No files matched your search
@@ -0,0 +1,85 @@
|
||||
'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;
|
||||
});
|
||||
@@ -72,7 +72,11 @@ try {
|
||||
const viewerSource = fs.readFileSync(path.join(__dirname, '../viewer/spine.html'), 'utf8');
|
||||
assert.match(viewerSource, /currentItem\.data\.customThumbnail === true && !window\.confirm/);
|
||||
assert.match(viewerSource, /activeAssets\.skeletonPath[\s\S]*activeAssets\.atlasPath[\s\S]*Object\.values\(activeAssets\.texturePaths/);
|
||||
assert.match(viewerSource, /fresh\.data\.customThumbnail === true\) \{ skipped\+\+; continue; \}[\s\S]*setEagleCustomThumbnail\(fresh\.id/);
|
||||
assert.match(viewerSource, /activeAssets\.skeletonCandidatePaths[\s\S]*activeAssets\.atlasCandidatePaths[\s\S]*utils\.normalizeStem/);
|
||||
assert.match(viewerSource, /selected: item\.data\.customThumbnail !== true && !utils\.isTextureFile\(sourcePath\)/);
|
||||
const groupThumbnailSource = fs.readFileSync(path.join(__dirname, '../js/spine-group-thumbnails.js'), 'utf8');
|
||||
assert.match(groupThumbnailSource, /fresh\.data\.customThumbnail === true && target\.allowOverwrite !== true\) \{ skipped\+\+; continue; \}[\s\S]*options\.setThumbnail\(fresh\.id/);
|
||||
assert.match(groupThumbnailSource, /itemTempPath = path\.join\(os\.tmpdir\(\), 'spineviewer-group-' \+ fresh\.id[\s\S]*options\.setThumbnail\(fresh\.id, itemTempPath\)/);
|
||||
assert.match(viewerSource, /groupThumbBtn[\s\S]*thumbBtn/);
|
||||
assert.match(viewerSource, /path\.join\(os\.tmpdir\(\), 'spineviewer-current-'/);
|
||||
assert.doesNotMatch(viewerSource, /fs\.writeFileSync\(outPath/);
|
||||
|
||||
Reference in new issue
Block a user