Spaces:
Restarting
Restarting
File size: 3,789 Bytes
30c32c8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
/**
* This test ensures that the VM gracefully handles an sb2 project with
* a missing vector costume. The VM should handle this safely by displaying
* a Gray Question Mark, but keeping track of the original costume data
* and serializing the original costume data back out. The saved project.json
* should not reflect that the costume is broken and should therefore re-attempt
* to load the costume if the saved project is re-loaded.
*/
const path = require('path');
const tap = require('tap');
const makeTestStorage = require('../fixtures/make-test-storage');
const FakeRenderer = require('../fixtures/fake-renderer');
const FakeBitmapAdapter = require('../fixtures/fake-bitmap-adapter');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
const {serializeCostumes} = require('../../src/serialization/serialize-assets');
const projectUri = path.resolve(__dirname, '../fixtures/missing_svg.sb2');
const project = readFileToBuffer(projectUri);
const missingCostumeAssetId = 'beca8009621913e2f5b3111eed2d8210';
global.Image = function () {
const image = {
width: 1,
height: 1
};
setTimeout(() => image.onload(), 1000);
return image;
};
global.document = {
createElement: () => ({
// Create mock canvas
getContext: () => ({
drawImage: () => ({})
})
})
};
let vm;
tap.beforeEach(() => {
const storage = makeTestStorage();
vm = new VirtualMachine();
vm.attachStorage(storage);
vm.attachRenderer(new FakeRenderer());
vm.attachV2BitmapAdapter(new FakeBitmapAdapter());
return vm.loadProject(project);
});
const test = tap.test;
test('loading sb2 project with missing vector costume file', t => {
t.equal(vm.runtime.targets.length, 2);
const stage = vm.runtime.targets[0];
t.ok(stage.isStage);
const blueGuySprite = vm.runtime.targets[1];
t.equal(blueGuySprite.getName(), 'Blue Guy');
t.equal(blueGuySprite.getCostumes().length, 1);
const missingCostume = blueGuySprite.getCostumes()[0];
t.equal(missingCostume.name, 'Blue Guy 2');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
const defaultVectorAssetId = vm.runtime.storage.defaultAssetId.ImageVector;
t.equal(missingCostume.assetId, defaultVectorAssetId);
t.equal(missingCostume.dataFormat, 'svg');
// Runtime should have info about broken asset
t.ok(missingCostume.broken);
t.equal(missingCostume.broken.assetId, missingCostumeAssetId);
t.end();
});
test('load and then save sb2 project with missing costume file', t => {
const resavedProject = JSON.parse(vm.toJSON());
t.equal(resavedProject.targets.length, 2);
const stage = resavedProject.targets[0];
t.ok(stage.isStage);
const blueGuySprite = resavedProject.targets[1];
t.equal(blueGuySprite.name, 'Blue Guy');
t.equal(blueGuySprite.costumes.length, 1);
const missingCostume = blueGuySprite.costumes[0];
t.equal(missingCostume.name, 'Blue Guy 2');
// Costume should have both default cosutme (e.g. Gray Question Mark) data and original data
t.equal(missingCostume.assetId, missingCostumeAssetId);
t.equal(missingCostume.dataFormat, 'svg');
// Test that we didn't save any data about the costume being broken
t.notOk(missingCostume.broken);
t.end();
});
test('serializeCostume does not save data for missing costume', t => {
const costumeDescs = serializeCostumes(vm.runtime);
t.equal(costumeDescs.length, 1); // Should only have one costume, the backdrop
t.not(costumeDescs[0].fileName, `${missingCostumeAssetId}.svg`);
t.end();
process.nextTick(process.exit);
});
|