Files
blockly/tests/mocha/blocks/variables_test.js
Christopher Allen ce22f42868 chore: Organise imports (#8527)
* chore(deps): Add pretter-plugin-organize-imports

* chore: Remove insignificant blank lines in import sections

  Since prettier-plugin-organize-imports sorts imports within
  sections separated by blank lines, but preserves the section
  divisions, remove any blank lines that are not dividing imports
  into meaningful sections.

  Do not remove blank lines separating side-effect-only imports
  from main imports.

* chore: Remove unneded eslint-disable directives

* chore: Organise imports
2024-08-15 03:16:14 +01:00

312 lines
9.1 KiB
JavaScript

/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {nameUsedWithConflictingParam} from '../../../build/src/core/variables.js';
import {assert} from '../../../node_modules/chai/chai.js';
import {
MockParameterModelWithVar,
MockProcedureModel,
} from '../test_helpers/procedures.js';
import {
sharedTestSetup,
sharedTestTeardown,
} from '../test_helpers/setup_teardown.js';
suite('Variables', function () {
setup(function () {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
Blockly.defineBlocksWithJsonArray([
{
'type': 'get_var_block',
'message0': '%1',
'args0': [
{
'type': 'field_variable',
'name': 'VAR',
'variableTypes': ['', 'type1', 'type2'],
},
],
},
]);
this.workspace.createVariable('foo', 'type1', '1');
this.workspace.createVariable('bar', 'type1', '2');
this.workspace.createVariable('baz', 'type1', '3');
});
teardown(function () {
sharedTestTeardown.call(this);
});
/**
* Create a test get_var_block.
* Will fail if get_var_block isn't defined.
* @param {!Blockly.Workspace} workspace The workspace on which to create the
* block.
* @param {!string} variableId The id of the variable to reference.
* @return {!Blockly.Block} The created block.
*/
function createTestVarBlock(workspace, variableId) {
// Turn off events to avoid testing XML at the same time.
Blockly.Events.disable();
const block = new Blockly.Block(workspace, 'get_var_block');
block.inputList[0].fieldRow[0].setValue(variableId);
Blockly.Events.enable();
return block;
}
suite('allUsedVarModels', function () {
test('All used', function () {
createTestVarBlock(this.workspace, '1');
createTestVarBlock(this.workspace, '2');
createTestVarBlock(this.workspace, '3');
const result = Blockly.Variables.allUsedVarModels(this.workspace);
assert.equal(
result.length,
3,
'Expected three variables in the list of used variables',
);
});
test('Some unused', function () {
createTestVarBlock(this.workspace, '2');
const result = Blockly.Variables.allUsedVarModels(this.workspace);
assert.equal(
result.length,
1,
'Expected one variable in the list of used variables',
);
assert.equal(
result[0].getId(),
'2',
'Expected variable with ID 2 in the list of used variables',
);
});
test('Var used twice', function () {
createTestVarBlock(this.workspace, '2');
createTestVarBlock(this.workspace, '2');
const result = Blockly.Variables.allUsedVarModels(this.workspace);
// Using the same variable multiple times should not change the number of
// elements in the list.
assert.equal(
result.length,
1,
'Expected one variable in the list of used variables',
);
assert.equal(
result[0].getId(),
'2',
'Expected variable with ID 2 in the list of used variables',
);
});
test('All unused', function () {
const result = Blockly.Variables.allUsedVarModels(this.workspace);
assert.equal(
result.length,
0,
'Expected no variables in the list of used variables',
);
});
});
suite('getVariable', function () {
test('By ID', function () {
const var1 = this.workspace.createVariable('name1', 'type1', 'id1');
const var2 = this.workspace.createVariable('name2', 'type1', 'id2');
const var3 = this.workspace.createVariable('name3', 'type2', 'id3');
const result1 = Blockly.Variables.getVariable(this.workspace, 'id1');
const result2 = Blockly.Variables.getVariable(this.workspace, 'id2');
const result3 = Blockly.Variables.getVariable(this.workspace, 'id3');
assert.equal(var1, result1);
assert.equal(var2, result2);
assert.equal(var3, result3);
});
test('By name and type', function () {
const var1 = this.workspace.createVariable('name1', 'type1', 'id1');
const var2 = this.workspace.createVariable('name2', 'type1', 'id2');
const var3 = this.workspace.createVariable('name3', 'type2', 'id3');
const result1 = Blockly.Variables.getVariable(
this.workspace,
null,
'name1',
'type1',
);
const result2 = Blockly.Variables.getVariable(
this.workspace,
null,
'name2',
'type1',
);
const result3 = Blockly.Variables.getVariable(
this.workspace,
null,
'name3',
'type2',
);
// Searching by name + type is correct.
assert.equal(var1, result1);
assert.equal(var2, result2);
assert.equal(var3, result3);
});
test('Bad ID with name and type fallback', function () {
const var1 = this.workspace.createVariable('name1', 'type1', 'id1');
const var2 = this.workspace.createVariable('name2', 'type1', 'id2');
const var3 = this.workspace.createVariable('name3', 'type2', 'id3');
const result1 = Blockly.Variables.getVariable(
this.workspace,
'badId',
'name1',
'type1',
);
const result2 = Blockly.Variables.getVariable(
this.workspace,
'badId',
'name2',
'type1',
);
const result3 = Blockly.Variables.getVariable(
this.workspace,
'badId',
'name3',
'type2',
);
// Searching by ID failed, but falling back onto name + type is correct.
assert.equal(var1, result1);
assert.equal(var2, result2);
assert.equal(var3, result3);
});
});
suite('renaming variables creating conflicts', function () {
suite('renaming variables creating parameter conflicts', function () {
test('conflicts within legacy procedure blocks return the procedure name', function () {
Blockly.serialization.blocks.append(
{
'type': 'procedures_defnoreturn',
'extraState': {
'params': [
{
'name': 'x',
'id': '6l3P%Y!9EgA(Nh{E`Tl,',
},
{
'name': 'y',
'id': 'l1EtlJe%z_M[O-@uPAQ8',
},
],
},
'fields': {
'NAME': 'test name',
},
},
this.workspace,
);
assert.equal(
'test name',
nameUsedWithConflictingParam('x', 'y', this.workspace),
'Expected the name of the procedure with the conflicting ' +
'param to be returned',
);
});
test(
'if no legacy block has the old var name, no procedure ' +
'name is returned',
function () {
Blockly.serialization.blocks.append(
{
'type': 'procedures_defnoreturn',
'extraState': {
'params': [
{
'name': 'definitely not x',
'id': '6l3P%Y!9EgA(Nh{E`Tl,',
},
{
'name': 'y',
'id': 'l1EtlJe%z_M[O-@uPAQ8',
},
],
},
'fields': {
'NAME': 'test name',
},
},
this.workspace,
);
assert.isNull(
nameUsedWithConflictingParam('x', 'y', this.workspace),
'Expected there to be no conflict',
);
},
);
test('conflicts within procedure models return the procedure name', function () {
this.workspace
.getProcedureMap()
.add(
new MockProcedureModel('test name')
.insertParameter(
new MockParameterModelWithVar('x', this.workspace),
0,
)
.insertParameter(
new MockParameterModelWithVar('y', this.workspace),
0,
),
);
assert.equal(
'test name',
nameUsedWithConflictingParam('x', 'y', this.workspace),
'Expected the name of the procedure with the conflicting ' +
'param to be returned',
);
});
test(
'if no procedure model has the old var, no procedure ' +
'name is returned',
function () {
this.workspace
.getProcedureMap()
.add(
new MockProcedureModel('test name')
.insertParameter(
new MockParameterModelWithVar(
'definitely not x',
this.workspace,
),
0,
)
.insertParameter(
new MockParameterModelWithVar('y', this.workspace),
0,
),
);
assert.isNull(
nameUsedWithConflictingParam('x', 'y', this.workspace),
'Expected there to be no conflict',
);
},
);
});
});
});