mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-22 14:02:37 -05:00
Ignore video sensing monitor and import music tempo monitor unless it is hidden. Load extensions for visible monitors. Add tests for new functionality.
This commit is contained in:
parent
fe186913ac
commit
cfa71723eb
8 changed files with 137 additions and 29 deletions
|
@ -245,17 +245,42 @@ const globalBroadcastMsgStateGenerator = (function () {
|
|||
* @param {ImportedExtensionsInfo} extensions - (in/out) parsed extension information will be stored here.
|
||||
*/
|
||||
const parseMonitorObject = (object, runtime, targets, extensions) => {
|
||||
let target = null;
|
||||
// In scratch 2.0, there are two monitors that now correspond to extension
|
||||
// blocks (tempo and video motion/direction). In the case of the
|
||||
// video motion/direction block, this reporter is not monitorable in Scratch 3.0.
|
||||
// In the case of the tempo block, we should import it and load the music extension
|
||||
// only when the monitor is actually visible.
|
||||
|
||||
const opcode = specMap[object.cmd].opcode;
|
||||
const extIndex = opcode.indexOf('_');
|
||||
const extID = opcode.substring(0, extIndex);
|
||||
|
||||
// All non-core extensions should be added by blocks at this point
|
||||
// We can assume this is an unintended monitor and skip parsing if it belongs to a non-core extension
|
||||
if (CORE_EXTENSIONS.indexOf(extID) === -1) {
|
||||
if (extID !== '') return;
|
||||
if (extID === 'videoSensing') {
|
||||
return;
|
||||
} else if (CORE_EXTENSIONS.indexOf(extID) === -1 && extID !== '' &&
|
||||
!extensions.extensionIDs.has(extID) && !object.visible) {
|
||||
// Don't import this monitor if it refers to a non-core extension that
|
||||
// doesn't exist anywhere else in the project and it isn't visible.
|
||||
// This should only apply to the tempo block at this point since
|
||||
// there are no other sb2 blocks that are now extension monitors.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if (!object.visible) {
|
||||
// // If the monitor is invisible, check to see if it tries to load a new extension
|
||||
// // (e.g. one that hasn't already been loaded by an actual block in the project).
|
||||
// // If so, exit without importing the monitor.
|
||||
//
|
||||
//
|
||||
// // All non-core extensions should be added by blocks at this point
|
||||
// // We can assume this is an unintended monitor and skip parsing if it belongs to a non-core extension
|
||||
// if () {
|
||||
// if ( && !extensions.has(extID)) return;
|
||||
// }
|
||||
// }
|
||||
|
||||
let target = null;
|
||||
// List blocks don't come in with their target name set.
|
||||
// Find the target by searching for a target with matching variable name/type.
|
||||
if (!object.hasOwnProperty('target')) {
|
||||
|
|
BIN
test/fixtures/invisible-tempo-monitor-no-other-music-blocks.sb2
vendored
Normal file
BIN
test/fixtures/invisible-tempo-monitor-no-other-music-blocks.sb2
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/load-extensions/music-visible-monitor-no-blocks.sb2
vendored
Normal file
BIN
test/fixtures/load-extensions/music-visible-monitor-no-blocks.sb2
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/visible-tempo-monitor-no-other-music-blocks.sb2
vendored
Normal file
BIN
test/fixtures/visible-tempo-monitor-no-other-music-blocks.sb2
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/visible-video-monitor-and-video-blocks.sb2
vendored
Normal file
BIN
test/fixtures/visible-video-monitor-and-video-blocks.sb2
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/visible-video-monitor-no-other-video-blocks.sb2
vendored
Normal file
BIN
test/fixtures/visible-video-monitor-no-other-video-blocks.sb2
vendored
Normal file
Binary file not shown.
107
test/integration/sb2-import-extension-monitors.js
Normal file
107
test/integration/sb2-import-extension-monitors.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
const path = require('path');
|
||||
const test = require('tap').test;
|
||||
const makeTestStorage = require('../fixtures/make-test-storage');
|
||||
const {readFileToBuffer, extractProjectJson} = require('../fixtures/readProjectFile');
|
||||
const VirtualMachine = require('../../src/index');
|
||||
const sb2 = require('../../src/serialization/sb2');
|
||||
|
||||
const invisibleVideoMonitorProjectUri = path.resolve(__dirname, '../fixtures/invisible-video-monitor.sb2');
|
||||
const invisibleVideoMonitorProject = readFileToBuffer(invisibleVideoMonitorProjectUri);
|
||||
|
||||
const visibleVideoMonitorProjectUri = path.resolve(
|
||||
__dirname, '../fixtures/visible-video-monitor-no-other-video-blocks.sb2');
|
||||
const visibleVideoMonitorProject = readFileToBuffer(visibleVideoMonitorProjectUri);
|
||||
|
||||
const visibleVideoMonitorAndBlocksProjectUri = path.resolve(
|
||||
__dirname, '../fixtures/visible-video-monitor-and-video-blocks.sb2');
|
||||
const visibleVideoMonitorAndBlocksProject = extractProjectJson(visibleVideoMonitorAndBlocksProjectUri);
|
||||
|
||||
const invisibleTempoMonitorProjectUri = path.resolve(
|
||||
__dirname, '../fixtures/invisible-tempo-monitor-no-other-music-blocks.sb2');
|
||||
const invisibleTempoMonitorProject = readFileToBuffer(invisibleTempoMonitorProjectUri);
|
||||
|
||||
const visibleTempoMonitorProjectUri = path.resolve(
|
||||
__dirname, '../fixtures/visible-tempo-monitor-no-other-music-blocks.sb2');
|
||||
const visibleTempoMonitorProject = readFileToBuffer(visibleTempoMonitorProjectUri);
|
||||
|
||||
test('loading sb2 project with invisible video monitor should not load monitor or extension', t => {
|
||||
const vm = new VirtualMachine();
|
||||
vm.attachStorage(makeTestStorage());
|
||||
|
||||
// Start VM, load project, and run
|
||||
vm.start();
|
||||
vm.clear();
|
||||
vm.setCompatibilityMode(false);
|
||||
vm.setTurboMode(false);
|
||||
vm.loadProject(invisibleVideoMonitorProject).then(() => {
|
||||
t.equal(vm.extensionManager.isExtensionLoaded('videoSensing'), false);
|
||||
t.equal(vm.runtime._monitorState.size, 0);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('loading sb2 project with visible video monitor should not load extension', t => {
|
||||
const vm = new VirtualMachine();
|
||||
vm.attachStorage(makeTestStorage());
|
||||
|
||||
// Start VM, load project, and run
|
||||
vm.start();
|
||||
vm.clear();
|
||||
vm.setCompatibilityMode(false);
|
||||
vm.setTurboMode(false);
|
||||
vm.loadProject(visibleVideoMonitorProject).then(() => {
|
||||
t.equal(vm.extensionManager.isExtensionLoaded('videoSensing'), false);
|
||||
t.equal(vm.runtime._monitorState.size, 0);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
// This test looks a little different than the rest because loading a project with
|
||||
// the video sensing block requires a mock renderer and other setup, so instead
|
||||
// we are just using deserialize to test what we need instead
|
||||
test('sb2 project with video sensing blocks and monitor should load extension but not monitor', t => {
|
||||
const vm = new VirtualMachine();
|
||||
|
||||
sb2.deserialize(visibleVideoMonitorAndBlocksProject, vm.runtime).then(project => {
|
||||
// Extension loads but monitor does not
|
||||
project.extensions.extensionIDs.has('videoSensing');
|
||||
// Non-core extension monitors haven't been added to the runtime
|
||||
t.equal(vm.runtime._monitorState.size, 0);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('sb2 project with invisible music monitor should not load monitor or extension', t => {
|
||||
const vm = new VirtualMachine();
|
||||
vm.attachStorage(makeTestStorage());
|
||||
|
||||
// Start VM, load project, and run
|
||||
vm.start();
|
||||
vm.clear();
|
||||
vm.setCompatibilityMode(false);
|
||||
vm.setTurboMode(false);
|
||||
vm.loadProject(invisibleTempoMonitorProject).then(() => {
|
||||
t.equal(vm.extensionManager.isExtensionLoaded('music'), false);
|
||||
t.equal(vm.runtime._monitorState.size, 0);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('sb2 project with visible music monitor should load monitor and extension', t => {
|
||||
const vm = new VirtualMachine();
|
||||
vm.attachStorage(makeTestStorage());
|
||||
|
||||
// Start VM, load project, and run
|
||||
vm.start();
|
||||
vm.clear();
|
||||
vm.setCompatibilityMode(false);
|
||||
vm.setTurboMode(false);
|
||||
vm.loadProject(visibleTempoMonitorProject).then(() => {
|
||||
t.equal(vm.extensionManager.isExtensionLoaded('music'), true);
|
||||
t.equal(vm.runtime._monitorState.size, 1);
|
||||
t.equal(vm.runtime._monitorState.has('music_getTempo'), true);
|
||||
t.equal(vm.runtime._monitorState.get('music_getTempo').visible, true);
|
||||
t.end();
|
||||
process.nextTick(process.exit); // This is needed because this is the end of the last test in this file!!
|
||||
});
|
||||
});
|
|
@ -5,7 +5,6 @@ const extractProjectJson = require('../fixtures/readProjectFile').extractProject
|
|||
const RenderedTarget = require('../../src/sprites/rendered-target');
|
||||
const Runtime = require('../../src/engine/runtime');
|
||||
const sb2 = require('../../src/serialization/sb2');
|
||||
const specMap = require('../../src/serialization/sb2_specmap.js');
|
||||
|
||||
test('spec', t => {
|
||||
t.type(sb2, 'object');
|
||||
|
@ -103,26 +102,3 @@ test('Ordering', t => {
|
|||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('Prevent monitors from adding non-core extensions', t => {
|
||||
const rt = new Runtime();
|
||||
// This test project's video motion reporter block was checked, saved, then unchecked and saved
|
||||
const videoSensingMonitor = path.resolve(__dirname, '../fixtures/invisible-video-monitor.sb2');
|
||||
const projectJSON = extractProjectJson(videoSensingMonitor);
|
||||
|
||||
sb2.deserialize(projectJSON, rt).then(project => {
|
||||
for (const child of projectJSON.children) {
|
||||
// Check that monitor's extension hasn't been added to the serialized project's extensions
|
||||
if (child.cmd) {
|
||||
const opcode = specMap[child.cmd].opcode;
|
||||
const extIndex = opcode.indexOf('_');
|
||||
const extID = opcode.substring(0, extIndex);
|
||||
t.notOk(project.extensions.extensionIDs.has(extID));
|
||||
}
|
||||
}
|
||||
|
||||
// Non-core extension monitors haven't been added to the runtime
|
||||
t.equal(rt._monitorState.size, 0);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue