mirror of
https://github.com/google/blockly.git
synced 2026-01-06 16:40:07 +01:00
* fix: shadows in insertion markers being displayed as shadows * chore: add unit tests * chore: remove only
443 lines
13 KiB
JavaScript
443 lines
13 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2022 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
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('children being set as insertion markers', function () {
|
|
setup(function () {
|
|
Blockly.Blocks['shadows_in_init'] = {
|
|
init: function () {
|
|
this.appendValueInput('test').connection.setShadowState({
|
|
'type': 'math_number',
|
|
});
|
|
this.setPreviousStatement(true);
|
|
},
|
|
};
|
|
|
|
Blockly.Blocks['shadows_in_load'] = {
|
|
init: function () {
|
|
this.appendValueInput('test');
|
|
this.setPreviousStatement(true);
|
|
},
|
|
|
|
loadExtraState: function () {
|
|
this.getInput('test').connection.setShadowState({
|
|
'type': 'math_number',
|
|
});
|
|
},
|
|
|
|
saveExtraState: function () {
|
|
return true;
|
|
},
|
|
};
|
|
});
|
|
|
|
teardown(function () {
|
|
delete Blockly.Blocks['shadows_in_init'];
|
|
delete Blockly.Blocks['shadows_in_load'];
|
|
});
|
|
|
|
test('Shadows added in init are set as insertion markers', function () {
|
|
const state = {
|
|
'blocks': {
|
|
'blocks': [
|
|
{
|
|
'id': 'first',
|
|
'type': 'shadows_in_init',
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const manager = createBlocksAndManager(this.workspace, state);
|
|
const markers = manager.getInsertionMarkers();
|
|
chai.assert.isTrue(
|
|
markers[0].getChildren()[0].isInsertionMarker(),
|
|
'Expected the shadow block to be an insertion maker',
|
|
);
|
|
});
|
|
|
|
test('Shadows added in `loadExtraState` are set as insertion markers', function () {
|
|
const state = {
|
|
'blocks': {
|
|
'blocks': [
|
|
{
|
|
'id': 'first',
|
|
'type': 'shadows_in_load',
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const manager = createBlocksAndManager(this.workspace, state);
|
|
const markers = manager.getInsertionMarkers();
|
|
chai.assert.isTrue(
|
|
markers[0].getChildren()[0].isInsertionMarker(),
|
|
'Expected the shadow block to be an insertion maker',
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
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());
|
|
});
|
|
});
|
|
});
|