From 3b364976aac504abda9889cd18a1f4ef233700c0 Mon Sep 17 00:00:00 2001 From: Monica Kozbial Date: Mon, 28 Sep 2020 10:49:32 -0700 Subject: [PATCH] Procedures test workspace cleanup (#4311) * Add basic cleanup. * Refactor to ensure proper workspace cleanup * Remove unecessary variable cleanup * Uncomment out logic --- tests/mocha/procedures_test.js | 1075 +++++++++++++++----------------- 1 file changed, 509 insertions(+), 566 deletions(-) diff --git a/tests/mocha/procedures_test.js b/tests/mocha/procedures_test.js index 4616e252b..1d44be77d 100644 --- a/tests/mocha/procedures_test.js +++ b/tests/mocha/procedures_test.js @@ -11,31 +11,6 @@ suite('Procedures', function() { setup(function() { sharedTestSetup.call(this); this.workspace = new Blockly.Workspace(); - - this.callForAllTypes = function(func, startName) { - 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]; - - context.defBlock = new Blockly.Block(this.workspace, context.defType); - context.defBlock.setFieldValue(startName, 'NAME'); - context.callBlock = new Blockly.Block(this.workspace, context.callType); - context.callBlock.setFieldValue(startName, 'NAME'); - context.stub = sinon.stub( - context.defBlock.getField('NAME'), 'resizeEditor_'); - func.call(context); - context.defBlock.dispose(); - context.callBlock.dispose(); - context.stub.restore(); - } - }; }); teardown(function() { sharedTestTeardown.call(this); @@ -50,7 +25,7 @@ suite('Procedures', function() { var allProcedures = Blockly.Procedures.allProcedures(this.workspace); chai.assert.lengthOf(allProcedures, 2); - + chai.assert.lengthOf(allProcedures[0], 1); chai.assert.equal(allProcedures[0][0][0], 'no return'); @@ -68,7 +43,7 @@ suite('Procedures', function() { var allProcedures = Blockly.Procedures.allProcedures(this.workspace); chai.assert.lengthOf(allProcedures, 2); - + chai.assert.lengthOf(allProcedures[0], 1); chai.assert.equal(allProcedures[0][0][0], 'no return'); @@ -84,268 +59,22 @@ suite('Procedures', function() { chai.assert.lengthOf(allProcedures[1], 0, 'No procedures_defreturn blocks expected'); }); }); + suite('isNameUsed', function() { test('No Blocks', function() { chai.assert.isFalse( Blockly.Procedures.isNameUsed('name1', this.workspace) ); }); - test('True', function() { - this.callForAllTypes(function() { - chai.assert.isTrue( - Blockly.Procedures.isNameUsed('name1', this.workspace) - ); - }, 'name1'); - }); - test('False', function() { - this.callForAllTypes(function() { - chai.assert.isFalse( - Blockly.Procedures.isNameUsed('name2', this.workspace) - ); - }, 'name1'); - }); }); - suite('rename', function() { - test('Simple, Programmatic', function() { - this.callForAllTypes(function() { - this.defBlock.setFieldValue( - this.defBlock.getFieldValue('NAME') + '2', - 'NAME' - ); - chai.assert.equal(this.defBlock.getFieldValue('NAME'), 'start name2'); - chai.assert.equal(this.callBlock.getFieldValue('NAME'), 'start name2'); - }, 'start name'); - }); - test('Simple, Input', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'start name'; - defInput.htmlInput_.untypedDefaultValue_ = 'start name'; - defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + '2'; - defInput.onHtmlInputChange_(null); - chai.assert.equal(this.defBlock.getFieldValue('NAME'), 'start name2'); - chai.assert.equal(this.callBlock.getFieldValue('NAME'), 'start name2'); - }, 'start name'); - }); - test('lower -> CAPS', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'start name'; - defInput.htmlInput_.untypedDefaultValue_ = 'start name'; - - defInput.htmlInput_.value = 'START NAME'; - defInput.onHtmlInputChange_(null); - chai.assert.equal(this.defBlock.getFieldValue('NAME'), 'START NAME'); - chai.assert.equal(this.callBlock.getFieldValue('NAME'), 'START NAME'); - }, 'start name'); - }); - test('CAPS -> lower', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'START NAME'; - defInput.htmlInput_.untypedDefaultValue_ = 'START NAME'; - - defInput.htmlInput_.value = 'start name'; - defInput.onHtmlInputChange_(null); - chai.assert.equal(this.defBlock.getFieldValue('NAME'), 'start name'); - chai.assert.equal(this.callBlock.getFieldValue('NAME'), 'start name'); - }, 'START NAME'); - }); - test('Whitespace', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'start name'; - defInput.htmlInput_.untypedDefaultValue_ = 'start name'; - - defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + ' '; - defInput.onHtmlInputChange_(null); - chai.assert.equal(this.defBlock.getFieldValue('NAME'), 'start name'); - chai.assert.equal(this.callBlock.getFieldValue('NAME'), 'start name'); - }, 'start name'); - }); - test('Whitespace then Text', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'start name'; - defInput.htmlInput_.untypedDefaultValue_ = 'start name'; - - defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + ' '; - defInput.onHtmlInputChange_(null); - defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + '2'; - defInput.onHtmlInputChange_(null); - chai.assert.equal(this.defBlock.getFieldValue('NAME'), 'start name 2'); - chai.assert.equal(this.callBlock.getFieldValue('NAME'), 'start name 2'); - }, 'start name'); - }); - test('Set Empty', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'start name'; - defInput.htmlInput_.untypedDefaultValue_ = 'start name'; - - defInput.htmlInput_.value = ''; - defInput.onHtmlInputChange_(null); - chai.assert.equal( - this.defBlock.getFieldValue('NAME'), - Blockly.Msg['UNNAMED_KEY']); - chai.assert.equal( - this.callBlock.getFieldValue('NAME'), - Blockly.Msg['UNNAMED_KEY']); - }, 'start name'); - }); - test('Set Empty, and Create New', function() { - this.callForAllTypes(function() { - var defInput = this.defBlock.getField('NAME'); - defInput.htmlInput_ = Object.create(null); - defInput.htmlInput_.oldValue_ = 'start name'; - defInput.htmlInput_.untypedDefaultValue_ = 'start name'; - - defInput.htmlInput_.value = ''; - defInput.onHtmlInputChange_(null); - var newDefBlock = new Blockly.Block(this.workspace, this.defType); - newDefBlock.setFieldValue('new name', 'NAME'); - chai.assert.equal( - this.defBlock.getFieldValue('NAME'), - Blockly.Msg['UNNAMED_KEY']); - chai.assert.equal( - this.callBlock.getFieldValue('NAME'), - Blockly.Msg['UNNAMED_KEY']); - - newDefBlock.dispose(); - }, 'start name'); - }); - }); - suite('getCallers', function() { - test('Simple', function() { - this.callForAllTypes(function() { - var callers = Blockly.Procedures.getCallers('name1', this.workspace); - chai.assert.equal(callers.length, 1); - chai.assert.equal(callers[0], this.callBlock); - }, 'name1'); - }); - test('Multiple Callers', function() { - this.callForAllTypes(function() { - var caller2 = new Blockly.Block(this.workspace, this.callType); - caller2.setFieldValue('name1', 'NAME'); - var caller3 = new Blockly.Block(this.workspace, this.callType); - caller3.setFieldValue('name1', 'NAME'); - - var callers = Blockly.Procedures.getCallers('name1', this.workspace); - chai.assert.equal(callers.length, 3); - chai.assert.equal(callers[0], this.callBlock); - chai.assert.equal(callers[1], caller2); - chai.assert.equal(callers[2], caller3); - - caller2.dispose(); - caller3.dispose(); - }, 'name1'); - }); - test('Multiple Procedures', function() { - this.callForAllTypes(function() { - var def2 = new Blockly.Block(this.workspace, this.defType); - def2.setFieldValue('name2', 'NAME'); - var caller2 = new Blockly.Block(this.workspace, this.callType); - caller2.setFieldValue('name2', 'NAME'); - - var callers = Blockly.Procedures.getCallers('name1', this.workspace); - chai.assert.equal(callers.length, 1); - chai.assert.equal(callers[0], this.callBlock); - - def2.dispose(); - caller2.dispose(); - }, 'name1'); - }); - // This can occur if you: - // 1) Create an uppercase definition and call block. - // 2) Delete both blocks. - // 3) Create a lowercase definition and call block. - // 4) Retrieve the uppercase call block from the trashcan. - // (And vise versa for creating lowercase blocks first) - // When converted to code all function names will be lowercase, so a - // caller should still be returned for a differently-cased procedure. - test('Call Different Case', function() { - this.callForAllTypes(function() { - this.callBlock.setFieldValue('NAME1', 'NAME'); - var callers = Blockly.Procedures.getCallers('name1', this.workspace); - chai.assert.equal(callers.length, 1); - chai.assert.equal(callers[0], this.callBlock); - }, 'name'); - }); - test('Multiple Workspaces', function() { - this.callForAllTypes(function() { - var workspace = new Blockly.Workspace(); - var def2 = new Blockly.Block(workspace, this.defType); - def2.setFieldValue('name', 'NAME'); - var caller2 = new Blockly.Block(workspace, this.callType); - caller2.setFieldValue('name', 'NAME'); - - var callers = Blockly.Procedures.getCallers('name', this.workspace); - chai.assert.equal(callers.length, 1); - chai.assert.equal(callers[0], this.callBlock); - - callers = Blockly.Procedures.getCallers('name', workspace); - chai.assert.equal(callers.length, 1); - chai.assert.equal(callers[0], caller2); - - def2.dispose(); - caller2.dispose(); - }, 'name'); - }); - }); - suite('getDefinition', function() { - test('Simple', function() { - this.callForAllTypes(function() { - var def = Blockly.Procedures.getDefinition('name1', this.workspace); - chai.assert.equal(def, this.defBlock); - }, 'name1'); - }); - test('Multiple Procedures', function() { - this.callForAllTypes(function() { - var def2 = new Blockly.Block(this.workspace, this.defType); - def2.setFieldValue('name2', 'NAME'); - var caller2 = new Blockly.Block(this.workspace, this.callType); - caller2.setFieldValue('name2', 'NAME'); - - var def = Blockly.Procedures.getDefinition('name1', this.workspace); - chai.assert.equal(def, this.defBlock); - - def2.dispose(); - caller2.dispose(); - }, 'name1'); - }); - test('Multiple Workspaces', function() { - this.callForAllTypes(function() { - var workspace = new Blockly.Workspace(); - var def2 = new Blockly.Block(workspace, this.defType); - def2.setFieldValue('name', 'NAME'); - var caller2 = new Blockly.Block(workspace, this.callType); - caller2.setFieldValue('name', 'NAME'); - - var def = Blockly.Procedures.getDefinition('name', this.workspace); - chai.assert.equal(def, this.defBlock); - - def = Blockly.Procedures.getDefinition('name', workspace); - chai.assert.equal(def, def2); - - def2.dispose(); - caller2.dispose(); - }, 'name'); - }); - }); suite('Enable/Disable', function() { setup(function() { var toolbox = document.getElementById('toolbox-categories'); this.workspaceSvg = Blockly.inject('blocklyDiv', {toolbox: toolbox}); }); teardown(function() { - this.workspaceSvg.dispose(); + workspaceTeardown.call(this, this.workspaceSvg); sinon.restore(); }); suite('Inherited disabled', function() { @@ -353,36 +82,36 @@ suite('Procedures', function() { var dom = Blockly.Xml.textToDom( '' + '' + - 'bar' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + + 'bar' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + '' + '' + - 'foo' + + 'foo' + '' + '' + - 'baz' + - '' + - '' + - '' + - '' + - '' + + 'baz' + + '' + + '' + + '' + + '' + + '' + '' + '' + - '' + + '' + '' + '' + - '' + + '' + '' + - ''); + ''); Blockly.Events.disable(); Blockly.Xml.appendDomToWorkspace(dom, this.workspaceSvg); Blockly.Events.enable(); @@ -459,37 +188,287 @@ suite('Procedures', function() { 'Caller in return remains disabled, not by inheritance'); }); }); - var testCases = [ - ['procedures_defnoreturn', - ('' + - '' + - 'bar' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '')], - ['procedures_defreturn', - ('' + - '' + - 'bar' + - '' + - '' + + }); + + const testSuites = [ + {title: 'procedures_defreturn', hasReturn: true, + defType: 'procedures_defreturn', callType: 'procedures_callreturn'}, + {title: 'procedures_defnoreturn', hasReturn: false, + defType: 'procedures_defnoreturn', callType: 'procedures_callnoreturn'}, + ]; + + testSuites.forEach((testSuite) => { + suite(testSuite.title, function() { + setup(function() { + this.defType = testSuite.defType; + this.callType = testSuite.callType; + this.defBlock = new Blockly.Block(this.workspace, testSuite.defType); + this.defBlock.setFieldValue('proc name', 'NAME'); + this.callBlock = new Blockly.Block(this.workspace, testSuite.callType); + this.callBlock.setFieldValue('proc name', 'NAME'); + }); + suite('isNameUsed', function() { + test('True', function() { + chai.assert.isTrue( + Blockly.Procedures.isNameUsed('proc name', this.workspace)); + }); + test('False', function() { + chai.assert.isFalse( + Blockly.Procedures.isNameUsed('unused proc name', this.workspace)); + }); + }); + suite('rename', function() { + setup(function() { + sinon.stub(this.defBlock.getField('NAME'), 'resizeEditor_'); + }); + test('Simple, Programmatic', function() { + this.defBlock.setFieldValue( + this.defBlock.getFieldValue('NAME') + '2', + 'NAME' + ); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), 'proc name2'); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), 'proc name2'); + }); + test('Simple, Input', function() { + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'proc name'; + defInput.htmlInput_.untypedDefaultValue_ = 'proc name'; + + defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + '2'; + defInput.onHtmlInputChange_(null); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), 'proc name2'); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), 'proc name2'); + }); + test('lower -> CAPS', function() { + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'proc name'; + defInput.htmlInput_.untypedDefaultValue_ = 'proc name'; + + defInput.htmlInput_.value = 'PROC NAME'; + defInput.onHtmlInputChange_(null); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), 'PROC NAME'); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), 'PROC NAME'); + }); + test('CAPS -> lower', function() { + this.defBlock.setFieldValue('PROC NAME', 'NAME'); + this.callBlock.setFieldValue('PROC NAME', 'NAME'); + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'PROC NAME'; + defInput.htmlInput_.untypedDefaultValue_ = 'PROC NAME'; + + defInput.htmlInput_.value = 'proc name'; + defInput.onHtmlInputChange_(null); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), 'proc name'); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), 'proc name'); + }); + test('Whitespace', function() { + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'proc name'; + defInput.htmlInput_.untypedDefaultValue_ = 'proc name'; + + defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + ' '; + defInput.onHtmlInputChange_(null); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), 'proc name'); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), 'proc name'); + }); + test('Whitespace then Text', function() { + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'proc name'; + defInput.htmlInput_.untypedDefaultValue_ = 'proc name'; + + defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + ' '; + defInput.onHtmlInputChange_(null); + defInput.htmlInput_.value = defInput.htmlInput_.oldValue_ + '2'; + defInput.onHtmlInputChange_(null); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), 'proc name 2'); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), 'proc name 2'); + }); + test('Set Empty', function() { + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'proc name'; + defInput.htmlInput_.untypedDefaultValue_ = 'proc name'; + + defInput.htmlInput_.value = ''; + defInput.onHtmlInputChange_(null); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), + Blockly.Msg['UNNAMED_KEY']); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), + Blockly.Msg['UNNAMED_KEY']); + }); + test('Set Empty, and Create New', function() { + var defInput = this.defBlock.getField('NAME'); + defInput.htmlInput_ = Object.create(null); + defInput.htmlInput_.oldValue_ = 'proc name'; + defInput.htmlInput_.untypedDefaultValue_ = 'proc name'; + + defInput.htmlInput_.value = ''; + defInput.onHtmlInputChange_(null); + var newDefBlock = new Blockly.Block(this.workspace, this.defType); + newDefBlock.setFieldValue('new name', 'NAME'); + chai.assert.equal( + this.defBlock.getFieldValue('NAME'), + Blockly.Msg['UNNAMED_KEY']); + chai.assert.equal( + this.callBlock.getFieldValue('NAME'), + Blockly.Msg['UNNAMED_KEY']); + }); + }); + suite('getCallers', function() { + test('Simple', function() { + var callers = + Blockly.Procedures.getCallers('proc name', this.workspace); + chai.assert.equal(callers.length, 1); + chai.assert.equal(callers[0], this.callBlock); + }); + test('Multiple Callers', function() { + var caller2 = new Blockly.Block(this.workspace, this.callType); + caller2.setFieldValue('proc name', 'NAME'); + var caller3 = new Blockly.Block(this.workspace, this.callType); + caller3.setFieldValue('proc name', 'NAME'); + + var callers = + Blockly.Procedures.getCallers('proc name', this.workspace); + chai.assert.equal(callers.length, 3); + chai.assert.equal(callers[0], this.callBlock); + chai.assert.equal(callers[1], caller2); + chai.assert.equal(callers[2], caller3); + }); + test('Multiple Procedures', function() { + var def2 = new Blockly.Block(this.workspace, this.defType); + def2.setFieldValue('proc name2', 'NAME'); + var caller2 = new Blockly.Block(this.workspace, this.callType); + caller2.setFieldValue('proc name2', 'NAME'); + + var callers = + Blockly.Procedures.getCallers('proc name', this.workspace); + chai.assert.equal(callers.length, 1); + chai.assert.equal(callers[0], this.callBlock); + }); + // This can occur if you: + // 1) Create an uppercase definition and call block. + // 2) Delete both blocks. + // 3) Create a lowercase definition and call block. + // 4) Retrieve the uppercase call block from the trashcan. + // (And vise versa for creating lowercase blocks first) + // When converted to code all function names will be lowercase, so a + // caller should still be returned for a differently-cased procedure. + test('Call Different Case', function() { + this.callBlock.setFieldValue('PROC NAME', 'NAME'); + var callers = + Blockly.Procedures.getCallers('proc name', this.workspace); + chai.assert.equal(callers.length, 1); + chai.assert.equal(callers[0], this.callBlock); + }); + test('Multiple Workspaces', function() { + var workspace = new Blockly.Workspace(); + try { + var def2 = new Blockly.Block(workspace, this.defType); + def2.setFieldValue('proc name', 'NAME'); + var caller2 = new Blockly.Block(workspace, this.callType); + caller2.setFieldValue('proc name', 'NAME'); + + var callers = + Blockly.Procedures.getCallers('proc name', this.workspace); + chai.assert.equal(callers.length, 1); + chai.assert.equal(callers[0], this.callBlock); + + callers = Blockly.Procedures.getCallers('proc name', workspace); + chai.assert.equal(callers.length, 1); + chai.assert.equal(callers[0], caller2); + } finally { + workspaceTeardown.call(this, workspace); + } + }); + }); + suite('getDefinition', function() { + test('Simple', function() { + var def = + Blockly.Procedures.getDefinition('proc name', this.workspace); + chai.assert.equal(def, this.defBlock); + }); + test('Multiple Procedures', function() { + var def2 = new Blockly.Block(this.workspace, this.defType); + def2.setFieldValue('proc name2', 'NAME'); + var caller2 = new Blockly.Block(this.workspace, this.callType); + caller2.setFieldValue('proc name2', 'NAME'); + + var def = + Blockly.Procedures.getDefinition('proc name', this.workspace); + chai.assert.equal(def, this.defBlock); + }); + test('Multiple Workspaces', function() { + var workspace = new Blockly.Workspace(); + try { + var def2 = new Blockly.Block(workspace, this.defType); + def2.setFieldValue('proc name', 'NAME'); + var caller2 = new Blockly.Block(workspace, this.callType); + caller2.setFieldValue('proc name', 'NAME'); + + var def = + Blockly.Procedures.getDefinition('proc name', this.workspace); + chai.assert.equal(def, this.defBlock); + + def = Blockly.Procedures.getDefinition('proc name', workspace); + chai.assert.equal(def, def2); + } finally { + workspaceTeardown.call(this, workspace); + } + }); + }); + + suite('Enable/Disable', function() { + setup(function() { + var toolbox = document.getElementById('toolbox-categories'); + this.workspaceSvg = Blockly.inject('blocklyDiv', {toolbox: toolbox}); + }); + teardown(function() { + workspaceTeardown.call(this, this.workspaceSvg); + }); + const domText = (testSuite.defType === 'procedures_defreturn') ? + ('' + + '' + + 'bar' + + '' + + '' + '' + - '' + - '' + - '' + - '' + - '' + - '' + - '')]]; - testCases.forEach(function(testCase) { - var suiteName = testCase[0]; - var domText = testCase[1]; - suite(suiteName, function() { + '' + + '' + + '' + + '' + + '' + + '' + + '') : + ('' + + '' + + 'bar' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''); setup(function() { var dom = Blockly.Xml.textToDom(domText); @@ -574,251 +553,215 @@ suite('Procedures', function() { } }); }); - }); - }); - suite('Mutation', function() { - setup(function() { - this.findParentStub = sinon.stub(Blockly.Mutator, 'findParentWs') - .returns(this.workspace); - }); - teardown(function() { - this.findParentStub.restore(); - }); - suite('Composition', function() { - suite('Statements', function() { - function setStatementValue(mainWorkspace, defBlock, value) { - var mutatorWorkspace = new Blockly.Workspace( - new Blockly.Options({ - parentWorkspace: mainWorkspace - })); - defBlock.decompose(mutatorWorkspace); - var containerBlock = mutatorWorkspace.getTopBlocks()[0]; - var statementField = containerBlock.getField('STATEMENTS'); - statementField.setValue(value); - defBlock.compose(containerBlock); - } - test('Has Statements', function() { - var defBlock = new Blockly.Block(this.workspace, 'procedures_defreturn'); - setStatementValue(this.workspace, defBlock, true); - chai.assert.isTrue(defBlock.hasStatements_); + suite('Mutation', function() { + setup(function() { + this.findParentStub = sinon.stub(Blockly.Mutator, 'findParentWs') + .returns(this.workspace); }); - test('Has No Statements', function() { - var defBlock = new Blockly.Block(this.workspace, 'procedures_defreturn'); - setStatementValue(this.workspace, defBlock, false); - chai.assert.isFalse(defBlock.hasStatements_); + teardown(function() { + this.findParentStub.restore(); }); - test('Saving Statements', function() { - var blockXml = Blockly.Xml.textToDom( - '' + - ' ' + - ' ' + - ' ' + - '' - ); - var defBlock = Blockly.Xml.domToBlock(blockXml, this.workspace); - setStatementValue(this.workspace, defBlock, false); - chai.assert.isNull(defBlock.getInput('STACK')); - setStatementValue(this.workspace, defBlock, true); - chai.assert.isNotNull(defBlock.getInput('STACK')); - var statementBlocks = defBlock.getChildren(); - chai.assert.equal(statementBlocks.length, 1); - var block = statementBlocks[0]; - chai.assert.equal(block.type, 'procedures_ifreturn'); - chai.assert.equal(block.id, 'test'); - }); - }); - suite('Untyped Arguments', function() { - function createMutator(argArray) { - this.mutatorWorkspace = new Blockly.Workspace( - new Blockly.Options({ - parentWorkspace: this.workspace - })); - this.containerBlock = this.defBlock.decompose(this.mutatorWorkspace); - this.connection = this.containerBlock.getInput('STACK').connection; - for (var i = 0; i < argArray.length; i++) { - this.argBlock = new Blockly.Block( - this.mutatorWorkspace, 'procedures_mutatorarg'); - this.argBlock.setFieldValue(argArray[i], 'NAME'); - this.connection.connect(this.argBlock.previousConnection); - this.connection = this.argBlock.nextConnection; - } - this.defBlock.compose(this.containerBlock); - } - function assertArgs(argArray) { - chai.assert.equal(this.defBlock.arguments_.length, argArray.length); - for (var i = 0; i < argArray.length; i++) { - chai.assert.equal(this.defBlock.arguments_[i], argArray[i]); - } - chai.assert.equal(this.callBlock.arguments_.length, argArray.length); - for (var i = 0; i < argArray.length; i++) { - chai.assert.equal(this.callBlock.arguments_[i], argArray[i]); - } - } - function clearVariables() { - // TODO: Update this for typed vars. - var variables = this.workspace.getVariablesOfType(''); - var variableMap = this.workspace.getVariableMap(); - for (var i = 0, variable; (variable = variables[i]); i++) { - variableMap.deleteVariable(variable); - } - } - test('Simple Add Arg', function() { - this.callForAllTypes(function() { - var args = ['arg1']; - createMutator.call(this, args); - assertArgs.call(this, args); - clearVariables.call(this); - }, 'name'); - }); - test('Multiple Args', function() { - this.callForAllTypes(function() { - var args = ['arg1', 'arg2', 'arg3']; - createMutator.call(this, args); - assertArgs.call(this, args); - clearVariables.call(this); - }, 'name'); - }); - test('Simple Change Arg', function() { - this.callForAllTypes(function() { - createMutator.call(this, ['arg1']); - this.argBlock.setFieldValue('arg2', 'NAME'); - this.defBlock.compose(this.containerBlock); - assertArgs.call(this, ['arg2']); - clearVariables.call(this); - }, 'name'); - }); - test('lower -> CAPS', function() { - this.callForAllTypes(function() { - createMutator.call(this, ['arg']); - this.argBlock.setFieldValue('ARG', 'NAME'); - this.defBlock.compose(this.containerBlock); - assertArgs.call(this, ['ARG']); - clearVariables.call(this); - }, 'name'); - }); - test('CAPS -> lower', function() { - this.callForAllTypes(function() { - createMutator.call(this, ['ARG']); - this.argBlock.setFieldValue('arg', 'NAME'); - this.defBlock.compose(this.containerBlock); - assertArgs.call(this, ['arg']); - clearVariables.call(this); - }, 'name'); - }); - // Test case for #1958 - test('Set Arg Empty', function() { - this.callForAllTypes(function() { - var args = ['arg1']; - createMutator.call(this, args); - this.argBlock.setFieldValue('', 'NAME'); - this.defBlock.compose(this.containerBlock); - assertArgs.call(this, args); - clearVariables.call(this); - }, 'name'); - }); - test('Whitespace', function() { - this.callForAllTypes(function() { - var args = ['arg1']; - createMutator.call(this, args); - this.argBlock.setFieldValue(' ', 'NAME'); - this.defBlock.compose(this.containerBlock); - assertArgs.call(this, args); - clearVariables.call(this); - }, 'name'); - }); - test('Whitespace and Text', function() { - this.callForAllTypes(function() { - createMutator.call(this, ['arg1']); - this.argBlock.setFieldValue(' text ', 'NAME'); - this.defBlock.compose(this.containerBlock); - assertArgs.call(this, ['text']); - clearVariables.call(this); - }, 'name'); - }); - test('<>', function() { - this.callForAllTypes(function() { - var args = ['<>']; - createMutator.call(this, args); - assertArgs.call(this, args); - clearVariables.call(this); - }, 'name'); - }); - }); - }); - suite('Decomposition', function() { - suite('Statements', function() { - test('Has Statement Input', function() { - this.callForAllTypes(function() { - var mutatorWorkspace = new Blockly.Workspace( - new Blockly.Options({ - parentWorkspace: this.workspace - })); - this.defBlock.decompose(mutatorWorkspace); - var statementInput = mutatorWorkspace.getTopBlocks()[0] - .getInput('STATEMENT_INPUT'); - if (this.defType == 'procedures_defreturn') { - chai.assert.isNotNull(statementInput); - } else { - chai.assert.isNull(statementInput); + suite('Composition', function() { + suite('Statements', function() { + function setStatementValue(mainWorkspace, defBlock, value) { + var mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: mainWorkspace + })); + defBlock.decompose(mutatorWorkspace); + var containerBlock = mutatorWorkspace.getTopBlocks()[0]; + var statementField = containerBlock.getField('STATEMENTS'); + statementField.setValue(value); + defBlock.compose(containerBlock); } - }, 'name'); + if (testSuite.defType === 'procedures_defreturn') { + test('Has Statements', function() { + setStatementValue(this.workspace, this.defBlock, true); + chai.assert.isTrue(this.defBlock.hasStatements_); + }); + test('Has No Statements', function() { + setStatementValue(this.workspace, this.defBlock, false); + chai.assert.isFalse(this.defBlock.hasStatements_); + }); + test('Saving Statements', function() { + var blockXml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + '' + ); + var defBlock = Blockly.Xml.domToBlock(blockXml, this.workspace); + setStatementValue(this.workspace, defBlock, false); + chai.assert.isNull(defBlock.getInput('STACK')); + setStatementValue(this.workspace, defBlock, true); + chai.assert.isNotNull(defBlock.getInput('STACK')); + var statementBlocks = defBlock.getChildren(); + chai.assert.equal(statementBlocks.length, 1); + var block = statementBlocks[0]; + chai.assert.equal(block.type, 'procedures_ifreturn'); + chai.assert.equal(block.id, 'test'); + }); + } + }); + suite('Untyped Arguments', function() { + function createMutator(argArray) { + this.mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: this.workspace + })); + this.containerBlock = this.defBlock.decompose(this.mutatorWorkspace); + this.connection = this.containerBlock.getInput('STACK').connection; + for (var i = 0; i < argArray.length; i++) { + this.argBlock = new Blockly.Block( + this.mutatorWorkspace, 'procedures_mutatorarg'); + this.argBlock.setFieldValue(argArray[i], 'NAME'); + this.connection.connect(this.argBlock.previousConnection); + this.connection = this.argBlock.nextConnection; + } + this.defBlock.compose(this.containerBlock); + } + function assertArgs(argArray) { + chai.assert.equal(this.defBlock.arguments_.length, argArray.length); + for (var i = 0; i < argArray.length; i++) { + chai.assert.equal(this.defBlock.arguments_[i], argArray[i]); + } + chai.assert.equal(this.callBlock.arguments_.length, argArray.length); + for (var i = 0; i < argArray.length; i++) { + chai.assert.equal(this.callBlock.arguments_[i], argArray[i]); + } + } + test('Simple Add Arg', function() { + var args = ['arg1']; + createMutator.call(this, args); + assertArgs.call(this, args); + }); + test('Multiple Args', function() { + var args = ['arg1', 'arg2', 'arg3']; + createMutator.call(this, args); + assertArgs.call(this, args); + }); + test('Simple Change Arg', function() { + createMutator.call(this, ['arg1']); + this.argBlock.setFieldValue('arg2', 'NAME'); + this.defBlock.compose(this.containerBlock); + assertArgs.call(this, ['arg2']); + }); + test('lower -> CAPS', function() { + createMutator.call(this, ['arg']); + this.argBlock.setFieldValue('ARG', 'NAME'); + this.defBlock.compose(this.containerBlock); + assertArgs.call(this, ['ARG']); + }); + test('CAPS -> lower', function() { + createMutator.call(this, ['ARG']); + this.argBlock.setFieldValue('arg', 'NAME'); + this.defBlock.compose(this.containerBlock); + assertArgs.call(this, ['arg']); + }); + // Test case for #1958 + test('Set Arg Empty', function() { + var args = ['arg1']; + createMutator.call(this, args); + this.argBlock.setFieldValue('', 'NAME'); + this.defBlock.compose(this.containerBlock); + assertArgs.call(this, args); + }); + test('Whitespace', function() { + var args = ['arg1']; + createMutator.call(this, args); + this.argBlock.setFieldValue(' ', 'NAME'); + this.defBlock.compose(this.containerBlock); + assertArgs.call(this, args); + }); + test('Whitespace and Text', function() { + createMutator.call(this, ['arg1']); + this.argBlock.setFieldValue(' text ', 'NAME'); + this.defBlock.compose(this.containerBlock); + assertArgs.call(this, ['text']); + }); + test('<>', function() { + var args = ['<>']; + createMutator.call(this, args); + assertArgs.call(this, args); + }); + }); }); - test('Has Statements', function() { - var defBlock = new Blockly.Block(this.workspace, 'procedures_defreturn'); - defBlock.hasStatements_ = true; - var mutatorWorkspace = new Blockly.Workspace( - new Blockly.Options({ - parentWorkspace: this.workspace - })); - defBlock.decompose(mutatorWorkspace); - var statementValue = mutatorWorkspace.getTopBlocks()[0] - .getField('STATEMENTS').getValueBoolean(); - chai.assert.isTrue(statementValue); - }); - test('No Has Statements', function() { - var defBlock = new Blockly.Block(this.workspace, 'procedures_defreturn'); - defBlock.hasStatements_ = false; - var mutatorWorkspace = new Blockly.Workspace( - new Blockly.Options({ - parentWorkspace: this.workspace - })); - defBlock.decompose(mutatorWorkspace); - var statementValue = mutatorWorkspace.getTopBlocks()[0] - .getField('STATEMENTS').getValueBoolean(); - chai.assert.isFalse(statementValue); - }); - }); - suite('Untyped Arguments', function() { - function assertArguments(argumentsArray) { - this.defBlock.arguments_ = argumentsArray; - var mutatorWorkspace = new Blockly.Workspace( - new Blockly.Options({ - parentWorkspace: this.workspace - })); - this.defBlock.decompose(mutatorWorkspace); - var argBlocks = mutatorWorkspace.getBlocksByType('procedures_mutatorarg'); - chai.assert.equal(argBlocks.length, argumentsArray.length); + suite('Decomposition', function() { + suite('Statements', function() { + if (testSuite.defType === 'procedures_defreturn') { + test('Has Statement Input', function() { + var mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: this.workspace + })); + this.defBlock.decompose(mutatorWorkspace); + var statementInput = mutatorWorkspace.getTopBlocks()[0] + .getInput('STATEMENT_INPUT'); + chai.assert.isNotNull(statementInput); + }); + test('Has Statements', function() { + this.defBlock.hasStatements_ = true; + var mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: this.workspace + })); + this.defBlock.decompose(mutatorWorkspace); + var statementValue = mutatorWorkspace.getTopBlocks()[0] + .getField('STATEMENTS').getValueBoolean(); + chai.assert.isTrue(statementValue); + }); + test('No Has Statements', function() { + this.defBlock.hasStatements_ = false; + var mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: this.workspace + })); + this.defBlock.decompose(mutatorWorkspace); + var statementValue = mutatorWorkspace.getTopBlocks()[0] + .getField('STATEMENTS').getValueBoolean(); + chai.assert.isFalse(statementValue); + }); + } else { + test('Has no Statement Input', function() { + var mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: this.workspace + })); + this.defBlock.decompose(mutatorWorkspace); + var statementInput = mutatorWorkspace.getTopBlocks()[0] + .getInput('STATEMENT_INPUT'); + chai.assert.isNull(statementInput); + }); + } + }); + suite('Untyped Arguments', function() { + function assertArguments(argumentsArray) { + this.defBlock.arguments_ = argumentsArray; + var mutatorWorkspace = new Blockly.Workspace( + new Blockly.Options({ + parentWorkspace: this.workspace + })); + this.defBlock.decompose(mutatorWorkspace); + var argBlocks = mutatorWorkspace.getBlocksByType('procedures_mutatorarg'); + chai.assert.equal(argBlocks.length, argumentsArray.length); - for (var i = 0; i < argumentsArray.length; i++) { - var argString = argumentsArray[i]; - var argBlockValue = argBlocks[i].getFieldValue('NAME'); - chai.assert.equal(argBlockValue, argString); - } - } - test('Simple Single Arg', function() { - this.callForAllTypes(function() { - assertArguments.call(this, ['arg']); - }, 'name'); - }); - test('Multiple Args', function() { - this.callForAllTypes(function() { - assertArguments.call(this, ['arg1', 'arg2']); - }, 'name'); - }); - test('<>', function() { - this.callForAllTypes(function() { - assertArguments.call(this, ['<>']); - }, 'name'); + for (var i = 0; i < argumentsArray.length; i++) { + var argString = argumentsArray[i]; + var argBlockValue = argBlocks[i].getFieldValue('NAME'); + chai.assert.equal(argBlockValue, argString); + } + } + test('Simple Single Arg', function() { + assertArguments.call(this, ['arg']); + }); + test('Multiple Args', function() { + assertArguments.call(this, ['arg1', 'arg2']); + }); + test('<>', function() { + assertArguments.call(this, ['<>']); + }); + }); }); }); });