Files
blockly/tests/jsunit/block_test.js
Neil Fraser b46a4fe286 Bring our license format up to date (#3127)
* Google changed from an Inc to an LLC.

This happened back in 2017 but we didn’t notice.  Officially we should update files from Inc to LLC when they are changed as part of regular edits, but this is a nightmare to remember for the next decade.

* Remove project description/titles from licenses

This is no longer part of Google’s header requirements.  Our existing descriptions were useless (“Visual Blocks Editor”) or grossly obselete (“Visual Blocks Language”).

* License no longer requires URL.

* Fix license regexps.
2019-10-02 14:46:56 -07:00

295 lines
7.0 KiB
JavaScript

/**
* @license
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Tests for Blockly.Block
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
var workspace;
var mockControl_;
function defineTestBlocks() {
Blockly.defineBlocksWithJsonArray([{
"type": "stack_block",
"message0": "",
"previousStatement": null,
"nextStatement": null
},
{
"type": "row_block",
"message0": "%1",
"args0": [
{
"type": "input_value",
"name": "INPUT"
}
],
"output": null
}]);
}
function undefineTestBlocks() {
delete Blockly.Blocks['stack_block'];
delete Blockly.Blocks['row_block'];
}
function blockTest_setUp() {
defineTestBlocks();
workspace = new Blockly.Workspace();
}
function blockTest_tearDown() {
undefineTestBlocks();
workspace.dispose();
if (mockControl_) {
mockControl_.restore();
}
}
function assertUnpluggedNoheal(blocks) {
// A has nothing connected to it.
assertEquals(0, blocks.A.getChildren().length);
// B and C are still connected.
assertEquals(blocks.B, blocks.C.getParent());
// B is the top of its stack.
assertNull(blocks.B.getParent());
}
function assertUnpluggedHealed(blocks) {
// A and C are connected.
assertEquals(1, blocks.A.getChildren().length);
assertEquals(blocks.A, blocks.C.getParent());
// B has nothing connected to it.
assertEquals(0, blocks.B.getChildren().length);
// B is the top of its stack.
assertNull(blocks.B.getParent());
}
function assertUnpluggedHealFailed(blocks) {
// A has nothing connected to it.
assertEquals(0, blocks.A.getChildren().length);
// B has nothing connected to it.
assertEquals(0, blocks.B.getChildren().length);
// B is the top of its stack.
assertNull(blocks.B.getParent());
// C is the top of its stack.
assertNull(blocks.C.getParent());
}
function setUpRowBlocks() {
var blockA = workspace.newBlock('row_block');
var blockB = workspace.newBlock('row_block');
var blockC = workspace.newBlock('row_block');
blockA.inputList[0].connection.connect(blockB.outputConnection);
blockB.inputList[0].connection.connect(blockC.outputConnection);
assertEquals(blockB, blockC.getParent());
return {
A: blockA,
B: blockB,
C: blockC
};
}
function setUpStackBlocks() {
var blockA = workspace.newBlock('stack_block');
var blockB = workspace.newBlock('stack_block');
var blockC = workspace.newBlock('stack_block');
blockA.nextConnection.connect(blockB.previousConnection);
blockB.nextConnection.connect(blockC.previousConnection);
assertEquals(blockB, blockC.getParent());
return {
A: blockA,
B: blockB,
C: blockC
};
}
function test_block_stack_unplug_noheal() {
blockTest_setUp();
try {
var blocks = setUpStackBlocks();
blocks.B.unplug();
assertUnpluggedNoheal(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_stack_unplug_heal() {
blockTest_setUp();
try {
var blocks = setUpStackBlocks();
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_stack_unplug_heal_bad_checks() {
blockTest_setUp();
try {
var blocks = setUpStackBlocks();
// A and C can't connect, but both can connect to B.
blocks.A.nextConnection.setCheck('type1');
blocks.C.previousConnection.setCheck('type2');
// The types don't work.
blocks.B.unplug(true);
assertUnpluggedHealFailed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_row_unplug_noheal() {
blockTest_setUp();
try {
var blocks = setUpRowBlocks();
blocks.B.unplug(false);
assertUnpluggedNoheal(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_row_unplug_heal() {
blockTest_setUp();
try {
var blocks = setUpRowBlocks();
// Each block has only one input, and the types work.
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_row_unplug_heal_bad_checks() {
blockTest_setUp();
try {
var blocks = setUpRowBlocks();
// A and C can't connect, but both can connect to B.
blocks.A.inputList[0].connection.setCheck('type1');
blocks.C.outputConnection.setCheck('type2');
// Each block has only one input, but the types don't work.
blocks.B.unplug(true);
assertUnpluggedHealFailed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_row_unplug_multi_inputs_parent() {
blockTest_setUp();
try {
var blocks = setUpRowBlocks();
// Add extra input to parent
blocks.A.appendValueInput('INPUT').setCheck(null);
// Parent block has multiple inputs.
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_row_unplug_multi_inputs_middle() {
blockTest_setUp();
try {
var blocks = setUpRowBlocks();
// Add extra input to middle block
blocks.B.appendValueInput('INPUT').setCheck(null);
// Middle block has multiple inputs.
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_block_row_unplug_multi_inputs_child() {
blockTest_setUp();
try {
var blocks = setUpRowBlocks();
// Add extra input to child block
blocks.C.appendValueInput('INPUT').setCheck(null);
// Child block input count doesn't matter.
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
} finally {
blockTest_tearDown();
}
}
function test_set_style() {
blockTest_setUp();
var styleStub = {
getBlockStyle: function() {
return {
"colourPrimary": "#ffffff",
"colourSecondary": "#aabbcc",
"colourTertiary": "#ddeeff"
};
}
};
mockControl_ = setUpMockMethod(workspace, 'getTheme', null, [styleStub]);
var blockA = workspace.newBlock('row_block');
blockA.setStyle('styleOne');
assertEquals('#ffffff', blockA.colour_);
assertEquals('#aabbcc', blockA.colourSecondary_);
assertEquals('#ddeeff', blockA.colourTertiary_);
blockTest_tearDown();
}
function test_set_style_throw_exception() {
blockTest_setUp();
var styleStub = {
getBlockStyle: function() {
return null;
}
};
mockControl_ = setUpMockMethod(workspace, 'getTheme', null, [styleStub]);
var blockA = workspace.newBlock('row_block');
try {
blockA.setStyle('styleOne');
} catch (error) {
assertEquals(error.message, 'Invalid style name: styleOne');
} finally {
blockTest_tearDown();
}
}