diff --git a/core/events/block_events.js b/core/events/block_events.js index 439603a86..ef9ae7229 100644 --- a/core/events/block_events.js +++ b/core/events/block_events.js @@ -26,8 +26,8 @@ goog.require('Blockly.Events.Abstract'); goog.require('Blockly.registry'); goog.require('Blockly.utils.Coordinate'); goog.require('Blockly.utils.object'); -goog.require('Blockly.utils.xml'); goog.require('Blockly.Xml'); +goog.require('Blockly.serialization.blocks'); goog.requireType('Blockly.Block'); @@ -247,12 +247,15 @@ Blockly.Events.Create = function(opt_block) { this.recordUndo = false; } - if (opt_block.workspace.rendered) { - this.xml = Blockly.Xml.blockToDomWithXY(opt_block); - } else { - this.xml = Blockly.Xml.blockToDom(opt_block); - } + this.xml = Blockly.Xml.blockToDomWithXY(opt_block); this.ids = Blockly.Events.getDescendantIds(opt_block); + + /** + * JSON representation of the block that was just created. + * @type {!Blockly.serialization.blocks.State} + */ + this.json = /** @type {!Blockly.serialization.blocks.State} */ + (Blockly.serialization.blocks.save(opt_block, {addCoordinates: true})); }; Blockly.utils.object.inherits(Blockly.Events.Create, Blockly.Events.BlockBase); @@ -279,6 +282,7 @@ Blockly.Events.Create.prototype.toJson = function() { var json = Blockly.Events.Create.superClass_.toJson.call(this); json['xml'] = Blockly.Xml.domToText(this.xml); json['ids'] = this.ids; + json['json'] = this.json; if (!this.recordUndo) { json['recordUndo'] = this.recordUndo; } @@ -293,6 +297,8 @@ Blockly.Events.Create.prototype.fromJson = function(json) { Blockly.Events.Create.superClass_.fromJson.call(this, json); this.xml = Blockly.Xml.textToDom(json['xml']); this.ids = json['ids']; + this.json = /** @type {!Blockly.serialization.blocks.State} */ + (json['json']); if (json['recordUndo'] !== undefined) { this.recordUndo = json['recordUndo']; } @@ -305,9 +311,7 @@ Blockly.Events.Create.prototype.fromJson = function(json) { Blockly.Events.Create.prototype.run = function(forward) { var workspace = this.getEventWorkspace_(); if (forward) { - var xml = Blockly.utils.xml.createElement('xml'); - xml.appendChild(this.xml); - Blockly.Xml.domToWorkspace(xml, workspace); + Blockly.serialization.blocks.load(this.json, workspace); } else { for (var i = 0, id; (id = this.ids[i]); i++) { var block = workspace.getBlockById(id); @@ -341,12 +345,22 @@ Blockly.Events.Delete = function(opt_block) { this.recordUndo = false; } - if (opt_block.workspace.rendered) { - this.oldXml = Blockly.Xml.blockToDomWithXY(opt_block); - } else { - this.oldXml = Blockly.Xml.blockToDom(opt_block); - } + this.oldXml = Blockly.Xml.blockToDomWithXY(opt_block); this.ids = Blockly.Events.getDescendantIds(opt_block); + + /** + * Was the block that was just deleted a shadow? + * @type {boolean} + */ + this.wasShadow = opt_block.isShadow(); + + /** + * JSON representation of the block that was just deleted. + * @type {!Blockly.serialization.blocks.State} + */ + this.oldJson = /** @type {!Blockly.serialization.blocks.State} */ + (Blockly.serialization.blocks.save(opt_block, {addCoordinates: true})); + }; Blockly.utils.object.inherits(Blockly.Events.Delete, Blockly.Events.BlockBase); @@ -372,6 +386,8 @@ Blockly.Events.Delete.prototype.toJson = function() { var json = Blockly.Events.Delete.superClass_.toJson.call(this); json['oldXml'] = Blockly.Xml.domToText(this.oldXml); json['ids'] = this.ids; + json['wasShadow'] = this.wasShadow; + json['oldJson'] = this.oldJson; if (!this.recordUndo) { json['recordUndo'] = this.recordUndo; } @@ -386,6 +402,10 @@ Blockly.Events.Delete.prototype.fromJson = function(json) { Blockly.Events.Delete.superClass_.fromJson.call(this, json); this.oldXml = Blockly.Xml.textToDom(json['oldXml']); this.ids = json['ids']; + this.wasShadow = + json['wasShadow'] || this.oldXml.tagName.toLowerCase() == 'shadow'; + this.oldJson = /** @type {!Blockly.serialization.blocks.State} */ + (json['oldJson']); if (json['recordUndo'] !== undefined) { this.recordUndo = json['recordUndo']; } @@ -408,9 +428,7 @@ Blockly.Events.Delete.prototype.run = function(forward) { } } } else { - var xml = Blockly.utils.xml.createElement('xml'); - xml.appendChild(this.oldXml); - Blockly.Xml.domToWorkspace(xml, workspace); + Blockly.serialization.blocks.load(this.oldJson, workspace); } }; diff --git a/core/trashcan.js b/core/trashcan.js index 831a26ba4..81d1d1861 100644 --- a/core/trashcan.js +++ b/core/trashcan.js @@ -30,7 +30,6 @@ goog.require('Blockly.utils.dom'); goog.require('Blockly.utils.Rect'); goog.require('Blockly.utils.Svg'); goog.require('Blockly.utils.toolbox'); -goog.require('Blockly.Xml'); goog.requireType('Blockly.Events.Abstract'); goog.requireType('Blockly.IDraggable'); @@ -64,7 +63,7 @@ Blockly.Trashcan = function(workspace) { this.id = 'trashcan'; /** - * A list of XML (stored as strings) representing blocks in the trashcan. + * A list of JSON (stored as strings) representing blocks in the trashcan. * @type {!Array} * @private */ @@ -426,8 +425,10 @@ Blockly.Trashcan.prototype.openFlyout = function() { if (this.contentsIsOpen()) { return; } - var xml = this.contents_.map(Blockly.Xml.textToDom); - this.flyout.show(xml); + var contents = this.contents_.map(function(string) { + return JSON.parse(string); + }); + this.flyout.show(contents); this.fireUiEvent_(true); }; @@ -706,14 +707,12 @@ Blockly.Trashcan.prototype.onDelete_ = function(event) { if (this.workspace_.options.maxTrashcanContents <= 0) { return; } - // Must check that the tagName exists since oldXml can be a DocumentFragment. - if (event.type == Blockly.Events.BLOCK_DELETE && event.oldXml.tagName && - event.oldXml.tagName.toLowerCase() != 'shadow') { - var cleanedXML = this.cleanBlockXML_(event.oldXml); - if (this.contents_.indexOf(cleanedXML) != -1) { + if (event.type == Blockly.Events.BLOCK_DELETE && !event.wasShadow) { + var cleanedJson = this.cleanBlockJson_(event.oldJson); + if (this.contents_.indexOf(cleanedJson) != -1) { return; } - this.contents_.unshift(cleanedXML); + this.contents_.unshift(cleanedJson); while (this.contents_.length > this.workspace_.options.maxTrashcanContents) { this.contents_.pop(); @@ -724,50 +723,49 @@ Blockly.Trashcan.prototype.onDelete_ = function(event) { }; /** - * Converts XML representing a block into text that can be stored in the - * content array. - * @param {!Element} xml An XML tree defining the block and any - * connected child blocks. - * @return {string} Text representing the XML tree, cleaned of all unnecessary - * attributes. + * Converts JSON representing a block into text that can be stored in the + * content array. + * @param {!Blockly.serialization.blocks.State} json A JSON representation of + * a block's state. + * @return {string} Text representing the JSON, cleaned of all unnecessary + * attributes. * @private */ -Blockly.Trashcan.prototype.cleanBlockXML_ = function(xml) { - var xmlBlock = xml.cloneNode(true); - var node = xmlBlock; - while (node) { - // Things like text inside tags are still treated as nodes, but they - // don't have attributes (or the removeAttribute function) so we can - // skip removing attributes from them. - if (node.removeAttribute) { - node.removeAttribute('x'); - node.removeAttribute('y'); - node.removeAttribute('id'); - node.removeAttribute('disabled'); - if (node.nodeName == 'comment') { // Future proof just in case. - node.removeAttribute('h'); - node.removeAttribute('w'); - node.removeAttribute('pinned'); - } +Blockly.Trashcan.prototype.cleanBlockJson_ = function(json) { + json = /** @type {!Blockly.serialization.blocks.State} */ + (JSON.parse(JSON.stringify(json))); // Create deep copy. + + function cleanRec(json) { + if (!json) { + return; } - // Try to go down the tree - var nextNode = node.firstChild || node.nextSibling; - // If we can't go down, try to go back up the tree. - if (!nextNode) { - nextNode = node.parentNode; - while (nextNode) { - // We are valid again! - if (nextNode.nextSibling) { - nextNode = nextNode.nextSibling; - break; - } - // Try going up again. If parentNode is null that means we have - // reached the top, and we will break out of both loops. - nextNode = nextNode.parentNode; - } + delete json['id']; + delete json['x']; + delete json['y']; + delete json['enabled']; + + if (json['icons'] && json['icons']['comment']) { + var comment = json['icons']['comment']; + delete comment['height']; + delete comment['width']; + delete comment['pinned']; + } + + var inputs = json['inputs']; + for (var name in inputs) { + var input = inputs[name]; + cleanRec(input['block']); + cleanRec(input['shadow']); + } + if (json['next']) { + var next = json['next']; + cleanRec(next['block']); + cleanRec(next['shadow']); } - node = nextNode; } - return Blockly.Xml.domToText(xmlBlock); + + cleanRec(json); + json['kind'] = 'BLOCK'; + return JSON.stringify(json); }; diff --git a/tests/mocha/event_test.js b/tests/mocha/event_test.js index 81ab69519..2ff555a62 100644 --- a/tests/mocha/event_test.js +++ b/tests/mocha/event_test.js @@ -562,48 +562,118 @@ suite('Events', function() { viewLeft: 0, scale: 1.2, oldScale: 1})}, ]; var blockEventTestCases = [ - {title: 'Block change', class: Blockly.Events.BlockChange, + { + title: 'Block change', + class: Blockly.Events.BlockChange, getArgs: (thisObj) => [thisObj.block, 'collapsed', null, false, true], - getExpectedJson: (thisObj) => ({type: 'change', - blockId: thisObj.block.id, element: 'collapsed', oldValue: false, - newValue: true})}, - {title: 'Block create', class: Blockly.Events.BlockCreate, + getExpectedJson: (thisObj) => ({ + type: 'change', + blockId: thisObj.block.id, + element: 'collapsed', + oldValue: false, + newValue: true + }) + }, + { + title: 'Block create', + class: Blockly.Events.BlockCreate, getArgs: (thisObj) => [thisObj.block], - getExpectedJson: (thisObj) => ({type: 'create', + getExpectedJson: (thisObj) => ({ + type: 'create', blockId: thisObj.block.id, xml: '', - ids: [thisObj.block.id]})}, - {title: 'Block create (shadow)', class: Blockly.Events.BlockCreate, + ' type="simple_test_block" id="testBlockId1" x="0" y="0">' + + '', + ids: [thisObj.block.id], + json: { + 'type': 'simple_test_block', + 'id': 'testBlockId1', + 'x': 0, + 'y': 0, + }, + }) + }, + { + title: 'Block create (shadow)', + class: Blockly.Events.BlockCreate, getArgs: (thisObj) => [thisObj.shadowBlock], - getExpectedJson: (thisObj) => ({type: 'create', + getExpectedJson: (thisObj) => ({ + type: 'create', blockId: thisObj.shadowBlock.id, xml: '', - ids: [thisObj.shadowBlock.id], recordUndo: false})}, - {title: 'Block delete', class: Blockly.Events.BlockDelete, + ' type="simple_test_block" id="testBlockId2" x="0" y="0">' + + '', + ids: [thisObj.shadowBlock.id], + json: { + 'type': 'simple_test_block', + 'id': 'testBlockId2', + 'x': 0, + 'y': 0, + }, + recordUndo: false + }) + }, + { + title: 'Block delete', + class: Blockly.Events.BlockDelete, getArgs: (thisObj) => [thisObj.block], - getExpectedJson: (thisObj) => ({type: 'delete', + getExpectedJson: (thisObj) => ({ + type: 'delete', blockId: thisObj.block.id, oldXml: '', - ids: [thisObj.block.id]})}, - {title: 'Block delete (shadow)', class: Blockly.Events.BlockDelete, + ' type="simple_test_block" id="testBlockId1" x="0" y="0">' + + '', + ids: [thisObj.block.id], + wasShadow: false, + oldJson: { + 'type': 'simple_test_block', + 'id': 'testBlockId1', + 'x': 0, + 'y': 0, + }, + }) + }, + { + title: 'Block delete (shadow)', + class: Blockly.Events.BlockDelete, getArgs: (thisObj) => [thisObj.shadowBlock], - getExpectedJson: (thisObj) => ({type: 'delete', + getExpectedJson: (thisObj) => ({ + type: 'delete', blockId: thisObj.shadowBlock.id, oldXml: '', - ids: [thisObj.shadowBlock.id], recordUndo: false})}, + ' type="simple_test_block" id="testBlockId2" x="0" y="0">' + + '', + ids: [thisObj.shadowBlock.id], + wasShadow: true, + oldJson: { + 'type': 'simple_test_block', + 'id': 'testBlockId2', + 'x': 0, + 'y': 0, + }, + recordUndo: false + }) + }, // TODO(#4577) Test serialization of move event coordinate properties. - {title: 'Block move', class: Blockly.Events.BlockMove, + { + title: 'Block move', + class: Blockly.Events.BlockMove, getArgs: (thisObj) => [thisObj.block], - getExpectedJson: (thisObj) => ({type: 'move', - blockId: thisObj.block.id})}, - {title: 'Block move (shadow)', class: Blockly.Events.BlockMove, + getExpectedJson: (thisObj) => ({ + type: 'move', + blockId: thisObj.block.id + }) + }, + { + title: 'Block move (shadow)', + class: Blockly.Events.BlockMove, getArgs: (thisObj) => [thisObj.shadowBlock], - getExpectedJson: (thisObj) => ({type: 'move', - blockId: thisObj.shadowBlock.id, recordUndo: false})}, + getExpectedJson: (thisObj) => ({ + type: 'move', + blockId: thisObj.shadowBlock.id, + recordUndo: false + }) + }, ]; var workspaceEventTestCases = [ {title: 'Finished Loading', class: Blockly.Events.FinishedLoading, diff --git a/tests/mocha/jso_deserialization_test.js b/tests/mocha/jso_deserialization_test.js index a5ed16238..d677198ad 100644 --- a/tests/mocha/jso_deserialization_test.js +++ b/tests/mocha/jso_deserialization_test.js @@ -684,7 +684,11 @@ suite('JSO Deserialization', function() { Blockly.Blocks['test_block'] = { init: function() { }, - mutationToDom: function() { }, + mutationToDom: function() { + var container = Blockly.utils.xml.createElement('mutation'); + container.setAttribute('value', 'some value'); + return container; + }, domToMutation: function(element) { this.someProperty = element.getAttribute('value'); diff --git a/tests/mocha/test_helpers.js b/tests/mocha/test_helpers.js index 03bf5e76a..6491d46c8 100644 --- a/tests/mocha/test_helpers.js +++ b/tests/mocha/test_helpers.js @@ -457,18 +457,18 @@ function assertNthCallEventArgEquals(spy, n, instanceType, expectedProperties, assertXmlProperties_(eventArg, xmlProperties); } -function defineStackBlock() { +function defineStackBlock(name = 'stack_block') { Blockly.defineBlocksWithJsonArray([{ - "type": "stack_block", + "type": name, "message0": "", "previousStatement": null, "nextStatement": null }]); } -function defineRowBlock() { +function defineRowBlock(name = 'row_block') { Blockly.defineBlocksWithJsonArray([{ - "type": "row_block", + "type": name, "message0": "%1", "args0": [ { @@ -480,9 +480,9 @@ function defineRowBlock() { }]); } -function defineStatementBlock() { +function defineStatementBlock(name = 'statement_block') { Blockly.defineBlocksWithJsonArray([{ - "type": "statement_block", + "type": name, "message0": "%1", "args0": [ { @@ -498,9 +498,9 @@ function defineStatementBlock() { }]); } -function defineBasicBlockWithField() { +function defineBasicBlockWithField(name = 'test_field_block') { Blockly.defineBlocksWithJsonArray([{ - "type": "test_field_block", + "type": name, "message0": "%1", "args0": [ { diff --git a/tests/mocha/trashcan_test.js b/tests/mocha/trashcan_test.js index 9e0122d71..a7a4083d3 100644 --- a/tests/mocha/trashcan_test.js +++ b/tests/mocha/trashcan_test.js @@ -10,14 +10,13 @@ suite("Trashcan", function() { '' + xmlString + ''); xml = xml.children[0]; - var event = new Blockly.Events.Delete(); - event.oldXml = xml; - event.workspaceId = workspace.id; + var block = Blockly.Xml.domToBlock(xml, workspace); + var event = new Blockly.Events.Delete(block); Blockly.Events.fire(event); } function fireNonDeleteEvent(workspace, oldXml) { var event = new Blockly.Events.Abstract(); - event.type = 'dummy_type'; + event.type = 'test_field_block'; event.workspaceId = workspace.id; if (oldXml) { event.oldXml = oldXml; @@ -27,17 +26,27 @@ suite("Trashcan", function() { setup(function() { sharedTestSetup.call(this); + defineBasicBlockWithField(); + defineRowBlock(); + defineRowBlock('row_block2'); + defineStatementBlock(); + defineStatementBlock('statement_block2'); + defineStackBlock(); + defineStackBlock('stack_block2'); + defineMutatorBlocks(); this.workspace = Blockly.inject('blocklyDiv', {'trashcan': true, 'maxTrashcanContents': Infinity}); this.trashcan = this.workspace.trashcan; }); teardown(function() { sharedTestTeardown.call(this); + Blockly.Extensions.unregister('xml_mutator'); + Blockly.Extensions.unregister('jso_mutator'); }); suite("Events", function() { test("Delete", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); chai.assert.equal(this.trashcan.contents_.length, 1); }); test("Non-Delete", function() { @@ -47,7 +56,7 @@ suite("Trashcan", function() { test("Non-Delete w/ oldXml", function() { var xml = Blockly.Xml.textToDom( '' + - ' ' + + ' ' + '' ); xml = xml.children[0]; @@ -55,7 +64,7 @@ suite("Trashcan", function() { chai.assert.equal(this.trashcan.contents_.length, 0); }); test("Shadow Delete", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); chai.assert.equal(this.trashcan.contents_.length, 0); }); test("Click without contents - fires workspace click", function() { @@ -68,7 +77,7 @@ suite("Trashcan", function() { this.workspace.id, null); }); test("Click with contents - fires trashcanOpen", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); chai.assert.equal(this.trashcan.contents_.length, 1); // Stub flyout interaction. var showFlyoutStub = sinon.stub(this.trashcan.flyout, "show"); @@ -102,56 +111,52 @@ suite("Trashcan", function() { }); suite("Unique Contents", function() { test("Simple", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); chai.assert.equal(this.trashcan.contents_.length, 1); }); test("Different Coords", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent( + this.workspace, ''); + fireDeleteEvent( + this.workspace, ''); chai.assert.equal(this.trashcan.contents_.length, 1); }); test("Different IDs", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent( + this.workspace, ''); + fireDeleteEvent( + this.workspace, ''); chai.assert.equal(this.trashcan.contents_.length, 1); }); test("No Disabled - Disabled True", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent( + this.workspace, ''); + fireDeleteEvent( + this.workspace, ''); // Disabled tags get removed because disabled blocks aren't allowed to // be dragged from flyouts. See #2239 and #3243. chai.assert.equal(this.trashcan.contents_.length, 1); }); - test("No Editable - Editable False", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); - chai.assert.equal(this.trashcan.contents_.length, 2); - }); - test("No Movable - Movable False", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); - chai.assert.equal(this.trashcan.contents_.length, 2); - }); test("Different Field Values", function() { fireDeleteEvent(this.workspace, - '' + - ' dummy_value1' + + '' + + ' dummy_value1' + '' ); fireDeleteEvent(this.workspace, - '' + - ' dummy_value2' + + '' + + ' dummy_value2' + '' ); chai.assert.equal(this.trashcan.contents_.length, 2); }); test("No Values - Values", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); fireDeleteEvent(this.workspace, - '' + - ' ' + - ' ' + + '' + + ' ' + + ' ' + ' ' + '' ); @@ -159,27 +164,27 @@ suite("Trashcan", function() { }); test("Different Value Blocks", function() { fireDeleteEvent(this.workspace, - '' + - ' ' + - ' ' + + '' + + ' ' + + ' ' + ' ' + '' ); fireDeleteEvent(this.workspace, - '' + - ' ' + - ' ' + + '' + + ' ' + + ' ' + ' ' + '' ); chai.assert.equal(this.trashcan.contents_.length, 2); }); test("No Statements - Statements", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); fireDeleteEvent(this.workspace, - '' + - ' ' + - ' ' + + '' + + ' ' + + ' ' + ' ' + '' ); @@ -187,27 +192,27 @@ suite("Trashcan", function() { }); test("Different Statement Blocks", function() { fireDeleteEvent(this.workspace, - '' + - ' ' + - ' ' + + '' + + ' ' + + ' ' + ' ' + '' ); fireDeleteEvent(this.workspace, - '' + - ' ' + - ' ' + + '' + + ' ' + + ' ' + ' ' + '' ); chai.assert.equal(this.trashcan.contents_.length, 2); }); test("No Next - Next", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); fireDeleteEvent(this.workspace, - '' + + '' + ' ' + - ' ' + + ' ' + ' ' + '' ); @@ -215,25 +220,25 @@ suite("Trashcan", function() { }); test("Different Next Blocks", function() { fireDeleteEvent(this.workspace, - '' + + '' + ' ' + - ' ' + + ' ' + ' ' + '' ); fireDeleteEvent(this.workspace, - '' + + '' + ' ' + - ' ' + + ' ' + ' ' + '' ); chai.assert.equal(this.trashcan.contents_.length, 2); }); test("No Comment - Comment", function() { - fireDeleteEvent(this.workspace, ''); + fireDeleteEvent(this.workspace, ''); fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text' + '' ); @@ -241,12 +246,12 @@ suite("Trashcan", function() { }); test("Different Comment Text", function() { fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text1' + '' ); fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text2' + '' ); @@ -254,12 +259,12 @@ suite("Trashcan", function() { }); test("Different Comment Size", function() { fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text' + '' ); fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text' + '' ); @@ -268,36 +273,27 @@ suite("Trashcan", function() { }); test("Different Comment Pinned", function() { fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text' + '' ); fireDeleteEvent(this.workspace, - '' + + '' + ' comment_text' + '' ); // pinned tags are removed b/c the blocks appear the same. chai.assert.equal(this.trashcan.contents_.length, 1); }); - test("No Mutator - Mutator", function() { - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, - '' + - ' ' + - '' - ); - chai.assert.equal(this.trashcan.contents_.length, 2); - }); test("Different Mutator", function() { fireDeleteEvent(this.workspace, - '' + - ' ' + + '' + + ' ' + '' ); fireDeleteEvent(this.workspace, - '' + - ' ' + + '' + + ' ' + '' ); chai.assert.equal(this.trashcan.contents_.length, 2); @@ -307,22 +303,10 @@ suite("Trashcan", function() { test("Max 0", function() { this.workspace.options.maxTrashcanContents = 0; fireDeleteEvent(this.workspace, - '' + '' ); chai.assert.equal(this.trashcan.contents_.length, 0); this.workspace.options.maxTrashcanContents = Infinity; }); - test("Last In First Out", function() { - this.workspace.options.maxTrashcanContents = 1; - fireDeleteEvent(this.workspace, ''); - fireDeleteEvent(this.workspace, ''); - chai.assert.equal(this.trashcan.contents_.length, 1); - chai.assert.equal( - Blockly.Xml.textToDom(this.trashcan.contents_[0]) - .getAttribute('type'), - 'dummy_type2' - ); - this.workspace.options.maxTrashcanContents = Infinity; - }); }); });