mirror of
https://github.com/google/blockly.git
synced 2026-01-08 17:40:09 +01:00
feat: add throwing errors for bad shadows (#5330)
* fix: add throwing errors for bad shadows * tests: add tests for setShadowDom
This commit is contained in:
committed by
alschmiedt
parent
9aecac3339
commit
fd12dcf1e7
@@ -122,8 +122,8 @@ Connection.prototype.connect_ = function(childConnection) {
|
||||
// Make sure the parentConnection is available.
|
||||
let orphan;
|
||||
if (parentConnection.isConnected()) {
|
||||
let shadowState = parentConnection.stashShadowState_();
|
||||
var target = parentConnection.targetBlock();
|
||||
const shadowState = parentConnection.stashShadowState_();
|
||||
const target = parentConnection.targetBlock();
|
||||
if (target.isShadow()) {
|
||||
target.dispose(false);
|
||||
} else {
|
||||
@@ -717,7 +717,7 @@ Connection.prototype.setShadowStateInternal_ =
|
||||
this.shadowDom_ = shadowDom;
|
||||
this.shadowState_ = shadowState;
|
||||
|
||||
var target = this.targetBlock();
|
||||
const target = this.targetBlock();
|
||||
if (!target) {
|
||||
this.respawnShadow_();
|
||||
if (this.targetBlock() && this.targetBlock().isShadow()) {
|
||||
@@ -730,7 +730,7 @@ Connection.prototype.setShadowStateInternal_ =
|
||||
this.serializeShadow_(this.targetBlock());
|
||||
}
|
||||
} else {
|
||||
var shadow = this.createShadowBlock_(false);
|
||||
const shadow = this.createShadowBlock_(false);
|
||||
this.serializeShadow_(shadow);
|
||||
if (shadow) {
|
||||
shadow.dispose(false);
|
||||
@@ -748,15 +748,16 @@ Connection.prototype.setShadowStateInternal_ =
|
||||
* @private
|
||||
*/
|
||||
Connection.prototype.createShadowBlock_ = function(attemptToConnect) {
|
||||
var parentBlock = this.getSourceBlock();
|
||||
var shadowState = this.getShadowState();
|
||||
var shadowDom = this.getShadowDom();
|
||||
const parentBlock = this.getSourceBlock();
|
||||
const shadowState = this.getShadowState();
|
||||
const shadowDom = this.getShadowDom();
|
||||
if (!parentBlock.workspace || (!shadowState && !shadowDom)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let blockShadow;
|
||||
if (shadowState) {
|
||||
var blockShadow = blocks.loadInternal(
|
||||
blockShadow = blocks.loadInternal(
|
||||
shadowState,
|
||||
parentBlock.workspace,
|
||||
attemptToConnect ? this : undefined,
|
||||
@@ -767,12 +768,23 @@ Connection.prototype.createShadowBlock_ = function(attemptToConnect) {
|
||||
if (shadowDom) {
|
||||
blockShadow = Xml.domToBlock(shadowDom, parentBlock.workspace);
|
||||
if (attemptToConnect) {
|
||||
if (blockShadow.outputConnection) {
|
||||
this.connect(blockShadow.outputConnection);
|
||||
} else if (blockShadow.previousConnection) {
|
||||
this.connect(blockShadow.previousConnection);
|
||||
if (this.type == Blockly.connectionTypes.INPUT_VALUE) {
|
||||
if (!blockShadow.outputConnection) {
|
||||
throw new Error('Shadow block is missing an output connection');
|
||||
}
|
||||
if (!this.connect(blockShadow.outputConnection)) {
|
||||
throw new Error('Could not connect shadow block to connection');
|
||||
}
|
||||
} else if (this.type == Blockly.connectionTypes.NEXT_STATEMENT) {
|
||||
if (!blockShadow.previousConnection) {
|
||||
throw new Error('Shadow block is missing previous connection');
|
||||
}
|
||||
if (!this.connect(blockShadow.previousConnection)) {
|
||||
throw new Error('Could not connect shadow block to connection');
|
||||
}
|
||||
} else {
|
||||
throw Error('Shadow block does not have output or previous statement.');
|
||||
throw new Error(
|
||||
'Cannot connect a shadow block to a previous/output connection');
|
||||
}
|
||||
}
|
||||
return blockShadow;
|
||||
|
||||
@@ -1296,6 +1296,56 @@ suite('Connection', function() {
|
||||
assertNextNotHasBlock(parent);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Invalid', function() {
|
||||
test('Attach to output', function() {
|
||||
const block = this.workspace.newBlock('row_block');
|
||||
chai.assert.throws(() =>
|
||||
block.outputConnection.setShadowDom(Blockly.Xml.textToDom(
|
||||
'<block type="row_block">')));
|
||||
});
|
||||
|
||||
test('Attach to previous', function() {
|
||||
const block = this.workspace.newBlock('stack_block');
|
||||
chai.assert.throws(() =>
|
||||
block.previousConnection.setShadowDom(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block">')));
|
||||
});
|
||||
|
||||
test('Missing output', function() {
|
||||
const block = this.workspace.newBlock('row_block');
|
||||
chai.assert.throws(() =>
|
||||
block.outputConnection.setShadowDom(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block">')));
|
||||
});
|
||||
|
||||
test('Missing previous', function() {
|
||||
const block = this.workspace.newBlock('stack_block');
|
||||
chai.assert.throws(() =>
|
||||
block.previousConnection.setShadowDom(Blockly.Xml.textToDom(
|
||||
'<block type="row_block">')));
|
||||
});
|
||||
|
||||
test('Invalid connection checks, output', function() {
|
||||
const block = this.workspace.newBlock('logic_operation');
|
||||
chai.assert.throws(() =>
|
||||
block.getInput('A').connection.setShadowDom(
|
||||
Blockly.Xml.textToDom('<block type="stack_block">')));
|
||||
});
|
||||
|
||||
test('Invalid connection checks, previous', function() {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "stack_checks_block",
|
||||
"message0": "",
|
||||
"previousStatement": "check 1",
|
||||
"nextStatement": "check 2"
|
||||
}]);
|
||||
const block = this.workspace.newBlock('stack_checks_block');
|
||||
chai.assert.throws(() =>
|
||||
block.nextConnection.setShadowDom(Blockly.Xml.textToDom(
|
||||
'<block type="stack_checks_block">')));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('setShadowState', function() {
|
||||
@@ -2516,6 +2566,53 @@ suite('Connection', function() {
|
||||
assertNextNotHasBlock(parent);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Invalid', function() {
|
||||
test('Attach to output', function() {
|
||||
const block = this.workspace.newBlock('row_block');
|
||||
chai.assert.throws(() =>
|
||||
block.outputConnection.setShadowState({'type': 'row_block'}));
|
||||
});
|
||||
|
||||
test('Attach to previous', function() {
|
||||
const block = this.workspace.newBlock('stack_block');
|
||||
chai.assert.throws(() =>
|
||||
block.previousConnection.setShadowState(
|
||||
{'type': 'stack_block'}));
|
||||
});
|
||||
|
||||
test('Missing output', function() {
|
||||
const block = this.workspace.newBlock('row_block');
|
||||
chai.assert.throws(() =>
|
||||
block.outputConnection.setShadowState({'type': 'stack_block'}));
|
||||
});
|
||||
|
||||
test('Missing previous', function() {
|
||||
const block = this.workspace.newBlock('stack_block');
|
||||
chai.assert.throws(() =>
|
||||
block.previousConnection.setShadowState({'type': 'row_block'}));
|
||||
});
|
||||
|
||||
test('Invalid connection checks, output', function() {
|
||||
const block = this.workspace.newBlock('logic_operation');
|
||||
chai.assert.throws(() =>
|
||||
block.getInput('A').connection.setShadowState(
|
||||
{'type': 'math_number'}));
|
||||
});
|
||||
|
||||
test('Invalid connection checks, previous', function() {
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "stack_checks_block",
|
||||
"message0": "",
|
||||
"previousStatement": "check 1",
|
||||
"nextStatement": "check 2"
|
||||
}]);
|
||||
const block = this.workspace.newBlock('stack_checks_block');
|
||||
chai.assert.throws(() =>
|
||||
block.nextConnection.setShadowState(
|
||||
{'type': 'stack_checks_block'}));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user