/**
* @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('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();
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',
});
}
};
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();
// TODO (#1199): make a similar test where the variable is given a non-empty
// type.f
workspace.createVariable('name1', '', 'id1');
var block = new Blockly.Block(workspace, 'field_variable_test_block');
block.inputList[0].fieldRow[0].setValue('id1');
var resultFieldDom = Blockly.Xml.blockToDom(block).childNodes[0];
xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', null, 'id1',
'name1');
xmlTest_tearDownWithMockBlocks();
}
function test_blockToDom_fieldToDom_defaultCase() {
xmlTest_setUpWithMockBlocks();
setUpMockMethod(mockControl_, 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();
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(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);
}