mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-08-28 22:30:40 -04:00
Add test for SB3 serialization round trip
This commit is contained in:
parent
cd1c72c7cc
commit
4b1aad5099
1 changed files with 110 additions and 0 deletions
110
test/integration/sb3-roundtrip.js
Normal file
110
test/integration/sb3-roundtrip.js
Normal file
|
@ -0,0 +1,110 @@
|
|||
const test = require('tap').test;
|
||||
|
||||
const Blocks = require('../../src/engine/blocks');
|
||||
const Clone = require('../../src/util/clone');
|
||||
const loadCostume = require('../../src/import/load-costume');
|
||||
const loadSound = require('../../src/import/load-sound');
|
||||
const makeTestStorage = require('../fixtures/make-test-storage');
|
||||
const Runtime = require('../../src/engine/runtime');
|
||||
const sb3 = require('../../src/serialization/sb3');
|
||||
const Sprite = require('../../src/sprites/sprite');
|
||||
|
||||
const defaultCostumeInfo = {
|
||||
bitmapResolution: 1,
|
||||
rotationCenterX: 0,
|
||||
rotationCenterY: 0
|
||||
};
|
||||
|
||||
const defaultSoundInfo = {
|
||||
};
|
||||
|
||||
test('sb3-roundtrip', t => {
|
||||
const runtime1 = new Runtime();
|
||||
runtime1.attachStorage(makeTestStorage());
|
||||
|
||||
const runtime2 = new Runtime();
|
||||
runtime2.attachStorage(makeTestStorage());
|
||||
|
||||
const testRuntimeState = (label, runtime) => {
|
||||
t.strictEqual(runtime.targets.length, 2, `${label}: target count`);
|
||||
const [stageClone, spriteClone] = runtime.targets;
|
||||
|
||||
t.strictEqual(stageClone.isOriginal, true);
|
||||
t.strictEqual(stageClone.isStage, true);
|
||||
|
||||
const stage = stageClone.sprite;
|
||||
t.strictEqual(stage.name, 'Stage');
|
||||
t.strictEqual(stage.clones.length, 1);
|
||||
t.strictEqual(stage.clones[0], stageClone);
|
||||
|
||||
t.strictEqual(stage.costumes.length, 1);
|
||||
const [building] = stage.costumes;
|
||||
t.strictEqual(building.assetId, 'fe5e3566965f9de793beeffce377d054');
|
||||
t.strictEqual(building.dataFormat, 'jpg');
|
||||
|
||||
t.strictEqual(stage.sounds.length, 0);
|
||||
|
||||
t.strictEqual(spriteClone.isOriginal, true);
|
||||
t.strictEqual(spriteClone.isStage, false);
|
||||
|
||||
const sprite = spriteClone.sprite;
|
||||
t.strictEqual(sprite.name, 'Sprite');
|
||||
t.strictEqual(sprite.clones.length, 1);
|
||||
t.strictEqual(sprite.clones[0], spriteClone);
|
||||
|
||||
t.strictEqual(sprite.costumes.length, 2);
|
||||
const [cat, squirrel] = sprite.costumes;
|
||||
t.strictEqual(cat.assetId, 'f88bf1935daea28f8ca098462a31dbb0');
|
||||
t.strictEqual(cat.dataFormat, 'svg');
|
||||
t.strictEqual(squirrel.assetId, '7e24c99c1b853e52f8e7f9004416fa34');
|
||||
t.strictEqual(squirrel.dataFormat, 'png');
|
||||
|
||||
t.strictEqual(sprite.sounds.length, 1);
|
||||
const [meow] = sprite.sounds;
|
||||
t.strictEqual(meow.md5, '83c36d806dc92327b9e7049a565c6bff.wav');
|
||||
};
|
||||
|
||||
const loadThings = Promise.all([
|
||||
loadCostume('fe5e3566965f9de793beeffce377d054.jpg', Clone.simple(defaultCostumeInfo), runtime1),
|
||||
loadCostume('f88bf1935daea28f8ca098462a31dbb0.svg', Clone.simple(defaultCostumeInfo), runtime1),
|
||||
loadCostume('7e24c99c1b853e52f8e7f9004416fa34.png', Clone.simple(defaultCostumeInfo), runtime1),
|
||||
loadSound(Object.assign({md5: '83c36d806dc92327b9e7049a565c6bff.wav'}, defaultSoundInfo), runtime1)
|
||||
]);
|
||||
|
||||
const installThings = loadThings.then(results => {
|
||||
const [building, cat, squirrel, meow] = results;
|
||||
|
||||
const stageBlocks = new Blocks();
|
||||
const stage = new Sprite(stageBlocks, runtime1);
|
||||
stage.name = 'Stage';
|
||||
stage.costumes = [building];
|
||||
stage.sounds = [];
|
||||
const stageClone = stage.createClone();
|
||||
stageClone.isStage = true;
|
||||
|
||||
const spriteBlocks = new Blocks();
|
||||
const sprite = new Sprite(spriteBlocks, runtime1);
|
||||
sprite.name = 'Sprite';
|
||||
sprite.costumes = [cat, squirrel];
|
||||
sprite.sounds = [meow];
|
||||
const spriteClone = sprite.createClone();
|
||||
|
||||
runtime1.targets = [stageClone, spriteClone];
|
||||
|
||||
testRuntimeState('original', runtime1);
|
||||
});
|
||||
|
||||
const serializeAndDeserialize = installThings.then(() => {
|
||||
// `Clone.simple` here helps in two ways:
|
||||
// 1. it ensures that any non-serializable data is thrown away, and
|
||||
// 2. `sb3.deserialize` does some `hasOwnProperty` checks which fail on the object returned by `sb3.serialize`
|
||||
// due to its inheritance structure.
|
||||
const serializedState = Clone.simple(sb3.serialize(runtime1));
|
||||
return sb3.deserialize(serializedState, runtime2);
|
||||
});
|
||||
|
||||
return serializeAndDeserialize.then(targets => {
|
||||
runtime2.targets = targets;
|
||||
testRuntimeState('copy', runtime2);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue