mirror of
https://github.com/google/blockly.git
synced 2026-01-05 08:00:09 +01:00
refactor!: Use navigation rulesets instead of ASTNode to control keyboard navigation. (#8992)
* feat: Add interfaces for keyboard navigation. * feat: Add the Navigator. * feat: Make core types conform to INavigable. * feat: Require FlyoutItems elements to be INavigable. * feat: Add navigation policies for built-in types. * refactor: Convert Marker and LineCursor to operate on INavigables instead of ASTNodes. * chore: Delete dead code in ASTNode. * fix: Fix the tests. * chore: Assuage the linter. * fix: Fix advanced build/tests. * chore: Restore ASTNode tests. * refactor: Move isNavigable() validation into Navigator. * refactor: Exercise navigation instead of ASTNode. * chore: Rename astnode_test.js to navigation_test.js. * chore: Enable the navigation tests. * fix: Fix bug when retrieving the first child of an empty workspace.
This commit is contained in:
@@ -1,850 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {ASTNode} from '../../build/src/core/keyboard_nav/ast_node.js';
|
||||
import {assert} from '../../node_modules/chai/chai.js';
|
||||
import {
|
||||
sharedTestSetup,
|
||||
sharedTestTeardown,
|
||||
workspaceTeardown,
|
||||
} from './test_helpers/setup_teardown.js';
|
||||
|
||||
suite('ASTNode', function () {
|
||||
setup(function () {
|
||||
sharedTestSetup.call(this);
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
'type': 'input_statement',
|
||||
'message0': '%1 %2 %3 %4',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
{
|
||||
'type': 'input_statement',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'previousStatement': null,
|
||||
'nextStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'value_input',
|
||||
'message0': '%1',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'message0': '%1',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
],
|
||||
'output': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
]);
|
||||
this.workspace = new Blockly.Workspace();
|
||||
this.cursor = this.workspace.cursor;
|
||||
const statementInput1 = this.workspace.newBlock('input_statement');
|
||||
const statementInput2 = this.workspace.newBlock('input_statement');
|
||||
const statementInput3 = this.workspace.newBlock('input_statement');
|
||||
const statementInput4 = this.workspace.newBlock('input_statement');
|
||||
const fieldWithOutput = this.workspace.newBlock('field_input');
|
||||
const valueInput = this.workspace.newBlock('value_input');
|
||||
|
||||
statementInput1.nextConnection.connect(statementInput2.previousConnection);
|
||||
statementInput1.inputList[0].connection.connect(
|
||||
fieldWithOutput.outputConnection,
|
||||
);
|
||||
statementInput2.inputList[1].connection.connect(
|
||||
statementInput3.previousConnection,
|
||||
);
|
||||
|
||||
this.blocks = {
|
||||
statementInput1: statementInput1,
|
||||
statementInput2: statementInput2,
|
||||
statementInput3: statementInput3,
|
||||
statementInput4: statementInput4,
|
||||
fieldWithOutput: fieldWithOutput,
|
||||
valueInput: valueInput,
|
||||
};
|
||||
});
|
||||
teardown(function () {
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
suite('HelperFunctions', function () {
|
||||
test('findNextForInput', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const input2 = this.blocks.statementInput1.inputList[1];
|
||||
const connection = input.connection;
|
||||
const node = ASTNode.createConnectionNode(connection);
|
||||
const newASTNode = node.findNextForInput(input);
|
||||
assert.equal(newASTNode.getLocation(), input2.connection);
|
||||
});
|
||||
|
||||
test('findPrevForInput', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const input2 = this.blocks.statementInput1.inputList[1];
|
||||
const connection = input2.connection;
|
||||
const node = ASTNode.createConnectionNode(connection);
|
||||
const newASTNode = node.findPrevForInput(input2);
|
||||
assert.equal(newASTNode.getLocation(), input.connection);
|
||||
});
|
||||
|
||||
test('findNextForField', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const field2 = this.blocks.statementInput1.inputList[0].fieldRow[1];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const newASTNode = node.findNextForField(field);
|
||||
assert.equal(newASTNode.getLocation(), field2);
|
||||
});
|
||||
|
||||
test('findPrevForField', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const field2 = this.blocks.statementInput1.inputList[0].fieldRow[1];
|
||||
const node = ASTNode.createFieldNode(field2);
|
||||
const newASTNode = node.findPrevForField(field2);
|
||||
assert.equal(newASTNode.getLocation(), field);
|
||||
});
|
||||
|
||||
test('navigateBetweenStacks_Forward', function () {
|
||||
const node = new ASTNode(
|
||||
ASTNode.types.NEXT,
|
||||
this.blocks.statementInput1.nextConnection,
|
||||
);
|
||||
const newASTNode = node.navigateBetweenStacks(true);
|
||||
assert.equal(newASTNode.getLocation(), this.blocks.statementInput4);
|
||||
});
|
||||
|
||||
test('navigateBetweenStacks_Backward', function () {
|
||||
const node = new ASTNode(
|
||||
ASTNode.types.BLOCK,
|
||||
this.blocks.statementInput4,
|
||||
);
|
||||
const newASTNode = node.navigateBetweenStacks(false);
|
||||
assert.equal(newASTNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('getOutAstNodeForBlock', function () {
|
||||
const node = new ASTNode(
|
||||
ASTNode.types.BLOCK,
|
||||
this.blocks.statementInput2,
|
||||
);
|
||||
const newASTNode = node.getOutAstNodeForBlock(
|
||||
this.blocks.statementInput2,
|
||||
);
|
||||
assert.equal(newASTNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('getOutAstNodeForBlock_OneBlock', function () {
|
||||
const node = new ASTNode(
|
||||
ASTNode.types.BLOCK,
|
||||
this.blocks.statementInput4,
|
||||
);
|
||||
const newASTNode = node.getOutAstNodeForBlock(
|
||||
this.blocks.statementInput4,
|
||||
);
|
||||
assert.equal(newASTNode.getLocation(), this.blocks.statementInput4);
|
||||
});
|
||||
test('findFirstFieldOrInput_', function () {
|
||||
const node = new ASTNode(
|
||||
ASTNode.types.BLOCK,
|
||||
this.blocks.statementInput4,
|
||||
);
|
||||
const field = this.blocks.statementInput4.inputList[0].fieldRow[0];
|
||||
const newASTNode = node.findFirstFieldOrInput(
|
||||
this.blocks.statementInput4,
|
||||
);
|
||||
assert.equal(newASTNode.getLocation(), field);
|
||||
});
|
||||
});
|
||||
|
||||
suite('NavigationFunctions', function () {
|
||||
setup(function () {
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
'type': 'top_connection',
|
||||
'message0': '',
|
||||
'previousStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'start_block',
|
||||
'message0': '',
|
||||
'nextStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'fields_and_input',
|
||||
'message0': '%1 hi %2 %3 %4',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_dummy',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'previousStatement': null,
|
||||
'nextStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'two_fields',
|
||||
'message0': '%1 hi',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'fields_and_input2',
|
||||
'message0': '%1 %2 %3 hi %4 bye',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
{
|
||||
'type': 'input_statement',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'dummy_input',
|
||||
'message0': 'Hello',
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'dummy_inputValue',
|
||||
'message0': 'Hello %1 %2',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'input_dummy',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'output_next',
|
||||
'message0': '',
|
||||
'output': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
'nextStatement': null,
|
||||
},
|
||||
]);
|
||||
const noNextConnection = this.workspace.newBlock('top_connection');
|
||||
const fieldAndInputs = this.workspace.newBlock('fields_and_input');
|
||||
const twoFields = this.workspace.newBlock('two_fields');
|
||||
const fieldAndInputs2 = this.workspace.newBlock('fields_and_input2');
|
||||
const noPrevConnection = this.workspace.newBlock('start_block');
|
||||
this.blocks.noNextConnection = noNextConnection;
|
||||
this.blocks.fieldAndInputs = fieldAndInputs;
|
||||
this.blocks.twoFields = twoFields;
|
||||
this.blocks.fieldAndInputs2 = fieldAndInputs2;
|
||||
this.blocks.noPrevConnection = noPrevConnection;
|
||||
|
||||
const dummyInput = this.workspace.newBlock('dummy_input');
|
||||
const dummyInputValue = this.workspace.newBlock('dummy_inputValue');
|
||||
const fieldWithOutput2 = this.workspace.newBlock('field_input');
|
||||
this.blocks.dummyInput = dummyInput;
|
||||
this.blocks.dummyInputValue = dummyInputValue;
|
||||
this.blocks.fieldWithOutput2 = fieldWithOutput2;
|
||||
|
||||
const secondBlock = this.workspace.newBlock('input_statement');
|
||||
const outputNextBlock = this.workspace.newBlock('output_next');
|
||||
this.blocks.secondBlock = secondBlock;
|
||||
this.blocks.outputNextBlock = outputNextBlock;
|
||||
});
|
||||
suite('Next', function () {
|
||||
setup(function () {
|
||||
this.singleBlockWorkspace = new Blockly.Workspace();
|
||||
const singleBlock = this.singleBlockWorkspace.newBlock('two_fields');
|
||||
this.blocks.singleBlock = singleBlock;
|
||||
});
|
||||
teardown(function () {
|
||||
workspaceTeardown.call(this, this.singleBlockWorkspace);
|
||||
});
|
||||
|
||||
test('fromPreviousToBlock', function () {
|
||||
const prevConnection = this.blocks.statementInput1.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(prevConnection);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromBlockToNext', function () {
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
const node = ASTNode.createBlockNode(this.blocks.statementInput1);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), nextConnection);
|
||||
});
|
||||
test('fromBlockToNull', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.noNextConnection);
|
||||
const nextNode = node.next();
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('fromNextToPrevious', function () {
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
const prevConnection = this.blocks.statementInput2.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(nextConnection);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), prevConnection);
|
||||
});
|
||||
test('fromNextToNull', function () {
|
||||
const nextConnection = this.blocks.statementInput2.nextConnection;
|
||||
const node = ASTNode.createConnectionNode(nextConnection);
|
||||
const nextNode = node.next();
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('fromInputToInput', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const inputConnection =
|
||||
this.blocks.statementInput1.inputList[1].connection;
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromInputToStatementInput', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[1];
|
||||
const inputConnection =
|
||||
this.blocks.fieldAndInputs2.inputList[2].connection;
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromInputToField', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[0];
|
||||
const field = this.blocks.fieldAndInputs2.inputList[1].fieldRow[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), field);
|
||||
});
|
||||
test('fromInputToNull', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[2];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const nextNode = node.next();
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('fromOutputToBlock', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const node = ASTNode.createConnectionNode(output);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), this.blocks.fieldWithOutput);
|
||||
});
|
||||
test('fromFieldToInput', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[1];
|
||||
const inputConnection =
|
||||
this.blocks.statementInput1.inputList[0].connection;
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromFieldToField', function () {
|
||||
const field = this.blocks.fieldAndInputs.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const field2 = this.blocks.fieldAndInputs.inputList[1].fieldRow[0];
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), field2);
|
||||
});
|
||||
test('fromFieldToNull', function () {
|
||||
const field = this.blocks.twoFields.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const nextNode = node.next();
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('fromStackToStack', function () {
|
||||
const node = ASTNode.createStackNode(this.blocks.statementInput1);
|
||||
const nextNode = node.next();
|
||||
assert.equal(nextNode.getLocation(), this.blocks.statementInput4);
|
||||
assert.equal(nextNode.getType(), ASTNode.types.STACK);
|
||||
});
|
||||
test('fromStackToNull', function () {
|
||||
const node = ASTNode.createStackNode(this.blocks.singleBlock);
|
||||
const nextNode = node.next();
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Previous', function () {
|
||||
test('fromPreviousToNull', function () {
|
||||
const prevConnection = this.blocks.statementInput1.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(prevConnection);
|
||||
const prevNode = node.prev();
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromPreviousToNext', function () {
|
||||
const prevConnection = this.blocks.statementInput2.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(prevConnection);
|
||||
const prevNode = node.prev();
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
assert.equal(prevNode.getLocation(), nextConnection);
|
||||
});
|
||||
test('fromPreviousToInput', function () {
|
||||
const prevConnection = this.blocks.statementInput3.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(prevConnection);
|
||||
const prevNode = node.prev();
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromBlockToPrevious', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.statementInput1);
|
||||
const prevNode = node.prev();
|
||||
const prevConnection = this.blocks.statementInput1.previousConnection;
|
||||
assert.equal(prevNode.getLocation(), prevConnection);
|
||||
});
|
||||
test('fromBlockToNull', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.noPrevConnection);
|
||||
const prevNode = node.prev();
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromBlockToOutput', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.fieldWithOutput);
|
||||
const prevNode = node.prev();
|
||||
const outputConnection = this.blocks.fieldWithOutput.outputConnection;
|
||||
assert.equal(prevNode.getLocation(), outputConnection);
|
||||
});
|
||||
test('fromNextToBlock', function () {
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
const node = ASTNode.createConnectionNode(nextConnection);
|
||||
const prevNode = node.prev();
|
||||
assert.equal(prevNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromInputToField', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const prevNode = node.prev();
|
||||
assert.equal(prevNode.getLocation(), input.fieldRow[1]);
|
||||
});
|
||||
test('fromInputToNull', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const prevNode = node.prev();
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromInputToInput', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[2];
|
||||
const inputConnection =
|
||||
this.blocks.fieldAndInputs2.inputList[1].connection;
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const prevNode = node.prev();
|
||||
assert.equal(prevNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromOutputToNull', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const node = ASTNode.createConnectionNode(output);
|
||||
const prevNode = node.prev();
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromFieldToNull', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const prevNode = node.prev();
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromFieldToInput', function () {
|
||||
const field = this.blocks.fieldAndInputs2.inputList[1].fieldRow[0];
|
||||
const inputConnection =
|
||||
this.blocks.fieldAndInputs2.inputList[0].connection;
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const prevNode = node.prev();
|
||||
assert.equal(prevNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromFieldToField', function () {
|
||||
const field = this.blocks.fieldAndInputs.inputList[1].fieldRow[0];
|
||||
const field2 = this.blocks.fieldAndInputs.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const prevNode = node.prev();
|
||||
assert.equal(prevNode.getLocation(), field2);
|
||||
});
|
||||
test('fromStackToStack', function () {
|
||||
const node = ASTNode.createStackNode(this.blocks.statementInput4);
|
||||
const prevNode = node.prev();
|
||||
assert.equal(prevNode.getLocation(), this.blocks.statementInput1);
|
||||
assert.equal(prevNode.getType(), ASTNode.types.STACK);
|
||||
});
|
||||
});
|
||||
|
||||
suite('In', function () {
|
||||
setup(function () {
|
||||
this.emptyWorkspace = new Blockly.Workspace();
|
||||
});
|
||||
teardown(function () {
|
||||
workspaceTeardown.call(this, this.emptyWorkspace);
|
||||
});
|
||||
|
||||
test('fromInputToOutput', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const inNode = node.in();
|
||||
const outputConnection = this.blocks.fieldWithOutput.outputConnection;
|
||||
assert.equal(inNode.getLocation(), outputConnection);
|
||||
});
|
||||
test('fromInputToNull', function () {
|
||||
const input = this.blocks.statementInput2.inputList[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const inNode = node.in();
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromInputToPrevious', function () {
|
||||
const input = this.blocks.statementInput2.inputList[1];
|
||||
const previousConnection =
|
||||
this.blocks.statementInput3.previousConnection;
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), previousConnection);
|
||||
});
|
||||
test('fromBlockToInput', function () {
|
||||
const input = this.blocks.valueInput.inputList[0];
|
||||
const node = ASTNode.createBlockNode(this.blocks.valueInput);
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), input.connection);
|
||||
});
|
||||
test('fromBlockToField', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.statementInput1);
|
||||
const inNode = node.in();
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
assert.equal(inNode.getLocation(), field);
|
||||
});
|
||||
test('fromBlockToPrevious', function () {
|
||||
const prevConnection = this.blocks.statementInput4.previousConnection;
|
||||
const node = ASTNode.createStackNode(this.blocks.statementInput4);
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), prevConnection);
|
||||
assert.equal(inNode.getType(), ASTNode.types.PREVIOUS);
|
||||
});
|
||||
test('fromBlockToNull_DummyInput', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.dummyInput);
|
||||
const inNode = node.in();
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromBlockToInput_DummyInputValue', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.dummyInputValue);
|
||||
const inputConnection =
|
||||
this.blocks.dummyInputValue.inputList[1].connection;
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromOuputToNull', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const node = ASTNode.createConnectionNode(output);
|
||||
const inNode = node.in();
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromFieldToNull', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const inNode = node.in();
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromWorkspaceToStack', function () {
|
||||
const coordinate = new Blockly.utils.Coordinate(100, 100);
|
||||
const node = ASTNode.createWorkspaceNode(this.workspace, coordinate);
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), this.workspace.getTopBlocks()[0]);
|
||||
assert.equal(inNode.getType(), ASTNode.types.STACK);
|
||||
});
|
||||
test('fromWorkspaceToNull', function () {
|
||||
const coordinate = new Blockly.utils.Coordinate(100, 100);
|
||||
const node = ASTNode.createWorkspaceNode(
|
||||
this.emptyWorkspace,
|
||||
coordinate,
|
||||
);
|
||||
const inNode = node.in();
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromStackToPrevious', function () {
|
||||
const node = ASTNode.createStackNode(this.blocks.statementInput1);
|
||||
const previous = this.blocks.statementInput1.previousConnection;
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), previous);
|
||||
assert.equal(inNode.getType(), ASTNode.types.PREVIOUS);
|
||||
});
|
||||
test('fromStackToOutput', function () {
|
||||
const node = ASTNode.createStackNode(this.blocks.fieldWithOutput2);
|
||||
const output = this.blocks.fieldWithOutput2.outputConnection;
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), output);
|
||||
assert.equal(inNode.getType(), ASTNode.types.OUTPUT);
|
||||
});
|
||||
test('fromStackToBlock', function () {
|
||||
const node = ASTNode.createStackNode(this.blocks.dummyInput);
|
||||
const inNode = node.in();
|
||||
assert.equal(inNode.getLocation(), this.blocks.dummyInput);
|
||||
assert.equal(inNode.getType(), ASTNode.types.BLOCK);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Out', function () {
|
||||
setup(function () {
|
||||
const secondBlock = this.blocks.secondBlock;
|
||||
const outputNextBlock = this.blocks.outputNextBlock;
|
||||
this.blocks.noPrevConnection.nextConnection.connect(
|
||||
secondBlock.previousConnection,
|
||||
);
|
||||
secondBlock.inputList[0].connection.connect(
|
||||
outputNextBlock.outputConnection,
|
||||
);
|
||||
});
|
||||
|
||||
test('fromInputToBlock', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.BLOCK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromOutputToInput', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const node = ASTNode.createConnectionNode(output);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.INPUT);
|
||||
assert.equal(
|
||||
outNode.getLocation(),
|
||||
this.blocks.statementInput1.inputList[0].connection,
|
||||
);
|
||||
});
|
||||
test('fromOutputToStack', function () {
|
||||
const output = this.blocks.fieldWithOutput2.outputConnection;
|
||||
const node = ASTNode.createConnectionNode(output);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.fieldWithOutput2);
|
||||
});
|
||||
test('fromFieldToBlock', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.BLOCK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromStackToWorkspace', function () {
|
||||
const stub = sinon
|
||||
.stub(this.blocks.statementInput4, 'getRelativeToSurfaceXY')
|
||||
.returns({x: 10, y: 10});
|
||||
const node = ASTNode.createStackNode(this.blocks.statementInput4);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.WORKSPACE);
|
||||
assert.equal(outNode.wsCoordinate.x, 10);
|
||||
assert.equal(outNode.wsCoordinate.y, -10);
|
||||
stub.restore();
|
||||
});
|
||||
test('fromPreviousToInput', function () {
|
||||
const previous = this.blocks.statementInput3.previousConnection;
|
||||
const inputConnection =
|
||||
this.blocks.statementInput2.inputList[1].connection;
|
||||
const node = ASTNode.createConnectionNode(previous);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.INPUT);
|
||||
assert.equal(outNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromPreviousToStack', function () {
|
||||
const previous = this.blocks.statementInput2.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(previous);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromNextToInput', function () {
|
||||
const next = this.blocks.statementInput3.nextConnection;
|
||||
const inputConnection =
|
||||
this.blocks.statementInput2.inputList[1].connection;
|
||||
const node = ASTNode.createConnectionNode(next);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.INPUT);
|
||||
assert.equal(outNode.getLocation(), inputConnection);
|
||||
});
|
||||
test('fromNextToStack', function () {
|
||||
const next = this.blocks.statementInput2.nextConnection;
|
||||
const node = ASTNode.createConnectionNode(next);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromNextToStack_NoPreviousConnection', function () {
|
||||
const next = this.blocks.secondBlock.nextConnection;
|
||||
const node = ASTNode.createConnectionNode(next);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.noPrevConnection);
|
||||
});
|
||||
/**
|
||||
* This is where there is a block with both an output connection and a
|
||||
* next connection attached to an input.
|
||||
*/
|
||||
test('fromNextToInput_OutputAndPreviousConnection', function () {
|
||||
const next = this.blocks.outputNextBlock.nextConnection;
|
||||
const node = ASTNode.createConnectionNode(next);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.INPUT);
|
||||
assert.equal(
|
||||
outNode.getLocation(),
|
||||
this.blocks.secondBlock.inputList[0].connection,
|
||||
);
|
||||
});
|
||||
test('fromBlockToStack', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.statementInput2);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromBlockToInput', function () {
|
||||
const input = this.blocks.statementInput2.inputList[1].connection;
|
||||
const node = ASTNode.createBlockNode(this.blocks.statementInput3);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.INPUT);
|
||||
assert.equal(outNode.getLocation(), input);
|
||||
});
|
||||
test('fromTopBlockToStack', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.statementInput1);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.statementInput1);
|
||||
});
|
||||
test('fromBlockToStack_OutputConnection', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.fieldWithOutput2);
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.STACK);
|
||||
assert.equal(outNode.getLocation(), this.blocks.fieldWithOutput2);
|
||||
});
|
||||
test('fromBlockToInput_OutputConnection', function () {
|
||||
const node = ASTNode.createBlockNode(this.blocks.outputNextBlock);
|
||||
const inputConnection = this.blocks.secondBlock.inputList[0].connection;
|
||||
const outNode = node.out();
|
||||
assert.equal(outNode.getType(), ASTNode.types.INPUT);
|
||||
assert.equal(outNode.getLocation(), inputConnection);
|
||||
});
|
||||
});
|
||||
|
||||
suite('createFunctions', function () {
|
||||
test('createFieldNode', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const node = ASTNode.createFieldNode(field);
|
||||
assert.equal(node.getLocation(), field);
|
||||
assert.equal(node.getType(), ASTNode.types.FIELD);
|
||||
assert.isFalse(node.isConnection());
|
||||
});
|
||||
test('createConnectionNode', function () {
|
||||
const prevConnection = this.blocks.statementInput4.previousConnection;
|
||||
const node = ASTNode.createConnectionNode(prevConnection);
|
||||
assert.equal(node.getLocation(), prevConnection);
|
||||
assert.equal(node.getType(), ASTNode.types.PREVIOUS);
|
||||
assert.isTrue(node.isConnection());
|
||||
});
|
||||
test('createInputNode', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const node = ASTNode.createInputNode(input);
|
||||
assert.equal(node.getLocation(), input.connection);
|
||||
assert.equal(node.getType(), ASTNode.types.INPUT);
|
||||
assert.isTrue(node.isConnection());
|
||||
});
|
||||
test('createWorkspaceNode', function () {
|
||||
const coordinate = new Blockly.utils.Coordinate(100, 100);
|
||||
const node = ASTNode.createWorkspaceNode(this.workspace, coordinate);
|
||||
assert.equal(node.getLocation(), this.workspace);
|
||||
assert.equal(node.getType(), ASTNode.types.WORKSPACE);
|
||||
assert.equal(node.getWsCoordinate(), coordinate);
|
||||
assert.isFalse(node.isConnection());
|
||||
});
|
||||
test('createStatementConnectionNode', function () {
|
||||
const nextConnection =
|
||||
this.blocks.statementInput1.inputList[1].connection;
|
||||
const inputConnection =
|
||||
this.blocks.statementInput1.inputList[1].connection;
|
||||
const node = ASTNode.createConnectionNode(nextConnection);
|
||||
assert.equal(node.getLocation(), inputConnection);
|
||||
assert.equal(node.getType(), ASTNode.types.INPUT);
|
||||
assert.isTrue(node.isConnection());
|
||||
});
|
||||
test('createTopNode-previous', function () {
|
||||
const block = this.blocks.statementInput1;
|
||||
const topNode = ASTNode.createTopNode(block);
|
||||
assert.equal(topNode.getLocation(), block.previousConnection);
|
||||
});
|
||||
test('createTopNode-block', function () {
|
||||
const block = this.blocks.noPrevConnection;
|
||||
const topNode = ASTNode.createTopNode(block);
|
||||
assert.equal(topNode.getLocation(), block);
|
||||
});
|
||||
test('createTopNode-output', function () {
|
||||
const block = this.blocks.outputNextBlock;
|
||||
const topNode = ASTNode.createTopNode(block);
|
||||
assert.equal(topNode.getLocation(), block.outputConnection);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,7 +4,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {ASTNode} from '../../build/src/core/keyboard_nav/ast_node.js';
|
||||
import {assert} from '../../node_modules/chai/chai.js';
|
||||
import {createRenderedBlock} from './test_helpers/block_definitions.js';
|
||||
import {
|
||||
@@ -87,70 +86,63 @@ suite('Cursor', function () {
|
||||
});
|
||||
|
||||
test('Next - From a Previous connection go to the next block', function () {
|
||||
const prevNode = ASTNode.createConnectionNode(
|
||||
this.blocks.A.previousConnection,
|
||||
);
|
||||
const prevNode = this.blocks.A.previousConnection;
|
||||
this.cursor.setCurNode(prevNode);
|
||||
this.cursor.next();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(curNode.getLocation(), this.blocks.A);
|
||||
assert.equal(curNode, this.blocks.A);
|
||||
});
|
||||
test('Next - From a block go to its statement input', function () {
|
||||
const prevNode = ASTNode.createBlockNode(this.blocks.B);
|
||||
const prevNode = this.blocks.B;
|
||||
this.cursor.setCurNode(prevNode);
|
||||
this.cursor.next();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(
|
||||
curNode.getLocation(),
|
||||
this.blocks.B.getInput('NAME4').connection,
|
||||
);
|
||||
assert.equal(curNode, this.blocks.B.getInput('NAME4').connection);
|
||||
});
|
||||
|
||||
test('In - From attached input connection', function () {
|
||||
const fieldBlock = this.blocks.E;
|
||||
const inputConnectionNode = ASTNode.createConnectionNode(
|
||||
this.blocks.A.inputList[0].connection,
|
||||
);
|
||||
const inputConnectionNode = this.blocks.A.inputList[0].connection;
|
||||
this.cursor.setCurNode(inputConnectionNode);
|
||||
this.cursor.in();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(curNode.getLocation(), fieldBlock);
|
||||
assert.equal(curNode, fieldBlock);
|
||||
});
|
||||
|
||||
test('Prev - From previous connection does not skip over next connection', function () {
|
||||
const prevConnection = this.blocks.B.previousConnection;
|
||||
const prevConnectionNode = ASTNode.createConnectionNode(prevConnection);
|
||||
const prevConnectionNode = prevConnection;
|
||||
this.cursor.setCurNode(prevConnectionNode);
|
||||
this.cursor.prev();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(curNode.getLocation(), this.blocks.A.nextConnection);
|
||||
assert.equal(curNode, this.blocks.A.nextConnection);
|
||||
});
|
||||
|
||||
test('Prev - From first connection loop to last next connection', function () {
|
||||
const prevConnection = this.blocks.A.previousConnection;
|
||||
const prevConnectionNode = ASTNode.createConnectionNode(prevConnection);
|
||||
const prevConnectionNode = prevConnection;
|
||||
this.cursor.setCurNode(prevConnectionNode);
|
||||
this.cursor.prev();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(curNode.getLocation(), this.blocks.D.nextConnection);
|
||||
assert.equal(curNode, this.blocks.D.nextConnection);
|
||||
});
|
||||
|
||||
test('Out - From field does not skip over block node', function () {
|
||||
const field = this.blocks.E.inputList[0].fieldRow[0];
|
||||
const fieldNode = ASTNode.createFieldNode(field);
|
||||
const fieldNode = field;
|
||||
this.cursor.setCurNode(fieldNode);
|
||||
this.cursor.out();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(curNode.getLocation(), this.blocks.E);
|
||||
assert.equal(curNode, this.blocks.E);
|
||||
});
|
||||
|
||||
test('Out - From first connection loop to last next connection', function () {
|
||||
const prevConnection = this.blocks.A.previousConnection;
|
||||
const prevConnectionNode = ASTNode.createConnectionNode(prevConnection);
|
||||
const prevConnectionNode = prevConnection;
|
||||
this.cursor.setCurNode(prevConnectionNode);
|
||||
this.cursor.out();
|
||||
const curNode = this.cursor.getCurNode();
|
||||
assert.equal(curNode.getLocation(), this.blocks.D.nextConnection);
|
||||
assert.equal(curNode, this.blocks.D.nextConnection);
|
||||
});
|
||||
});
|
||||
suite('Searching', function () {
|
||||
@@ -216,11 +208,11 @@ suite('Cursor', function () {
|
||||
});
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
assert.equal(node.getLocation(), this.blockA);
|
||||
assert.equal(node, this.blockA);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
assert.equal(node.getLocation(), this.blockA);
|
||||
assert.equal(node, this.blockA);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -233,11 +225,11 @@ suite('Cursor', function () {
|
||||
});
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
assert.equal(node.getLocation(), this.blockA.previousConnection);
|
||||
assert.equal(node, this.blockA.previousConnection);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
assert.equal(node.getLocation(), this.blockA.nextConnection);
|
||||
assert.equal(node, this.blockA.nextConnection);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -250,11 +242,11 @@ suite('Cursor', function () {
|
||||
});
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
assert.equal(node.getLocation(), this.blockA.outputConnection);
|
||||
assert.equal(node, this.blockA.outputConnection);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
assert.equal(node.getLocation(), this.blockA.inputList[0].connection);
|
||||
assert.equal(node, this.blockA.inputList[0].connection);
|
||||
});
|
||||
});
|
||||
suite('one c-hat block', function () {
|
||||
@@ -266,11 +258,11 @@ suite('Cursor', function () {
|
||||
});
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
assert.equal(node.getLocation(), this.blockA);
|
||||
assert.equal(node, this.blockA);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
assert.equal(node.getLocation(), this.blockA.inputList[0].connection);
|
||||
assert.equal(node, this.blockA.inputList[0].connection);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -303,12 +295,12 @@ suite('Cursor', function () {
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
const blockA = this.workspace.getBlockById('A');
|
||||
assert.equal(node.getLocation(), blockA.previousConnection);
|
||||
assert.equal(node, blockA.previousConnection);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
const blockB = this.workspace.getBlockById('B');
|
||||
assert.equal(node.getLocation(), blockB.nextConnection);
|
||||
assert.equal(node, blockB.nextConnection);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -343,14 +335,15 @@ suite('Cursor', function () {
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
const blockA = this.workspace.getBlockById('A');
|
||||
assert.equal(node.getLocation(), blockA.outputConnection);
|
||||
assert.equal(node, blockA.outputConnection);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
const blockB = this.workspace.getBlockById('B');
|
||||
assert.equal(node.getLocation(), blockB.inputList[0].connection);
|
||||
assert.equal(node, blockB.inputList[0].connection);
|
||||
});
|
||||
});
|
||||
|
||||
suite('two stacks', function () {
|
||||
setup(function () {
|
||||
const state = {
|
||||
@@ -391,14 +384,14 @@ suite('Cursor', function () {
|
||||
});
|
||||
test('getFirstNode', function () {
|
||||
const node = this.cursor.getFirstNode();
|
||||
const location = node.getLocation();
|
||||
const location = node;
|
||||
const previousConnection =
|
||||
this.workspace.getBlockById('A').previousConnection;
|
||||
assert.equal(location, previousConnection);
|
||||
});
|
||||
test('getLastNode', function () {
|
||||
const node = this.cursor.getLastNode();
|
||||
const location = node.getLocation();
|
||||
const location = node;
|
||||
const nextConnection = this.workspace.getBlockById('D').nextConnection;
|
||||
assert.equal(location, nextConnection);
|
||||
});
|
||||
@@ -447,7 +440,7 @@ suite('Cursor', function () {
|
||||
this.neverValid = () => false;
|
||||
this.alwaysValid = () => true;
|
||||
this.isConnection = (node) => {
|
||||
return node && node.isConnection();
|
||||
return node && node instanceof Blockly.RenderedConnection;
|
||||
};
|
||||
});
|
||||
teardown(function () {
|
||||
@@ -489,9 +482,7 @@ suite('Cursor', function () {
|
||||
this.workspace.clear();
|
||||
});
|
||||
test('Never valid - start at top', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -500,7 +491,7 @@ suite('Cursor', function () {
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('Never valid - start in middle', function () {
|
||||
const startNode = ASTNode.createBlockNode(this.blockB);
|
||||
const startNode = this.blockB;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -509,9 +500,7 @@ suite('Cursor', function () {
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('Never valid - start at end', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -521,29 +510,25 @@ suite('Cursor', function () {
|
||||
});
|
||||
|
||||
test('Always valid - start at top', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
false,
|
||||
);
|
||||
assert.equal(nextNode.getLocation(), this.blockA);
|
||||
assert.equal(nextNode, this.blockA);
|
||||
});
|
||||
test('Always valid - start in middle', function () {
|
||||
const startNode = ASTNode.createBlockNode(this.blockB);
|
||||
const startNode = this.blockB;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
false,
|
||||
);
|
||||
assert.equal(nextNode.getLocation(), this.blockB.getField('FIELD'));
|
||||
assert.equal(nextNode, this.blockB.getField('FIELD'));
|
||||
});
|
||||
test('Always valid - start at end', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
@@ -553,29 +538,25 @@ suite('Cursor', function () {
|
||||
});
|
||||
|
||||
test('Valid if connection - start at top', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
false,
|
||||
);
|
||||
assert.equal(nextNode.getLocation(), this.blockA.nextConnection);
|
||||
assert.equal(nextNode, this.blockA.nextConnection);
|
||||
});
|
||||
test('Valid if connection - start in middle', function () {
|
||||
const startNode = ASTNode.createBlockNode(this.blockB);
|
||||
const startNode = this.blockB;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
false,
|
||||
);
|
||||
assert.equal(nextNode.getLocation(), this.blockB.nextConnection);
|
||||
assert.equal(nextNode, this.blockB.nextConnection);
|
||||
});
|
||||
test('Valid if connection - start at end', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
@@ -584,9 +565,7 @@ suite('Cursor', function () {
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('Never valid - start at end - with loopback', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -595,27 +574,23 @@ suite('Cursor', function () {
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('Always valid - start at end - with loopback', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
true,
|
||||
);
|
||||
assert.equal(nextNode.getLocation(), this.blockA.previousConnection);
|
||||
assert.equal(nextNode, this.blockA.previousConnection);
|
||||
});
|
||||
|
||||
test('Valid if connection - start at end - with loopback', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const nextNode = this.cursor.getNextNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
true,
|
||||
);
|
||||
assert.equal(nextNode.getLocation(), this.blockA.previousConnection);
|
||||
assert.equal(nextNode, this.blockA.previousConnection);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -663,7 +638,7 @@ suite('Cursor', function () {
|
||||
this.neverValid = () => false;
|
||||
this.alwaysValid = () => true;
|
||||
this.isConnection = (node) => {
|
||||
return node && node.isConnection();
|
||||
return node && node instanceof Blockly.RenderedConnection;
|
||||
};
|
||||
});
|
||||
teardown(function () {
|
||||
@@ -705,9 +680,7 @@ suite('Cursor', function () {
|
||||
this.workspace.clear();
|
||||
});
|
||||
test('Never valid - start at top', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -716,7 +689,7 @@ suite('Cursor', function () {
|
||||
assert.isNull(previousNode);
|
||||
});
|
||||
test('Never valid - start in middle', function () {
|
||||
const startNode = ASTNode.createBlockNode(this.blockB);
|
||||
const startNode = this.blockB;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -725,9 +698,7 @@ suite('Cursor', function () {
|
||||
assert.isNull(previousNode);
|
||||
});
|
||||
test('Never valid - start at end', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -737,44 +708,35 @@ suite('Cursor', function () {
|
||||
});
|
||||
|
||||
test('Always valid - start at top', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
false,
|
||||
);
|
||||
assert.isNotNull(previousNode);
|
||||
assert.isNull(previousNode);
|
||||
});
|
||||
test('Always valid - start in middle', function () {
|
||||
const startNode = ASTNode.createBlockNode(this.blockB);
|
||||
const startNode = this.blockB;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
previousNode.getLocation(),
|
||||
this.blockB.previousConnection,
|
||||
);
|
||||
assert.equal(previousNode, this.blockB.previousConnection);
|
||||
});
|
||||
test('Always valid - start at end', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
false,
|
||||
);
|
||||
assert.equal(previousNode.getLocation(), this.blockC.getField('FIELD'));
|
||||
assert.equal(previousNode, this.blockC.getField('FIELD'));
|
||||
});
|
||||
|
||||
test('Valid if connection - start at top', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
@@ -783,35 +745,25 @@ suite('Cursor', function () {
|
||||
assert.isNull(previousNode);
|
||||
});
|
||||
test('Valid if connection - start in middle', function () {
|
||||
const startNode = ASTNode.createBlockNode(this.blockB);
|
||||
const startNode = this.blockB;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
previousNode.getLocation(),
|
||||
this.blockB.previousConnection,
|
||||
);
|
||||
assert.equal(previousNode, this.blockB.previousConnection);
|
||||
});
|
||||
test('Valid if connection - start at end', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockC.nextConnection,
|
||||
);
|
||||
const startNode = this.blockC.nextConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
false,
|
||||
);
|
||||
assert.equal(
|
||||
previousNode.getLocation(),
|
||||
this.blockC.previousConnection,
|
||||
);
|
||||
assert.equal(previousNode, this.blockC.previousConnection);
|
||||
});
|
||||
test('Never valid - start at top - with loopback', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.neverValid,
|
||||
@@ -820,27 +772,22 @@ suite('Cursor', function () {
|
||||
assert.isNull(previousNode);
|
||||
});
|
||||
test('Always valid - start at top - with loopback', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.alwaysValid,
|
||||
true,
|
||||
);
|
||||
// Previous node will be a stack node in this case.
|
||||
assert.equal(previousNode.getLocation(), this.blockA);
|
||||
assert.equal(previousNode, this.blockC.nextConnection);
|
||||
});
|
||||
test('Valid if connection - start at top - with loopback', function () {
|
||||
const startNode = ASTNode.createConnectionNode(
|
||||
this.blockA.previousConnection,
|
||||
);
|
||||
const startNode = this.blockA.previousConnection;
|
||||
const previousNode = this.cursor.getPreviousNode(
|
||||
startNode,
|
||||
this.isConnection,
|
||||
true,
|
||||
);
|
||||
assert.equal(previousNode.getLocation(), this.blockC.nextConnection);
|
||||
assert.equal(previousNode, this.blockC.nextConnection);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -180,7 +180,6 @@
|
||||
import {javascriptGenerator} from '../../build/javascript.loader.mjs';
|
||||
|
||||
// Import tests.
|
||||
import './astnode_test.js';
|
||||
import './block_json_test.js';
|
||||
import './block_test.js';
|
||||
import './clipboard_test.js';
|
||||
@@ -249,6 +248,7 @@
|
||||
import './metrics_test.js';
|
||||
import './mutator_test.js';
|
||||
import './names_test.js';
|
||||
import './navigation_test.js';
|
||||
// TODO: Remove these tests.
|
||||
import './old_workspace_comment_test.js';
|
||||
import './procedure_map_test.js';
|
||||
|
||||
567
tests/mocha/navigation_test.js
Normal file
567
tests/mocha/navigation_test.js
Normal file
@@ -0,0 +1,567 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {assert} from '../../node_modules/chai/chai.js';
|
||||
import {
|
||||
sharedTestSetup,
|
||||
sharedTestTeardown,
|
||||
workspaceTeardown,
|
||||
} from './test_helpers/setup_teardown.js';
|
||||
|
||||
suite('Navigation', function () {
|
||||
setup(function () {
|
||||
sharedTestSetup.call(this);
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
'type': 'input_statement',
|
||||
'message0': '%1 %2 %3 %4',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
{
|
||||
'type': 'input_statement',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'previousStatement': null,
|
||||
'nextStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'value_input',
|
||||
'message0': '%1',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'message0': '%1',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
],
|
||||
'output': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
]);
|
||||
this.workspace = Blockly.inject('blocklyDiv', {});
|
||||
this.navigator = this.workspace.getNavigator();
|
||||
const statementInput1 = this.workspace.newBlock('input_statement');
|
||||
const statementInput2 = this.workspace.newBlock('input_statement');
|
||||
const statementInput3 = this.workspace.newBlock('input_statement');
|
||||
const statementInput4 = this.workspace.newBlock('input_statement');
|
||||
const fieldWithOutput = this.workspace.newBlock('field_input');
|
||||
const valueInput = this.workspace.newBlock('value_input');
|
||||
|
||||
statementInput1.nextConnection.connect(statementInput2.previousConnection);
|
||||
statementInput1.inputList[0].connection.connect(
|
||||
fieldWithOutput.outputConnection,
|
||||
);
|
||||
statementInput2.inputList[1].connection.connect(
|
||||
statementInput3.previousConnection,
|
||||
);
|
||||
|
||||
this.blocks = {
|
||||
statementInput1: statementInput1,
|
||||
statementInput2: statementInput2,
|
||||
statementInput3: statementInput3,
|
||||
statementInput4: statementInput4,
|
||||
fieldWithOutput: fieldWithOutput,
|
||||
valueInput: valueInput,
|
||||
};
|
||||
});
|
||||
teardown(function () {
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
suite('NavigationFunctions', function () {
|
||||
setup(function () {
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
'type': 'top_connection',
|
||||
'message0': '',
|
||||
'previousStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'start_block',
|
||||
'message0': '',
|
||||
'nextStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'fields_and_input',
|
||||
'message0': '%1 hi %2 %3 %4',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_dummy',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'previousStatement': null,
|
||||
'nextStatement': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'two_fields',
|
||||
'message0': '%1 hi',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'fields_and_input2',
|
||||
'message0': '%1 %2 %3 hi %4 bye',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
{
|
||||
'type': 'field_input',
|
||||
'name': 'NAME',
|
||||
'text': 'default',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
{
|
||||
'type': 'input_statement',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'dummy_input',
|
||||
'message0': 'Hello',
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'dummy_inputValue',
|
||||
'message0': 'Hello %1 %2',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'input_dummy',
|
||||
},
|
||||
{
|
||||
'type': 'input_value',
|
||||
'name': 'NAME',
|
||||
},
|
||||
],
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
},
|
||||
{
|
||||
'type': 'output_next',
|
||||
'message0': '',
|
||||
'output': null,
|
||||
'colour': 230,
|
||||
'tooltip': '',
|
||||
'helpUrl': '',
|
||||
'nextStatement': null,
|
||||
},
|
||||
]);
|
||||
const noNextConnection = this.workspace.newBlock('top_connection');
|
||||
const fieldAndInputs = this.workspace.newBlock('fields_and_input');
|
||||
const twoFields = this.workspace.newBlock('two_fields');
|
||||
const fieldAndInputs2 = this.workspace.newBlock('fields_and_input2');
|
||||
const noPrevConnection = this.workspace.newBlock('start_block');
|
||||
this.blocks.noNextConnection = noNextConnection;
|
||||
this.blocks.fieldAndInputs = fieldAndInputs;
|
||||
this.blocks.twoFields = twoFields;
|
||||
this.blocks.fieldAndInputs2 = fieldAndInputs2;
|
||||
this.blocks.noPrevConnection = noPrevConnection;
|
||||
|
||||
const dummyInput = this.workspace.newBlock('dummy_input');
|
||||
const dummyInputValue = this.workspace.newBlock('dummy_inputValue');
|
||||
const fieldWithOutput2 = this.workspace.newBlock('field_input');
|
||||
this.blocks.dummyInput = dummyInput;
|
||||
this.blocks.dummyInputValue = dummyInputValue;
|
||||
this.blocks.fieldWithOutput2 = fieldWithOutput2;
|
||||
|
||||
const secondBlock = this.workspace.newBlock('input_statement');
|
||||
const outputNextBlock = this.workspace.newBlock('output_next');
|
||||
this.blocks.secondBlock = secondBlock;
|
||||
this.blocks.outputNextBlock = outputNextBlock;
|
||||
});
|
||||
suite('Next', function () {
|
||||
setup(function () {
|
||||
this.singleBlockWorkspace = new Blockly.Workspace();
|
||||
const singleBlock = this.singleBlockWorkspace.newBlock('two_fields');
|
||||
this.blocks.singleBlock = singleBlock;
|
||||
});
|
||||
teardown(function () {
|
||||
workspaceTeardown.call(this, this.singleBlockWorkspace);
|
||||
});
|
||||
|
||||
test('fromPreviousToBlock', function () {
|
||||
const prevConnection = this.blocks.statementInput1.previousConnection;
|
||||
const nextNode = this.navigator.getNextSibling(prevConnection);
|
||||
assert.equal(nextNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromBlockToNext', function () {
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
const nextNode = this.navigator.getNextSibling(
|
||||
this.blocks.statementInput1,
|
||||
);
|
||||
assert.equal(nextNode, nextConnection);
|
||||
});
|
||||
test('fromNextToPrevious', function () {
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
const prevConnection = this.blocks.statementInput2.previousConnection;
|
||||
const nextNode = this.navigator.getNextSibling(nextConnection);
|
||||
assert.equal(nextNode, prevConnection);
|
||||
});
|
||||
test('fromInputToInput', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const inputConnection =
|
||||
this.blocks.statementInput1.inputList[1].connection;
|
||||
const nextNode = this.navigator.getNextSibling(input.connection);
|
||||
assert.equal(nextNode, inputConnection);
|
||||
});
|
||||
test('fromInputToStatementInput', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[1];
|
||||
const inputConnection =
|
||||
this.blocks.fieldAndInputs2.inputList[2].connection;
|
||||
const nextNode = this.navigator.getNextSibling(input.connection);
|
||||
assert.equal(nextNode, inputConnection);
|
||||
});
|
||||
test('fromInputToField', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[0];
|
||||
const field = this.blocks.fieldAndInputs2.inputList[1].fieldRow[0];
|
||||
const nextNode = this.navigator.getNextSibling(input.connection);
|
||||
assert.equal(nextNode, field);
|
||||
});
|
||||
test('fromInputToNull', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[2];
|
||||
const nextNode = this.navigator.getNextSibling(input.connection);
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
test('fromOutputToBlock', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const nextNode = this.navigator.getNextSibling(output);
|
||||
assert.equal(nextNode, this.blocks.fieldWithOutput);
|
||||
});
|
||||
test('fromFieldToInput', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[1];
|
||||
const inputConnection =
|
||||
this.blocks.statementInput1.inputList[0].connection;
|
||||
const nextNode = this.navigator.getNextSibling(field);
|
||||
assert.equal(nextNode, inputConnection);
|
||||
});
|
||||
test('fromFieldToField', function () {
|
||||
const field = this.blocks.fieldAndInputs.inputList[0].fieldRow[0];
|
||||
const field2 = this.blocks.fieldAndInputs.inputList[1].fieldRow[0];
|
||||
const nextNode = this.navigator.getNextSibling(field);
|
||||
assert.equal(nextNode, field2);
|
||||
});
|
||||
test('fromFieldToNull', function () {
|
||||
const field = this.blocks.twoFields.inputList[0].fieldRow[0];
|
||||
const nextNode = this.navigator.getNextSibling(field);
|
||||
assert.isNull(nextNode);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Previous', function () {
|
||||
test('fromPreviousToNext', function () {
|
||||
const prevConnection = this.blocks.statementInput2.previousConnection;
|
||||
const prevNode = this.navigator.getPreviousSibling(prevConnection);
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
assert.equal(prevNode, nextConnection);
|
||||
});
|
||||
test('fromPreviousToInput', function () {
|
||||
const prevConnection = this.blocks.statementInput3.previousConnection;
|
||||
const prevNode = this.navigator.getPreviousSibling(prevConnection);
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromBlockToPrevious', function () {
|
||||
const prevNode = this.navigator.getPreviousSibling(
|
||||
this.blocks.statementInput1,
|
||||
);
|
||||
const prevConnection = this.blocks.statementInput1.previousConnection;
|
||||
assert.equal(prevNode, prevConnection);
|
||||
});
|
||||
test('fromBlockToOutput', function () {
|
||||
const prevNode = this.navigator.getPreviousSibling(
|
||||
this.blocks.fieldWithOutput,
|
||||
);
|
||||
const outputConnection = this.blocks.fieldWithOutput.outputConnection;
|
||||
assert.equal(prevNode, outputConnection);
|
||||
});
|
||||
test('fromNextToBlock', function () {
|
||||
const nextConnection = this.blocks.statementInput1.nextConnection;
|
||||
const prevNode = this.navigator.getPreviousSibling(nextConnection);
|
||||
assert.equal(prevNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromInputToField', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const prevNode = this.navigator.getPreviousSibling(input.connection);
|
||||
assert.equal(prevNode, input.fieldRow[1]);
|
||||
});
|
||||
test('fromInputToNull', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[0];
|
||||
const prevNode = this.navigator.getPreviousSibling(input.connection);
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromInputToInput', function () {
|
||||
const input = this.blocks.fieldAndInputs2.inputList[2];
|
||||
const inputConnection =
|
||||
this.blocks.fieldAndInputs2.inputList[1].connection;
|
||||
const prevNode = this.navigator.getPreviousSibling(input.connection);
|
||||
assert.equal(prevNode, inputConnection);
|
||||
});
|
||||
test('fromOutputToNull', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const prevNode = this.navigator.getPreviousSibling(output);
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromFieldToNull', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const prevNode = this.navigator.getPreviousSibling(field);
|
||||
assert.isNull(prevNode);
|
||||
});
|
||||
test('fromFieldToInput', function () {
|
||||
const field = this.blocks.fieldAndInputs2.inputList[1].fieldRow[0];
|
||||
const inputConnection =
|
||||
this.blocks.fieldAndInputs2.inputList[0].connection;
|
||||
const prevNode = this.navigator.getPreviousSibling(field);
|
||||
assert.equal(prevNode, inputConnection);
|
||||
});
|
||||
test('fromFieldToField', function () {
|
||||
const field = this.blocks.fieldAndInputs.inputList[1].fieldRow[0];
|
||||
const field2 = this.blocks.fieldAndInputs.inputList[0].fieldRow[0];
|
||||
const prevNode = this.navigator.getPreviousSibling(field);
|
||||
assert.equal(prevNode, field2);
|
||||
});
|
||||
});
|
||||
|
||||
suite('In', function () {
|
||||
setup(function () {
|
||||
this.emptyWorkspace = Blockly.inject(document.createElement('div'), {});
|
||||
});
|
||||
teardown(function () {
|
||||
workspaceTeardown.call(this, this.emptyWorkspace);
|
||||
});
|
||||
|
||||
test('fromInputToOutput', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const inNode = this.navigator.getFirstChild(input.connection);
|
||||
const outputConnection = this.blocks.fieldWithOutput.outputConnection;
|
||||
assert.equal(inNode, outputConnection);
|
||||
});
|
||||
test('fromInputToNull', function () {
|
||||
const input = this.blocks.statementInput2.inputList[0];
|
||||
const inNode = this.navigator.getFirstChild(input.connection);
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromInputToPrevious', function () {
|
||||
const input = this.blocks.statementInput2.inputList[1];
|
||||
const previousConnection =
|
||||
this.blocks.statementInput3.previousConnection;
|
||||
const inNode = this.navigator.getFirstChild(input.connection);
|
||||
assert.equal(inNode, previousConnection);
|
||||
});
|
||||
test('fromBlockToInput', function () {
|
||||
const input = this.blocks.valueInput.inputList[0];
|
||||
const inNode = this.navigator.getFirstChild(this.blocks.valueInput);
|
||||
assert.equal(inNode, input.connection);
|
||||
});
|
||||
test('fromBlockToField', function () {
|
||||
const inNode = this.navigator.getFirstChild(
|
||||
this.blocks.statementInput1,
|
||||
);
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
assert.equal(inNode, field);
|
||||
});
|
||||
test('fromBlockToNull_DummyInput', function () {
|
||||
const inNode = this.navigator.getFirstChild(this.blocks.dummyInput);
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromBlockToInput_DummyInputValue', function () {
|
||||
const inputConnection =
|
||||
this.blocks.dummyInputValue.inputList[1].connection;
|
||||
const inNode = this.navigator.getFirstChild(
|
||||
this.blocks.dummyInputValue,
|
||||
);
|
||||
assert.equal(inNode, inputConnection);
|
||||
});
|
||||
test('fromOuputToNull', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const inNode = this.navigator.getFirstChild(output);
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromFieldToNull', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const inNode = this.navigator.getFirstChild(field);
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
test('fromWorkspaceToBlock', function () {
|
||||
const inNode = this.navigator.getFirstChild(this.workspace);
|
||||
assert.equal(inNode, this.workspace.getTopBlocks(true)[0]);
|
||||
});
|
||||
test('fromWorkspaceToNull', function () {
|
||||
const inNode = this.navigator.getFirstChild(this.emptyWorkspace);
|
||||
assert.isNull(inNode);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Out', function () {
|
||||
setup(function () {
|
||||
const secondBlock = this.blocks.secondBlock;
|
||||
const outputNextBlock = this.blocks.outputNextBlock;
|
||||
this.blocks.noPrevConnection.nextConnection.connect(
|
||||
secondBlock.previousConnection,
|
||||
);
|
||||
secondBlock.inputList[0].connection.connect(
|
||||
outputNextBlock.outputConnection,
|
||||
);
|
||||
});
|
||||
|
||||
test('fromInputToBlock', function () {
|
||||
const input = this.blocks.statementInput1.inputList[0];
|
||||
const outNode = this.navigator.getParent(input.connection);
|
||||
assert.equal(outNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromOutputToInput', function () {
|
||||
const output = this.blocks.fieldWithOutput.outputConnection;
|
||||
const outNode = this.navigator.getParent(output);
|
||||
assert.equal(
|
||||
outNode,
|
||||
this.blocks.statementInput1.inputList[0].connection,
|
||||
);
|
||||
});
|
||||
test('fromOutputToBlock', function () {
|
||||
const output = this.blocks.fieldWithOutput2.outputConnection;
|
||||
const outNode = this.navigator.getParent(output);
|
||||
assert.equal(outNode, this.blocks.fieldWithOutput2);
|
||||
});
|
||||
test('fromFieldToBlock', function () {
|
||||
const field = this.blocks.statementInput1.inputList[0].fieldRow[0];
|
||||
const outNode = this.navigator.getParent(field);
|
||||
assert.equal(outNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromPreviousToInput', function () {
|
||||
const previous = this.blocks.statementInput3.previousConnection;
|
||||
const inputConnection =
|
||||
this.blocks.statementInput2.inputList[1].connection;
|
||||
const outNode = this.navigator.getParent(previous);
|
||||
assert.equal(outNode, inputConnection);
|
||||
});
|
||||
test('fromPreviousToBlock', function () {
|
||||
const previous = this.blocks.statementInput2.previousConnection;
|
||||
const outNode = this.navigator.getParent(previous);
|
||||
assert.equal(outNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromNextToInput', function () {
|
||||
const next = this.blocks.statementInput3.nextConnection;
|
||||
const inputConnection =
|
||||
this.blocks.statementInput2.inputList[1].connection;
|
||||
const outNode = this.navigator.getParent(next);
|
||||
assert.equal(outNode, inputConnection);
|
||||
});
|
||||
test('fromNextToBlock', function () {
|
||||
const next = this.blocks.statementInput2.nextConnection;
|
||||
const outNode = this.navigator.getParent(next);
|
||||
assert.equal(outNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromNextToBlock_NoPreviousConnection', function () {
|
||||
const next = this.blocks.secondBlock.nextConnection;
|
||||
const outNode = this.navigator.getParent(next);
|
||||
assert.equal(outNode, this.blocks.noPrevConnection);
|
||||
});
|
||||
/**
|
||||
* This is where there is a block with both an output connection and a
|
||||
* next connection attached to an input.
|
||||
*/
|
||||
test('fromNextToInput_OutputAndPreviousConnection', function () {
|
||||
const next = this.blocks.outputNextBlock.nextConnection;
|
||||
const outNode = this.navigator.getParent(next);
|
||||
assert.equal(outNode, this.blocks.secondBlock.inputList[0].connection);
|
||||
});
|
||||
test('fromBlockToStack', function () {
|
||||
const outNode = this.navigator.getParent(this.blocks.statementInput2);
|
||||
assert.equal(outNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromBlockToInput', function () {
|
||||
const input = this.blocks.statementInput2.inputList[1].connection;
|
||||
const outNode = this.navigator.getParent(this.blocks.statementInput3);
|
||||
assert.equal(outNode, input);
|
||||
});
|
||||
test('fromTopBlockToStack', function () {
|
||||
const outNode = this.navigator.getParent(this.blocks.statementInput1);
|
||||
assert.equal(outNode, this.blocks.statementInput1);
|
||||
});
|
||||
test('fromBlockToStack_OutputConnection', function () {
|
||||
const outNode = this.navigator.getParent(this.blocks.fieldWithOutput2);
|
||||
assert.equal(outNode, this.blocks.fieldWithOutput2);
|
||||
});
|
||||
test('fromBlockToInput_OutputConnection', function () {
|
||||
const inputConnection = this.blocks.secondBlock.inputList[0].connection;
|
||||
const outNode = this.navigator.getParent(this.blocks.outputNextBlock);
|
||||
assert.equal(outNode, inputConnection);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -61,6 +61,10 @@ class FieldMitosis extends Field<CellGroup> {
|
||||
});
|
||||
this.value_ = {cells};
|
||||
}
|
||||
|
||||
getClass() {
|
||||
return FieldMitosis;
|
||||
}
|
||||
}
|
||||
|
||||
fieldRegistry.register('field_mitosis', FieldMitosis);
|
||||
|
||||
Reference in New Issue
Block a user