From e9a480c51f593797154971db54428f3f5869ba3e Mon Sep 17 00:00:00 2001 From: marisaleung Date: Thu, 1 Jun 2017 15:35:13 -0700 Subject: [PATCH] Add VAR events. --- core/events.js | 240 ++++++++++++++++++++++++++-- core/variable_map.js | 11 +- core/variable_model.js | 9 +- core/workspace.js | 14 +- tests/jsunit/event_test.js | 210 ++++++++++++++++++++++-- tests/jsunit/variable_map_test.js | 9 +- tests/jsunit/variable_model_test.js | 39 +++-- 7 files changed, 487 insertions(+), 45 deletions(-) diff --git a/core/events.js b/core/events.js index 36dc17069..3e196dc56 100644 --- a/core/events.js +++ b/core/events.js @@ -102,6 +102,24 @@ Blockly.Events.MOVE = 'move'; */ Blockly.Events.BLOCK_MOVE = Blockly.Events.MOVE; +/** + * Name of event that creates a variable. + * @const + */ +Blockly.Events.VAR_CREATE = 'var_create'; + +/** + * Name of event that deletes a variable. + * @const + */ +Blockly.Events.VAR_DELETE = 'var_delete'; + +/** + * Name of event that renames a variable. + * @const + */ +Blockly.Events.VAR_RENAME = 'var_rename'; + /** * Name of event that records a UI change. * @const @@ -300,6 +318,15 @@ Blockly.Events.fromJson = function(json, workspace) { case Blockly.Events.MOVE: event = new Blockly.Events.Move(null); break; + case Blockly.Events.VAR_CREATE: + event = new Blockly.Events.VarCreate(null); + break; + case Blockly.Events.VAR_DELETE: + event = new Blockly.Events.VarDelete(null); + break; + case Blockly.Events.VAR_RENAME: + event = new Blockly.Events.VarRename(null); + break; case Blockly.Events.UI: event = new Blockly.Events.Ui(null); break; @@ -313,13 +340,17 @@ Blockly.Events.fromJson = function(json, workspace) { /** * Abstract class for an event. - * @param {Blockly.Block} block The block. + * @param {Blockly.Block|Blockly.VariableModel} elem The block or variable. * @constructor */ -Blockly.Events.Abstract = function(block) { - if (block) { - this.blockId = block.id; - this.workspaceId = block.workspace.id; +Blockly.Events.Abstract = function(elem) { + if (elem instanceof Blockly.Block) { + this.blockId = elem.id; + this.workspaceId = elem.workspace.id; + } + else if (elem instanceof Blockly.VariableModel){ + this.workspaceId = elem.workspace.id; + this.varId = elem.getId(); } this.group = Blockly.Events.group_; this.recordUndo = Blockly.Events.recordUndo; @@ -336,6 +367,9 @@ Blockly.Events.Abstract.prototype.toJson = function() { if (this.blockId) { json['blockId'] = this.blockId; } + if (this.varId) { + json['varId'] = this.varId; + } if (this.group) { json['group'] = this.group; } @@ -348,6 +382,7 @@ Blockly.Events.Abstract.prototype.toJson = function() { */ Blockly.Events.Abstract.prototype.fromJson = function(json) { this.blockId = json['blockId']; + this.varId = json['varId']; this.group = json['group']; }; @@ -367,6 +402,21 @@ Blockly.Events.Abstract.prototype.run = function(forward) { // Defined by subclasses. }; +/** + * Get workspace the event belongs to. + * @return {Blockly.Workspace} The workspace the event belongs to. + * @throws {Error} if workspace is null. + * @private + */ +Blockly.Events.Abstract.prototype.getEventWorkspace_ = function() { + var workspace = Blockly.Workspace.getById(this.workspaceId); + if (!workspace) { + throw Error('Workspace is null. Event must have been generated from real' + + ' Blockly events.'); + } + return workspace; +}; + /** * Class for a block creation event. * @param {Blockly.Block} block The created block. Null for a blank event. @@ -428,7 +478,7 @@ Blockly.Events.Create.prototype.fromJson = function(json) { * @param {boolean} forward True if run forward, false if run backward (undo). */ Blockly.Events.Create.prototype.run = function(forward) { - var workspace = Blockly.Workspace.getById(this.workspaceId); + var workspace = this.getEventWorkspace_(); if (forward) { var xml = goog.dom.createDom('xml'); xml.appendChild(this.xml); @@ -508,7 +558,7 @@ Blockly.Events.Delete.prototype.fromJson = function(json) { * @param {boolean} forward True if run forward, false if run backward (undo). */ Blockly.Events.Delete.prototype.run = function(forward) { - var workspace = Blockly.Workspace.getById(this.workspaceId); + var workspace = this.getEventWorkspace_(); if (forward) { for (var i = 0, id; id = this.ids[i]; i++) { var block = workspace.getBlockById(id); @@ -604,7 +654,7 @@ Blockly.Events.Change.prototype.isNull = function() { * @param {boolean} forward True if run forward, false if run backward (undo). */ Blockly.Events.Change.prototype.run = function(forward) { - var workspace = Blockly.Workspace.getById(this.workspaceId); + var workspace = this.getEventWorkspace_(); var block = workspace.getBlockById(this.blockId); if (!block) { console.warn("Can't change non-existant block: " + this.blockId); @@ -773,7 +823,7 @@ Blockly.Events.Move.prototype.isNull = function() { * @param {boolean} forward True if run forward, false if run backward (undo). */ Blockly.Events.Move.prototype.run = function(forward) { - var workspace = Blockly.Workspace.getById(this.workspaceId); + var workspace = this.getEventWorkspace_(); var block = workspace.getBlockById(this.blockId); if (!block) { console.warn("Can't move non-existant block: " + this.blockId); @@ -862,6 +912,178 @@ Blockly.Events.Ui.prototype.fromJson = function(json) { this.newValue = json['newValue']; }; +/** + * Class for a variable creation event. + * @param {Blockly.VariableModel} variable The created variable. + * Null for a blank event. + * @extends {Blockly.Events.Abstract} + * @constructor + */ +Blockly.Events.VarCreate = function(variable) { + if (!variable) { + return; // Blank event to be populated by fromJson. + } + Blockly.Events.VarCreate.superClass_.constructor.call(this, variable); + this.varType = variable.type; + this.varName = variable.name; +}; +goog.inherits(Blockly.Events.VarCreate, Blockly.Events.Abstract); + +/** + * Type of this event. + * @type {string} + */ +Blockly.Events.VarCreate.prototype.type = Blockly.Events.VAR_CREATE; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +Blockly.Events.VarCreate.prototype.toJson = function() { + var json = Blockly.Events.VarCreate.superClass_.toJson.call(this); + json['varType'] = this.varType; + json['varName'] = this.varName; + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.VarCreate.prototype.fromJson = function(json) { + Blockly.Events.VarCreate.superClass_.fromJson.call(this, json); + this.varType = json['varType']; + this.varName = json['varName']; +}; + +/** + * Run a variable creation event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +Blockly.Events.VarCreate.prototype.run = function(forward) { + var workspace = this.getEventWorkspace_(); + if (forward) { + workspace.createVariable(this.varName, this.varType, this.varId); + } else { + workspace.deleteVariableById(this.varId); + } +}; + +/** + * Class for a variable deletion event. + * @param {Blockly.VariableModel} variable The deleted variable. + * Null for a blank event. + * @extends {Blockly.Events.Abstract} + * @constructor + */ +Blockly.Events.VarDelete = function(variable) { + if (!variable) { + return; // Blank event to be populated by fromJson. + } + Blockly.Events.VarDelete.superClass_.constructor.call(this, variable); + this.varType = variable.type; + this.varName = variable.name; +}; +goog.inherits(Blockly.Events.VarDelete, Blockly.Events.Abstract); + +/** + * Type of this event. + * @type {string} + */ +Blockly.Events.VarDelete.prototype.type = Blockly.Events.VAR_DELETE; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +Blockly.Events.VarDelete.prototype.toJson = function() { + var json = Blockly.Events.VarDelete.superClass_.toJson.call(this); + json['varType'] = this.varType; + json['varName'] = this.varName; + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.VarDelete.prototype.fromJson = function(json) { + Blockly.Events.VarDelete.superClass_.fromJson.call(this, json); + this.varType = json['varType']; + this.varName = json['varName']; +}; + +/** + * Run a variable deletion event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +Blockly.Events.VarDelete.prototype.run = function(forward) { + var workspace = this.getEventWorkspace_(); + if (forward) { + workspace.deleteVariableById(this.varId); + } else { + workspace.createVariable(this.varName, this.varType, this.varId); + } +}; + +/** + * Class for a variable rename event. + * @param {Blockly.VariableModel} variable The renamed variable. + * Null for a blank event. + * @param {string} newName The new name the variable will be changed to. + * @extends {Blockly.Events.Abstract} + * @constructor + */ +Blockly.Events.VarRename = function(variable, newName) { + if (!variable) { + return; // Blank event to be populated by fromJson. + } + Blockly.Events.VarRename.superClass_.constructor.call(this, variable); + this.oldName = variable.name; + this.newName = newName; +}; +goog.inherits(Blockly.Events.VarRename, Blockly.Events.Abstract); + +/** + * Type of this event. + * @type {string} + */ +Blockly.Events.VarRename.prototype.type = Blockly.Events.VAR_RENAME; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +Blockly.Events.VarRename.prototype.toJson = function() { + var json = Blockly.Events.VarRename.superClass_.toJson.call(this); + json['oldName'] = this.oldName; + json['newName'] = this.newName; + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.VarRename.prototype.fromJson = function(json) { + Blockly.Events.VarRename.superClass_.fromJson.call(this, json); + this.oldName = json['oldName']; + this.newName = json['newName']; +}; + +/** + * Run a variable rename event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +Blockly.Events.VarRename.prototype.run = function(forward) { + var workspace = this.getEventWorkspace_(); + if (forward) { + workspace.renameVariableById(this.varId, this.newName); + } else { + workspace.renameVariableById(this.varId, this.oldName); + } +}; + /** * Enable/disable a block depending on whether it is properly connected. * Use this on applications where all blocks should be connected to a top block. diff --git a/core/variable_map.js b/core/variable_map.js index 0dce2474b..0a25384cb 100644 --- a/core/variable_map.js +++ b/core/variable_map.js @@ -30,9 +30,10 @@ goog.provide('Blockly.VariableMap'); * Class for a variable map. This contains a dictionary data structure with * variable types as keys and lists of variables as values. The list of * variables are the type indicated by the key. + * @param {!Blockly.Workspace} workspace The workspace this map belongs to. * @constructor */ - Blockly.VariableMap = function() { + Blockly.VariableMap = function(workspace) { /** * @type {!Object>} * A map from variable type to list of variable names. The lists contain all @@ -41,6 +42,12 @@ goog.provide('Blockly.VariableMap'); * @private */ this.variableMap_ = {}; + + /** + * The workspace this map belongs to. + * @type {!Blockly.Workspace} + */ + this.workspace = workspace; }; /** @@ -121,7 +128,7 @@ Blockly.VariableMap.prototype.createVariable = function(name, opt_type, opt_id) opt_id = opt_id || Blockly.utils.genUid(); opt_type = opt_type || ''; - variable = new Blockly.VariableModel(name, opt_type, opt_id); + variable = new Blockly.VariableModel(this.workspace, name, opt_type, opt_id); // If opt_type is not a key, create a new list. if (!this.variableMap_[opt_type]) { this.variableMap_[opt_type] = [variable]; diff --git a/core/variable_model.js b/core/variable_model.js index b5ec897ac..7124ed16e 100644 --- a/core/variable_model.js +++ b/core/variable_model.js @@ -32,6 +32,7 @@ goog.require('goog.string'); /** * Class for a variable model. * Holds information for the variable including name, id, and type. + * @param {!Blockly.Workspace} workspace The variable's workspace. * @param {!string} name The name of the variable. This must be unique across * variables and procedures. * @param {?string} opt_type The type of the variable like 'int' or 'string'. @@ -42,7 +43,13 @@ goog.require('goog.string'); * @see {Blockly.FieldVariable} * @constructor */ -Blockly.VariableModel = function(name, opt_type, opt_id) { +Blockly.VariableModel = function(workspace, name, opt_type, opt_id) { + /** + * The workspace the variable is in. + * @type {!Blockly.Workspace} + */ + this.workspace = workspace; + /** * The name of the variable, typically defined by the user. It must be * unique across all names used for procedures and variables. It may be diff --git a/core/workspace.js b/core/workspace.js index fa99869d6..b707c968b 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -83,7 +83,7 @@ Blockly.Workspace = function(opt_options) { * that are not currently in use. * @private */ - this.variableMap_ = new Blockly.VariableMap(); + this.variableMap_ = new Blockly.VariableMap(this); }; /** @@ -383,6 +383,8 @@ Blockly.Workspace.prototype.deleteVariableById = function(id) { var variable = this.getVariableById(id); if (variable) { this.deleteVariableInternal_(variable); + } else { + console.warn("Can't delete non-existant variable: " + id); } }; @@ -494,10 +496,14 @@ Blockly.Workspace.prototype.undo = function(redo) { } events = Blockly.Events.filter(events, redo); Blockly.Events.recordUndo = false; - for (var i = 0, event; event = events[i]; i++) { - event.run(redo); + try { + for (var i = 0, event; event = events[i]; i++) { + event.run(redo); + } + } + finally { + Blockly.Events.recordUndo = true; } - Blockly.Events.recordUndo = true; }; /** diff --git a/tests/jsunit/event_test.js b/tests/jsunit/event_test.js index e4513026a..82b95cc46 100644 --- a/tests/jsunit/event_test.js +++ b/tests/jsunit/event_test.js @@ -72,10 +72,20 @@ function test_abstract_constructor_block() { setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, '1'); var block = new Blockly.Block(workspace, 'field_variable_test_block'); var event = new Blockly.Events.Abstract(block); - assertEquals('1', event.blockId); - assertEquals(workspace.id, event.workspaceId); - assertEquals('', event.group); - assertEquals(true, event.recordUndo); + assertUndefined(event.varId); + checkExactEventValues(event, {'blockId': '1', 'workspaceId': workspace.id, + 'group': '', 'recordUndo': true}); + eventTest_tearDownWithMockBlocks(); +} + +function test_abstract_constructor_variable() { + eventTest_setUpWithMockBlocks(); + setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, '1'); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.Abstract(variable); + assertUndefined(event.blockId); + checkExactEventValues(event, {'varId': 'id1', + 'workspaceId': workspace.id, 'group': '', 'recordUndo': true}); eventTest_tearDownWithMockBlocks(); } @@ -84,8 +94,7 @@ function test_abstract_constructor_null() { var event = new Blockly.Events.Abstract(null); assertUndefined(event.blockId); assertUndefined(event.workspaceId); - assertEquals('', event.group); - assertEquals(true, event.recordUndo); + checkExactEventValues(event, {'group': '', 'recordUndo': true}); eventTest_tearDownWithMockBlocks(); } @@ -105,13 +114,27 @@ function checkDeleteEventValues(event, block, ids, type) { assertEquals(type, event.type); } -function checkChangeAndMoveEventValues(event, values) { +function checkExactEventValues(event, values) { var keys = Object.keys(values); for (var i = 0, field; field = keys[i]; i++) { assertEquals(values[field], event[field]); } } +/** + * Check if a variable with the given values exists. + * @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. + */ +function eventTest_checkVariableValues(name, type, id) { + var variable = workspace.getVariableById(id); + assertNotUndefined(variable); + assertEquals(name, variable.name); + assertEquals(type, variable.type); + assertEquals(id, variable.getId()); +} + function test_create_constructor() { eventTest_setUpWithMockBlocks(); setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']); @@ -154,7 +177,7 @@ function test_change_constructor() { setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']); var block = new Blockly.Block(workspace, 'field_variable_test_block'); var event = new Blockly.Events.Change(block, 'field', 'VAR', 'item', 'item2'); - checkChangeAndMoveEventValues(event, {'element': 'field', 'name': 'VAR', + checkExactEventValues(event, {'element': 'field', 'name': 'VAR', 'oldValue': 'item', 'newValue': 'item2', 'type': 'change'}); eventTest_tearDownWithMockBlocks(); } @@ -165,7 +188,7 @@ function test_blockChange_constructor() { var block = new Blockly.Block(workspace, 'field_variable_test_block'); var event = new Blockly.Events.BlockChange(block, 'field', 'VAR', 'item', 'item2'); - checkChangeAndMoveEventValues(event, {'element': 'field', 'name': 'VAR', + checkExactEventValues(event, {'element': 'field', 'name': 'VAR', 'oldValue': 'item', 'newValue': 'item2', 'type': 'change'}); eventTest_tearDownWithMockBlocks(); } @@ -179,7 +202,7 @@ function test_move_constructorCoordinate() { block1.xy_ = coordinate; var event = new Blockly.Events.Move(block1); - checkChangeAndMoveEventValues(event, {'oldCoordinate': coordinate, + checkExactEventValues(event, {'oldCoordinate': coordinate, 'type': 'move'}); eventTest_tearDownWithMockBlocks(); } @@ -194,7 +217,7 @@ function test_move_constructoroldParentId() { block1.xy_ = new goog.math.Coordinate(3,4); var event = new Blockly.Events.Move(block1); - checkChangeAndMoveEventValues(event, {'oldCoordinate': undefined, + checkExactEventValues(event, {'oldCoordinate': undefined, 'oldParentId': '2', 'type': 'move'}); block1.parentBlock_ = null; eventTest_tearDownWithMockBlocks(); @@ -209,7 +232,7 @@ function test_blockMove_constructorCoordinate() { block1.xy_ = coordinate; var event = new Blockly.Events.BlockMove(block1); - checkChangeAndMoveEventValues(event, {'oldCoordinate': coordinate, + checkExactEventValues(event, {'oldCoordinate': coordinate, 'type': 'move'}); eventTest_tearDownWithMockBlocks(); } @@ -224,8 +247,169 @@ function test_blockMove_constructoroldParentId() { block1.xy_ = new goog.math.Coordinate(3,4); var event = new Blockly.Events.BlockMove(block1); - checkChangeAndMoveEventValues(event, {'oldCoordinate': undefined, + checkExactEventValues(event, {'oldCoordinate': undefined, 'oldParentId': '2', 'type': 'move'}); block1.parentBlock_ = null; eventTest_tearDownWithMockBlocks(); } + +function test_varCreate_constructor() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarCreate(variable); + checkExactEventValues(event, {'varName': 'name1', 'varType': 'type1', + 'type': 'var_create'}); + eventTest_tearDown(); +} + +function test_varCreate_toJson() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarCreate(variable); + var json = event.toJson(); + var expectedJson = ({type: "var_create", varId: "id1", varType: "type1", + varName: "name1"}); + + assertEquals(JSON.stringify(expectedJson), JSON.stringify(json)); + eventTest_tearDown(); +} + +function test_varCreate_fromJson() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarCreate(variable); + var event2 = new Blockly.Events.VarCreate(null); + var json = event.toJson(); + event2.fromJson(json); + + assertEquals(JSON.stringify(json), JSON.stringify(event2.toJson())); + eventTest_tearDown(); +} + +function test_varCreate_runForward() { + eventTest_setUp(); + var json = {type: "var_create", varId: "id1", varType: "type1", + varName: "name1"}; + var event = Blockly.Events.fromJson(json, workspace); + assertNull(workspace.getVariableById('id1')); + event.run(true); + eventTest_checkVariableValues('name1', 'type1', 'id1'); + eventTest_tearDown(); +} + +function test_varCreate_runBackwards() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarCreate(variable); + assertNotNull(workspace.getVariableById('id1')); + event.run(false); + assertNull(workspace.getVariableById('id1')); + eventTest_tearDown(); +} + +function test_varDelete_constructor() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarDelete(variable); + checkExactEventValues(event, {'varName': 'name1', 'varType': 'type1', + 'varId':'id1', 'type': 'var_delete'}); + eventTest_tearDown(); +} + +function test_varDelete_toJson() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarDelete(variable); + var json = event.toJson(); + var expectedJson = ({type: "var_delete", varId: "id1", varType: "type1", + varName: "name1"}); + + assertEquals(JSON.stringify(expectedJson), JSON.stringify(json)); + eventTest_tearDown(); +} + +function test_varDelete_fromJson() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarDelete(variable); + var event2 = new Blockly.Events.VarDelete(null); + var json = event.toJson(); + event2.fromJson(json); + + assertEquals(JSON.stringify(json), JSON.stringify(event2.toJson())); + eventTest_tearDown(); +} + +function test_varDelete_runForwards() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarDelete(variable); + assertNotNull(workspace.getVariableById('id1')); + event.run(true); + assertNull(workspace.getVariableById('id1')); + eventTest_tearDown(); +} + +function test_varDelete_runBackwards() { + eventTest_setUp(); + var json = {type: "var_delete", varId: "id1", varType: "type1", + varName: "name1"}; + var event = Blockly.Events.fromJson(json, workspace); + assertNull(workspace.getVariableById('id1')); + event.run(false); + eventTest_checkVariableValues('name1', 'type1', 'id1'); + eventTest_tearDown(); +} + +function test_varRename_constructor() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarRename(variable, 'name2'); + checkExactEventValues(event, {'varId': 'id1', 'oldName': 'name1', + 'newName': 'name2', 'type': 'var_rename'}); + eventTest_tearDown(); +} + +function test_varRename_toJson() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarRename(variable, 'name2'); + var json = event.toJson(); + var expectedJson = ({type: "var_rename", varId: "id1", oldName: "name1", + newName: "name2"}); + + assertEquals(JSON.stringify(expectedJson), JSON.stringify(json)); + eventTest_tearDown(); +} + +function test_varRename_fromJson() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarRename(variable, ''); + var event2 = new Blockly.Events.VarRename(null); + var json = event.toJson(); + event2.fromJson(json); + + assertEquals(JSON.stringify(json), JSON.stringify(event2.toJson())); + eventTest_tearDown(); +} + +function test_varRename_runForward() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarRename(variable, 'name2'); + event.run(true); + assertNull(workspace.getVariable('name1')); + eventTest_checkVariableValues('name2', 'type1', 'id1'); + eventTest_tearDown(); +} + +function test_varBackard_runForward() { + eventTest_setUp(); + var variable = workspace.createVariable('name1', 'type1', 'id1'); + var event = new Blockly.Events.VarRename(variable, 'name2'); + event.run(false); + assertNull(workspace.getVariable('name2')); + eventTest_checkVariableValues('name1', 'type1', 'id1'); + eventTest_tearDown(); +} diff --git a/tests/jsunit/variable_map_test.js b/tests/jsunit/variable_map_test.js index c40f19285..30cd9283a 100644 --- a/tests/jsunit/variable_map_test.js +++ b/tests/jsunit/variable_map_test.js @@ -24,13 +24,16 @@ goog.require('goog.testing.MockControl'); var variable_map; var mockControl_; +var workspace; function variableMapTest_setUp() { - variable_map = new Blockly.VariableMap(); + workspace = new Blockly.Workspace(); + variable_map = new Blockly.VariableMap(workspace); mockControl_ = new goog.testing.MockControl(); } function variableMapTest_tearDown() { + workspace.dispose(); mockControl_.$tearDown(); variable_map = null; } @@ -133,7 +136,7 @@ function test_createVariableNullAndUndefinedType() { function test_createVariableNullId() { variableMapTest_setUp(); - setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']); + setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']); try { variable_map.createVariable('name1', 'type1', null); variableMapTest_checkVariableValues('name1', 'type1', '1'); @@ -145,7 +148,7 @@ function test_createVariableNullId() { function test_createVariableUndefinedId() { variableMapTest_setUp(); - setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']); + setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']); try { variable_map.createVariable('name1', 'type1', undefined); variableMapTest_checkVariableValues('name1', 'type1', '1'); diff --git a/tests/jsunit/variable_model_test.js b/tests/jsunit/variable_model_test.js index e1245233e..3f22f287a 100644 --- a/tests/jsunit/variable_model_test.js +++ b/tests/jsunit/variable_model_test.js @@ -25,8 +25,14 @@ 'use strict'; var variable; +var workspace; -function variableTest_tearDown() { +function variableModelTest_setUp() { + workspace = new Blockly.Workspace(); +} + +function variableModelTest_tearDown() { + workspace.dispose(); variable = null; } @@ -34,45 +40,52 @@ function variableTest_tearDown() { * These tests check the constructor of the variable model. */ function testInit_Trivial() { - variable = new Blockly.VariableModel('test', 'test_type', 'test_id'); + variableModelTest_setUp(); + variable = new Blockly.VariableModel(workspace, 'test', 'test_type', + 'test_id'); assertEquals('test', variable.name); assertEquals('test_type', variable.type); assertEquals('test_id', variable.id_); - variableTest_tearDown(); + variableModelTest_tearDown(); } function testInit_NullType() { - variable = new Blockly.VariableModel('test', null, 'test_id'); + variableModelTest_setUp(); + variable = new Blockly.VariableModel(workspace, 'test', null, 'test_id'); assertEquals('', variable.type); - variableTest_tearDown(); + variableModelTest_tearDown(); } function testInit_UndefinedType() { - variable = new Blockly.VariableModel('test', undefined, 'test_id'); + variableModelTest_setUp(); + variable = new Blockly.VariableModel(workspace, 'test', undefined, 'test_id'); assertEquals('', variable.type); - variableTest_tearDown(); + variableModelTest_tearDown(); } function testInit_NullId() { - variable = new Blockly.VariableModel('test', 'test_type', null); + variableModelTest_setUp(); + variable = new Blockly.VariableModel(workspace, 'test', 'test_type', null); assertEquals('test', variable.name); assertEquals('test_type', variable.type); assertNotNull(variable.id_); - variableTest_tearDown(); + variableModelTest_tearDown(); } function testInit_UndefinedId() { - variable = new Blockly.VariableModel('test', 'test_type', undefined); + variableModelTest_setUp(); + variable = new Blockly.VariableModel(workspace, 'test', 'test_type', undefined); assertEquals('test', variable.name); assertEquals('test_type', variable.type); assertNotNull(variable.id_); - variableTest_tearDown(); + variableModelTest_tearDown(); } function testInit_OnlyNameProvided() { - variable = new Blockly.VariableModel('test'); + variableModelTest_setUp(); + variable = new Blockly.VariableModel(workspace, 'test'); assertEquals('test', variable.name); assertEquals('', variable.type); assertNotNull(variable.id_); - variableTest_tearDown(); + variableModelTest_tearDown(); }