mirror of
https://github.com/google/blockly.git
synced 2026-01-09 10:00:09 +01:00
Add programmatically setting shadows Take 2 (#4215)
* Add programmatically setting shadows
This commit is contained in:
@@ -218,6 +218,10 @@ Blockly.Events.Create = function(opt_block) {
|
||||
if (!opt_block) {
|
||||
return; // Blank event to be populated by fromJson.
|
||||
}
|
||||
if (opt_block.isShadow()) {
|
||||
// Moving shadow blocks is handled via disconnection.
|
||||
this.recordUndo = false;
|
||||
}
|
||||
|
||||
if (opt_block.workspace.rendered) {
|
||||
this.xml = Blockly.Xml.blockToDomWithXY(opt_block);
|
||||
@@ -302,6 +306,10 @@ Blockly.Events.Delete = function(opt_block) {
|
||||
if (opt_block.getParent()) {
|
||||
throw Error('Connected blocks cannot be deleted.');
|
||||
}
|
||||
if (opt_block.isShadow()) {
|
||||
// Respawning shadow blocks is handled via disconnection.
|
||||
this.recordUndo = false;
|
||||
}
|
||||
|
||||
if (opt_block.workspace.rendered) {
|
||||
this.oldXml = Blockly.Xml.blockToDomWithXY(opt_block);
|
||||
@@ -380,6 +388,10 @@ Blockly.Events.Move = function(opt_block) {
|
||||
if (!opt_block) {
|
||||
return; // Blank event to be populated by fromJson.
|
||||
}
|
||||
if (opt_block.isShadow()) {
|
||||
// Moving shadow blocks is handled via disconnection.
|
||||
this.recordUndo = false;
|
||||
}
|
||||
|
||||
var location = this.currentLocation_();
|
||||
this.oldParentId = location.parentId;
|
||||
|
||||
@@ -111,7 +111,7 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
|
||||
var orphanBlock = parentConnection.targetBlock();
|
||||
var shadowDom = parentConnection.getShadowDom();
|
||||
// Temporarily set the shadow DOM to null so it does not respawn.
|
||||
parentConnection.setShadowDom(null);
|
||||
parentConnection.shadowDom_ = null;
|
||||
// Displaced shadow blocks dissolve rather than reattaching or bumping.
|
||||
if (orphanBlock.isShadow()) {
|
||||
// Save the shadow block so that field values are preserved.
|
||||
@@ -179,7 +179,7 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
|
||||
}
|
||||
}
|
||||
// Restore the shadow DOM.
|
||||
parentConnection.setShadowDom(shadowDom);
|
||||
parentConnection.shadowDom_ = shadowDom;
|
||||
}
|
||||
|
||||
var event;
|
||||
@@ -204,12 +204,11 @@ Blockly.Connection.prototype.dispose = function() {
|
||||
|
||||
// isConnected returns true for shadows and non-shadows.
|
||||
if (this.isConnected()) {
|
||||
// Destroy the attached shadow block & its children (if it exists).
|
||||
this.setShadowDom(null);
|
||||
|
||||
var targetBlock = this.targetBlock();
|
||||
if (targetBlock.isShadow()) {
|
||||
// Destroy the attached shadow block & its children.
|
||||
targetBlock.dispose(false);
|
||||
} else {
|
||||
if (targetBlock) {
|
||||
// Disconnect the attached normal block.
|
||||
targetBlock.unplug();
|
||||
}
|
||||
@@ -444,7 +443,10 @@ Blockly.Connection.prototype.disconnect = function() {
|
||||
Blockly.Events.setGroup(true);
|
||||
}
|
||||
this.disconnectInternal_(parentBlock, childBlock);
|
||||
parentConnection.respawnShadow_();
|
||||
if (!childBlock.isShadow()) {
|
||||
// If we were disconnecting a shadow, no need to spawn a new one.
|
||||
parentConnection.respawnShadow_();
|
||||
}
|
||||
if (!eventGroup) {
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
@@ -479,7 +481,7 @@ Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
|
||||
Blockly.Connection.prototype.respawnShadow_ = function() {
|
||||
var parentBlock = this.getSourceBlock();
|
||||
var shadow = this.getShadowDom();
|
||||
if (parentBlock.workspace && shadow && Blockly.Events.recordUndo) {
|
||||
if (parentBlock.workspace && shadow) {
|
||||
var blockShadow =
|
||||
Blockly.Xml.domToBlock(shadow, parentBlock.workspace);
|
||||
if (blockShadow.outputConnection) {
|
||||
@@ -586,15 +588,23 @@ Blockly.Connection.prototype.getCheck = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Change a connection's shadow block.
|
||||
* Changes the connection's shadow block.
|
||||
* @param {Element} shadow DOM representation of a block or null.
|
||||
*/
|
||||
Blockly.Connection.prototype.setShadowDom = function(shadow) {
|
||||
this.shadowDom_ = shadow;
|
||||
var target = this.targetBlock();
|
||||
if (!target) {
|
||||
this.respawnShadow_();
|
||||
} else if (target.isShadow()) {
|
||||
// The disconnect from dispose will automatically generate the new shadow.
|
||||
target.dispose(false);
|
||||
this.respawnShadow_();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a connection's shadow block.
|
||||
* Returns the xml representation of the connection's shadow block.
|
||||
* @return {Element} Shadow DOM representation of a block or null.
|
||||
*/
|
||||
Blockly.Connection.prototype.getShadowDom = function() {
|
||||
|
||||
@@ -245,6 +245,30 @@ Blockly.Input.prototype.setAlign = function(align) {
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the connection's shadow block.
|
||||
* @param {Element} shadow DOM representation of a block or null.
|
||||
* @return {Blockly.Input} The input being modified (to allow chaining).
|
||||
*/
|
||||
Blockly.Input.prototype.setShadowDom = function(shadow) {
|
||||
if (!this.connection) {
|
||||
throw Error('This input does not have a connection.');
|
||||
}
|
||||
this.connection.setShadowDom(shadow);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the xml representation of the connection's shadow block.
|
||||
* @return {Element} Shadow DOM representation of a block or null.
|
||||
*/
|
||||
Blockly.Input.prototype.getShadowDom = function() {
|
||||
if (!this.connection) {
|
||||
throw Error('This input does not have a connection.');
|
||||
}
|
||||
return this.connection.getShadowDom();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the fields on this input.
|
||||
*/
|
||||
|
||||
@@ -478,20 +478,18 @@ Blockly.RenderedConnection.prototype.disconnectInternal_ = function(parentBlock,
|
||||
* @private
|
||||
*/
|
||||
Blockly.RenderedConnection.prototype.respawnShadow_ = function() {
|
||||
Blockly.RenderedConnection.superClass_.respawnShadow_.call(this);
|
||||
var blockShadow = this.targetBlock();
|
||||
if (!blockShadow) {
|
||||
// This connection must not have a shadowDom_.
|
||||
return;
|
||||
}
|
||||
blockShadow.initSvg();
|
||||
blockShadow.render(false);
|
||||
|
||||
var parentBlock = this.getSourceBlock();
|
||||
// Respawn the shadow block if there is one.
|
||||
var shadow = this.getShadowDom();
|
||||
if (parentBlock.workspace && shadow && Blockly.Events.recordUndo) {
|
||||
Blockly.RenderedConnection.superClass_.respawnShadow_.call(this);
|
||||
var blockShadow = this.targetBlock();
|
||||
if (!blockShadow) {
|
||||
throw Error('Couldn\'t respawn the shadow block that should exist here.');
|
||||
}
|
||||
blockShadow.initSvg();
|
||||
blockShadow.render(false);
|
||||
if (parentBlock.rendered) {
|
||||
parentBlock.render();
|
||||
}
|
||||
if (parentBlock.rendered) {
|
||||
parentBlock.render();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
18
core/xml.js
18
core/xml.js
@@ -650,10 +650,6 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use the shadow block if there is no child block.
|
||||
if (!childBlockElement && childShadowElement) {
|
||||
childBlockElement = childShadowElement;
|
||||
}
|
||||
|
||||
var name = xmlChild.getAttribute('name');
|
||||
var xmlChildElement = /** @type {!Element} */ (xmlChild);
|
||||
@@ -708,9 +704,6 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
prototypeName);
|
||||
break;
|
||||
}
|
||||
if (childShadowElement) {
|
||||
input.connection.setShadowDom(childShadowElement);
|
||||
}
|
||||
if (childBlockElement) {
|
||||
blockChild = Blockly.Xml.domToBlockHeadless_(childBlockElement,
|
||||
workspace);
|
||||
@@ -723,11 +716,12 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
'Child block does not have output or previous statement.');
|
||||
}
|
||||
}
|
||||
// Set shadow after so we don't create a shadow we delete immediately.
|
||||
if (childShadowElement) {
|
||||
input.connection.setShadowDom(childShadowElement);
|
||||
}
|
||||
break;
|
||||
case 'next':
|
||||
if (childShadowElement && block.nextConnection) {
|
||||
block.nextConnection.setShadowDom(childShadowElement);
|
||||
}
|
||||
if (childBlockElement) {
|
||||
if (!block.nextConnection) {
|
||||
throw TypeError('Next statement does not exist.');
|
||||
@@ -743,6 +737,10 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
}
|
||||
block.nextConnection.connect(blockChild.previousConnection);
|
||||
}
|
||||
// Set shadow after so we don't create a shadow we delete immediately.
|
||||
if (childShadowElement && block.nextConnection) {
|
||||
block.nextConnection.setShadowDom(childShadowElement);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Unknown tag; ignore. Same principle as HTML parsers.
|
||||
|
||||
@@ -18,9 +18,11 @@ suite('Connection', function() {
|
||||
return connection;
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
test('Deprecated - canConnectWithReason passes', function() {
|
||||
var deprecateWarnSpy = createDeprecationWarningStub();
|
||||
var conn1 = this.createConnection(Blockly.PREVIOUS_STATEMENT);
|
||||
@@ -30,6 +32,7 @@ suite('Connection', function() {
|
||||
assertSingleDeprecationWarningCall(deprecateWarnSpy,
|
||||
'Connection.prototype.canConnectWithReason');
|
||||
});
|
||||
|
||||
test('Deprecated - canConnectWithReason fails', function() {
|
||||
var deprecateWarnSpy = createDeprecationWarningStub();
|
||||
var conn1 = this.createConnection(Blockly.PREVIOUS_STATEMENT);
|
||||
@@ -39,6 +42,7 @@ suite('Connection', function() {
|
||||
assertSingleDeprecationWarningCall(deprecateWarnSpy,
|
||||
'Connection.prototype.canConnectWithReason');
|
||||
});
|
||||
|
||||
test('Deprecated - checkConnection passes', function() {
|
||||
var deprecateWarnSpy = createDeprecationWarningStub();
|
||||
var conn1 = this.createConnection(Blockly.PREVIOUS_STATEMENT);
|
||||
@@ -49,6 +53,7 @@ suite('Connection', function() {
|
||||
assertSingleDeprecationWarningCall(deprecateWarnSpy,
|
||||
'Connection.prototype.checkConnection');
|
||||
});
|
||||
|
||||
test('Deprecated - checkConnection fails', function() {
|
||||
var deprecateWarnSpy = createDeprecationWarningStub();
|
||||
var conn1 = this.createConnection(Blockly.PREVIOUS_STATEMENT);
|
||||
@@ -59,4 +64,724 @@ suite('Connection', function() {
|
||||
assertSingleDeprecationWarningCall(deprecateWarnSpy,
|
||||
'Connection.prototype.checkConnection');
|
||||
});
|
||||
|
||||
suite('Set Shadow Dom', function() {
|
||||
|
||||
function assertBlockMatches(block, isShadow, opt_id) {
|
||||
chai.assert.equal(block.isShadow(), isShadow,
|
||||
`expected block ${block.id} to ${isShadow ? '' : 'not'} be a shadow`);
|
||||
if (opt_id) {
|
||||
chai.assert.equal(block.id, opt_id);
|
||||
}
|
||||
}
|
||||
|
||||
function assertInputHasBlock(parent, inputName, isShadow, opt_name) {
|
||||
var block = parent.getInputTargetBlock(inputName);
|
||||
chai.assert.exists(block,
|
||||
`expected block ${opt_name || ''} to be attached to ${inputName}`);
|
||||
assertBlockMatches(block, isShadow, opt_name);
|
||||
}
|
||||
|
||||
function assertNextHasBlock(parent, isShadow, opt_name) {
|
||||
var block = parent.getNextBlock();
|
||||
chai.assert.exists(block,
|
||||
`expected block ${opt_name || ''} to be attached to next connection`);
|
||||
assertBlockMatches(block, isShadow, opt_name);
|
||||
}
|
||||
|
||||
function assertInputNotHasBlock(parent, inputName) {
|
||||
var block = parent.getInputTargetBlock(inputName);
|
||||
chai.assert.notExists(block,
|
||||
`expected block ${block && block.id} to not be attached to ${inputName}`);
|
||||
}
|
||||
|
||||
function assertNextNotHasBlock(parent) {
|
||||
var block = parent.getNextBlock();
|
||||
chai.assert.notExists(block,
|
||||
`expected block ${block && block.id} to not be attached to next connection`);
|
||||
}
|
||||
|
||||
var testSuites = [
|
||||
{
|
||||
title: 'Rendered',
|
||||
createWorkspace: () => {
|
||||
return Blockly.inject('blocklyDiv');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Headless',
|
||||
createWorkspace: () => {
|
||||
return new Blockly.Workspace();
|
||||
},
|
||||
}
|
||||
];
|
||||
|
||||
testSuites.forEach((testSuite) => {
|
||||
// Create a suite for each suite.
|
||||
suite(testSuite.title, function() {
|
||||
setup(function() {
|
||||
this.workspace = testSuite.createWorkspace();
|
||||
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
"type": "stack_block",
|
||||
"message0": "",
|
||||
"previousStatement": null,
|
||||
"nextStatement": null
|
||||
},
|
||||
{
|
||||
"type": "row_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "INPUT"
|
||||
}
|
||||
],
|
||||
"output": null
|
||||
},
|
||||
{
|
||||
"type": "statement_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_statement",
|
||||
"name": "STATEMENT"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null
|
||||
}]);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
workspaceTeardown.call(this, this.workspace);
|
||||
delete Blockly.Blocks['stack_block'];
|
||||
delete Blockly.Blocks['row_block'];
|
||||
delete Blockly.Blocks['statement_block'];
|
||||
});
|
||||
|
||||
suite('Add - No Block Connected', function() {
|
||||
// These are defined separately in each suite.
|
||||
function createRowBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStatementBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStackBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
test('Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block"/>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
});
|
||||
|
||||
test('Multiple Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('INPUT'), 'INPUT', true);
|
||||
});
|
||||
|
||||
test('Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block"/>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
});
|
||||
|
||||
test('Multiple Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT', true);
|
||||
});
|
||||
|
||||
test('Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block"/>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true);
|
||||
});
|
||||
|
||||
test('Multiple Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true);
|
||||
assertNextHasBlock(parent.getNextBlock(), true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Add - With Block Connected', function() {
|
||||
// These are defined separately in each suite.
|
||||
function createRowBlocks(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <block type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStatementBlocks(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <block type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStackBlocks(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block">' +
|
||||
' <next>' +
|
||||
' <block type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
test('Value', function() {
|
||||
var parent = createRowBlocks(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block"/>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', false);
|
||||
parent.getInput('INPUT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
});
|
||||
|
||||
test('Multiple Value', function() {
|
||||
var parent = createRowBlocks(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', false);
|
||||
assertInputNotHasBlock(parent.getInputTargetBlock('INPUT'), 'INPUT');
|
||||
parent.getInput('INPUT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('INPUT'), 'INPUT', true);
|
||||
});
|
||||
|
||||
test('Statement', function() {
|
||||
var parent = createStatementBlocks(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block"/>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', false);
|
||||
parent.getInput('STATEMENT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
});
|
||||
|
||||
test('Multiple Statement', function() {
|
||||
var parent = createStatementBlocks(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', false);
|
||||
assertInputNotHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT');
|
||||
parent.getInput('STATEMENT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT', true);
|
||||
});
|
||||
|
||||
test('Next', function() {
|
||||
var parent = createStackBlocks(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block"/>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, false);
|
||||
parent.nextConnection.disconnect();
|
||||
assertNextHasBlock(parent, true);
|
||||
});
|
||||
|
||||
test('Multiple Next', function() {
|
||||
var parent = createStackBlocks(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, false);
|
||||
assertNextNotHasBlock(parent.getNextBlock());
|
||||
parent.nextConnection.disconnect();
|
||||
assertNextHasBlock(parent, true);
|
||||
assertNextHasBlock(parent.getNextBlock(), true);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Add - With Shadow Connected', function() {
|
||||
// These are defined separately in each suite.
|
||||
function createRowBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStatementBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStackBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
test('Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block" id="1"/>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true, '1');
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block" id="2"/>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true, '2');
|
||||
});
|
||||
|
||||
test('Multiple Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block" id="1">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block" id="a"/>' +
|
||||
' </value>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true, '1');
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('INPUT'), 'INPUT', true, 'a');
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block" id="2">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block" id="b"/>' +
|
||||
' </value>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true, '2');
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('INPUT'), 'INPUT', true, 'b');
|
||||
});
|
||||
|
||||
test('Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block" id="1"/>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true, '1');
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block" id="2"/>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true, '2');
|
||||
});
|
||||
|
||||
test('Multiple Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block" id="1">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block" id="a"/>' +
|
||||
' </statement>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true, '1');
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT', true, 'a');
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block" id="2">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block" id="b"/>' +
|
||||
' </statement>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true, '2');
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT', true, 'b');
|
||||
});
|
||||
|
||||
test('Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block" id="1"/>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true, '1');
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block" id="2"/>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true, '2');
|
||||
});
|
||||
|
||||
test('Multiple Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block" id="1">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block" id="a"/>' +
|
||||
' </next>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true, '1');
|
||||
assertNextHasBlock(parent.getNextBlock(), true, 'a');
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block" id="2">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block" id="b"/>' +
|
||||
' </next>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true, '2');
|
||||
assertNextHasBlock(parent.getNextBlock(), true, 'b');
|
||||
});
|
||||
});
|
||||
|
||||
suite('Remove - No Block Connected', function() {
|
||||
// These are defined separately in each suite.
|
||||
function createRowBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStatementBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStackBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
test('Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
parent.getInput('INPUT').connection.setShadowDom(null);
|
||||
assertInputNotHasBlock(parent, 'INPUT');
|
||||
});
|
||||
|
||||
test('Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(null);
|
||||
assertInputNotHasBlock(parent, 'STATMENT');
|
||||
});
|
||||
|
||||
test('Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
parent.nextConnection.setShadowDom(null);
|
||||
assertNextNotHasBlock(parent);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Remove - Block Connected', function() {
|
||||
// These are defined separately in each suite.
|
||||
function createRowBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block"/>' +
|
||||
' <block type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStatementBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block"/>' +
|
||||
' <block type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStackBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block"/>' +
|
||||
' <block type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</block>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
test('Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
parent.getInput('INPUT').connection.setShadowDom(null);
|
||||
assertInputHasBlock(parent, 'INPUT', false);
|
||||
parent.getInput('INPUT').connection.disconnect();
|
||||
assertInputNotHasBlock(parent, 'INPUT');
|
||||
});
|
||||
|
||||
test('Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(null);
|
||||
assertInputHasBlock(parent, 'STATEMENT', false);
|
||||
parent.getInput('STATEMENT').connection.disconnect();
|
||||
assertInputNotHasBlock(parent, 'STATEMENT');
|
||||
});
|
||||
|
||||
test('Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
parent.nextConnection.setShadowDom(null);
|
||||
assertNextHasBlock(parent, false);
|
||||
parent.nextConnection.disconnect();
|
||||
assertNextNotHasBlock(parent);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Add - Connect & Disconnect - Remove', function() {
|
||||
// These are defined separately in each suite.
|
||||
function createRowBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStatementBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
function createStackBlock(workspace) {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block"/>'
|
||||
), workspace);
|
||||
return block;
|
||||
}
|
||||
|
||||
test('Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block"/>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
var child = createRowBlock(this.workspace);
|
||||
parent.getInput('INPUT').connection.connect(child.outputConnection);
|
||||
assertInputHasBlock(parent, 'INPUT', false);
|
||||
parent.getInput('INPUT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
parent.getInput('INPUT').connection.setShadowDom(null);
|
||||
assertInputNotHasBlock(parent, 'INPUT');
|
||||
});
|
||||
|
||||
test('Multiple Value', function() {
|
||||
var parent = createRowBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="row_block">' +
|
||||
' <value name="INPUT">' +
|
||||
' <shadow type="row_block"/>' +
|
||||
' </value>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('INPUT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('INPUT'), 'INPUT', true);
|
||||
var child = createRowBlock(this.workspace);
|
||||
parent.getInput('INPUT').connection.connect(child.outputConnection);
|
||||
assertInputHasBlock(parent, 'INPUT', false);
|
||||
parent.getInput('INPUT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'INPUT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('INPUT'), 'INPUT', true);
|
||||
parent.getInput('INPUT').connection.setShadowDom(null);
|
||||
assertInputNotHasBlock(parent, 'INPUT');
|
||||
});
|
||||
|
||||
test('Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block"/>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
var child = createStatementBlock(this.workspace);
|
||||
parent.getInput('STATEMENT').connection
|
||||
.connect(child.previousConnection);
|
||||
assertInputHasBlock(parent, 'STATEMENT', false);
|
||||
parent.getInput('STATEMENT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(null);
|
||||
assertInputNotHasBlock(parent, 'STATEMENT');
|
||||
});
|
||||
|
||||
test('Multiple Statement', function() {
|
||||
var parent = createStatementBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="statement_block">' +
|
||||
' <statement name="STATEMENT">' +
|
||||
' <shadow type="statement_block"/>' +
|
||||
' </statement>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(xml);
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT', true);
|
||||
var child = createStatementBlock(this.workspace);
|
||||
parent.getInput('STATEMENT').connection
|
||||
.connect(child.previousConnection);
|
||||
assertInputHasBlock(parent, 'STATEMENT', false);
|
||||
parent.getInput('STATEMENT').connection.disconnect();
|
||||
assertInputHasBlock(parent, 'STATEMENT', true);
|
||||
assertInputHasBlock(
|
||||
parent.getInputTargetBlock('STATEMENT'), 'STATEMENT', true);
|
||||
parent.getInput('STATEMENT').connection.setShadowDom(null);
|
||||
assertInputNotHasBlock(parent, 'STATEMENT');
|
||||
});
|
||||
|
||||
test('Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block"/>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true);
|
||||
var child = createStatementBlock(this.workspace);
|
||||
parent.nextConnection.connect(child.previousConnection);
|
||||
assertNextHasBlock(parent, false);
|
||||
parent.nextConnection.disconnect();
|
||||
assertNextHasBlock(parent, true);
|
||||
parent.nextConnection.setShadowDom(null);
|
||||
assertNextNotHasBlock(parent);
|
||||
});
|
||||
|
||||
test('Multiple Next', function() {
|
||||
var parent = createStackBlock(this.workspace);
|
||||
var xml = Blockly.Xml.textToDom(
|
||||
'<shadow type="stack_block">' +
|
||||
' <next>' +
|
||||
' <shadow type="stack_block"/>' +
|
||||
' </next>' +
|
||||
'</shadow>'
|
||||
);
|
||||
parent.nextConnection.setShadowDom(xml);
|
||||
assertNextHasBlock(parent, true);
|
||||
assertNextHasBlock(parent.getNextBlock(), true);
|
||||
var child = createStatementBlock(this.workspace);
|
||||
parent.nextConnection.connect(child.previousConnection);
|
||||
assertNextHasBlock(parent, false);
|
||||
parent.nextConnection.disconnect();
|
||||
assertNextHasBlock(parent, true);
|
||||
assertNextHasBlock(parent.getNextBlock(), true);
|
||||
parent.nextConnection.setShadowDom(null);
|
||||
assertNextNotHasBlock(parent);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -221,6 +221,148 @@ suite('Events', function() {
|
||||
});
|
||||
});
|
||||
|
||||
suite('With shadow blocks', function() {
|
||||
setup(function() {
|
||||
this.TEST_BLOCK_ID = 'test_block_id';
|
||||
this.TEST_PARENT_ID = 'parent';
|
||||
// genUid is expected to be called either once or twice in this suite.
|
||||
this.genUidStub = createGenUidStubWithReturns(
|
||||
[this.TEST_BLOCK_ID, this.TEST_PARENT_ID]);
|
||||
this.block = createSimpleTestBlock(this.workspace);
|
||||
this.block.setShadow(true);
|
||||
});
|
||||
|
||||
test('Block base', function() {
|
||||
var event = new Blockly.Events.BlockBase(this.block);
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, undefined,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'varId': undefined,
|
||||
'recordUndo': true,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
test('Change', function() {
|
||||
var event = new Blockly.Events.Change(
|
||||
this.block, 'field', 'FIELD_NAME', 'old', 'new');
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.CHANGE,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'varId': undefined,
|
||||
'element': 'field',
|
||||
'name': 'FIELD_NAME',
|
||||
'oldValue': 'old',
|
||||
'newValue': 'new',
|
||||
'recordUndo': true,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
test('Block change', function() {
|
||||
var event = new Blockly.Events.BlockChange(
|
||||
this.block, 'field', 'FIELD_NAME', 'old', 'new');
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.CHANGE,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'varId': undefined,
|
||||
'element': 'field',
|
||||
'name': 'FIELD_NAME',
|
||||
'oldValue': 'old',
|
||||
'newValue': 'new',
|
||||
'recordUndo': true,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
test('Create', function() {
|
||||
var event = new Blockly.Events.Create(this.block);
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.CREATE,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'recordUndo': false,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
test('Block create', function() {
|
||||
var event = new Blockly.Events.BlockCreate(this.block);
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.CREATE,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'recordUndo': false,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
test('Delete', function() {
|
||||
var event = new Blockly.Events.Delete(this.block);
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.DELETE,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'recordUndo': false,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
test('Block delete', function() {
|
||||
var event = new Blockly.Events.BlockDelete(this.block);
|
||||
sinon.assert.calledOnce(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.DELETE,
|
||||
this.workspace.id, this.TEST_BLOCK_ID,
|
||||
{
|
||||
'recordUndo': false,
|
||||
'group': '',
|
||||
});
|
||||
});
|
||||
|
||||
suite('Move', function() {
|
||||
setup(function() {
|
||||
this.parentBlock = createSimpleTestBlock(this.workspace);
|
||||
this.block.parentBlock_ = this.parentBlock;
|
||||
this.block.xy_ = new Blockly.utils.Coordinate(3, 4);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
// This needs to be cleared, otherwise workspace.dispose will fail.
|
||||
this.block.parentBlock_ = null;
|
||||
});
|
||||
|
||||
test('Move', function() {
|
||||
var event = new Blockly.Events.Move(this.block);
|
||||
sinon.assert.calledTwice(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id,
|
||||
this.TEST_BLOCK_ID, {
|
||||
'oldParentId': this.TEST_PARENT_ID,
|
||||
'oldInputName': undefined,
|
||||
'oldCoordinate': undefined,
|
||||
'recordUndo': false,
|
||||
'group': ''
|
||||
});
|
||||
});
|
||||
|
||||
test('Block move', function() {
|
||||
var event = new Blockly.Events.BlockMove(this.block);
|
||||
sinon.assert.calledTwice(this.genUidStub);
|
||||
assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id,
|
||||
this.TEST_BLOCK_ID,
|
||||
{
|
||||
'oldParentId': this.TEST_PARENT_ID,
|
||||
'oldInputName': undefined,
|
||||
'oldCoordinate': undefined,
|
||||
'recordUndo': false,
|
||||
'group': ''
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('With variable getter blocks', function() {
|
||||
setup(function() {
|
||||
this.genUidStub = createGenUidStubWithReturns(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user