diff --git a/tests/blocks/index.html b/tests/blocks/index.html deleted file mode 100644 index 3187af9d2..000000000 --- a/tests/blocks/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - Unit Tests for Blockly Blocks - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/blocks/logic_ternary_test.js b/tests/blocks/logic_ternary_test.js deleted file mode 100644 index 81142c349..000000000 --- a/tests/blocks/logic_ternary_test.js +++ /dev/null @@ -1,302 +0,0 @@ -/** - * @license - * Copyright 2017 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -'use strict'; - -function test_logic_ternary_structure() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - assertEquals(3, block.inputList && block.inputList.length); - assertEquals(1, block.getInput('IF').connection.check_.length); - assertEquals('Boolean', block.getInput('IF').connection.check_[0]); - assertTrue(!!block.onchangeWrapper_); // Has onchange handler - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachSameTypeCheckInThenAndElseWithoutParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - - var string1 = workspace.newBlock('text'); - var string2 = workspace.newBlock('text_charAt'); - - block.getInput('THEN').connection.connect(string1.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string1.getRootBlock()); - block.getInput('ELSE').connection.connect(string2.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string1.getRootBlock()); // Still connected. - assertEquals(block, string2.getRootBlock()); - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachDifferectTypeChecksInThenAndElseWithoutParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - - var string = workspace.newBlock('text'); - var number = workspace.newBlock('math_number'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); - block.getInput('ELSE').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); // Input THEN still connected. - assertEquals(block, number.getRootBlock()); - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachSameTypeCheckInThenAndElseWithMatchingParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var parent = workspace.newBlock('text_trim'); - - parent.getInput('TEXT').connection.connect(block.outputConnection); - assertEquals(parent, block.getRootBlock()); - - var string1 = workspace.newBlock('text'); - var string2 = workspace.newBlock('text_charAt'); - - block.getInput('THEN').connection.connect(string1.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string1.getRootBlock()); - block.getInput('ELSE').connection.connect(string2.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string1.getRootBlock()); // Input THEN still connected. - assertEquals(parent, string2.getRootBlock()); - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachDifferectTypeChecksInThenAndElseWithUncheckedParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var parent = workspace.newBlock('text_print'); - - parent.getInput('TEXT').connection.connect(block.outputConnection); - assertEquals(parent, block.parentBlock_); - - var string = workspace.newBlock('text'); - var number = workspace.newBlock('math_number'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string.getRootBlock()); - block.getInput('ELSE').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string.getRootBlock()); // Input THEN still connected. - assertEquals(parent, number.getRootBlock()); - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachDifferectTypeChecksInThenAndElseWithPermissiveParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var parent = workspace.newBlock('text_length'); // Allows String or Array - - parent.getInput('VALUE').connection.connect(block.outputConnection); - assertEquals(parent, block.parentBlock_); - - var string = workspace.newBlock('text'); - var array = workspace.newBlock('lists_create_empty'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string.getRootBlock()); - block.getInput('ELSE').connection.connect(array.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string.getRootBlock()); // Input THEN still connected. - assertEquals(parent, array.getRootBlock()); - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachMismatchTypeToThen_breakWithParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var parent = workspace.newBlock('text_length'); // Allows String or Array - - parent.getInput('VALUE').connection.connect(block.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.parentBlock_); - - var string = workspace.newBlock('text'); - var number = workspace.newBlock('math_number'); - - block.getInput('ELSE').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string.getRootBlock()); - - // Adding mismatching number. - block.getInput('THEN').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, block.getRootBlock()); // Disconnected from parent. - assertEquals(block, number.getRootBlock()); - assertEquals(block, string.getRootBlock()); // ELSE string still connected. - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachMismatchTypeToElse_breakWithParent() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var parent = workspace.newBlock('text_length'); // Allows String or Array - - parent.getInput('VALUE').connection.connect(block.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.parentBlock_); - - var string = workspace.newBlock('text'); - var number = workspace.newBlock('math_number'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Still connected to parent. - assertEquals(parent, string.getRootBlock()); - - // Adding mismatching number. - block.getInput('ELSE').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, block.getRootBlock()); // Disconnected from parent. - assertEquals(block, number.getRootBlock()); - assertEquals(block, string.getRootBlock()); // THEN string still connected. - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachToUncheckedParentWithDifferentTypes() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var string = workspace.newBlock('text'); - var number = workspace.newBlock('math_number'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); - block.getInput('ELSE').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); // Input THEN still connected. - assertEquals(block, number.getRootBlock()); - - // Attaching to parent. - var parent = workspace.newBlock('text_print'); - parent.getInput('TEXT').connection.connect(block.outputConnection); - assertEquals(parent, block.getRootBlock()); - assertEquals(parent, string.getRootBlock()); // Input THEN still connected. - assertEquals(parent, number.getRootBlock()); // Input ELSE still connected. - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachToPermissiveParentWithDifferentTypes() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var string = workspace.newBlock('text'); - var array = workspace.newBlock('lists_create_empty'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); - block.getInput('ELSE').connection.connect(array.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); // Input THEN still connected. - assertEquals(block, array.getRootBlock()); - - // Attaching to parent. - var parent = workspace.newBlock('text_print'); - parent.getInput('TEXT').connection.connect(block.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); - assertEquals(parent, string.getRootBlock()); // Input THEN still connected. - assertEquals(parent, array.getRootBlock()); // Input ELSE still connected. - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachToParentWithMismatchingThen_disconnectThen() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var number = workspace.newBlock('math_number'); - var string = workspace.newBlock('text'); - - block.getInput('THEN').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, number.getRootBlock()); - block.getInput('ELSE').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, number.getRootBlock()); // Input THEN still connected. - assertEquals(block, string.getRootBlock()); - - // Attaching to parent. - var parent = workspace.newBlock('text_trim'); - parent.getInput('TEXT').connection.connect(block.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Successful connection to parent. - assertEquals(parent, string.getRootBlock()); // Input ELSE still connected. - assertEquals(number, number.getRootBlock()); // Input THEN disconnected. - } finally { - workspace.dispose(); - } -} - -function test_logic_ternary_attachToParentWithMismatchingElse_disconnectElse() { - var workspace = new Blockly.Workspace(); - try { - var block = workspace.newBlock('logic_ternary'); - var string = workspace.newBlock('text'); - var number = workspace.newBlock('math_number'); - - block.getInput('THEN').connection.connect(string.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); - block.getInput('ELSE').connection.connect(number.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(block, string.getRootBlock()); // Input THEN still connected. - assertEquals(block, number.getRootBlock()); - - // Attaching to parent. - var parent = workspace.newBlock('text_trim'); - parent.getInput('TEXT').connection.connect(block.outputConnection); - Blockly.Events.fireNow_(); // Force synchronous onchange() call. - assertEquals(parent, block.getRootBlock()); // Successful connection to parent. - assertEquals(parent, string.getRootBlock()); // Input THEN still connected. - assertEquals(number, number.getRootBlock()); // Input ELSE disconnected. - } finally { - workspace.dispose(); - } -} diff --git a/tests/mocha/index.html b/tests/mocha/index.html index ff94913bb..75869ca30 100644 --- a/tests/mocha/index.html +++ b/tests/mocha/index.html @@ -12,8 +12,11 @@ - + + + + @@ -58,6 +61,7 @@ + diff --git a/tests/mocha/logic_ternary_test.js b/tests/mocha/logic_ternary_test.js new file mode 100644 index 000000000..e94598e69 --- /dev/null +++ b/tests/mocha/logic_ternary_test.js @@ -0,0 +1,194 @@ +/** + * @license + * Copyright 2020 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +suite('Logic ternary', function() { + setup(function() { + this.workspace = new Blockly.Workspace(); + this.block = this.workspace.newBlock('logic_ternary'); + }); + + teardown(function() { + this.workspace.dispose(); + }); + + test('Structure', function() { + chai.assert.exists(this.block.inputList, 'Has inputList'); + chai.assert.equal(this.block.inputList.length, 3); + chai.assert.equal(this.block.getInput('IF').connection.check_.length, 1); + chai.assert.equal(this.block.getInput('IF').connection.check_[0], 'Boolean'); + chai.assert.exists(this.block.onchangeWrapper_, 'Has onchange handler'); + }); + + function connectParentAndCheckConnections( + block, parent, parentInputName, opt_thenInput, opt_elseInput) { + parent.getInput(parentInputName).connection.connect(block.outputConnection); + Blockly.Events.fireNow_(); // Force synchronous onchange() call. + chai.assert.equal(block.getParent(), parent, + 'Successful connection to parent'); + if (opt_thenInput) { + chai.assert.equal(opt_thenInput.getParent(), block, + 'Input THEN still connected after connecting parent'); + } + if (opt_elseInput) { + chai.assert.equal(opt_elseInput.getParent(), block, + 'Input ELSE still connected after connecting parent'); + } + } + function connectThenInputAndCheckConnections( + block, thenInput, opt_elseInput, opt_parent) { + block.getInput('THEN').connection.connect(thenInput.outputConnection); + Blockly.Events.fireNow_(); // Force synchronous onchange() call. + chai.assert.equal(thenInput.getParent(), block, 'THEN is connected'); + if (opt_parent) { + chai.assert.equal(block.getParent(), opt_parent, + 'Still connected to parent after connecting THEN'); + } + if (opt_elseInput) { + chai.assert.equal(opt_elseInput.getParent(), block, + 'Input ELSE still connected after connecting THEN'); + } + } + function connectElseInputAndCheckConnections( + block, elseInput, opt_thenInput, opt_parent) { + block.getInput('ELSE').connection.connect(elseInput.outputConnection); + Blockly.Events.fireNow_(); // Force synchronous onchange() call. + chai.assert.equal(elseInput.getParent(), block, 'ELSE is connected'); + if (opt_parent) { + chai.assert.equal(block.getParent(), opt_parent, + 'Still connected to parent after connecting ELSE'); + } + if (opt_thenInput) { + chai.assert.equal(opt_thenInput.getParent(), block, + 'Input THEN still connected after connecting ELSE'); + } + } + function connectInputsAndCheckConnections( + block, thenInput, elseInput, opt_parent) { + connectThenInputAndCheckConnections(block, thenInput, null, opt_parent); + connectElseInputAndCheckConnections(block, elseInput, thenInput, opt_parent); + } + suite('No parent', function() { + test('Attach inputs same type', function() { + var string1 = this.workspace.newBlock('text'); + var string2 = this.workspace.newBlock('text_charAt'); + + connectInputsAndCheckConnections(this.block, string1, string2); + }); + test('Attach inputs different types', function() { + var string = this.workspace.newBlock('text'); + var number = this.workspace.newBlock('math_number'); + + connectInputsAndCheckConnections(this.block, string, number); + }); + }); + suite('With parent already attached', function() { + test('Attach inputs same type with matching parent', function() { + var parent = this.workspace.newBlock('text_trim'); + + connectParentAndCheckConnections(this.block, parent, 'TEXT'); + + var string1 = this.workspace.newBlock('text'); + var string2 = this.workspace.newBlock('text_charAt'); + + connectInputsAndCheckConnections(this.block, string1, string2, parent); + }); + test('Attach inputs different types with unchecked parent', function() { + var parent = this.workspace.newBlock('text_print'); + + connectParentAndCheckConnections(this.block, parent, 'TEXT'); + + var string = this.workspace.newBlock('text'); + var number = this.workspace.newBlock('math_number'); + + connectInputsAndCheckConnections(this.block, string, number, parent); + }); + test('Attach inputs different types with permissive parent', function() { + var parent = this.workspace.newBlock('text_length'); // Allows String or Array + + connectParentAndCheckConnections(this.block, parent, 'VALUE'); + + var string = this.workspace.newBlock('text'); + var array = this.workspace.newBlock('lists_create_empty'); + + connectInputsAndCheckConnections(this.block, string, array, parent); + }); + test('Attach mismatch type to then causes break with parent', function() { + var parent = this.workspace.newBlock('text_length'); // Allows String or Array + + connectParentAndCheckConnections(this.block, parent, 'VALUE'); + + var string = this.workspace.newBlock('text'); + var number = this.workspace.newBlock('math_number'); + + connectElseInputAndCheckConnections(this.block, string, null, parent); + + // Adding mismatching number. + connectThenInputAndCheckConnections(this.block, number, string); + chai.assert.equal(this.block.getRootBlock(), this.block, + 'Disconnected from parent'); + }); + test('Attach mismatch type to else causes break with parent', function() { + var parent = this.workspace.newBlock('text_length'); // Allows String or Array + + connectParentAndCheckConnections(this.block, parent, 'VALUE'); + + var string = this.workspace.newBlock('text'); + var number = this.workspace.newBlock('math_number'); + + connectThenInputAndCheckConnections(this.block, string, null, parent); + + // Adding mismatching number. + connectElseInputAndCheckConnections(this.block, number, string); + chai.assert.equal(this.block.getRootBlock(), this.block, + 'Disconnected from parent'); + }); + }); + suite('Attaching parent after inputs', function() { + test('Unchecked parent with inputs different types', function() { + var string = this.workspace.newBlock('text'); + var number = this.workspace.newBlock('math_number'); + + connectInputsAndCheckConnections(this.block, string, number); + + var parent = this.workspace.newBlock('text_print'); + connectParentAndCheckConnections( + this.block, parent, 'TEXT', string, number); + }); + test('Permissive parent with inputs different types', function() { + var string = this.workspace.newBlock('text'); + var array = this.workspace.newBlock('lists_create_empty'); + + connectInputsAndCheckConnections(this.block, string, array); + + var parent = this.workspace.newBlock('text_print'); + connectParentAndCheckConnections( + this.block, parent, 'TEXT', string, array); + }); + test('Mismatch with then causes break with then', function() { + var number = this.workspace.newBlock('math_number'); + var string = this.workspace.newBlock('text'); + + connectInputsAndCheckConnections(this.block, number, string); + + var parent = this.workspace.newBlock('text_trim'); + connectParentAndCheckConnections( + this.block, parent, 'TEXT', null, string); + chai.assert.equal(number.getRootBlock(), number, + 'Input THEN disconnected'); + }); + test('Mismatch with else causes break with else', function() { + var string = this.workspace.newBlock('text'); + var number = this.workspace.newBlock('math_number'); + + connectInputsAndCheckConnections(this.block, string, number); + + var parent = this.workspace.newBlock('text_trim'); + connectParentAndCheckConnections(this.block, parent, 'TEXT', string); + chai.assert.equal(number.getRootBlock(), number, + 'Input ELSE disconnected'); + }); + }); +});