Files
blockly/tests/mocha/flyout_test.js
alschmiedt 5b1586ee1b test: update mocha tests to use goog_module (#5440)
* Use goog.module in mocha tests

* Fix compiler warnings

* Make test helpers a module

* Name test modules Blockly.test.*

This is to be more consistent with how non-test modules are named.

Also remove top-level goog.require of TestHelpers (now
Blockly.test.helpers) since requiring a side-effect-less module does
nothing.

* Convert block_test.js and comment_test.js to goog.module syntax

* Address PR comments

* Goog modulify tests

* Goog modulify toolbox helpers

* Fixes imports and moves common tests from workspace_test.js to a helper file.

* Update test deps after rebase

Co-authored-by: Christopher Allen <cpcallen+git@google.com>
2021-09-16 13:00:38 -07:00

316 lines
13 KiB
JavaScript

/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.module('Blockly.test.flyout');
const {defineStackBlock, sharedTestSetup, sharedTestTeardown, workspaceTeardown} = goog.require('Blockly.test.helpers');
const {getBasicToolbox, getChildItem, getCollapsibleItem, getDeeplyNestedJSON, getInjectedToolbox, getNonCollapsibleItem, getSeparator, getSimpleJSON, getXmlArray} = goog.require('Blockly.test.toolboxHelpers');
suite('Flyout', function() {
setup(function() {
sharedTestSetup.call(this);
Blockly.defineBlocksWithJsonArray([{
"type": "basic_block",
"message0": "%1",
"args0": [
{
"type": "field_input",
"name": "TEXT",
"text": "default"
}
]
}]);
this.toolboxXml = document.getElementById('toolbox-simple');
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: this.toolboxXml
});
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('position', function() {
suite('vertical flyout', function() {
suite('simple flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
this.targetMetricsManager = this.flyout.targetWorkspace.getMetricsManager();
});
test('y is always 0', function() {
chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout should be 0');
});
test('x is right of workspace if flyout at right', function() {
sinon.stub(this.targetMetricsManager, 'getViewMetrics').returns({
width: 100,
});
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.RIGHT;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.RIGHT;
chai.assert.equal(this.flyout.getX(), 100, 'x should be right of workspace');
});
test('x is 0 if flyout at left', function() {
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.LEFT;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.LEFT;
chai.assert.equal(this.flyout.getX(), 0, 'x should be 0 if the flyout is on the left');
});
});
suite('toolbox flyout', function() {
setup(function() {
var toolbox = document.getElementById('toolbox-categories');
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: toolbox
});
this.flyout = this.workspace.getToolbox().getFlyout();
this.targetMetricsManager = this.flyout.targetWorkspace.getMetricsManager();
});
teardown(function() {
workspaceTeardown.call(this, this.workspace);
});
test('x is aligned with toolbox at left', function() {
sinon.stub(this.targetMetricsManager, 'getToolboxMetrics').returns({
width: 20,
});
this.flyout.setVisible(true);
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.LEFT;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.LEFT;
chai.assert.equal(this.flyout.getX(), 20, 'x should be aligned with toolbox');
});
test('x is aligned with toolbox at right', function() {
sinon.stub(this.targetMetricsManager, 'getToolboxMetrics').returns({
width: 20,
});
sinon.stub(this.targetMetricsManager, 'getViewMetrics').returns({
width: 100,
});
this.flyout.width_ = 10;
this.flyout.setVisible(true);
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.RIGHT;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.RIGHT;
chai.assert.equal(this.flyout.getX(), 90, 'x + width should be aligned with toolbox');
});
});
// These tests simulate a trashcan flyout, i.e. the flyout under test is on the
// opposite side of the workspace toolbox setting.
suite('trashcan flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
this.targetMetricsManager = this.flyout.targetWorkspace.getMetricsManager();
});
test('x is 0 if trashcan on left', function() {
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
viewWidth: 100,
});
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.RIGHT;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.LEFT;
chai.assert.equal(this.flyout.getX(), 0, 'x should be aligned with left edge');
});
test('trashcan on right covers right edge of workspace', function() {
this.flyout.width_ = 20;
sinon.stub(this.targetMetricsManager, 'getAbsoluteMetrics').returns({
left: 10,
});
sinon.stub(this.targetMetricsManager, 'getViewMetrics').returns({
width: 100,
});
this.flyout.setVisible(true);
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.LEFT;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.RIGHT;
chai.assert.equal(this.flyout.getX(), 90, 'x + width should be aligned with right edge');
});
});
});
suite('horizontal flyout', function() {
setup(function() {
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: this.toolboxXml,
horizontalLayout: true,
});
});
teardown(function() {
workspaceTeardown.call(this, this.workspace);
});
suite('simple flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
this.targetMetricsManager = this.flyout.targetWorkspace.getMetricsManager();
});
test('x is always 0', function() {
chai.assert.equal(this.flyout.getX(), 0, 'x coordinate in horizontal flyout should be 0');
});
test('y is 0 if flyout at top', function() {
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.TOP;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.TOP;
chai.assert.equal(this.flyout.getY(), 0, 'y should be 0 if flyout is at the top');
});
test('y is below workspace if flyout at bottom', function() {
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.BOTTOM;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.BOTTOM;
sinon.stub(this.targetMetricsManager, 'getViewMetrics').returns({
height: 50,
});
chai.assert.equal(this.flyout.getY(), 50, 'y should be below the workspace');
});
});
suite('toolbox flyout', function() {
setup(function() {
var toolbox = document.getElementById('toolbox-categories');
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: toolbox,
horizontalLayout: true,
});
this.flyout = this.workspace.getToolbox().getFlyout();
this.targetMetricsManager =
this.flyout.targetWorkspace.getMetricsManager();
});
teardown(function() {
workspaceTeardown.call(this, this.workspace);
});
test('y is aligned with toolbox at top', function() {
sinon.stub(this.targetMetricsManager, 'getToolboxMetrics').returns({
height: 20,
});
this.flyout.setVisible(true);
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.TOP;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.TOP;
chai.assert.equal(this.flyout.getY(), 20, 'y should be aligned with toolbox');
});
test('y is aligned with toolbox at bottom', function() {
sinon.stub(this.targetMetricsManager, 'getToolboxMetrics').returns({
height: 20,
});
sinon.stub(this.targetMetricsManager, 'getViewMetrics').returns({
height: 100,
});
this.flyout.height_ = 30;
this.flyout.setVisible(true);
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.BOTTOM;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.BOTTOM;
chai.assert.equal(this.flyout.getY(), 70, 'y + height should be aligned with toolbox');
});
});
// These tests simulate a trashcan flyout, i.e. the flyout under test is on the
// opposite side of the workspace toolbox setting.
suite('trashcan flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
this.targetMetricsManager =
this.flyout.targetWorkspace.getMetricsManager();
});
test('y is 0 if trashcan at top', function() {
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.BOTTOM;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.TOP;
chai.assert.equal(this.flyout.getY(), 0, 'y should be aligned with top');
});
test('trashcan on bottom covers bottom of workspace', function() {
this.flyout.targetWorkspace.toolboxPosition =
Blockly.utils.toolbox.Position.TOP;
this.flyout.toolboxPosition_ = Blockly.utils.toolbox.Position.BOTTOM;
sinon.stub(this.targetMetricsManager, 'getAbsoluteMetrics').returns({
top: 10,
});
sinon.stub(this.targetMetricsManager, 'getViewMetrics').returns({
height: 50,
});
this.flyout.setVisible(true);
this.flyout.height_ = 20;
chai.assert.equal(this.flyout.getY(), 40, 'y + height should be aligned with bottom');
});
});
});
});
suite('createFlyoutInfo_', function() {
setup(function() {
this.simpleToolboxJSON = getSimpleJSON();
this.flyout = this.workspace.getFlyout();
this.createFlyoutSpy = sinon.spy(this.flyout, 'createFlyoutInfo_');
});
function checkLayoutContents(actual, expected, opt_message) {
chai.assert.equal(actual.length, expected.length, opt_message);
for (var i = 0; i < actual.length; i++) {
chai.assert.equal(actual[i].type, expected[i].type, opt_message);
if (actual[i].type == 'BLOCK') {
chai.assert.typeOf(actual[i]['block'], 'Blockly.Block');
} else if (actual[i].type == 'BUTTON' || actual[i].type == 'LABEL') {
chai.assert.typeOf(actual[i]['block'], 'Blockly.FlyoutButton');
}
}
}
function checkFlyoutInfo(flyoutSpy) {
var expectedContents = [
{type: "block"},
{type: "button"},
{type: "button"}
];
var expectedGaps = [20, 24, 24];
var flyoutInfo = flyoutSpy.returnValues[0];
var contents = flyoutInfo.contents;
var gaps = flyoutInfo.gaps;
chai.assert.deepEqual(gaps, expectedGaps);
checkLayoutContents(contents, expectedContents, 'Contents');
}
test('Node', function() {
this.flyout.show(this.toolboxXml);
checkFlyoutInfo(this.createFlyoutSpy);
});
test('NodeList', function() {
var nodeList = document.getElementById('toolbox-simple').childNodes;
this.flyout.show(nodeList);
checkFlyoutInfo(this.createFlyoutSpy);
});
test('Array of JSON', function() {
this.flyout.show(this.simpleToolboxJSON);
checkFlyoutInfo(this.createFlyoutSpy);
});
test('Array of xml', function() {
this.flyout.show(getXmlArray());
checkFlyoutInfo(this.createFlyoutSpy);
});
test('Custom Toolbox: No Category Available', function() {
chai.assert.throws(function() {
this.flyout.show('someString');
}.bind(this), 'Couldn\'t find a callback function when opening' +
' a toolbox category.');
});
test('Custom Toolbox: Function does not return array', function() {
sinon.stub(this.flyout.workspace_.targetWorkspace,
'getToolboxCategoryCallback').returns(function(){return null;});
chai.assert.throws(function() {
this.flyout.show('someString');
}.bind(this), 'Result of toolbox category callback must be an array.');
});
test('Custom Toolbox: Returns Array', function() {
sinon.stub(this.flyout.workspace_.targetWorkspace,
'getToolboxCategoryCallback').returns(function(){return getXmlArray();});
chai.assert.doesNotThrow(function() {
this.flyout.show('someString');
}.bind(this));
});
});
});