/** * @license * Blockly Tests * * Copyright 2019 Google Inc. * https://developers.google.com/blockly/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ goog.require('Blockly.Blocks.procedures'); goog.require('Blockly.Msg'); suite('Procedures XML', function() { suite('Deserialization', function() { setup(function() { Blockly.setTheme(new Blockly.Theme({ "procedure_blocks": { "colourPrimary": "290" } })); this.workspace = new Blockly.Workspace(); this.callForAllTypes = function(func) { var typesArray = [ ['procedures_defnoreturn', 'procedures_callnoreturn'], ['procedures_defreturn', 'procedures_callreturn'] ]; for (var i = 0, types; types = typesArray[i]; i++) { var context = Object.create(null); context.workspace = this.workspace; context.defType = types[0]; context.callType = types[1]; func.call(context); this.workspace.clear(); } }; }); teardown(function() { this.workspace.dispose(); }); suite('Definition Blocks', function() { test('Minimal', function() { this.callForAllTypes(function() { var xml = Blockly.Xml.textToDom( '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); // TODO: Is this how you want this to work? or do you want it to // be 'unnamed'? chai.assert.equal(block.getFieldValue('NAME'), ''); chai.assert.isArray(block.arguments_); chai.assert.isEmpty(block.arguments_); chai.assert.isArray(block.argumentVarModels_); chai.assert.isEmpty(block.argumentVarModels_); chai.assert.isNotNull(block.getInput('STACK')); }); }); // This is like what's in the toolbox. test('Common', function() { this.callForAllTypes(function() { var xml = Blockly.Xml.textToDom( '' + ' do something' + '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.isArray(block.arguments_); chai.assert.isEmpty(block.arguments_); chai.assert.isArray(block.argumentVarModels_); chai.assert.isEmpty(block.argumentVarModels_); chai.assert.isNotNull(block.getInput('STACK')); }); }); test('Arg Vars Pre-Created', function() { this.callForAllTypes(function() { this.workspace.createVariable('x', '', 'arg'); var xml = Blockly.Xml.textToDom( '' + ' do something' + ' ' + ' ' + ' ' + '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.deepEqual(block.arguments_, ['x']); chai.assert.deepEqual(block.argumentVarModels_, [this.workspace.getVariableById('arg')]); chai.assert.isNotNull(block.getInput('STACK')); }); }); test('Arg Vars Not Created', function() { this.callForAllTypes(function() { var xml = Blockly.Xml.textToDom( '' + ' do something' + ' ' + ' ' + ' ' + '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.deepEqual(block.arguments_, ['x']); chai.assert.deepEqual(block.argumentVarModels_, [this.workspace.getVariableById('arg')]); chai.assert.isNotNull(block.getInput('STACK')); }); }); // TODO: I don't know a lot about typing vars, and even less out it in // this context. Is allowing typed vars to be args the correct behavior? test('Arg Vars Pre-Created Typed', function() { this.callForAllTypes(function() { this.workspace.createVariable('x', 'type', 'arg'); var xml = Blockly.Xml.textToDom( '' + ' do something' + ' ' + ' ' + ' ' + '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.deepEqual(block.arguments_, ['x']); chai.assert.deepEqual(block.argumentVarModels_, [this.workspace.getVariableById('arg')]); chai.assert.isNotNull(block.getInput('STACK')); }); }); test('Statements False', function() { var xml = Blockly.Xml.textToDom( '' + ' do something' + ' ' + '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.isArray(block.arguments_); chai.assert.isEmpty(block.arguments_); chai.assert.isArray(block.argumentVarModels_); chai.assert.isEmpty(block.argumentVarModels_); chai.assert.isNull(block.getInput('STACK')); }); test('Statements True', function() { var xml = Blockly.Xml.textToDom( '' + ' do something' + ' ' + '' ); var block = Blockly.Xml.domToBlock(xml, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.isArray(block.arguments_); chai.assert.isEmpty(block.arguments_); chai.assert.isArray(block.argumentVarModels_); chai.assert.isEmpty(block.argumentVarModels_); chai.assert.isNotNull(block.getInput('STACK')); }); }); suite('Call Blocks', function() { test('Caller W/ Def', function() { this.callForAllTypes(function() { Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' + ' do something' + '' ), this.workspace); var callerXML = Blockly.Xml.textToDom( '' + ' ' + '' ); var block = Blockly.Xml.domToBlock(callerXML, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.isArray(block.arguments_); chai.assert.isEmpty(block.arguments_); // TODO: argumentVarModels_ is undefined for call_return, but // defined for call_noreturn. Make it defined for both. /*chai.assert.isArray(block.argumentVarModels_); chai.assert.isEmpty(block.argumentVarModels_);*/ }); }); // TODO: I couldn't get this test (of creating a definition) to work // b/c of the events delay. test.skip('Caller No Def', function() { this.callForAllTypes(function() { var callerXML = Blockly.Xml.textToDom( '' + ' ' + '' ); var block = Blockly.Xml.domToBlock(callerXML, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.isArray(block.arguments_); chai.assert.isEmpty(block.arguments_); // TODO: argumentVarModels_ is undefined for call_return, but // defined for call_noreturn. Make it defined for both. /*chai.assert.isArray(block.argumentVarModels_); chai.assert.isEmpty(block.argumentVarModels_);*/ chai.assert.equal(this.workspace.getAllBlocks().count, 2); }); }); test('Caller W/ Params', function() { this.callForAllTypes(function() { Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' + ' do something' + ' ' + ' ' + ' ' + '' ), this.workspace); var callerXML = Blockly.Xml.textToDom( '' + ' ' + ' ' + ' ' + '' ); var block = Blockly.Xml.domToBlock(callerXML, this.workspace); chai.assert.equal( block.getFieldValue('NAME'), 'do something'); chai.assert.deepEqual(block.arguments_, ['x']); chai.assert.deepEqual(block.argumentVarModels_, [this.workspace.getVariableById('arg')]); }); }); // TODO: How do you want it to behave in this situation? test.skip('Caller W/out Params', function() { this.callForAllTypes(function() { Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' + ' do something' + ' ' + ' ' + ' ' + '' ), this.workspace); var callerXML = Blockly.Xml.textToDom( '' + ' ' + '' ); // TODO: Remove this when you fix this test. // eslint-disable-next-line no-unused-vars var block = Blockly.Xml.domToBlock(callerXML, this.workspace); }); }); // TODO: How do you want it to behave in this situation? test.skip('Caller W/ Bad Params', function() { this.callForAllTypes(function() { Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' + ' do something' + ' ' + ' ' + ' ' + '' ), this.workspace); var callerXML = Blockly.Xml.textToDom( '' + ' ' + ' ' + ' ' + '' ); // TODO: Remove this when you fix this test. // eslint-disable-next-line no-unused-vars var block = Blockly.Xml.domToBlock(callerXML, this.workspace); }); }); }); }); });