mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-27 16:32:25 -05:00
466 lines
10 KiB
JavaScript
466 lines
10 KiB
JavaScript
|
const tap = require('tap');
|
||
|
const path = require('path');
|
||
|
const readFileToBuffer = require('../fixtures/readProjectFile').readFileToBuffer;
|
||
|
const makeTestStorage = require('../fixtures/make-test-storage');
|
||
|
const VirtualMachine = require('../../src/virtual-machine');
|
||
|
|
||
|
let vm;
|
||
|
let projectChanged;
|
||
|
let blockContainer;
|
||
|
|
||
|
tap.beforeEach(() => {
|
||
|
const projectUri = path.resolve(__dirname, '../fixtures/default.sb2');
|
||
|
const project = readFileToBuffer(projectUri);
|
||
|
|
||
|
vm = new VirtualMachine();
|
||
|
|
||
|
vm.runtime.addListener('PROJECT_CHANGED', () => {
|
||
|
projectChanged = true;
|
||
|
});
|
||
|
|
||
|
vm.attachStorage(makeTestStorage());
|
||
|
return vm.loadProject(project).then(() => {
|
||
|
blockContainer = vm.editingTarget.blocks;
|
||
|
|
||
|
// Add mock blocks to use for tests
|
||
|
blockContainer.createBlock({
|
||
|
id: 'a parent block',
|
||
|
opcode: 'my_testParentBlock',
|
||
|
fields: {},
|
||
|
inputs: {}
|
||
|
});
|
||
|
|
||
|
|
||
|
blockContainer.createBlock({
|
||
|
id: 'a new block',
|
||
|
opcode: 'my_testBlock',
|
||
|
topLevel: true,
|
||
|
x: -10,
|
||
|
y: 35,
|
||
|
fields: {
|
||
|
A_FIELD: {
|
||
|
name: 'A_FIELD',
|
||
|
value: 10
|
||
|
}
|
||
|
},
|
||
|
inputs: {},
|
||
|
parent: 'a block'
|
||
|
});
|
||
|
|
||
|
// Reset project changes from new blocks
|
||
|
projectChanged = false;
|
||
|
|
||
|
});
|
||
|
});
|
||
|
|
||
|
tap.tearDown(() => process.nextTick(process.exit));
|
||
|
|
||
|
const test = tap.test;
|
||
|
|
||
|
test('Creating a block should emit a project changed event', t => {
|
||
|
blockContainer.createBlock({
|
||
|
id: 'another block',
|
||
|
opcode: 'my_testBlock',
|
||
|
topLevel: true
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Deleting a block should emit a project changed event', t => {
|
||
|
blockContainer.deleteBlock('a new block');
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Changing a block should emit a project changed event', t => {
|
||
|
blockContainer.changeBlock({
|
||
|
element: 'field',
|
||
|
id: 'a new block',
|
||
|
name: 'A_FIELD',
|
||
|
value: 300
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.changeBlock({
|
||
|
element: 'checkbox',
|
||
|
id: 'a new block',
|
||
|
value: true
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.changeBlock({
|
||
|
element: 'mutation',
|
||
|
id: 'a new block',
|
||
|
value: '<mutation></mutation>'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Moving a block to a new position should emit a project changed event', t => {
|
||
|
blockContainer.moveBlock({
|
||
|
id: 'a new block',
|
||
|
newCoordinate: {
|
||
|
x: -40,
|
||
|
y: 350
|
||
|
}
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Connecting a block to a new parent should emit a project changed event', t => {
|
||
|
blockContainer.createBlock({
|
||
|
id: 'another block',
|
||
|
opcode: 'my_testBlock'
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.moveBlock({
|
||
|
id: 'a new block',
|
||
|
newParent: 'another block'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Disconnecting a block from another should emit a project changed event', t => {
|
||
|
blockContainer.moveBlock({
|
||
|
id: 'a new block',
|
||
|
oldParent: 'a parent block'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Creating a local variable should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_create',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: true,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
// Creating the same variable twice should not emit a project changed event
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_create',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: true,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, false);
|
||
|
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Creating a global variable should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_create',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: false,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
// Creating the same variable twice should not emit a project changed event
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_create',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: false,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, false);
|
||
|
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Renaming a variable should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_create',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: false,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_rename',
|
||
|
varId: 'a new variable',
|
||
|
oldName: 'foo',
|
||
|
newName: 'bar'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Deleting a variable should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_create',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: false,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'var_delete',
|
||
|
varId: 'a new variable',
|
||
|
varName: 'foo',
|
||
|
varType: '',
|
||
|
isLocal: false,
|
||
|
isCloud: false
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Creating a block comment should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_create',
|
||
|
blockId: 'a new block',
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Creating a workspace comment should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_create',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Changing a comment should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_create',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_change',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
newContents_: {
|
||
|
minimized: true
|
||
|
},
|
||
|
oldContents_: {
|
||
|
minimized: false
|
||
|
}
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Attempting to change a comment that does not exist should not emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_change',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
newContents_: {
|
||
|
minimized: true
|
||
|
},
|
||
|
oldContents_: {
|
||
|
minimized: false
|
||
|
}
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, false);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Deleting a block comment should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_create',
|
||
|
blockId: 'a new block',
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_delete',
|
||
|
blockId: 'a new block',
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Deleting a workspace comment should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_create',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_delete',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Deleting a comment that does not exist should not emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_delete',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, false);
|
||
|
t.end();
|
||
|
});
|
||
|
|
||
|
test('Moving a comment should emit a project changed event', t => {
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_create',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
height: 250,
|
||
|
width: 400,
|
||
|
xy: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
minimized: false,
|
||
|
text: 'comment'
|
||
|
});
|
||
|
|
||
|
projectChanged = false;
|
||
|
|
||
|
blockContainer.blocklyListen({
|
||
|
type: 'comment_move',
|
||
|
blockId: null,
|
||
|
commentId: 'a new comment',
|
||
|
oldCoordinate_: {
|
||
|
x: -40,
|
||
|
y: 27
|
||
|
},
|
||
|
newCoordinate_: {
|
||
|
x: -35,
|
||
|
y: 50
|
||
|
}
|
||
|
});
|
||
|
|
||
|
t.equal(projectChanged, true);
|
||
|
t.end();
|
||
|
});
|