From 82dc9664bae25dcc8dc3b35511d9033be95825da Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 3 Nov 2022 12:58:33 -0700 Subject: [PATCH] test: add tests for the insertion marker manager (#6596) * test: make sure the insertion marker manager creates the correct number of markers * test: add more tests for insertion marker manager * chore: format * test: respond to pr feedback * test: make test names more descriptive * test: add row_to_stack test block --- tests/mocha/index.html | 1 + tests/mocha/insertion_marker_manager_test.js | 358 ++++++++++++++++++ tests/mocha/test_helpers/block_definitions.js | 9 + 3 files changed, 368 insertions(+) create mode 100644 tests/mocha/insertion_marker_manager_test.js diff --git a/tests/mocha/index.html b/tests/mocha/index.html index ae9d7efff..62e249e2d 100644 --- a/tests/mocha/index.html +++ b/tests/mocha/index.html @@ -83,6 +83,7 @@ 'Blockly.test.gesture', 'Blockly.test.input', 'Blockly.test.insertionMarker', + 'Blockly.test.insertionMarkerManager', 'Blockly.test.jsoDeserialization', 'Blockly.test.jsoSerialization', 'Blockly.test.json', diff --git a/tests/mocha/insertion_marker_manager_test.js b/tests/mocha/insertion_marker_manager_test.js new file mode 100644 index 000000000..211bf3518 --- /dev/null +++ b/tests/mocha/insertion_marker_manager_test.js @@ -0,0 +1,358 @@ +/** + * @license + * Copyright 2022 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +goog.declareModuleId('Blockly.test.insertionMarkerManager'); + +import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js'; +import {defineRowBlock, defineRowToStackBlock, defineStackBlock} from './test_helpers/block_definitions.js'; + +suite('Insertion marker manager', function() { + setup(function() { + sharedTestSetup.call(this); + defineRowBlock(); + defineStackBlock(); + defineRowToStackBlock(); + this.workspace = Blockly.inject('blocklyDiv'); + }); + teardown(function() { + sharedTestTeardown.call(this); + }); + + suite('Creating markers', function() { + function createBlocksAndManager(workspace, state) { + Blockly.serialization.workspaces.load(state, workspace); + const block = workspace.getBlockById('first'); + const manager = new Blockly.InsertionMarkerManager(block); + return manager; + } + + test('One stack block creates one marker', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'stack_block', + 'id': 'first', + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 1); + }); + + test('Two stack blocks create two markers', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'stack_block', + 'id': 'first', + 'next': { + 'block': { + 'type': 'stack_block', + 'id': 'second', + }, + }, + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 2); + }); + + test('Three stack blocks create two markers', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'stack_block', + 'id': 'first', + 'next': { + 'block': { + 'type': 'stack_block', + 'id': 'second', + 'next': { + 'block': { + 'type': 'stack_block', + 'id': 'third', + }, + }, + }, + }, + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 2); + }); + + test('One value block creates one marker', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'row_block', + 'id': 'first', + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 1); + }); + + test('Two value blocks create one marker', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'row_block', + 'id': 'first', + 'inputs': { + 'INPUT': { + 'block': { + 'type': 'row_block', + 'id': 'second', + }, + }, + }, + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 1); + }); + + test('One row to stack block creates one marker', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'row_to_stack_block', + 'id': 'first', + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 1); + }); + + test('Row to stack block with child creates two markers', function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'row_to_stack_block', + 'id': 'first', + 'next': { + 'block': { + 'type': 'stack_block', + 'id': 'second', + }, + }, + }, + ], + }, + }; + const manager = createBlocksAndManager(this.workspace, state); + const markers = manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 2); + }); + }); + + suite('Would delete block', function() { + setup(function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'stack_block', + 'id': 'first', + }, + ], + }, + }; + Blockly.serialization.workspaces.load(state, this.workspace); + this.block = this.workspace.getBlockById('first'); + this.manager = new Blockly.InsertionMarkerManager(this.block); + + const componentManager = this.workspace.getComponentManager(); + this.stub = sinon.stub(componentManager, 'hasCapability'); + this.dxy = new Blockly.utils.Coordinate(0, 0); + }); + + test('Over delete area and accepted would delete', function() { + this.stub + .withArgs( + 'fakeDragTarget', Blockly.ComponentManager.Capability.DELETE_AREA) + .returns(true); + const fakeDragTarget = { + wouldDelete: sinon.fake.returns(true), + id: 'fakeDragTarget', + }; + this.manager.update(this.dxy, fakeDragTarget); + chai.assert.isTrue(this.manager.wouldDeleteBlock()); + }); + + test('Over delete area and rejected would not delete', function() { + this.stub + .withArgs( + 'fakeDragTarget', Blockly.ComponentManager.Capability.DELETE_AREA) + .returns(true); + const fakeDragTarget = { + wouldDelete: sinon.fake.returns(false), + id: 'fakeDragTarget', + }; + this.manager.update(this.dxy, fakeDragTarget); + chai.assert.isFalse(this.manager.wouldDeleteBlock()); + }); + + test('Drag target is not a delete area would not delete', function() { + this.stub + .withArgs( + 'fakeDragTarget', Blockly.ComponentManager.Capability.DELETE_AREA) + .returns(false); + const fakeDragTarget = { + wouldDelete: sinon.fake.returns(false), + id: 'fakeDragTarget', + }; + this.manager.update(this.dxy, fakeDragTarget); + chai.assert.isFalse(this.manager.wouldDeleteBlock()); + }); + + test('Not over drag target would not delete', function() { + this.manager.update(this.dxy, null); + chai.assert.isFalse(this.manager.wouldDeleteBlock()); + }); + }); + + suite('Would connect stack blocks', function() { + setup(function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'stack_block', + 'id': 'first', + 'x': 0, + 'y': 0, + }, + { + 'type': 'stack_block', + 'id': 'other', + 'x': 200, + 'y': 200, + }, + ], + }, + }; + Blockly.serialization.workspaces.load(state, this.workspace); + this.block = this.workspace.getBlockById('first'); + this.block.setDragging(true); + this.manager = new Blockly.InsertionMarkerManager(this.block); + }); + + test('No other blocks nearby would not connect', function() { + this.manager.update(new Blockly.utils.Coordinate(0, 0), null); + chai.assert.isFalse(this.manager.wouldConnectBlock()); + }); + + test('Near other block and above would connect before', function() { + this.manager.update(new Blockly.utils.Coordinate(200, 190), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + const markers = this.manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 1); + const marker = markers[0]; + chai.assert.isTrue(marker.nextConnection.isConnected()); + }); + + test('Near other block and below would connect after', function() { + this.manager.update(new Blockly.utils.Coordinate(200, 210), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + const markers = this.manager.getInsertionMarkers(); + chai.assert.equal(markers.length, 1); + const marker = markers[0]; + chai.assert.isTrue(marker.previousConnection.isConnected()); + }); + + test('Near other block and left would connect', function() { + this.manager.update(new Blockly.utils.Coordinate(190, 200), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + }); + + test('Near other block and right would connect', function() { + this.manager.update(new Blockly.utils.Coordinate(210, 200), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + }); + }); + + suite('Would connect row blocks', function() { + setup(function() { + const state = { + 'blocks': { + 'blocks': [ + { + 'type': 'row_block', + 'id': 'first', + 'x': 0, + 'y': 0, + }, + { + 'type': 'row_block', + 'id': 'other', + 'x': 200, + 'y': 200, + }, + ], + }, + }; + Blockly.serialization.workspaces.load(state, this.workspace); + this.block = this.workspace.getBlockById('first'); + this.block.setDragging(true); + this.manager = new Blockly.InsertionMarkerManager(this.block); + }); + + test('No other blocks nearby would not connect', function() { + this.manager.update(new Blockly.utils.Coordinate(0, 0), null); + chai.assert.isFalse(this.manager.wouldConnectBlock()); + }); + + test('Near other block and above would connect', function() { + this.manager.update(new Blockly.utils.Coordinate(200, 190), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + }); + + test('Near other block and below would connect', function() { + this.manager.update(new Blockly.utils.Coordinate(200, 210), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + }); + + test('Near other block and left would connect before', function() { + this.manager.update(new Blockly.utils.Coordinate(190, 200), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + const markers = this.manager.getInsertionMarkers(); + chai.assert.isTrue(markers[0].getInput('INPUT').connection.isConnected()); + }); + + test('Near other block and right would connect after', function() { + this.manager.update(new Blockly.utils.Coordinate(210, 200), null); + chai.assert.isTrue(this.manager.wouldConnectBlock()); + const markers = this.manager.getInsertionMarkers(); + chai.assert.isTrue(markers[0].outputConnection.isConnected()); + }); + }); +}); diff --git a/tests/mocha/test_helpers/block_definitions.js b/tests/mocha/test_helpers/block_definitions.js index 7d05523c2..8fa937dd7 100644 --- a/tests/mocha/test_helpers/block_definitions.js +++ b/tests/mocha/test_helpers/block_definitions.js @@ -30,6 +30,15 @@ export function defineRowBlock(name = 'row_block') { }]); } +export function defineRowToStackBlock(name = 'row_to_stack_block') { + Blockly.defineBlocksWithJsonArray([{ + "type": name, + "message0": "", + "output": null, + "nextStatement": null, + }]); +} + export function defineStatementBlock(name = 'statement_block') { Blockly.defineBlocksWithJsonArray([{ "type": name,