Fix saving and loading of slider min max values. Add test for sb2 to sb3 conversion that tests all montior properties remain the same after save and load.

This commit is contained in:
Karishma Chadha 2019-01-25 14:14:46 -05:00
parent 98b92be2d7
commit 94fa3d56c8
2 changed files with 158 additions and 3 deletions

View file

@ -502,8 +502,8 @@ const serializeMonitors = function (monitors) {
visible: monitorData.visible
};
if (monitorData.mode !== 'list') {
serializedMonitor.min = monitorData.sliderMin;
serializedMonitor.max = monitorData.sliderMax;
serializedMonitor.sliderMin = monitorData.sliderMin;
serializedMonitor.sliderMax = monitorData.sliderMax;
}
return serializedMonitor;
});
@ -556,7 +556,7 @@ const serialize = function (runtime, targetId) {
meta.vm = vmPackage.version;
// Attach full user agent string to metadata if available
meta.agent = null;
meta.agent = 'none';
if (typeof navigator !== 'undefined') meta.agent = navigator.userAgent;
// Assemble payload and return

View file

@ -0,0 +1,155 @@
const path = require('path');
const test = require('tap').test;
const makeTestStorage = require('../fixtures/make-test-storage');
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
const VirtualMachine = require('../../src/index');
const projectUri = path.resolve(__dirname, '../fixtures/monitors.sb2');
const project = readFileToBuffer(projectUri);
const vm = new VirtualMachine();
vm.attachStorage(makeTestStorage());
// TODO figure out why running threads doesn't work in this test
// vm.start();
vm.clear();
vm.setCompatibilityMode(false);
vm.setTurboMode(false);
test('Set Up - load the sb2 project', t => {
vm.loadProject(project).then(() => {
t.pass('Successfully Loaded!');
t.end();
});
});
test('saving and loading sb2 project with monitors preserves sliderMin and sliderMax', t => {
vm.on('playgroundData', e /* eslint-disable-line no-unused-vars */ => {
// TODO related to above TODO, comment these back in when we figure out
// why running threads doesn't work with this test
// const threads = JSON.parse(e.threads);
// All monitors should create threads that finish during the step and
// are revoved from runtime.threads.
// t.equal(threads.length, 0);
// we care that the last step updated the right number of monitors
// we don't care whether the last step ran other threads or not
// const lastStepUpdatedMonitorThreads = vm.runtime._lastStepDoneThreads.filter(thread => thread.updateMonitor);
// t.equal(lastStepUpdatedMonitorThreads.length, 8);
// There should be one additional hidden monitor that is in the monitorState but
// does not start a thread.
t.equal(vm.runtime._monitorState.size, 9);
const stage = vm.runtime.targets[0];
const target = vm.runtime.targets[1];
// Global variable named "global" is a slider
let variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global')[0];
// Used later when checking save and load of slider min/max
let monitorRecord = vm.runtime._monitorState.get(variableId);
t.equal(monitorRecord.opcode, 'data_variable');
t.equal(monitorRecord.mode, 'slider');
t.equal(monitorRecord.sliderMin, -200); // Make sure these are imported for sliders.
t.equal(monitorRecord.sliderMax, 30);
t.equal(monitorRecord.x, 5); // These are imported for all monitors, just check once.
t.equal(monitorRecord.y, 59);
t.equal(monitorRecord.visible, true);
// Global variable named "global list" is a list
variableId = Object.keys(stage.variables).filter(k => stage.variables[k].name === 'global list')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
t.equal(monitorRecord.opcode, 'data_listcontents');
t.equal(monitorRecord.mode, 'list');
t.equal(monitorRecord.visible, true);
// Local variable named "local" is hidden
variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
t.equal(monitorRecord.opcode, 'data_variable');
t.equal(monitorRecord.mode, 'default');
t.equal(monitorRecord.visible, false);
// Local list named "local list" is visible
variableId = Object.keys(target.variables).filter(k => target.variables[k].name === 'local list')[0];
monitorRecord = vm.runtime._monitorState.get(variableId);
t.equal(monitorRecord.opcode, 'data_listcontents');
t.equal(monitorRecord.mode, 'list');
t.equal(monitorRecord.visible, true);
t.equal(monitorRecord.width, 104); // Make sure these are imported from lists.
t.equal(monitorRecord.height, 204);
// Backdrop name monitor is visible, not sprite specific
// should get imported with id that references the name parameter
// via '_name' at the end since the 3.0 block has a dropdown.
monitorRecord = vm.runtime._monitorState.get('backdropnumbername_name');
t.equal(monitorRecord.opcode, 'looks_backdropnumbername');
t.equal(monitorRecord.mode, 'default');
t.equal(monitorRecord.visible, true);
t.equal(monitorRecord.spriteName, null);
t.equal(monitorRecord.targetId, null);
// x position monitor is in large mode, specific to sprite 1
monitorRecord = vm.runtime._monitorState.get(`${target.id}_xposition`);
t.equal(monitorRecord.opcode, 'motion_xposition');
t.equal(monitorRecord.mode, 'large');
t.equal(monitorRecord.visible, true);
t.equal(monitorRecord.spriteName, 'Sprite1');
t.equal(monitorRecord.targetId, target.id);
let monitorId;
let monitorBlock;
// The monitor IDs for the sensing_current block should be unique
// to the parameter that is selected on the block being monitored.
// The paramater portion of the id should be lowercase even
// though the field value on the block is uppercase.
monitorId = 'current_date';
monitorRecord = vm.runtime._monitorState.get(monitorId);
t.equal(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
t.equal(monitorBlock.fields.CURRENTMENU.value, 'DATE');
t.equal(monitorRecord.mode, 'default');
t.equal(monitorRecord.visible, true);
t.equal(monitorRecord.spriteName, null);
t.equal(monitorRecord.targetId, null);
monitorId = 'current_minute';
monitorRecord = vm.runtime._monitorState.get(monitorId);
t.equal(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
t.equal(monitorBlock.fields.CURRENTMENU.value, 'MINUTE');
t.equal(monitorRecord.mode, 'default');
t.equal(monitorRecord.visible, true);
t.equal(monitorRecord.spriteName, null);
t.equal(monitorRecord.targetId, null);
monitorId = 'current_dayofweek';
monitorRecord = vm.runtime._monitorState.get(monitorId);
t.equal(monitorRecord.opcode, 'sensing_current');
monitorBlock = vm.runtime.monitorBlocks.getBlock(monitorId);
t.equal(monitorBlock.fields.CURRENTMENU.value, 'DAYOFWEEK');
t.equal(monitorRecord.mode, 'default');
t.equal(monitorRecord.visible, true);
t.equal(monitorRecord.spriteName, null);
t.equal(monitorRecord.targetId, null);
t.end();
process.nextTick(process.exit);
});
// Start VM, load project, and run
t.doesNotThrow(() => {
const sb3ProjectJson = vm.toJSON();
return vm.loadProject(sb3ProjectJson).then(() => {
setTimeout(() => {
vm.getPlaygroundData();
vm.stopAll();
}, 100);
});
});
});