diff --git a/core/xml.js b/core/xml.js index d8b2cd61d..da6595aa6 100644 --- a/core/xml.js +++ b/core/xml.js @@ -42,6 +42,7 @@ goog.require('goog.dom'); */ Blockly.Xml.workspaceToDom = function(workspace, opt_noId) { var xml = goog.dom.createDom('xml'); + xml.appendChild(Blockly.Xml.variablesToDom(workspace.getAllVariables())); var blocks = workspace.getTopBlocks(true); for (var i = 0, block; block = blocks[i]; i++) { xml.appendChild(Blockly.Xml.blockToDomWithXY(block, opt_noId)); @@ -49,6 +50,23 @@ Blockly.Xml.workspaceToDom = function(workspace, opt_noId) { return xml; }; +/** + * Encode a list of variables as XML. + * @param {!Array.} variableList List of all variable + * models. + * @return {!Element} List of XML elements. + */ +Blockly.Xml.variablesToDom = function(variableList) { + var variables = goog.dom.createDom('variables'); + for (var i = 0, variable; variable = variableList[i]; i++) { + var element = goog.dom.createDom('variable', null, variable.name); + element.setAttribute('type', variable.type); + element.setAttribute('id', variable.getId()); + variables.appendChild(element); + } + return variables; +}; + /** * Encode a block subtree as XML with XY coordinates. * @param {!Blockly.Block} block The root block to encode. diff --git a/tests/jsunit/xml_test.js b/tests/jsunit/xml_test.js index e0db19c28..a118413ba 100644 --- a/tests/jsunit/xml_test.js +++ b/tests/jsunit/xml_test.js @@ -52,10 +52,13 @@ var XML_TEXT = ['', ' ', ''].join('\n'); - -function xmlTest_setUpWithMockBlocks() { +function xmlTest_setUp() { workspace = new Blockly.Workspace(); mockControl_ = new goog.testing.MockControl(); +} + +function xmlTest_setUpWithMockBlocks() { + xmlTest_setUp(); // Need to define this because field_variable's dropdownCreate() calls replace // on undefined value, Blockly.Msg.DELETE_VARIABLE. To fix this, define // Blockly.Msg.DELETE_VARIABLE as %1 so the replace function finds the %1 it @@ -63,9 +66,13 @@ function xmlTest_setUpWithMockBlocks() { Blockly.Msg.DELETE_VARIABLE = '%1'; } -function xmlTest_tearDownWithMockBlocks() { +function xmlTest_tearDown() { mockControl_.$tearDown(); workspace.dispose(); +} + +function xmlTest_tearDownWithMockBlocks() { + xmlTest_tearDown(); delete Blockly.Blocks.field_variable_test_block; Blockly.Msg.DELETE_VARIABLE = saved_msg; } @@ -91,13 +98,26 @@ function xmlTest_checkNonVariableField(fieldDom, name, text) { * @param {!string} id The expected id of the variable. * @param {!string} text The expected text of the variable. */ -function xmlTest_checkVariableDomValues(fieldDom, name, type, id, text) { +function xmlTest_checkVariableFieldDomValues(fieldDom, name, type, id, text) { assertEquals(name, fieldDom.getAttribute('name')); assertEquals(type, fieldDom.getAttribute('variableType')); assertEquals(id, fieldDom.getAttribute('id')); assertEquals(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, variableDom.getAttribute('type')); + assertEquals(id, variableDom.getAttribute('id')); + assertEquals(text, variableDom.textContent); +} + function test_textToDom() { var dom = Blockly.Xml.textToDom(XML_TEXT); assertEquals('XML tag', 'xml', dom.nodeName); @@ -191,7 +211,7 @@ function test_blockToDom_fieldToDom_trivial() { var block = new Blockly.Block(workspace, 'field_variable_test_block'); block.inputList[0].fieldRow[0].setValue('name1'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; - xmlTest_checkVariableDomValues(resultFieldDom, 'VAR', 'type1', 'id1', 'name1') + xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', 'type1', 'id1', 'name1') xmlTest_tearDownWithMockBlocks() } @@ -216,7 +236,7 @@ function test_blockToDom_fieldToDom_defaultCase() { block.inputList[0].fieldRow[0].setValue('name1'); var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0]; // Expect type is '' and id is '1' since we don't specify type and id. - xmlTest_checkVariableDomValues(resultFieldDom, 'VAR', '', '1', 'name1') + xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', '', '1', 'name1') xmlTest_tearDownWithMockBlocks() } @@ -239,3 +259,55 @@ function test_blockToDom_fieldToDom_notAFieldVariable() { delete Blockly.Blocks.field_angle_block; xmlTest_tearDownWithMockBlocks() } + +function test_variablesToDom_oneVariable() { + xmlTest_setUp(); + var mockGenUid = mockControl_.createMethodMock(Blockly.utils, 'genUid'); + mockGenUid().$returns('1'); + mockGenUid().$replay(); + + 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('', resultVariableDom.getAttribute('type')); + assertEquals('1', resultVariableDom.getAttribute('id')); + xmlTest_tearDown(); +} + +function test_variablesToDom_twoVariables_oneBlock() { + Blockly.defineBlocksWithJsonArray([{ + 'type': 'field_variable_test_block', + 'message0': '%1', + 'args0': [ + { + 'type': 'field_variable', + 'name': 'VAR', + 'variable': 'item' + } + ], + }]); + xmlTest_setUpWithMockBlocks(); + + workspace.createVariable('name1', 'type1', 'id1'); + workspace.createVariable('name2', 'type2', 'id2'); + var block = new Blockly.Block(workspace, 'field_variable_test_block'); + block.inputList[0].fieldRow[0].setValue('name1'); + + var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables()); + assertEquals(2, resultDom.children.length); + xmlTest_checkVariableDomValues(resultDom.children[0], 'type1', '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(0, resultDom.children.length); + xmlTest_tearDown(); +}