Spaces:
Runtime error
Runtime error
| 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(runtime1); | |
| 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(runtime1); | |
| 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(() => { | |
| // Doing a JSON `stringify` and `parse` here more accurately simulate a save/load cycle. In particular: | |
| // 1. it ensures that any non-serializable data is thrown away, and | |
| // 2. `sb3.deserialize` and its helpers do some `hasOwnProperty` checks which fail on the object returned by | |
| // `sb3.serialize` but succeed if that object is "flattened" in this way. | |
| const serializedState = JSON.parse(JSON.stringify(sb3.serialize(runtime1))); | |
| return sb3.deserialize(serializedState, runtime2); | |
| }); | |
| return serializeAndDeserialize.then(({targets}) => { | |
| runtime2.targets = targets; | |
| testRuntimeState('copy', runtime2); | |
| }); | |
| }); | |