From 8a2fe6411f65141978e2a8236ca8ed30976c456b Mon Sep 17 00:00:00 2001 From: Monica Kozbial Date: Tue, 14 Apr 2020 14:10:10 -0700 Subject: [PATCH] Converting xml tests to mocha. (#3818) * Converting xml tests to mocha. * Remove async * Updating no variable test. * Addressing PR comments. --- tests/jsunit/index.html | 1 - tests/jsunit/xml_test.js | 375 ------------------------- tests/mocha/xml_test.js | 583 +++++++++++++++++++++++++-------------- 3 files changed, 381 insertions(+), 578 deletions(-) delete mode 100644 tests/jsunit/xml_test.js diff --git a/tests/jsunit/index.html b/tests/jsunit/index.html index da931cf70..29a3e4d51 100644 --- a/tests/jsunit/index.html +++ b/tests/jsunit/index.html @@ -29,7 +29,6 @@ - diff --git a/tests/jsunit/xml_test.js b/tests/jsunit/xml_test.js deleted file mode 100644 index 117cd4ed6..000000000 --- a/tests/jsunit/xml_test.js +++ /dev/null @@ -1,375 +0,0 @@ -/** - * @license - * Copyright 2014 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ -'use strict'; - -var mockControl_; -var workspace; -var XML_TEXT = ['', - ' ', - ' ', - ' ', - ' 10', - ' ', - ' ', - ' ', - ' ', - ' item', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' Hello', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ' ', - ''].join('\n'); - -function xmlTest_setUp() { - workspace = new Blockly.Workspace(); -} - -function xmlTest_setUpWithMockBlocks() { - xmlTest_setUp(); - Blockly.defineBlocksWithJsonArray([{ - 'type': 'field_variable_test_block', - 'message0': '%1', - 'args0': [ - { - 'type': 'field_variable', - 'name': 'VAR', - 'variable': 'item' - } - ] - }]); -} - -function xmlTest_tearDown() { - if (mockControl_) { - mockControl_.restore(); - } - workspace.dispose(); -} - -function xmlTest_tearDownWithMockBlocks() { - xmlTest_tearDown(); - delete Blockly.Blocks.field_variable_test_block; -} - -/** - * Check the values of the non variable field DOM. - * @param {!Element} fieldDom The XML DOM of the non variable field. - * @param {!string} name The expected name of the variable. - * @param {!string} text The expected text of the variable. - */ -function xmlTest_checkNonVariableField(fieldDom, name, text) { - assertEquals('textContent', text, fieldDom.textContent); - assertEquals('name', name, fieldDom.getAttribute('name')); - assertNull('id', fieldDom.getAttribute('id')); - assertNull('variabletype', fieldDom.getAttribute('variabletype')); -} - -/** - * Check the values of the variable field DOM. - * @param {!Element} fieldDom The XML DOM of the variable field. - * @param {!string} name The expected name of the variable. - * @param {!string} type The expected type of the variable. - * @param {!string} id The expected ID of the variable. - * @param {!string} text The expected text of the variable. - */ -function xmlTest_checkVariableFieldDomValues(fieldDom, name, type, id, text) { - assertEquals('name', name, fieldDom.getAttribute('name')); - assertEquals('variabletype', type, fieldDom.getAttribute('variabletype')); - assertEquals('id', id, fieldDom.getAttribute('id')); - assertEquals('textContent', text, fieldDom.textContent); -} - -/** - * Check the values of the variable DOM. - * @param {!Element} variableDom The XML DOM of the variable. - * @param {!string} type The expected type of the variable. - * @param {!string} id The expected ID of the variable. - * @param {!string} text The expected text of the variable. - */ -function xmlTest_checkVariableDomValues(variableDom, type, id, text) { - assertEquals('type', type, variableDom.getAttribute('type')); - assertEquals('id', id, variableDom.getAttribute('id')); - assertEquals('textContent', text, variableDom.textContent); -} - -function test_textToDom() { - var dom = Blockly.Xml.textToDom(XML_TEXT); - assertEquals('XML tag', 'xml', dom.nodeName); - assertEquals('Block tags', 6, dom.getElementsByTagName('block').length); -} - -function test_domToText() { - var dom = Blockly.Xml.textToDom(XML_TEXT); - var text = Blockly.Xml.domToText(dom); - assertEquals('Round trip', XML_TEXT.replace(/\s+/g, ''), - text.replace(/\s+/g, '')); -} - -function test_domToWorkspace_BackwardCompatibility() { - // Expect that workspace still loads without serialized variables. - xmlTest_setUpWithMockBlocks(); - mockControl_ = setUpMockMethod(Blockly.utils, 'genUid', null, ['1', '1']); - try { - var dom = Blockly.Xml.textToDom( - '' + - ' ' + - ' name1' + - ' ' + - ''); - Blockly.Xml.domToWorkspace(dom, workspace); - assertEquals('Block count', 1, workspace.getAllBlocks(false).length); - checkVariableValues(workspace, 'name1', '', '1'); - } finally { - xmlTest_tearDownWithMockBlocks(); - } -} - -function test_domToWorkspace_VariablesAtTop() { - // Expect that unused variables are preserved. - xmlTest_setUpWithMockBlocks(); - try { - var dom = Blockly.Xml.textToDom( - '' + - ' ' + - ' name1' + - ' name2' + - ' name3' + - ' ' + - ' ' + - ' name3' + - ' ' + - ''); - Blockly.Xml.domToWorkspace(dom, workspace); - assertEquals('Block count', 1, workspace.getAllBlocks(false).length); - checkVariableValues(workspace, 'name1', 'type1', 'id1'); - checkVariableValues(workspace, 'name2', 'type2', 'id2'); - checkVariableValues(workspace, 'name3', '', 'id3'); - } finally { - xmlTest_tearDownWithMockBlocks(); - } -} - -function test_domToWorkspace_VariablesAtTop_DuplicateVariablesTag() { - // Expect thrown Error because of duplicate 'variables' tag. - xmlTest_setUpWithMockBlocks(); - try { - var dom = Blockly.Xml.textToDom( - '' + - ' ' + - ' ' + - ' ' + - ' ' + - ''); - Blockly.Xml.domToWorkspace(dom, workspace); - fail(); - } - catch (e) { - // expected - } finally { - xmlTest_tearDownWithMockBlocks(); - } -} - -function test_domToWorkspace_VariablesAtTop_MissingType() { - // Expect thrown error when a variable tag is missing the type attribute. - workspace = new Blockly.Workspace(); - try { - var dom = Blockly.Xml.textToDom( - '' + - ' ' + - ' name1' + - ' ' + - ' ' + - ' name3' + - ' ' + - ''); - Blockly.Xml.domToWorkspace(dom, workspace); - fail(); - } catch (e) { - // expected - } finally { - workspace.dispose(); - } -} - -function test_domToWorkspace_VariablesAtTop_MismatchBlockType() { - // Expect thrown error when the serialized type of a variable does not match - // the type of a variable field that references it. - xmlTest_setUpWithMockBlocks(); - try { - var dom = Blockly.Xml.textToDom( - '' + - ' ' + - ' name1' + - ' ' + - ' ' + - ' name1' + - ' ' + - ''); - Blockly.Xml.domToWorkspace(dom, workspace); - fail(); - } catch (e) { - // expected - } finally { - xmlTest_tearDownWithMockBlocks(); - } -} - -function test_domToPrettyText() { - var dom = Blockly.Xml.textToDom(XML_TEXT); - var text = Blockly.Xml.domToPrettyText(dom); - assertEquals('Round trip', XML_TEXT.replace(/\s+/g, ''), - text.replace(/\s+/g, '')); -} - -/** - * Tests the that appendDomToWorkspace works in a headless mode. - * Also see test_appendDomToWorkspace() in workspace_svg_test.js. - */ -function test_appendDomToWorkspace() { - Blockly.Blocks.test_block = { - init: function() { - this.jsonInit({ - message0: 'test', - }); - } - }; - - try { - var dom = Blockly.Xml.textToDom( - '' + - ' ' + - ' ' + - ''); - workspace = new Blockly.Workspace(); - Blockly.Xml.appendDomToWorkspace(dom, workspace); - assertEquals('Block count', 1, workspace.getAllBlocks(false).length); - var newBlockIds = Blockly.Xml.appendDomToWorkspace(dom, workspace); - assertEquals('Block count', 2, workspace.getAllBlocks(false).length); - assertEquals('Number of new block ids',1,newBlockIds.length); - } finally { - delete Blockly.Blocks.test_block; - workspace.dispose(); - } -} - -function test_blockToDom_fieldToDom_defaultCase() { - xmlTest_setUpWithMockBlocks(); - mockControl_ = setUpMockMethod(Blockly.utils, 'genUid', null, ['1', '1']); - try { - workspace.createVariable('name1'); - - Blockly.Events.disable(); - var block = new Blockly.Block(workspace, 'field_variable_test_block'); - block.inputList[0].fieldRow[0].setValue('1'); - Blockly.Events.enable(); - - var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - // Expect type is null and ID is '1' since we don't specify type and ID. - xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', null, '1', - 'name1'); - } finally { - xmlTest_tearDownWithMockBlocks(); - } -} - -function test_blockToDom_fieldToDom_notAFieldVariable() { - Blockly.defineBlocksWithJsonArray([{ - "type": "field_angle_test_block", - "message0": "%1", - "args0": [ - { - "type": "field_angle", - "name": "VAR", - "angle": 90 - } - ], - }]); - xmlTest_setUpWithMockBlocks(); - var block = new Blockly.Block(workspace, 'field_angle_test_block'); - var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - xmlTest_checkNonVariableField(resultFieldDom, 'VAR', '90'); - delete Blockly.Blocks.field_angle_block; - xmlTest_tearDownWithMockBlocks(); -} - -function test_variablesToDom_oneVariable() { - xmlTest_setUp(); - mockControl_ = setUpMockMethod(Blockly.utils, 'genUid', null, ['1']); - - workspace.createVariable('name1'); - var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables()); - assertEquals(1, resultDom.children.length); - var resultVariableDom = resultDom.children[0]; - assertEquals('name1', resultVariableDom.textContent); - assertEquals(null, resultVariableDom.getAttribute('type')); - assertEquals('1', resultVariableDom.getAttribute('id')); - xmlTest_tearDown(); -} - -function test_variablesToDom_twoVariables_oneBlock() { - xmlTest_setUpWithMockBlocks(); - - workspace.createVariable('name1', '', 'id1'); - workspace.createVariable('name2', 'type2', 'id2'); - // If events are enabled during block construction, it will create a default - // variable. - Blockly.Events.disable(); - var block = new Blockly.Block(workspace, 'field_variable_test_block'); - block.inputList[0].fieldRow[0].setValue('id1'); - Blockly.Events.enable(); - - var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables()); - assertEquals(2, resultDom.children.length); - xmlTest_checkVariableDomValues(resultDom.children[0], null, 'id1', - 'name1'); - xmlTest_checkVariableDomValues(resultDom.children[1], 'type2', 'id2', - 'name2'); - xmlTest_tearDownWithMockBlocks(); -} - -function test_variablesToDom_noVariables() { - xmlTest_setUp(); - workspace.createVariable('name1'); - var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables()); - assertEquals(1, resultDom.children.length); - xmlTest_tearDown(); -} - -function test_variableFieldXml_caseSensitive() { - var id = 'testId'; - var type = 'testType'; - var name = 'testName'; - - var mockVariableModel = { - type: type, - name: name, - getId: function() { - return id; - } - }; - - var generatedXml = Blockly.Xml.domToText( - Blockly.Variables.generateVariableFieldDom(mockVariableModel)); - var goldenXml = - '' + name + ''; - assertEquals(goldenXml, generatedXml); -} diff --git a/tests/mocha/xml_test.js b/tests/mocha/xml_test.js index 51b39e684..05635de73 100644 --- a/tests/mocha/xml_test.js +++ b/tests/mocha/xml_test.js @@ -5,19 +5,35 @@ */ suite('XML', function() { - var assertSimpleField = function(fieldDom, name, text) { + var assertSimpleFieldDom = function(fieldDom, name, text) { assertEquals(text, fieldDom.textContent); assertEquals(name, fieldDom.getAttribute('name')); }; - var assertNonSerializingField = function(fieldDom) { + var assertNonSerializingFieldDom = function(fieldDom) { assertEquals(undefined, fieldDom.childNodes[0]); }; - var assertVariableField = function(fieldDom, name, type, id, text) { - assertEquals(name, fieldDom.getAttribute('name')); + var assertNonVariableField = function(fieldDom, name, text) { + assertSimpleFieldDom(fieldDom, name, text); + assertNull('id', fieldDom.getAttribute('id')); + assertNull('variabletype', fieldDom.getAttribute('variabletype')); + }; + var assertVariableDomField = function(fieldDom, name, type, id, text) { + assertSimpleFieldDom(fieldDom, name, text); assertEquals(type, fieldDom.getAttribute('variabletype')); assertEquals(id, fieldDom.getAttribute('id')); + }; + var assertVariableDom = function(fieldDom, type, id, text) { + assertEquals(type, fieldDom.getAttribute('type')); + assertEquals(id, fieldDom.getAttribute('id')); assertEquals(text, fieldDom.textContent); }; + var assertVariableValues = function(container, name, type, id) { + var variable = container.getVariableById(id); + assertNotUndefined(variable); + assertEquals(name, variable.name); + assertEquals(type, variable.type); + assertEquals(id, variable.getId()); + }; setup(function() { Blockly.defineBlocksWithJsonArray([ { @@ -26,11 +42,50 @@ suite('XML', function() { "args0": [] }, ]); + this.blockTypes_ = ['empty_block']; + this.complexXmlText = [ + '', + ' ', + ' ', + ' ', + ' 10', + ' ', + ' ', + ' ', + ' ', + ' item', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' Hello', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ''].join('\n'); }); teardown(function() { - delete Blockly.Blocks['empty_block']; + for (var i = 0; i < this.blockTypes_.length; i++) { + delete Blockly.Blocks[this.blockTypes_[i]]; + } + this.blockTypes_.length = 0; + sinon.restore(); }); - suite('Serialization', function() { + suite('textToDom', function() { + test('Basic', function() { + var dom = Blockly.Xml.textToDom(this.complexXmlText); + assertEquals('XML tag', 'xml', dom.nodeName); + assertEquals('Block tags', 6, dom.getElementsByTagName('block').length); + }); + }); + suite('blockToDom', function() { setup(function() { this.workspace = new Blockly.Workspace(); }); @@ -50,11 +105,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_angle_test_block'); var block = new Blockly.Block(this.workspace, 'field_angle_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'ANGLE', '90'); - delete Blockly.Blocks['field_angle_test_block']; + assertNonVariableField(resultFieldDom, 'ANGLE', '90'); }); test('Checkbox', function() { Blockly.defineBlocksWithJsonArray([{ @@ -68,11 +123,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_checkbox_test_block'); var block = new Blockly.Block(this.workspace, 'field_checkbox_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'CHECKBOX', 'TRUE'); - delete Blockly.Blocks['field_checkbox_test_block']; + assertNonVariableField(resultFieldDom, 'CHECKBOX', 'TRUE'); }); test('Colour', function() { Blockly.defineBlocksWithJsonArray([{ @@ -86,11 +141,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_colour_test_block'); var block = new Blockly.Block(this.workspace, 'field_colour_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'COLOUR', '#000099'); - delete Blockly.Blocks['field_colour_test_block']; + assertNonVariableField(resultFieldDom, 'COLOUR', '#000099'); }); /* If you want to run date tests add the date picker here: * https://github.com/google/blockly/blob/master/core/blockly.js#L41 @@ -108,11 +163,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_date_test_block'); var block = new Blockly.Block(this.workspace, 'field_date_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'DATE', '2020-02-20'); - delete Blockly.Blocks['field_date_test_block']; + assertNonVariableField(resultFieldDom, 'DATE', '2020-02-20'); }); test('Dropdown', function() { Blockly.defineBlocksWithJsonArray([{ @@ -139,11 +194,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_dropdown_test_block'); var block = new Blockly.Block(this.workspace, 'field_dropdown_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'DROPDOWN', 'A'); - delete Blockly.Blocks['field_dropdown_test_block']; + assertNonVariableField(resultFieldDom, 'DROPDOWN', 'A'); }); test('Image', function() { Blockly.defineBlocksWithJsonArray([{ @@ -160,11 +215,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_image_test_block'); var block = new Blockly.Block(this.workspace, 'field_image_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block); - assertNonSerializingField(resultFieldDom); - delete Blockly.Blocks['field_image_test_block']; + assertNonSerializingFieldDom(resultFieldDom); }); test('Label', function() { Blockly.defineBlocksWithJsonArray([{ @@ -178,11 +233,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_label_test_block'); var block = new Blockly.Block(this.workspace, 'field_label_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block); - assertNonSerializingField(resultFieldDom); - delete Blockly.Blocks['field_label_test_block']; + assertNonSerializingFieldDom(resultFieldDom); }); test('Label Serializable', function() { Blockly.defineBlocksWithJsonArray([{ @@ -196,11 +251,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_label_serializable_test_block'); var block = new Blockly.Block(this.workspace, 'field_label_serializable_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'LABEL', 'default'); - delete Blockly.Blocks['field_label_serializable_test_block']; + assertNonVariableField(resultFieldDom, 'LABEL', 'default'); }); test('Number', function() { Blockly.defineBlocksWithJsonArray([{ @@ -214,11 +269,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_number_test_block'); var block = new Blockly.Block(this.workspace, 'field_number_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'NUMBER', '97'); - delete Blockly.Blocks['field_number_test_block']; + assertNonVariableField(resultFieldDom, 'NUMBER', '97'); }); test('Text Input', function() { Blockly.defineBlocksWithJsonArray([{ @@ -232,10 +287,11 @@ suite('XML', function() { } ], }]); + this.blockTypes_.push('field_text_input_test_block'); var block = new Blockly.Block(this.workspace, 'field_text_input_test_block'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertSimpleField(resultFieldDom, 'TEXT', 'default'); + assertNonVariableField(resultFieldDom, 'TEXT', 'default'); }); suite('Variable Fields', function() { setup(function() { @@ -250,9 +306,7 @@ suite('XML', function() { } ] }]); - }); - teardown(function() { - delete Blockly.Blocks['field_variable_test_block']; + this.blockTypes_.push('field_variable_test_block'); }); test('Variable Trivial', function() { this.workspace.createVariable('name1', '', 'id1'); @@ -260,7 +314,7 @@ suite('XML', function() { 'field_variable_test_block'); block.inputList[0].fieldRow[0].setValue('id1'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertVariableField(resultFieldDom, 'VAR', null, 'id1', 'name1'); + assertVariableDomField(resultFieldDom, 'VAR', null, 'id1', 'name1'); }); test('Variable Typed', function() { this.workspace.createVariable('name1', 'string', 'id1'); @@ -268,29 +322,21 @@ suite('XML', function() { 'field_variable_test_block'); block.inputList[0].fieldRow[0].setValue('id1'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - assertVariableField(resultFieldDom, 'VAR', 'string', 'id1', 'name1'); + assertVariableDomField(resultFieldDom, 'VAR', 'string', 'id1', 'name1'); }); test('Variable Default Case', function() { - var cacheGenUid = Blockly.utils.genUid; - Blockly.utils.genUid = function() { - return '1'; - }; + sinon.stub(Blockly.utils, 'genUid').returns('1'); + this.workspace.createVariable('name1'); - try { - this.workspace.createVariable('name1'); + Blockly.Events.disable(); + var block = new Blockly.Block(this.workspace, + 'field_variable_test_block'); + block.inputList[0].fieldRow[0].setValue('1'); + Blockly.Events.enable(); - Blockly.Events.disable(); - var block = new Blockly.Block(this.workspace, - 'field_variable_test_block'); - block.inputList[0].fieldRow[0].setValue('1'); - Blockly.Events.enable(); - - var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - // Expect type is null and ID is '1' since we don't specify type and ID. - assertVariableField(resultFieldDom, 'VAR', null, '1', 'name1'); - } finally { - Blockly.utils.genUid = cacheGenUid; - } + var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; + // Expect type is null and ID is '1' since we don't specify type and ID. + assertVariableDomField(resultFieldDom, 'VAR', null, '1', 'name1'); }); }); }); @@ -369,143 +415,151 @@ suite('XML', function() { }); }); }); - suite('Deserialization', function() { + suite('variablesToDom', function() { setup(function() { this.workspace = new Blockly.Workspace(); + Blockly.defineBlocksWithJsonArray([{ + 'type': 'field_variable_test_block', + 'message0': '%1', + 'args0': [ + { + 'type': 'field_variable', + 'name': 'VAR', + 'variable': 'item' + } + ] + }]); + this.blockTypes_.push('field_variable_test_block'); + }); + teardown(function() { + this.workspace.dispose(); + }); + test('One Variable', function() { + sinon.stub(Blockly.utils, 'genUid').returns('1'); + this.workspace.createVariable('name1'); + var resultDom = + Blockly.Xml.variablesToDom(this.workspace.getAllVariables()); + assertEquals(1, resultDom.children.length); + var resultVariableDom = resultDom.children[0]; + assertEquals('name1', resultVariableDom.textContent); + assertEquals(null, resultVariableDom.getAttribute('type')); + assertEquals('1', resultVariableDom.getAttribute('id')); + }); + test('Two Variable one block', function() { + this.workspace.createVariable('name1', '', 'id1'); + this.workspace.createVariable('name2', 'type2', 'id2'); + // If events are enabled during block construction, it will create a + // default variable. + Blockly.Events.disable(); + var block = new Blockly.Block(this.workspace, 'field_variable_test_block'); + block.inputList[0].fieldRow[0].setValue('id1'); + Blockly.Events.enable(); + + var resultDom = Blockly.Xml.variablesToDom(this.workspace.getAllVariables()); + assertEquals(2, resultDom.children.length); + assertVariableDom(resultDom.children[0], null, 'id1', + 'name1'); + assertVariableDom(resultDom.children[1], 'type2', 'id2', + 'name2'); + }); + test('No variables', function() { + var resultDom = + Blockly.Xml.variablesToDom(this.workspace.getAllVariables()); + assertEquals(0, resultDom.children.length); + }); + }); + suite('domToText', function() { + test('Round tripping', function() { + var dom = Blockly.Xml.textToDom(this.complexXmlText); + var text = Blockly.Xml.domToText(dom); + assertEquals('Round trip', this.complexXmlText.replace(/\s+/g, ''), + text.replace(/\s+/g, '')); + }); + }); + suite('domToPrettyText', function() { + test('Round tripping', function() { + var dom = Blockly.Xml.textToDom(this.complexXmlText); + var text = Blockly.Xml.domToPrettyText(dom); + assertEquals('Round trip', this.complexXmlText.replace(/\s+/g, ''), + text.replace(/\s+/g, '')); + }); + }); + suite('domToBlock', function() { + setup(function() { + this.workspace = new Blockly.Workspace(); + Blockly.defineBlocksWithJsonArray([{ + "type": "variables_get", + "message0": "%1", + "args0": [ + { + "type": "field_variable", + "name": "VAR" + } + ] + }, + { + "type": "variables_set", + "message0": "%1 %2", + "args0": [ + { + "type": "field_variable", + "name": "VAR" + }, + { + "type": "input_value", + "name": "VALUE" + } + ] + }, + { + "type": "math_change", + "message0": "%1 %2", + "args0": [ + { + "type": "field_variable", + "name": "VAR" + }, + { + "type": "input_value", + "name": "DELTA", + "check": "Number" + } + ] + }, + { + "type": "math_number", + "message0": "%1", + "args0": [{ + "type": "field_number", + "name": "NUM", + "value": 0 + }], + "output": "Number" + }]); + Array.prototype.push.apply( + this.blockTypes_, + ['variables_get', 'variables_set', 'math_change', 'math_number']); }); teardown(function() { this.workspace.dispose(); }); suite('Dynamic Category Blocks', function() { test('Untyped Variables', function() { - Blockly.defineBlocksWithJsonArray([{ - "type": "variables_get", - "message0": "%1", - "args0": [ - { - "type": "field_variable", - "name": "VAR", - } - ] - }, - { - "type": "variables_set", - "message0": "%1 %2", - "args0": [ - { - "type": "field_variable", - "name": "VAR" - }, - { - "type": "input_value", - "name": "VALUE" - } - ] - }, - { - "type": "math_change", - "message0": "%1 %2", - "args0": [ - { - "type": "field_variable", - "name": "VAR", - }, - { - "type": "input_value", - "name": "DELTA", - "check": "Number" - } - ] - }, - { - "type": "math_number", - "message0": "%1", - "args0": [{ - "type": "field_number", - "name": "NUM", - "value": 0 - }], - "output": "Number" - }]); - this.workspace.createVariable('name1', '', 'id1'); - var blocksArray = Blockly.Variables.flyoutCategoryBlocks(this.workspace); - try { - for (var i = 0, xml; (xml = blocksArray[i]); i++) { - Blockly.Xml.domToBlock(xml, this.workspace); - } - } finally { - delete Blockly.Blocks['variables_get']; - delete Blockly.Blocks['variables_set']; - delete Blockly.Blocks['math_change']; - delete Blockly.Blocks['math_number']; + var blocksArray = + Blockly.Variables.flyoutCategoryBlocks(this.workspace); + for (var i = 0, xml; (xml = blocksArray[i]); i++) { + Blockly.Xml.domToBlock(xml, this.workspace); } }); test('Typed Variables', function() { - Blockly.defineBlocksWithJsonArray([{ - "type": "variables_get", - "message0": "%1", - "args0": [ - { - "type": "field_variable", - "name": "VAR", - } - ] - }, - { - "type": "variables_set", - "message0": "%1 %2", - "args0": [ - { - "type": "field_variable", - "name": "VAR" - }, - { - "type": "input_value", - "name": "VALUE" - } - ] - }, - { - "type": "math_change", - "message0": "%1 %2", - "args0": [ - { - "type": "field_variable", - "name": "VAR", - }, - { - "type": "input_value", - "name": "DELTA", - "check": "Number" - } - ] - }, - { - "type": "math_number", - "message0": "%1", - "args0": [{ - "type": "field_number", - "name": "NUM", - "value": 0 - }], - "output": "Number" - }]); - this.workspace.createVariable('name1', 'String', 'id1'); this.workspace.createVariable('name2', 'Number', 'id2'); this.workspace.createVariable('name3', 'Colour', 'id3'); - var blocksArray = Blockly.VariablesDynamic - .flyoutCategoryBlocks(this.workspace); - try { - for (var i = 0, xml; (xml = blocksArray[i]); i++) { - Blockly.Xml.domToBlock(xml, this.workspace); - } - } finally { - delete Blockly.Blocks['variables_get']; - delete Blockly.Blocks['variables_set']; - delete Blockly.Blocks['math_change']; - delete Blockly.Blocks['math_number']; + var blocksArray = + Blockly.VariablesDynamic.flyoutCategoryBlocks(this.workspace); + for (var i = 0, xml; (xml = blocksArray[i]); i++) { + Blockly.Xml.domToBlock(xml, this.workspace); } }); }); @@ -600,9 +654,6 @@ suite('XML', function() { setup(function() { this.clock = sinon.useFakeTimers(); }); - teardown(function() { - this.clock.restore(); - }); test('Pinned True', function() { var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' + @@ -640,7 +691,125 @@ suite('XML', function() { }); }); }); - suite('Round Tripping', function() { + suite('domToWorkspace', function() { + setup(function() { + this.workspace = new Blockly.Workspace(); + Blockly.defineBlocksWithJsonArray([{ + 'type': 'field_variable_test_block', + 'message0': '%1', + 'args0': [ + { + 'type': 'field_variable', + 'name': 'VAR', + 'variable': 'item' + } + ] + }]); + this.blockTypes_.push('field_variable_test_block'); + }); + teardown(function() { + this.workspace.dispose(); + }); + test('Backwards compatibility', function() { + sinon.stub(Blockly.utils, 'genUid').returns('1'); + var dom = Blockly.Xml.textToDom( + '' + + ' ' + + ' name1' + + ' ' + + ''); + Blockly.Xml.domToWorkspace(dom, this.workspace); + assertEquals('Block count', 1, this.workspace.getAllBlocks(false).length); + assertVariableValues(this.workspace, 'name1', '', '1'); + }); + test('Variables at top', function() { + var dom = Blockly.Xml.textToDom( + '' + + ' ' + + ' name1' + + ' name2' + + ' name3' + + ' ' + + ' ' + + ' name3' + + ' ' + + ''); + Blockly.Xml.domToWorkspace(dom, this.workspace); + assertEquals('Block count', 1, this.workspace.getAllBlocks(false).length); + assertVariableValues(this.workspace, 'name1', 'type1', 'id1'); + assertVariableValues(this.workspace, 'name2', 'type2', 'id2'); + assertVariableValues(this.workspace, 'name3', '', 'id3'); + }); + test('Variables at top duplicated variables tag', function() { + var dom = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + chai.assert.throws(function() { + Blockly.Xml.domToWorkspace(dom, this.workspace); + }); + }); + test('Variables at top missing type', function() { + var dom = Blockly.Xml.textToDom( + '' + + ' ' + + ' name1' + + ' ' + + ' ' + + ' name3' + + ' ' + + ''); + chai.assert.throws(function() { + Blockly.Xml.domToWorkspace(dom, this.workspace); + }); + }); + test('Variables at top mismatch block type', function() { + var dom = Blockly.Xml.textToDom( + '' + + ' ' + + ' name1' + + ' ' + + ' ' + + ' name1' + + ' ' + + ''); + chai.assert.throws(function() { + Blockly.Xml.domToWorkspace(dom, this.workspace); + }); + }); + }); + suite('appendDomToWorkspace', function() { + setup(function() { + Blockly.Blocks.test_block = { + init: function() { + this.jsonInit({ + message0: 'test', + }); + } + }; + this.workspace = new Blockly.Workspace(); + }); + teardown(function() { + delete Blockly.Blocks.test_block; + this.workspace.dispose(); + }); + test('Headless', function() { + var dom = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ''); + Blockly.Xml.appendDomToWorkspace(dom, this.workspace); + assertEquals('Block count', 1, this.workspace.getAllBlocks(false).length); + var newBlockIds = Blockly.Xml.appendDomToWorkspace(dom, this.workspace); + assertEquals('Block count', 2, this.workspace.getAllBlocks(false).length); + assertEquals('Number of new block ids', 1, newBlockIds.length); + }); + }); + suite('workspaceToDom -> domToWorkspace -> workspaceToDom', function() { setup(function() { var options = { comments: true @@ -653,19 +822,17 @@ suite('XML', function() { this.renderedWorkspace.dispose(); this.headlessWorkspace.dispose(); }); + var assertRoundTrip = function(originWs, targetWs) { + var originXml = Blockly.Xml.workspaceToDom(originWs); + Blockly.Xml.domToWorkspace(originXml, targetWs); + var targetXml = Blockly.Xml.workspaceToDom(targetWs); + + var expectedXmlText = Blockly.Xml.domToText(originXml); + var actualXmlText = Blockly.Xml.domToText(targetXml); + + chai.assert.equal(actualXmlText, expectedXmlText); + }; suite('Rendered -> XML -> Headless -> XML', function() { - setup(function() { - this.assertRoundTrip = function() { - var renderedXml = Blockly.Xml.workspaceToDom(this.renderedWorkspace); - Blockly.Xml.domToWorkspace(renderedXml, this.headlessWorkspace); - var headlessXml = Blockly.Xml.workspaceToDom(this.headlessWorkspace); - - var renderedText = Blockly.Xml.domToText(renderedXml); - var headlessText = Blockly.Xml.domToText(headlessXml); - - chai.assert.equal(headlessText, renderedText); - }; - }); test('Comment', function() { var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' @@ -673,23 +840,10 @@ suite('XML', function() { block.setCommentText('test text'); block.getCommentIcon().setBubbleSize(100, 100); block.getCommentIcon().setVisible(true); - - this.assertRoundTrip(); + assertRoundTrip(this.renderedWorkspace, this.headlessWorkspace); }); }); suite('Headless -> XML -> Rendered -> XML', function() { - setup(function() { - this.assertRoundTrip = function() { - var headlessXml = Blockly.Xml.workspaceToDom(this.headlessWorkspace); - Blockly.Xml.domToWorkspace(headlessXml, this.renderedWorkspace); - var renderedXml = Blockly.Xml.workspaceToDom(this.renderedWorkspace); - - var renderedText = Blockly.Xml.domToText(renderedXml); - var headlessText = Blockly.Xml.domToText(headlessXml); - - chai.assert.equal(renderedText, headlessText); - }; - }); test('Comment', function() { var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom( '' @@ -697,9 +851,34 @@ suite('XML', function() { block.setCommentText('test text'); block.commentModel.size = new Blockly.utils.Size(100, 100); block.commentModel.pinned = true; - - this.assertRoundTrip(); + + assertRoundTrip(this.headlessWorkspace, this.renderedWorkspace); }); }); }); + suite('generateVariableFieldDom', function() { + test('Case Sensitive', function() { + var varId = 'testId'; + var type = 'testType'; + var name = 'testName'; + + var mockVariableModel = { + type: type, + name: name, + getId: function() { + return varId; + } + }; + + var generatedXml = Blockly.Xml.domToText( + Blockly.Variables.generateVariableFieldDom(mockVariableModel)); + var expectedXml = + '' + name + ''; + assertEquals(expectedXml, generatedXml); + }); + }); });