/** * @license * Blockly Tests * * Copyright 2014 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. */ 'use strict'; goog.require('goog.testing'); goog.require('goog.testing.MockControl'); var mockControl_; var workspace; var XML_TEXT = ['', ' ', ' ', ' ', ' 10', ' ', ' ', ' ', ' ', ' item', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' Hello', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ''].join('\n'); function xmlTest_setUp() { workspace = new Blockly.Workspace(); mockControl_ = new goog.testing.MockControl(); } 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() { mockControl_.$tearDown(); 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(text, fieldDom.textContent); assertEquals(name, fieldDom.getAttribute('name')); assertNull(fieldDom.getAttribute('id')); assertNull(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, 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); 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(); setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '1']); try { var dom = Blockly.Xml.textToDom( '' + ' ' + ' name1' + ' ' + ''); Blockly.Xml.domToWorkspace(dom, workspace); assertEquals('Block count', 1, workspace.getAllBlocks().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().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', }); } }; var workspace = new Blockly.Workspace(); try { var dom = Blockly.Xml.textToDom( '' + ' ' + ' ' + ''); workspace = new Blockly.Workspace(); Blockly.Xml.appendDomToWorkspace(dom, workspace); assertEquals('Block count', 1, workspace.getAllBlocks().length); var newBlockIds = Blockly.Xml.appendDomToWorkspace(dom, workspace); assertEquals('Block count', 2, workspace.getAllBlocks().length); assertEquals('Number of new block ids',1,newBlockIds.length); } finally { delete Blockly.Blocks.test_block; workspace.dispose(); } } function test_blockToDom_fieldToDom_trivial() { xmlTest_setUpWithMockBlocks(); workspace.createVariable('name1', 'type1', 'id1'); 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_checkVariableFieldDomValues(resultFieldDom, 'VAR', 'type1', 'id1', 'name1'); xmlTest_tearDownWithMockBlocks(); } function test_blockToDom_fieldToDom_defaultCase() { xmlTest_setUpWithMockBlocks(); try { setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '1']); workspace.createVariable('name1'); 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]; // Expect type is '' and id is '1' since we don't specify type and id. xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', '', '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(); setUpMockMethod(mockControl_, 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('', resultVariableDom.getAttribute('type')); assertEquals('1', resultVariableDom.getAttribute('id')); xmlTest_tearDown(); } function test_variablesToDom_twoVariables_oneBlock() { 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(1, resultDom.children.length); xmlTest_tearDown(); }