mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
Merge 06-22
This commit is contained in:
parent
bec631512e
commit
fce962c0fc
31 changed files with 1553 additions and 364 deletions
|
@ -182,7 +182,7 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
|
|||
/** @type {boolean|undefined} */
|
||||
this.inputsInlineDefault = this.inputsInline;
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Create(this));
|
||||
Blockly.Events.fire(new Blockly.Events.BlockCreate(this));
|
||||
}
|
||||
// Bind an onchange function, if it exists.
|
||||
if (goog.isFunction(this.onchange)) {
|
||||
|
@ -235,7 +235,7 @@ Blockly.Block.prototype.dispose = function(healStack) {
|
|||
}
|
||||
this.unplug(healStack);
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Delete(this));
|
||||
Blockly.Events.fire(new Blockly.Events.BlockDelete(this));
|
||||
}
|
||||
Blockly.Events.disable();
|
||||
|
||||
|
@ -957,7 +957,7 @@ Blockly.Block.prototype.setOutput = function(newBoolean, opt_check) {
|
|||
*/
|
||||
Blockly.Block.prototype.setInputsInline = function(newBoolean) {
|
||||
if (this.inputsInline != newBoolean) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this, 'inline', null, this.inputsInline, newBoolean));
|
||||
this.inputsInline = newBoolean;
|
||||
}
|
||||
|
@ -996,7 +996,7 @@ Blockly.Block.prototype.getInputsInline = function() {
|
|||
*/
|
||||
Blockly.Block.prototype.setDisabled = function(disabled) {
|
||||
if (this.disabled != disabled) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this, 'disabled', null, this.disabled, disabled));
|
||||
this.disabled = disabled;
|
||||
}
|
||||
|
@ -1033,7 +1033,7 @@ Blockly.Block.prototype.isCollapsed = function() {
|
|||
*/
|
||||
Blockly.Block.prototype.setCollapsed = function(collapsed) {
|
||||
if (this.collapsed_ != collapsed) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this, 'collapsed', null, this.collapsed_, collapsed));
|
||||
this.collapsed_ = collapsed;
|
||||
}
|
||||
|
@ -1629,7 +1629,7 @@ Blockly.Block.prototype.getCommentText = function() {
|
|||
*/
|
||||
Blockly.Block.prototype.setCommentText = function(text) {
|
||||
if (this.comment != text) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this, 'comment', null, this.comment, text || ''));
|
||||
this.comment = text;
|
||||
}
|
||||
|
@ -1719,7 +1719,7 @@ Blockly.Block.prototype.getRelativeToSurfaceXY = function() {
|
|||
*/
|
||||
Blockly.Block.prototype.moveBy = function(dx, dy) {
|
||||
goog.asserts.assert(!this.parentBlock_, 'Block has parent.');
|
||||
var event = new Blockly.Events.Move(this);
|
||||
var event = new Blockly.Events.BlockMove(this);
|
||||
this.xy_.translate(dx, dy);
|
||||
event.recordNew();
|
||||
Blockly.Events.fire(event);
|
||||
|
|
|
@ -234,7 +234,7 @@ Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
|
|||
* @private
|
||||
*/
|
||||
Blockly.BlockDragger.prototype.fireMoveEvent_ = function() {
|
||||
var event = new Blockly.Events.Move(this.draggingBlock_);
|
||||
var event = new Blockly.Events.BlockMove(this.draggingBlock_);
|
||||
event.oldCoordinate = this.startXY_;
|
||||
event.recordNew();
|
||||
Blockly.Events.fire(event);
|
||||
|
|
|
@ -379,7 +379,7 @@ Blockly.BlockSvg.prototype.moveBy = function(dx, dy) {
|
|||
goog.asserts.assert(!this.parentBlock_, 'Block has parent.');
|
||||
var eventsEnabled = Blockly.Events.isEnabled();
|
||||
if (eventsEnabled) {
|
||||
var event = new Blockly.Events.Move(this);
|
||||
var event = new Blockly.Events.BlockMove(this);
|
||||
}
|
||||
var xy = this.getRelativeToSurfaceXY();
|
||||
this.translate(xy.x + dx, xy.y + dy);
|
||||
|
|
|
@ -121,7 +121,7 @@ Blockly.Comment.prototype.createEditor_ = function() {
|
|||
});
|
||||
Blockly.bindEventWithChecks_(textarea, 'change', this, function(/* e */) {
|
||||
if (this.text_ != textarea.value) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.block_, 'comment', null, this.text_, textarea.value));
|
||||
this.text_ = textarea.value;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ Blockly.Comment.prototype.getText = function() {
|
|||
*/
|
||||
Blockly.Comment.prototype.setText = function(text) {
|
||||
if (this.text_ != text) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.block_, 'comment', null, this.text_, text));
|
||||
this.text_ = text;
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ Blockly.Connection.prototype.connect_ = function(childConnection) {
|
|||
|
||||
var event;
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
event = new Blockly.Events.Move(childBlock);
|
||||
event = new Blockly.Events.BlockMove(childBlock);
|
||||
}
|
||||
// Establish the connections.
|
||||
Blockly.Connection.connectReciprocally_(parentConnection, childConnection);
|
||||
|
@ -561,7 +561,7 @@ Blockly.Connection.prototype.disconnectInternal_ = function(parentBlock,
|
|||
childBlock) {
|
||||
var event;
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
event = new Blockly.Events.Move(childBlock);
|
||||
event = new Blockly.Events.BlockMove(childBlock);
|
||||
}
|
||||
var otherConnection = this.targetConnection;
|
||||
otherConnection.targetConnection = null;
|
||||
|
|
|
@ -184,7 +184,7 @@ Blockly.ContextMenu.callbackFactory = function(block, xml) {
|
|||
Blockly.Events.enable();
|
||||
}
|
||||
if (Blockly.Events.isEnabled() && !newBlock.isShadow()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Create(newBlock));
|
||||
Blockly.Events.fire(new Blockly.Events.BlockCreate(newBlock));
|
||||
}
|
||||
newBlock.select();
|
||||
};
|
||||
|
|
309
core/events.js
309
core/events.js
|
@ -55,29 +55,71 @@ Blockly.Events.recordUndo = true;
|
|||
Blockly.Events.disabled_ = 0;
|
||||
|
||||
/**
|
||||
* Name of event that creates a block.
|
||||
* Name of event that creates a block. Will be deprecated for BLOCK_CREATE.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.CREATE = 'create';
|
||||
|
||||
/**
|
||||
* Name of event that deletes a block.
|
||||
* Name of event that creates a block.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.BLOCK_CREATE = Blockly.Events.CREATE;
|
||||
|
||||
/**
|
||||
* Name of event that deletes a block. Will be deprecated for BLOCK_DELETE.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.DELETE = 'delete';
|
||||
|
||||
/**
|
||||
* Name of event that changes a block.
|
||||
* Name of event that deletes a block.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.BLOCK_DELETE = Blockly.Events.DELETE;
|
||||
|
||||
/**
|
||||
* Name of event that changes a block. Will be deprecated for BLOCK_CHANGE.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.CHANGE = 'change';
|
||||
|
||||
/**
|
||||
* Name of event that moves a block.
|
||||
* Name of event that changes a block.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.BLOCK_CHANGE = Blockly.Events.CHANGE;
|
||||
|
||||
/**
|
||||
* Name of event that moves a block. Will be deprecated for BLOCK_MOVE.
|
||||
* @const
|
||||
*/
|
||||
Blockly.Events.MOVE = 'move';
|
||||
|
||||
/**
|
||||
* Name of event that moves a block.
|
||||
* @const
|
||||
*/
|
||||
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
|
||||
|
@ -276,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;
|
||||
|
@ -289,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;
|
||||
|
@ -312,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;
|
||||
}
|
||||
|
@ -324,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'];
|
||||
};
|
||||
|
||||
|
@ -344,6 +403,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.
|
||||
|
@ -365,6 +439,14 @@ Blockly.Events.Create = function(block) {
|
|||
};
|
||||
goog.inherits(Blockly.Events.Create, Blockly.Events.Abstract);
|
||||
|
||||
/**
|
||||
* Class for a block creation event.
|
||||
* @param {Blockly.Block} block The created block. Null for a blank event.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.BlockCreate = Blockly.Events.Create;
|
||||
|
||||
/**
|
||||
* Type of this event.
|
||||
* @type {string}
|
||||
|
@ -397,7 +479,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);
|
||||
|
@ -439,6 +521,14 @@ Blockly.Events.Delete = function(block) {
|
|||
};
|
||||
goog.inherits(Blockly.Events.Delete, Blockly.Events.Abstract);
|
||||
|
||||
/**
|
||||
* Class for a block deletion event.
|
||||
* @param {Blockly.Block} block The deleted block. Null for a blank event.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.BlockDelete = Blockly.Events.Delete;
|
||||
|
||||
/**
|
||||
* Type of this event.
|
||||
* @type {string}
|
||||
|
@ -469,7 +559,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);
|
||||
|
@ -509,6 +599,18 @@ Blockly.Events.Change = function(block, element, name, oldValue, newValue) {
|
|||
};
|
||||
goog.inherits(Blockly.Events.Change, Blockly.Events.Abstract);
|
||||
|
||||
/**
|
||||
* Class for a block change event.
|
||||
* @param {Blockly.Block} block The changed block. Null for a blank event.
|
||||
* @param {string} element One of 'field', 'comment', 'disabled', etc.
|
||||
* @param {?string} name Name of input or field affected, or null.
|
||||
* @param {string} oldValue Previous value of element.
|
||||
* @param {string} newValue New value of element.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.BlockChange = Blockly.Events.Change;
|
||||
|
||||
/**
|
||||
* Type of this event.
|
||||
* @type {string}
|
||||
|
@ -553,7 +655,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);
|
||||
|
@ -625,6 +727,15 @@ Blockly.Events.Move = function(block) {
|
|||
};
|
||||
goog.inherits(Blockly.Events.Move, Blockly.Events.Abstract);
|
||||
|
||||
|
||||
/**
|
||||
* Class for a block move event. Created before the move.
|
||||
* @param {Blockly.Block} block The moved block. Null for a blank event.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.BlockMove = Blockly.Events.Move;
|
||||
|
||||
/**
|
||||
* Type of this event.
|
||||
* @type {string}
|
||||
|
@ -713,7 +824,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);
|
||||
|
@ -802,6 +913,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.
|
||||
|
|
|
@ -399,8 +399,6 @@ Blockly.Field.prototype.render_ = function() {
|
|||
**/
|
||||
Blockly.Field.prototype.updateWidth = function() {
|
||||
var width = Blockly.Field.getCachedWidth(this.textElement_);
|
||||
// Calculate width of field
|
||||
width = Blockly.Field.getCachedWidth(this.textElement_);
|
||||
|
||||
// Add padding to left and right of text.
|
||||
if (this.EDITABLE) {
|
||||
|
@ -623,7 +621,7 @@ Blockly.Field.prototype.setValue = function(newValue) {
|
|||
return;
|
||||
}
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, oldValue, newValue));
|
||||
}
|
||||
this.setText(newValue);
|
||||
|
|
|
@ -94,7 +94,7 @@ Blockly.FieldCheckbox.prototype.setValue = function(newBool) {
|
|||
(newBool.toUpperCase() == 'TRUE') : !!newBool;
|
||||
if (this.state_ !== newState) {
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.state_, newState));
|
||||
}
|
||||
this.state_ = newState;
|
||||
|
|
|
@ -101,7 +101,7 @@ Blockly.FieldColour.prototype.getValue = function() {
|
|||
Blockly.FieldColour.prototype.setValue = function(colour) {
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled() &&
|
||||
this.colour_ != colour) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.colour_, colour));
|
||||
}
|
||||
this.colour_ = colour;
|
||||
|
|
|
@ -388,7 +388,7 @@ Blockly.FieldDropdown.prototype.setValue = function(newValue) {
|
|||
return; // No change if null.
|
||||
}
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.value_, newValue));
|
||||
}
|
||||
// Clear menu item for old value.
|
||||
|
|
|
@ -144,7 +144,7 @@ Blockly.FieldTextInput.prototype.setText = function(newText) {
|
|||
return;
|
||||
}
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.text_, newText));
|
||||
}
|
||||
Blockly.Field.prototype.setText.call(this, newText);
|
||||
|
|
|
@ -107,9 +107,24 @@ Blockly.FieldVariable.prototype.getValue = function() {
|
|||
*/
|
||||
Blockly.FieldVariable.prototype.setValue = function(newValue) {
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.value_, newValue));
|
||||
}
|
||||
if (this.sourceBlock_) {
|
||||
var variable = this.sourceBlock_.workspace.getVariableById(newValue);
|
||||
if (variable) {
|
||||
this.setText(variable.name);
|
||||
this.value_ = newValue;
|
||||
return;
|
||||
}
|
||||
// TODO(marisaleung): Remove name lookup after converting all Field Variable
|
||||
// instances to use id instead of name.
|
||||
else if (variable = this.sourceBlock_.workspace.getVariable(newValue)) {
|
||||
this.setText(newValue);
|
||||
this.value_ = variable.getId();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.value_ = newValue;
|
||||
this.setText(newValue);
|
||||
};
|
||||
|
|
|
@ -19,9 +19,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Base class for a file tray containing blocks that may be
|
||||
* dragged into the workspace. Defines basic interactions that are shared
|
||||
* between vertical and horizontal flyouts.
|
||||
* @fileoverview Flyout tray containing blocks which may be created.
|
||||
* @author fraser@google.com (Neil Fraser)
|
||||
*/
|
||||
'use strict';
|
||||
|
@ -278,6 +276,13 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) {
|
|||
// A flyout connected to a workspace doesn't have its own current gesture.
|
||||
this.workspace_.getGesture =
|
||||
this.targetWorkspace_.getGesture.bind(this.targetWorkspace_);
|
||||
|
||||
// Get variables from the main workspace rather than the target workspace.
|
||||
this.workspace_.getVariable =
|
||||
this.targetWorkspace_.getVariable.bind(this.targetWorkspace_);
|
||||
|
||||
this.workspace_.getVariableById =
|
||||
this.targetWorkspace_.getVariableById.bind(this.targetWorkspace_);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -529,7 +534,7 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
|
|||
|
||||
/**
|
||||
* Add listeners to a block that has been added to the flyout.
|
||||
* @param {Element} root The root node of the SVG group the block is in.
|
||||
* @param {!Element} root The root node of the SVG group the block is in.
|
||||
* @param {!Blockly.Block} block The block to add listeners for.
|
||||
* @param {!Element} rect The invisible rectangle under the block that acts as
|
||||
* a button for that block.
|
||||
|
@ -631,7 +636,6 @@ Blockly.Flyout.prototype.reflow = function() {
|
|||
this.workspace_.removeChangeListener(this.reflowWrapper_);
|
||||
}
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
|
||||
this.reflowInternal_(blocks);
|
||||
if (this.reflowWrapper_) {
|
||||
this.workspace_.addChangeListener(this.reflowWrapper_);
|
||||
|
|
|
@ -325,7 +325,7 @@ Blockly.Mutator.prototype.workspaceChanged_ = function() {
|
|||
var newMutationDom = block.mutationToDom();
|
||||
var newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
|
||||
if (oldMutation != newMutation) {
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
block, 'mutation', null, oldMutation, newMutation));
|
||||
// Ensure that any bump is part of this mutation's event group.
|
||||
var group = Blockly.Events.getGroup();
|
||||
|
|
|
@ -278,7 +278,7 @@ Blockly.Procedures.mutateCallers = function(defBlock) {
|
|||
// undo action since it is deterministically tied to the procedure's
|
||||
// definition mutation.
|
||||
Blockly.Events.recordUndo = false;
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
caller, 'mutation', null, oldMutation, newMutation));
|
||||
Blockly.Events.recordUndo = oldRecordUndo;
|
||||
}
|
||||
|
|
|
@ -32,10 +32,11 @@ goog.require('Blockly.VariableModel');
|
|||
* 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<string, !Array.<Blockly.VariableModel>>}
|
||||
* A map from variable type to list of variable names. The lists contain all
|
||||
* of the named variables in the workspace, including variables
|
||||
|
@ -43,6 +44,12 @@ Blockly.VariableMap = function() {
|
|||
* @private
|
||||
*/
|
||||
this.variableMap_ = {};
|
||||
|
||||
/**
|
||||
* The workspace this map belongs to.
|
||||
* @type {!Blockly.Workspace}
|
||||
*/
|
||||
this.workspace = workspace;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -54,7 +61,6 @@ Blockly.VariableMap.prototype.clear = function() {
|
|||
|
||||
/**
|
||||
* Rename the given variable by updating its name in the variable map.
|
||||
* TODO: #468
|
||||
* @param {?Blockly.VariableModel} variable Variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
*/
|
||||
|
@ -81,11 +87,19 @@ Blockly.VariableMap.prototype.renameVariable = function(variable, newName) {
|
|||
} else if (variableIndex == newVariableIndex ||
|
||||
variableIndex != -1 && newVariableIndex == -1) {
|
||||
// Only changing case, or renaming to a completely novel name.
|
||||
this.variableMap_[type][variableIndex].name = newName;
|
||||
var variableToRename = this.variableMap_[type][variableIndex];
|
||||
Blockly.Events.fire(new Blockly.Events.VarRename(variableToRename,
|
||||
newName));
|
||||
variableToRename.name = newName;
|
||||
} else if (variableIndex != -1 && newVariableIndex != -1) {
|
||||
// Renaming one existing variable to another existing variable.
|
||||
// The case might have changed, so we update the destination ID.
|
||||
this.variableMap_[type][newVariableIndex].name = newName;
|
||||
var variableToRename = this.variableMap_[type][newVariableIndex];
|
||||
Blockly.Events.fire(new Blockly.Events.VarRename(variableToRename,
|
||||
newName));
|
||||
var variableToDelete = this.variableMap_[type][variableIndex];
|
||||
Blockly.Events.fire(new Blockly.Events.VarDelete(variableToDelete));
|
||||
variableToRename.name = newName;
|
||||
this.variableMap_[type].splice(variableIndex, 1);
|
||||
}
|
||||
};
|
||||
|
@ -123,7 +137,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];
|
||||
|
@ -143,6 +157,7 @@ Blockly.VariableMap.prototype.deleteVariable = function(variable) {
|
|||
for (var i = 0, tempVar; tempVar = variableList[i]; i++) {
|
||||
if (tempVar.getId() == variable.getId()) {
|
||||
variableList.splice(i, 1);
|
||||
Blockly.Events.fire(new Blockly.Events.VarDelete(variable));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -68,6 +75,8 @@ Blockly.VariableModel = function(name, opt_type, opt_id) {
|
|||
* @private
|
||||
*/
|
||||
this.id_ = opt_id || Blockly.utils.genUid();
|
||||
|
||||
Blockly.Events.fire(new Blockly.Events.VarCreate(this));
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -89,7 +89,7 @@ Blockly.Workspace = function(opt_options) {
|
|||
* that are not currently in use.
|
||||
* @private
|
||||
*/
|
||||
this.variableMap_ = new Blockly.VariableMap();
|
||||
this.variableMap_ = new Blockly.VariableMap(this);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -251,7 +251,6 @@ Blockly.Workspace.prototype.updateVariableStore = function(clear) {
|
|||
/**
|
||||
* Rename a variable by updating its name in the variable map. Identify the
|
||||
* variable to rename with the given variable.
|
||||
* TODO: #468
|
||||
* @param {?Blockly.VariableModel} variable Variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
*/
|
||||
|
@ -280,16 +279,14 @@ Blockly.Workspace.prototype.renameVariableInternal_ = function(variable, newName
|
|||
blocks[i].renameVar(oldCase, newName);
|
||||
}
|
||||
}
|
||||
Blockly.Events.setGroup(false);
|
||||
|
||||
this.variableMap_.renameVariable(variable, newName);
|
||||
Blockly.Events.setGroup(false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rename a variable by updating its name in the variable map. Identify the
|
||||
* variable to rename with the given name.
|
||||
* TODO: #468
|
||||
* @param {string} oldName Variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
*/
|
||||
|
@ -299,6 +296,7 @@ Blockly.Workspace.prototype.renameVariable = function(oldName, newName) {
|
|||
this.renameVariableInternal_(variable, newName);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rename a variable by updating its name in the variable map. Identify the
|
||||
* variable to rename with the given id.
|
||||
|
@ -343,7 +341,7 @@ Blockly.Workspace.prototype.getVariableUses = function(name) {
|
|||
for (var j = 0; j < blockVariables.length; j++) {
|
||||
var varName = blockVariables[j];
|
||||
// Variable name may be null if the block is only half-built.
|
||||
if (varName && Blockly.Names.equals(varName, name)) {
|
||||
if (varName && name && Blockly.Names.equals(varName, name)) {
|
||||
uses.push(blocks[i]);
|
||||
}
|
||||
}
|
||||
|
@ -399,6 +397,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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -414,9 +414,8 @@ Blockly.Workspace.prototype.deleteVariableInternal_ = function(variable) {
|
|||
for (var i = 0; i < uses.length; i++) {
|
||||
uses[i].dispose(true, false);
|
||||
}
|
||||
Blockly.Events.setGroup(false);
|
||||
|
||||
this.variableMap_.deleteVariable(variable);
|
||||
Blockly.Events.setGroup(false);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -498,10 +497,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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -972,7 +972,7 @@ Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) {
|
|||
Blockly.Events.enable();
|
||||
}
|
||||
if (Blockly.Events.isEnabled() && !block.isShadow()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Create(block));
|
||||
Blockly.Events.fire(new Blockly.Events.BlockCreate(block));
|
||||
}
|
||||
block.select();
|
||||
};
|
||||
|
@ -1036,7 +1036,6 @@ Blockly.WorkspaceSvg.prototype.deleteVariableById = function(id) {
|
|||
/**
|
||||
* Create a new variable with the given name. Update the flyout to show the new
|
||||
* variable immediately.
|
||||
* TODO: #468
|
||||
* @param {string} name The new variable's name.
|
||||
* @param {string=} opt_type The type of the variable like 'int' or 'string'.
|
||||
* Does not need to be unique. Field_variable can filter variables based on
|
||||
|
|
69
core/xml.js
69
core/xml.js
|
@ -333,38 +333,46 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
|||
if (workspace.setResizesEnabled) {
|
||||
workspace.setResizesEnabled(false);
|
||||
}
|
||||
for (var i = 0; i < childCount; i++) {
|
||||
var xmlChild = xml.childNodes[i];
|
||||
var name = xmlChild.nodeName.toLowerCase();
|
||||
if (name == 'block' ||
|
||||
(name == 'shadow' && !Blockly.Events.recordUndo)) {
|
||||
// Allow top-level shadow blocks if recordUndo is disabled since
|
||||
// that means an undo is in progress. Such a block is expected
|
||||
// to be moved to a nested destination in the next operation.
|
||||
var block = Blockly.Xml.domToBlock(xmlChild, workspace);
|
||||
newBlockIds.push(block.id);
|
||||
var blockX = parseInt(xmlChild.getAttribute('x'), 10);
|
||||
var blockY = parseInt(xmlChild.getAttribute('y'), 10);
|
||||
if (!isNaN(blockX) && !isNaN(blockY)) {
|
||||
block.moveBy(workspace.RTL ? width - blockX : blockX, blockY);
|
||||
}
|
||||
} else if (name == 'shadow') {
|
||||
goog.asserts.fail('Shadow block cannot be a top-level block.');
|
||||
} else if (name == 'variables') {
|
||||
if (i == 1) {
|
||||
Blockly.Xml.domToVariables(xmlChild, workspace);
|
||||
}
|
||||
else {
|
||||
throw Error('\'variables\' tag must be the first element in the' +
|
||||
'workspace XML, but it was found in another location.');
|
||||
var variablesFirst = true;
|
||||
try {
|
||||
for (var i = 0; i < childCount; i++) {
|
||||
var xmlChild = xml.childNodes[i];
|
||||
var name = xmlChild.nodeName.toLowerCase();
|
||||
if (name == 'block' ||
|
||||
(name == 'shadow' && !Blockly.Events.recordUndo)) {
|
||||
// Allow top-level shadow blocks if recordUndo is disabled since
|
||||
// that means an undo is in progress. Such a block is expected
|
||||
// to be moved to a nested destination in the next operation.
|
||||
var block = Blockly.Xml.domToBlock(xmlChild, workspace);
|
||||
newBlockIds.push(block.id);
|
||||
var blockX = parseInt(xmlChild.getAttribute('x'), 10);
|
||||
var blockY = parseInt(xmlChild.getAttribute('y'), 10);
|
||||
if (!isNaN(blockX) && !isNaN(blockY)) {
|
||||
block.moveBy(workspace.RTL ? width - blockX : blockX, blockY);
|
||||
}
|
||||
variablesFirst = false;
|
||||
} else if (name == 'shadow') {
|
||||
goog.asserts.fail('Shadow block cannot be a top-level block.');
|
||||
variablesFirst = false;
|
||||
} else if (name == 'variables') {
|
||||
if (variablesFirst) {
|
||||
Blockly.Xml.domToVariables(xmlChild, workspace);
|
||||
}
|
||||
else {
|
||||
throw Error('\'variables\' tag must exist once before block and ' +
|
||||
'shadow tag elements in the workspace XML, but it was found in ' +
|
||||
'another location.');
|
||||
}
|
||||
variablesFirst = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!existingGroup) {
|
||||
Blockly.Events.setGroup(false);
|
||||
finally {
|
||||
if (!existingGroup) {
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
Blockly.Field.stopCache();
|
||||
}
|
||||
Blockly.Field.stopCache();
|
||||
|
||||
workspace.updateVariableStore(false);
|
||||
// Re-enable workspace resizing.
|
||||
if (workspace.setResizesEnabled) {
|
||||
|
@ -491,7 +499,7 @@ Blockly.Xml.domToBlock = function(xmlBlock, workspace) {
|
|||
Blockly.Events.enable();
|
||||
}
|
||||
if (Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.Create(topBlock));
|
||||
Blockly.Events.fire(new Blockly.Events.BlockCreate(topBlock));
|
||||
}
|
||||
return topBlock;
|
||||
};
|
||||
|
@ -701,6 +709,9 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
|||
goog.asserts.assert(child.isShadow(),
|
||||
'Shadow block not allowed non-shadow child.');
|
||||
}
|
||||
// Ensure this block doesn't have any variable inputs.
|
||||
goog.asserts.assert(block.getVars().length == 0,
|
||||
'Shadow blocks cannot have variable fields.');
|
||||
block.setShadow(true);
|
||||
}
|
||||
return block;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"@metadata": {
|
||||
"author": "Ellen Spertus <ellen.spertus@gmail.com>",
|
||||
"lastupdated": "2017-05-25 07:58:37.810709",
|
||||
"lastupdated": "2017-06-22 11:21:38.108160",
|
||||
"locale": "en",
|
||||
"messagedocumentation" : "qqq"
|
||||
},
|
||||
|
|
394
tests/jsunit/event_test.js
Normal file
394
tests/jsunit/event_test.js
Normal file
|
@ -0,0 +1,394 @@
|
|||
/**
|
||||
* @license
|
||||
* Visual Blocks Editor
|
||||
*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Tests for Blockly.Events
|
||||
* @author marisaleung@google.com (Marisa Leung)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.require('goog.testing');
|
||||
goog.require('goog.testing.MockControl');
|
||||
|
||||
var mockControl_;
|
||||
var workspace;
|
||||
|
||||
function eventTest_setUp() {
|
||||
workspace = new Blockly.Workspace();
|
||||
mockControl_ = new goog.testing.MockControl();
|
||||
}
|
||||
|
||||
function eventTest_setUpWithMockBlocks() {
|
||||
eventTest_setUp();
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
'type': 'field_variable_test_block',
|
||||
'message0': '%1',
|
||||
'args0': [
|
||||
{
|
||||
'type': 'field_variable',
|
||||
'name': 'VAR',
|
||||
'variable': 'item'
|
||||
}
|
||||
],
|
||||
}]);
|
||||
}
|
||||
|
||||
function eventTest_tearDown() {
|
||||
mockControl_.$tearDown();
|
||||
workspace.dispose();
|
||||
}
|
||||
|
||||
function eventTest_tearDownWithMockBlocks() {
|
||||
eventTest_tearDown();
|
||||
delete Blockly.Blocks.field_variable_test_block;
|
||||
}
|
||||
|
||||
function test_abstract_constructor_block() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, '1');
|
||||
var block = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var event = new Blockly.Events.Abstract(block);
|
||||
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();
|
||||
}
|
||||
|
||||
function test_abstract_constructor_null() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
var event = new Blockly.Events.Abstract(null);
|
||||
assertUndefined(event.blockId);
|
||||
assertUndefined(event.workspaceId);
|
||||
checkExactEventValues(event, {'group': '', 'recordUndo': true});
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function checkCreateEventValues(event, block, ids, type) {
|
||||
var expected_xml = Blockly.Xml.domToText(Blockly.Xml.blockToDom(block));
|
||||
var result_xml = Blockly.Xml.domToText(event.xml);
|
||||
assertEquals(expected_xml, result_xml);
|
||||
isEqualArrays(ids, event.ids);
|
||||
assertEquals(type, event.type);
|
||||
}
|
||||
|
||||
function checkDeleteEventValues(event, block, ids, type) {
|
||||
var expected_xml = Blockly.Xml.domToText(Blockly.Xml.blockToDom(block));
|
||||
var result_xml = Blockly.Xml.domToText(event.oldXml);
|
||||
assertEquals(expected_xml, result_xml);
|
||||
isEqualArrays(ids, event.ids);
|
||||
assertEquals(type, event.type);
|
||||
}
|
||||
|
||||
function checkExactEventValues(event, values) {
|
||||
var keys = Object.keys(values);
|
||||
for (var i = 0, field; field = keys[i]; i++) {
|
||||
assertEquals(values[field], event[field]);
|
||||
}
|
||||
}
|
||||
|
||||
function test_create_constructor() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
var block = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var event = new Blockly.Events.Create(block);
|
||||
checkCreateEventValues(event, block, ['1'], 'create');
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockCreate_constructor() {
|
||||
// expect that blockCreate behaves the same as create.
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
var block = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var event = new Blockly.Events.BlockCreate(block);
|
||||
checkCreateEventValues(event, block, ['1'], 'create');
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_delete_constructor() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
var block = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var event = new Blockly.Events.Delete(block);
|
||||
checkDeleteEventValues(event, block, ['1'], 'delete');
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockDelete_constructor() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
var block = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var event = new Blockly.Events.BlockDelete(block);
|
||||
checkDeleteEventValues(event, block, ['1'], 'delete');
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_change_constructor() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
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');
|
||||
checkExactEventValues(event, {'element': 'field', 'name': 'VAR',
|
||||
'oldValue': 'item', 'newValue': 'item2', 'type': 'change'});
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockChange_constructor() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
var block = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var event = new Blockly.Events.BlockChange(block, 'field', 'VAR', 'item',
|
||||
'item2');
|
||||
checkExactEventValues(event, {'element': 'field', 'name': 'VAR',
|
||||
'oldValue': 'item', 'newValue': 'item2', 'type': 'change'});
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_move_constructorCoordinate() {
|
||||
// Expect the oldCoordinate to be set.
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
|
||||
var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var coordinate = new goog.math.Coordinate(3,4);
|
||||
block1.xy_ = coordinate;
|
||||
|
||||
var event = new Blockly.Events.Move(block1);
|
||||
checkExactEventValues(event, {'oldCoordinate': coordinate,
|
||||
'type': 'move'});
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_move_constructoroldParentId() {
|
||||
// Expect the oldParentId to be set but not the oldCoordinate to be set.
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
|
||||
var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var block2 = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
block1.parentBlock_ = block2;
|
||||
block1.xy_ = new goog.math.Coordinate(3,4);
|
||||
|
||||
var event = new Blockly.Events.Move(block1);
|
||||
checkExactEventValues(event, {'oldCoordinate': undefined,
|
||||
'oldParentId': '2', 'type': 'move'});
|
||||
block1.parentBlock_ = null;
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockMove_constructorCoordinate() {
|
||||
// Expect the oldCoordinate to be set.
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
|
||||
var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var coordinate = new goog.math.Coordinate(3,4);
|
||||
block1.xy_ = coordinate;
|
||||
|
||||
var event = new Blockly.Events.BlockMove(block1);
|
||||
checkExactEventValues(event, {'oldCoordinate': coordinate,
|
||||
'type': 'move'});
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockMove_constructoroldParentId() {
|
||||
// Expect the oldParentId to be set but not the oldCoordinate to be set.
|
||||
eventTest_setUpWithMockBlocks();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
|
||||
var block1 = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
var block2 = new Blockly.Block(workspace, 'field_variable_test_block');
|
||||
block1.parentBlock_ = block2;
|
||||
block1.xy_ = new goog.math.Coordinate(3,4);
|
||||
|
||||
var event = new Blockly.Events.BlockMove(block1);
|
||||
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);
|
||||
checkVariableValues(workspace, '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);
|
||||
checkVariableValues(workspace, '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'));
|
||||
checkVariableValues(workspace, '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'));
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
eventTest_tearDown();
|
||||
}
|
79
tests/jsunit/field_variable_test.js
Normal file
79
tests/jsunit/field_variable_test.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @license
|
||||
* Visual Blocks Editor
|
||||
*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Tests for Blockly.FieldVariable
|
||||
* @author marisaleung@google.com (Marisa Leung)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.require('goog.testing');
|
||||
|
||||
|
||||
function fieldVariable_mockBlock(workspace) {
|
||||
return {'workspace': workspace, 'isShadow': function(){return false;}};
|
||||
}
|
||||
|
||||
function test_fieldVariable_Constructor() {
|
||||
var workspace = new Blockly.Workspace();
|
||||
var fieldVariable = new Blockly.FieldVariable('name1');
|
||||
assertEquals('name1', fieldVariable.getText());
|
||||
workspace.dispose();
|
||||
}
|
||||
|
||||
function test_fieldVariable_setValueMatchId() {
|
||||
// Expect the fieldVariable value to be set to variable name
|
||||
var workspace = new Blockly.Workspace();
|
||||
workspace.createVariable('name2', null, 'id1');
|
||||
var fieldVariable = new Blockly.FieldVariable('name1');
|
||||
var mockBlock = fieldVariable_mockBlock(workspace);
|
||||
fieldVariable.setSourceBlock(mockBlock);
|
||||
fieldVariable.setValue('id1');
|
||||
assertEquals('name2', fieldVariable.getText());
|
||||
assertEquals('id1', fieldVariable.value_);
|
||||
workspace.dispose();
|
||||
}
|
||||
|
||||
function test_fieldVariable_setValueMatchName() {
|
||||
// Expect the fieldVariable value to be set to variable name
|
||||
var workspace = new Blockly.Workspace();
|
||||
workspace.createVariable('name2', null, 'id2');
|
||||
var fieldVariable = new Blockly.FieldVariable('name1');
|
||||
var mockBlock = fieldVariable_mockBlock(workspace);
|
||||
fieldVariable.setSourceBlock(mockBlock);
|
||||
fieldVariable.setValue('name2');
|
||||
assertEquals('name2', fieldVariable.getText());
|
||||
assertEquals('id2', fieldVariable.value_);
|
||||
workspace.dispose();
|
||||
}
|
||||
|
||||
function test_fieldVariable_setValueNoVariable() {
|
||||
// Expect the fieldVariable value to be set to the passed in string. No error
|
||||
// should be thrown.
|
||||
var workspace = new Blockly.Workspace();
|
||||
var fieldVariable = new Blockly.FieldVariable('name1');
|
||||
var mockBlock = {'workspace': workspace,
|
||||
'isShadow': function(){return false;}};
|
||||
fieldVariable.setSourceBlock(mockBlock);
|
||||
fieldVariable.setValue('id1');
|
||||
assertEquals('id1', fieldVariable.getText());
|
||||
assertEquals('id1', fieldVariable.value_);
|
||||
workspace.dispose();
|
||||
}
|
|
@ -4,17 +4,21 @@
|
|||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<script src="test_utilities.js"></script>
|
||||
<script src="utils_test.js"></script>
|
||||
<script src="connection_test.js"></script>
|
||||
<script src="connection_db_test.js"></script>
|
||||
<script src="extensions_test.js"></script>
|
||||
<script src="event_test.js"></script>
|
||||
<script src="field_test.js"></script>
|
||||
<script src="field_angle_test.js"></script>
|
||||
<script src="field_number_test.js"></script>
|
||||
<script src="field_variable_test.js"></script>
|
||||
<script src="generator_test.js"></script>
|
||||
<script src="input_test.js"></script>
|
||||
<script src="names_test.js"></script>
|
||||
<script src="workspace_test.js"></script>
|
||||
<script src="workspace_undo_redo_test.js"></script>
|
||||
<script src="xml_test.js"></script>
|
||||
<script src="json_test.js"></script>
|
||||
<script src="variable_model_test.js"></script>
|
||||
|
|
91
tests/jsunit/test_utilities.js
Normal file
91
tests/jsunit/test_utilities.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* @license
|
||||
* Visual Blocks Editor
|
||||
*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Test utilities.
|
||||
* @author marisaleung@google.com (Marisa Leung)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.require('goog.testing');
|
||||
|
||||
|
||||
/**
|
||||
* Check that two arrays have the same content.
|
||||
* @param {!Array.<string>} array1 The first array.
|
||||
* @param {!Array.<string>} array2 The second array.
|
||||
*/
|
||||
function isEqualArrays(array1, array2) {
|
||||
assertEquals(array1.length, array2.length);
|
||||
for (var i = 0; i < array1.length; i++) {
|
||||
assertEquals(array1[i], array2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a controlled MethodMock. Sets the expected return values and
|
||||
* the parameters if any exist. Sets the method to replay.
|
||||
* @param {!goog.testing.MockControl} mockControl Object that holds a set
|
||||
* of mocks for this test.
|
||||
* @param {!Object} scope The scope of the method to be mocked out.
|
||||
* @param {!string} funcName The name of the function we're going to mock.
|
||||
* @param {Array<Object>} parameters The parameters to call the mock with.
|
||||
* @param {Array<!Object>} return_values The values to return when called.
|
||||
* @return {!goog.testing.MockInterface} The mocked method.
|
||||
*/
|
||||
function setUpMockMethod(mockControl, scope, funcName, parameters,
|
||||
return_values) {
|
||||
var mockMethod = mockControl.createMethodMock(scope, funcName);
|
||||
if (return_values) {
|
||||
for (var i = 0, return_value; return_value = return_values[i]; i++) {
|
||||
if (parameters && i < parameters.length) {
|
||||
mockMethod(parameters[i]).$returns(return_value);
|
||||
}
|
||||
else {
|
||||
mockMethod().$returns(return_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there are no return values but there are parameters, we are only
|
||||
// recording specific method calls.
|
||||
else if (parameters) {
|
||||
for (var i = 0; i < parameters.length; i++) {
|
||||
mockMethod(parameters[i]);
|
||||
}
|
||||
}
|
||||
mockMethod.$replay();
|
||||
return mockMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a variable with the given values exists.
|
||||
* @param {Blockly.Workspace|Blockly.VariableMap} container The workspace or
|
||||
* variableMap the checked variable belongs to.
|
||||
* @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 checkVariableValues(container, name, type, id) {
|
||||
var variable = container.getVariableById(id);
|
||||
assertNotUndefined(variable);
|
||||
assertEquals(name, variable.name);
|
||||
assertEquals(type, variable.type);
|
||||
assertEquals(id, variable.getId());
|
||||
}
|
|
@ -24,31 +24,20 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 variableMapTest_checkVariableValues(name, type, id) {
|
||||
var variable = variable_map.getVariable(name);
|
||||
assertNotUndefined(variable);
|
||||
assertEquals(name, variable.name);
|
||||
assertEquals(type, variable.type);
|
||||
assertEquals(id, variable.getId());
|
||||
}
|
||||
|
||||
function test_getVariable_Trivial() {
|
||||
variableMapTest_setUp();
|
||||
var var_1 = variable_map.createVariable('name1', 'type1', 'id1');
|
||||
|
@ -96,14 +85,14 @@ function test_getVariableById_NotFound() {
|
|||
function test_createVariableTrivial() {
|
||||
variableMapTest_setUp();
|
||||
variable_map.createVariable('name1', 'type1', 'id1');
|
||||
variableMapTest_checkVariableValues('name1', 'type1', 'id1')
|
||||
checkVariableValues(variable_map, 'name1', 'type1', 'id1');
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
function test_createVariableAlreadyExists() {
|
||||
// Expect that when the variable already exists, the variableMap_ is unchanged.
|
||||
variableMapTest_setUp();
|
||||
var var_1 = variable_map.createVariable('name1', 'type1', 'id1');
|
||||
variable_map.createVariable('name1', 'type1', 'id1');
|
||||
|
||||
// Assert there is only one variable in the variable_map.
|
||||
var keys = Object.keys(variable_map.variableMap_);
|
||||
|
@ -112,7 +101,7 @@ function test_createVariableAlreadyExists() {
|
|||
assertEquals(1, varMapLength);
|
||||
|
||||
variable_map.createVariable('name1');
|
||||
variableMapTest_checkVariableValues('name1', 'type1', 'id1');
|
||||
checkVariableValues(variable_map, 'name1', 'type1', 'id1');
|
||||
// Check that the size of the variableMap_ did not change.
|
||||
keys = Object.keys(variable_map.variableMap_);
|
||||
assertEquals(1, keys.length);
|
||||
|
@ -126,18 +115,17 @@ function test_createVariableNullAndUndefinedType() {
|
|||
variable_map.createVariable('name1', null, 'id1');
|
||||
variable_map.createVariable('name2', undefined, 'id2');
|
||||
|
||||
variableMapTest_checkVariableValues('name1', '', 'id1');
|
||||
variableMapTest_checkVariableValues('name2', '', 'id2');
|
||||
checkVariableValues(variable_map, 'name1', '', 'id1');
|
||||
checkVariableValues(variable_map, 'name2', '', 'id2');
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
function test_createVariableNullId() {
|
||||
variableMapTest_setUp();
|
||||
var mockGenUid = setUpMockMethod(Blockly.utils, 'genUid', null, '1');
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
|
||||
try {
|
||||
variable_map.createVariable('name1', 'type1', null);
|
||||
mockGenUid.$verify();
|
||||
variableMapTest_checkVariableValues('name1', 'type1', '1');
|
||||
checkVariableValues(variable_map, 'name1', 'type1', '1');
|
||||
}
|
||||
finally {
|
||||
variableMapTest_tearDown();
|
||||
|
@ -146,11 +134,10 @@ function test_createVariableNullId() {
|
|||
|
||||
function test_createVariableUndefinedId() {
|
||||
variableMapTest_setUp();
|
||||
var mockGenUid = setUpMockMethod(Blockly.utils, 'genUid', null, '1');
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '2']);
|
||||
try {
|
||||
variable_map.createVariable('name1', 'type1', undefined);
|
||||
mockGenUid.$verify();
|
||||
variableMapTest_checkVariableValues('name1', 'type1', '1');
|
||||
checkVariableValues(variable_map, 'name1', 'type1', '1');
|
||||
}
|
||||
finally {
|
||||
variableMapTest_tearDown();
|
||||
|
@ -192,8 +179,8 @@ function test_createVariableTwoSameTypes() {
|
|||
variable_map.createVariable('name1', 'type1', 'id1');
|
||||
variable_map.createVariable('name2', 'type1', 'id2');
|
||||
|
||||
variableMapTest_checkVariableValues('name1', 'type1', 'id1');
|
||||
variableMapTest_checkVariableValues('name2', 'type1', 'id2');
|
||||
checkVariableValues(variable_map, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(variable_map, 'name2', 'type1', 'id2');
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
|
@ -205,8 +192,8 @@ function test_getVariablesOfType_Trivial() {
|
|||
variable_map.createVariable('name4', 'type3', 'id4');
|
||||
var result_array_1 = variable_map.getVariablesOfType('type1');
|
||||
var result_array_2 = variable_map.getVariablesOfType('type5');
|
||||
this.isEqualArrays([var_1, var_2], result_array_1);
|
||||
this.isEqualArrays([], result_array_2);
|
||||
isEqualArrays([var_1, var_2], result_array_1);
|
||||
isEqualArrays([], result_array_2);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
|
@ -217,7 +204,7 @@ function test_getVariablesOfType_Null() {
|
|||
var var_3 = variable_map.createVariable('name3', '', 'id3');
|
||||
variable_map.createVariable('name4', 'type1', 'id4');
|
||||
var result_array = variable_map.getVariablesOfType(null);
|
||||
this.isEqualArrays([var_1, var_2, var_3], result_array);
|
||||
isEqualArrays([var_1, var_2, var_3], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
|
@ -226,7 +213,7 @@ function test_getVariablesOfType_EmptyString() {
|
|||
var var_1 = variable_map.createVariable('name1', null, 'id1');
|
||||
var var_2 = variable_map.createVariable('name2', null, 'id2');
|
||||
var result_array = variable_map.getVariablesOfType('');
|
||||
this.isEqualArrays([var_1, var_2], result_array);
|
||||
isEqualArrays([var_1, var_2], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
|
@ -235,14 +222,14 @@ function test_getVariablesOfType_Deleted() {
|
|||
var variable = variable_map.createVariable('name1', null, 'id1');
|
||||
variable_map.deleteVariable(variable);
|
||||
var result_array = variable_map.getVariablesOfType('');
|
||||
this.isEqualArrays([], result_array);
|
||||
isEqualArrays([], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
function test_getVariablesOfType_DoesNotExist() {
|
||||
variableMapTest_setUp();
|
||||
var result_array = variable_map.getVariablesOfType('type1');
|
||||
this.isEqualArrays([], result_array);
|
||||
isEqualArrays([], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
|
@ -253,14 +240,14 @@ function test_getVariableTypes_Trivial() {
|
|||
variable_map.createVariable('name3', 'type2', 'id3');
|
||||
variable_map.createVariable('name4', 'type3', 'id4');
|
||||
var result_array = variable_map.getVariableTypes();
|
||||
this.isEqualArrays(['type1', 'type2', 'type3'], result_array);
|
||||
isEqualArrays(['type1', 'type2', 'type3'], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
function test_getVariableTypes_None() {
|
||||
variableMapTest_setUp();
|
||||
var result_array = variable_map.getVariableTypes();
|
||||
this.isEqualArrays([], result_array);
|
||||
isEqualArrays([], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
|
@ -270,13 +257,13 @@ function test_getAllVariables_Trivial() {
|
|||
var var_2 = variable_map.createVariable('name2', 'type1', 'id2');
|
||||
var var_3 = variable_map.createVariable('name3', 'type2', 'id3');
|
||||
var result_array = variable_map.getAllVariables();
|
||||
this.isEqualArrays([var_1, var_2, var_3], result_array);
|
||||
isEqualArrays([var_1, var_2, var_3], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
||||
function test_getAllVariables_None() {
|
||||
variableMapTest_setUp();
|
||||
var result_array = variable_map.getAllVariables();
|
||||
this.isEqualArrays([], result_array);
|
||||
isEqualArrays([], result_array);
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -24,16 +24,15 @@ goog.require('goog.testing.MockControl');
|
|||
|
||||
var workspace;
|
||||
var mockControl_;
|
||||
var saved_msg = Blockly.Msg.DELETE_VARIABLE;
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "get_var_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_variable",
|
||||
"name": "VAR",
|
||||
}
|
||||
]
|
||||
"type": "get_var_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_variable",
|
||||
"name": "VAR",
|
||||
}
|
||||
]
|
||||
}]);
|
||||
|
||||
function workspaceTest_setUp() {
|
||||
|
@ -41,25 +40,11 @@ function workspaceTest_setUp() {
|
|||
mockControl_ = new goog.testing.MockControl();
|
||||
}
|
||||
|
||||
function workspaceTest_setUpWithMockBlocks() {
|
||||
workspaceTest_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
|
||||
// expects.
|
||||
Blockly.Msg.DELETE_VARIABLE = '%1';
|
||||
}
|
||||
|
||||
function workspaceTest_tearDown() {
|
||||
mockControl_.$tearDown();
|
||||
workspace.dispose();
|
||||
}
|
||||
|
||||
function workspaceTest_tearDownWithMockBlocks() {
|
||||
workspaceTest_tearDown();
|
||||
Blockly.Msg.DELETE_VARIABLE = saved_msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test get_var_block.
|
||||
* @param {?string} variable_name The string to put into the variable field.
|
||||
|
@ -71,53 +56,6 @@ function createMockBlock(variable_name) {
|
|||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that two arrays have the same content.
|
||||
* @param {!Array.<string>} array1 The first array.
|
||||
* @param {!Array.<string>} array2 The second array.
|
||||
*/
|
||||
function isEqualArrays(array1, array2) {
|
||||
assertEquals(array1.length, array2.length);
|
||||
for (var i = 0; i < array1.length; i++) {
|
||||
assertEquals(array1[i], array2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 workspaceTest_checkVariableValues(name, type, id) {
|
||||
var variable = workspace.getVariable(name);
|
||||
assertNotUndefined(variable);
|
||||
assertEquals(name, variable.name);
|
||||
assertEquals(type, variable.type);
|
||||
assertEquals(id, variable.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a controlled MethodMock. Set the expected return values. Set the
|
||||
* method to replay.
|
||||
* @param {!Object} scope The scope of the method to be mocked out.
|
||||
* @param {!string} funcName The name of the function we're going to mock.
|
||||
* @param {Object} parameters The parameters to call the mock with.
|
||||
* @param {!Object} return_value The value to return when called.
|
||||
* @return {!goog.testing.MockInterface} The mocked method.
|
||||
*/
|
||||
function setUpMockMethod(scope, funcName, parameters, return_value) {
|
||||
var mockMethod = mockControl_.createMethodMock(scope, funcName);
|
||||
if (parameters) {
|
||||
mockMethod(parameters).$returns(return_value);
|
||||
}
|
||||
else {
|
||||
mockMethod().$returns(return_value);
|
||||
}
|
||||
mockMethod.$replay();
|
||||
return mockMethod;
|
||||
}
|
||||
|
||||
function test_emptyWorkspace() {
|
||||
workspaceTest_setUp();
|
||||
try {
|
||||
|
@ -220,7 +158,7 @@ function test_getBlockById() {
|
|||
}
|
||||
|
||||
function test_deleteVariable_InternalTrivial() {
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var var_1 = workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
createMockBlock('name1');
|
||||
|
@ -231,9 +169,9 @@ function test_deleteVariable_InternalTrivial() {
|
|||
var variable = workspace.getVariable('name1');
|
||||
var block_var_name = workspace.topBlocks_[0].getVars()[0];
|
||||
assertNull(variable);
|
||||
workspaceTest_checkVariableValues('name2', 'type2', 'id2');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
assertEquals('name2', block_var_name);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
// TODO(marisaleung): Test the alert for deleting a variable that is a procedure.
|
||||
|
@ -242,14 +180,13 @@ function test_updateVariableStore_TrivialNoClear() {
|
|||
workspaceTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
var mockAllUsedVariables = setUpMockMethod(Blockly.Variables,
|
||||
'allUsedVariables', workspace, ['name1', 'name2']);
|
||||
setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
|
||||
[workspace], [['name1', 'name2']]);
|
||||
|
||||
try {
|
||||
workspace.updateVariableStore();
|
||||
mockAllUsedVariables.$verify();
|
||||
workspaceTest_checkVariableValues('name1', 'type1', 'id1');
|
||||
workspaceTest_checkVariableValues('name2', 'type2', 'id2');
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
}
|
||||
finally {
|
||||
workspaceTest_tearDown();
|
||||
|
@ -258,13 +195,13 @@ function test_updateVariableStore_TrivialNoClear() {
|
|||
|
||||
function test_updateVariableStore_NameNotInvariableMap_NoClear() {
|
||||
workspaceTest_setUp();
|
||||
setUpMockMethod(Blockly.Variables, 'allUsedVariables', workspace, ['name1']);
|
||||
setUpMockMethod(Blockly.utils, 'genUid', null, '1');
|
||||
setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
|
||||
[workspace], [['name1']]);
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
|
||||
try {
|
||||
workspace.updateVariableStore();
|
||||
mockControl_.$verifyAll();
|
||||
workspaceTest_checkVariableValues('name1', '', '1');
|
||||
checkVariableValues(workspace, 'name1', '', '1');
|
||||
}
|
||||
finally {
|
||||
workspaceTest_tearDown();
|
||||
|
@ -275,14 +212,13 @@ function test_updateVariableStore_ClearAndAllInUse() {
|
|||
workspaceTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
var mockAllUsedVariables = setUpMockMethod(Blockly.Variables,
|
||||
'allUsedVariables', workspace, ['name1', 'name2']);
|
||||
setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
|
||||
[workspace], [['name1', 'name2']]);
|
||||
|
||||
try {
|
||||
workspace.updateVariableStore(true);
|
||||
mockAllUsedVariables.$verify();
|
||||
workspaceTest_checkVariableValues('name1', 'type1', 'id1');
|
||||
workspaceTest_checkVariableValues('name2', 'type2', 'id2');
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
}
|
||||
finally {
|
||||
workspaceTest_tearDown();
|
||||
|
@ -293,13 +229,12 @@ function test_updateVariableStore_ClearAndOneInUse() {
|
|||
workspaceTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
var mockAllUsedVariables = setUpMockMethod(Blockly.Variables,
|
||||
'allUsedVariables', workspace, ['name1']);
|
||||
setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables',
|
||||
[workspace], [['name1']]);
|
||||
|
||||
try {
|
||||
workspace.updateVariableStore(true);
|
||||
mockAllUsedVariables.$verify();
|
||||
workspaceTest_checkVariableValues('name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
var variabe = workspace.getVariable('name2');
|
||||
assertNull(variable);
|
||||
}
|
||||
|
@ -309,20 +244,20 @@ function test_updateVariableStore_ClearAndOneInUse() {
|
|||
}
|
||||
|
||||
function test_addTopBlock_TrivialFlyoutIsTrue() {
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
workspace.isFlyout = true;
|
||||
var block = createMockBlock();
|
||||
workspace.removeTopBlock(block);
|
||||
setUpMockMethod(Blockly.Variables, 'allUsedVariables', block, ['name1']);
|
||||
setUpMockMethod(Blockly.utils, 'genUid', null, '1');
|
||||
setUpMockMethod(mockControl_, Blockly.Variables, 'allUsedVariables', [block],
|
||||
[['name1']]);
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
|
||||
try {
|
||||
workspace.addTopBlock(block);
|
||||
mockControl_.$verifyAll();
|
||||
workspaceTest_checkVariableValues('name1', '', '1');
|
||||
checkVariableValues(workspace, 'name1', '', '1');
|
||||
}
|
||||
finally {
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,14 +265,11 @@ function test_clear_Trivial() {
|
|||
workspaceTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
var mockSetGroup = mockControl_.createMethodMock(Blockly.Events, 'setGroup');
|
||||
mockSetGroup(true);
|
||||
mockSetGroup(false);
|
||||
mockSetGroup.$replay();
|
||||
setUpMockMethod(mockControl_, Blockly.Events, 'setGroup', [true, false],
|
||||
null);
|
||||
|
||||
try {
|
||||
workspace.clear();
|
||||
mockControl_.$verifyAll();
|
||||
var topBlocks_length = workspace.topBlocks_.length;
|
||||
var varMapLength = Object.keys(workspace.variableMap_.variableMap_).length;
|
||||
assertEquals(0, topBlocks_length);
|
||||
|
@ -350,14 +282,11 @@ function test_clear_Trivial() {
|
|||
|
||||
function test_clear_NoVariables() {
|
||||
workspaceTest_setUp();
|
||||
var mockSetGroup = mockControl_.createMethodMock(Blockly.Events, 'setGroup');
|
||||
mockSetGroup(true);
|
||||
mockSetGroup(false);
|
||||
mockSetGroup.$replay();
|
||||
setUpMockMethod(mockControl_, Blockly.Events, 'setGroup', [true, false],
|
||||
null);
|
||||
|
||||
try {
|
||||
workspace.clear();
|
||||
mockSetGroup.$verify();
|
||||
var topBlocks_length = workspace.topBlocks_.length;
|
||||
var varMapLength = Object.keys(workspace.variableMap_.variableMap_).length;
|
||||
assertEquals(0, topBlocks_length);
|
||||
|
@ -373,18 +302,14 @@ function test_renameVariable_NoBlocks() {
|
|||
workspaceTest_setUp();
|
||||
var oldName = 'name1';
|
||||
var newName = 'name2';
|
||||
var mockSetGroup = mockControl_.createMethodMock(Blockly.Events, 'setGroup');
|
||||
var mockGenUid = mockControl_.createMethodMock(Blockly.utils, 'genUid');
|
||||
// Mocked setGroup to ensure only one call to the mocked genUid.
|
||||
mockSetGroup(true);
|
||||
mockSetGroup(false);
|
||||
mockGenUid().$returns('1');
|
||||
mockControl_.$replayAll();
|
||||
// Mocked setGroup to ensure only one call to the mocked genUid.
|
||||
setUpMockMethod(mockControl_, Blockly.Events, 'setGroup', [true, false],
|
||||
null);
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
|
||||
try {
|
||||
workspace.renameVariable(oldName, newName);
|
||||
mockControl_.$verifyAll();
|
||||
workspaceTest_checkVariableValues('name2', '', '1');
|
||||
checkVariableValues(workspace, 'name2', '', '1');
|
||||
var variable = workspace.getVariable(oldName);
|
||||
assertNull(variable);
|
||||
}
|
||||
|
@ -395,36 +320,36 @@ function test_renameVariable_NoBlocks() {
|
|||
|
||||
function test_renameVariable_SameNameNoBlocks() {
|
||||
// Expect 'renameVariable' to create new variable with newName.
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var name = 'name1';
|
||||
workspace.createVariable(name, 'type1', 'id1');
|
||||
|
||||
workspace.renameVariable(name, name);
|
||||
workspaceTest_checkVariableValues(name, 'type1', 'id1');
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
checkVariableValues(workspace, name, 'type1', 'id1');
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_renameVariable_OnlyOldNameBlockExists() {
|
||||
// Expect 'renameVariable' to change oldName variable name to newName.
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var oldName = 'name1';
|
||||
var newName = 'name2';
|
||||
workspace.createVariable(oldName, 'type1', 'id1');
|
||||
createMockBlock(oldName);
|
||||
|
||||
workspace.renameVariable(oldName, newName);
|
||||
workspaceTest_checkVariableValues(newName, 'type1', 'id1');
|
||||
checkVariableValues(workspace, newName, 'type1', 'id1');
|
||||
var variable = workspace.getVariable(oldName);
|
||||
var block_var_name = workspace.topBlocks_[0].getVars()[0];
|
||||
assertNull(variable);
|
||||
assertEquals(newName, block_var_name);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_renameVariable_TwoVariablesSameType() {
|
||||
// Expect 'renameVariable' to change oldName variable name to newName.
|
||||
// Expect oldName block name to change to newName
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var oldName = 'name1';
|
||||
var newName = 'name2';
|
||||
workspace.createVariable(oldName, 'type1', 'id1');
|
||||
|
@ -433,19 +358,19 @@ function test_renameVariable_TwoVariablesSameType() {
|
|||
createMockBlock(newName);
|
||||
|
||||
workspace.renameVariable(oldName, newName);
|
||||
workspaceTest_checkVariableValues(newName, 'type1', 'id2');
|
||||
checkVariableValues(workspace, newName, 'type1', 'id2');
|
||||
var variable = workspace.getVariable(oldName);
|
||||
var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
|
||||
var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
|
||||
assertNull(variable);
|
||||
assertEquals(newName, block_var_name_1);
|
||||
assertEquals(newName, block_var_name_2);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_renameVariable_TwoVariablesDifferentType() {
|
||||
// Expect triggered error because of different types
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var oldName = 'name1';
|
||||
var newName = 'name2';
|
||||
workspace.createVariable(oldName, 'type1', 'id1');
|
||||
|
@ -459,33 +384,33 @@ function test_renameVariable_TwoVariablesDifferentType() {
|
|||
} catch (e) {
|
||||
// expected
|
||||
}
|
||||
workspaceTest_checkVariableValues(oldName, 'type1', 'id1');
|
||||
workspaceTest_checkVariableValues(newName, 'type2', 'id2');
|
||||
checkVariableValues(workspace, oldName, 'type1', 'id1');
|
||||
checkVariableValues(workspace, newName, 'type2', 'id2');
|
||||
var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
|
||||
var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
|
||||
assertEquals(oldName, block_var_name_1);
|
||||
assertEquals(newName, block_var_name_2);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_renameVariable_OldCase() {
|
||||
// Expect triggered error because of different types
|
||||
workspaceTest_setUpWithMockBlocks();
|
||||
workspaceTest_setUp();
|
||||
var oldCase = 'Name1';
|
||||
var newName = 'name1';
|
||||
workspace.createVariable(oldCase, 'type1', 'id1');
|
||||
createMockBlock(oldCase);
|
||||
|
||||
workspace.renameVariable(oldCase, newName);
|
||||
workspaceTest_checkVariableValues(newName, 'type1', 'id1');
|
||||
var result_oldCase = workspace.getVariable(oldCase).name
|
||||
checkVariableValues(workspace, newName, 'type1', 'id1');
|
||||
var result_oldCase = workspace.getVariable(oldCase).name;
|
||||
assertNotEquals(oldCase, result_oldCase);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_renameVariable_TwoVariablesAndOldCase() {
|
||||
// Expect triggered error because of different types
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var oldName = 'name1';
|
||||
var oldCase = 'Name2';
|
||||
var newName = 'name2';
|
||||
|
@ -496,7 +421,7 @@ function test_renameVariable_TwoVariablesAndOldCase() {
|
|||
|
||||
workspace.renameVariable(oldName, newName);
|
||||
|
||||
workspaceTest_checkVariableValues(newName, 'type1', 'id2');
|
||||
checkVariableValues(workspace, newName, 'type1', 'id2');
|
||||
var variable = workspace.getVariable(oldName);
|
||||
var result_oldCase = workspace.getVariable(oldCase).name;
|
||||
var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
|
||||
|
@ -505,7 +430,7 @@ function test_renameVariable_TwoVariablesAndOldCase() {
|
|||
assertNotEquals(oldCase, result_oldCase);
|
||||
assertEquals(newName, block_var_name_1);
|
||||
assertEquals(newName, block_var_name_2);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
// Extra testing not required for renameVariableById. It calls renameVariable
|
||||
|
@ -513,7 +438,7 @@ function test_renameVariable_TwoVariablesAndOldCase() {
|
|||
function test_renameVariableById_TwoVariablesSameType() {
|
||||
// Expect 'renameVariableById' to change oldName variable name to newName.
|
||||
// Expect oldName block name to change to newName
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
var oldName = 'name1';
|
||||
var newName = 'name2';
|
||||
workspace.createVariable(oldName, 'type1', 'id1');
|
||||
|
@ -522,44 +447,44 @@ function test_renameVariableById_TwoVariablesSameType() {
|
|||
createMockBlock(newName);
|
||||
|
||||
workspace.renameVariableById('id1', newName);
|
||||
workspaceTest_checkVariableValues(newName, 'type1', 'id2');
|
||||
var variable = workspace.getVariable(oldName)
|
||||
checkVariableValues(workspace, newName, 'type1', 'id2');
|
||||
var variable = workspace.getVariable(oldName);
|
||||
var block_var_name_1 = workspace.topBlocks_[0].getVars()[0];
|
||||
var block_var_name_2 = workspace.topBlocks_[1].getVars()[0];
|
||||
assertNull(variable);
|
||||
assertEquals(newName, block_var_name_1);
|
||||
assertEquals(newName, block_var_name_2);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_deleteVariable_Trivial() {
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type1', 'id2');
|
||||
createMockBlock('name1');
|
||||
createMockBlock('name2');
|
||||
|
||||
workspace.deleteVariable('name1');
|
||||
workspaceTest_checkVariableValues('name2', 'type1', 'id2');
|
||||
checkVariableValues(workspace, 'name2', 'type1', 'id2');
|
||||
var variable = workspace.getVariable('name1');
|
||||
var block_var_name = workspace.topBlocks_[0].getVars()[0];
|
||||
assertNull(variable);
|
||||
assertEquals('name2', block_var_name);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
||||
function test_deleteVariableById_Trivial() {
|
||||
workspaceTest_setUpWithMockBlocks()
|
||||
workspaceTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type1', 'id2');
|
||||
createMockBlock('name1');
|
||||
createMockBlock('name2');
|
||||
|
||||
workspace.deleteVariableById('id1');
|
||||
workspaceTest_checkVariableValues('name2', 'type1', 'id2');
|
||||
checkVariableValues(workspace, 'name2', 'type1', 'id2');
|
||||
var variable = workspace.getVariable('name1');
|
||||
var block_var_name = workspace.topBlocks_[0].getVars()[0];
|
||||
assertNull(variable);
|
||||
assertEquals('name2', block_var_name);
|
||||
workspaceTest_tearDownWithMockBlocks();
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
|
|
417
tests/jsunit/workspace_undo_redo_test.js
Normal file
417
tests/jsunit/workspace_undo_redo_test.js
Normal file
|
@ -0,0 +1,417 @@
|
|||
/**
|
||||
* @license
|
||||
* Visual Blocks Editor
|
||||
*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Tests for Blockly.Workspace.undo.
|
||||
* @author marisaleung@google.com (Marisa Leung)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.require('goog.events.EventHandler');
|
||||
goog.require('goog.testing');
|
||||
goog.require('goog.testing.events');
|
||||
goog.require('goog.testing.MockControl');
|
||||
|
||||
|
||||
var workspace;
|
||||
var mockControl_;
|
||||
var savedFireFunc = Blockly.Events.fire;
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "get_var_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_variable",
|
||||
"name": "VAR",
|
||||
}
|
||||
]
|
||||
}]);
|
||||
|
||||
function temporary_fireEvent(event) {
|
||||
if (!Blockly.Events.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.FIRE_QUEUE_.push(event);
|
||||
Blockly.Events.fireNow_();
|
||||
}
|
||||
|
||||
function undoRedoTest_setUp() {
|
||||
workspace = new Blockly.Workspace();
|
||||
mockControl_ = new goog.testing.MockControl();
|
||||
Blockly.Events.fire = temporary_fireEvent;
|
||||
}
|
||||
|
||||
function undoRedoTest_tearDown() {
|
||||
mockControl_.$tearDown();
|
||||
workspace.dispose();
|
||||
Blockly.Events.fire = savedFireFunc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test get_var_block.
|
||||
* @param {string} variableName The string to put into the variable field.
|
||||
* @return {!Blockly.Block} The created block.
|
||||
*/
|
||||
function createMockBlock(variableName) {
|
||||
var block = new Blockly.Block(workspace, 'get_var_block');
|
||||
block.inputList[0].fieldRow[0].setValue(variableName);
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the top block with the given index contains a variable with
|
||||
* the given name.
|
||||
* @param {number} blockIndex The index of the top block.
|
||||
* @param {string} name The expected name of the variable in the block.
|
||||
*/
|
||||
function undoRedoTest_checkBlockVariableName(blockIndex, name) {
|
||||
var blockVarName = workspace.topBlocks_[blockIndex].getVars()[0];
|
||||
assertEquals(name, blockVarName);
|
||||
}
|
||||
|
||||
function createTwoVarsEmptyType() {
|
||||
workspace.createVariable('name1', '', 'id1');
|
||||
workspace.createVariable('name2', '', 'id2');
|
||||
}
|
||||
|
||||
function test_undoCreateVariable_Trivial() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
assertNull(workspace.getVariableById('id2'));
|
||||
workspace.undo();
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
assertNull(workspace.getVariableById('id2'));
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_redoAndUndoCreateVariable_Trivial() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
|
||||
workspace.undo();
|
||||
workspace.undo(true);
|
||||
|
||||
// Expect that variable 'id2' is recreated
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
|
||||
workspace.undo();
|
||||
workspace.undo();
|
||||
workspace.undo(true);
|
||||
|
||||
// Expect that variable 'id1' is recreated
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
assertNull(workspace.getVariableById('id2'));
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoDeleteVariable_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
workspace.deleteVariableById('id1');
|
||||
workspace.deleteVariableById('id2');
|
||||
|
||||
workspace.undo();
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoDeleteVariable_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
createMockBlock('name1');
|
||||
createMockBlock('name2');
|
||||
workspace.deleteVariableById('id1');
|
||||
workspace.deleteVariableById('id2');
|
||||
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name2');
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name2');
|
||||
undoRedoTest_checkBlockVariableName(1, 'name1');
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_redoAndUndoDeleteVariable_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
workspace.deleteVariableById('id1');
|
||||
workspace.deleteVariableById('id2');
|
||||
|
||||
workspace.undo();
|
||||
workspace.undo(true);
|
||||
// Expect that both variables are deleted
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
assertNull(workspace.getVariableById('id2'));
|
||||
|
||||
workspace.undo();
|
||||
workspace.undo();
|
||||
workspace.undo(true);
|
||||
// Expect that variable 'id2' is recreated
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_redoAndUndoDeleteVariable_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
createMockBlock('name1');
|
||||
createMockBlock('name2');
|
||||
workspace.deleteVariableById('id1');
|
||||
workspace.deleteVariableById('id2');
|
||||
|
||||
workspace.undo();
|
||||
workspace.undo(true);
|
||||
// Expect that both variables are deleted
|
||||
assertEquals(0, workspace.topBlocks_.length);
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
assertNull(workspace.getVariableById('id2'));
|
||||
|
||||
workspace.undo();
|
||||
workspace.undo();
|
||||
workspace.undo(true);
|
||||
// Expect that variable 'id2' is recreated
|
||||
undoRedoTest_checkBlockVariableName(0, 'name2');
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_redoAndUndoDeleteVariableTwice_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.deleteVariableById('id1');
|
||||
workspace.deleteVariableById('id1');
|
||||
|
||||
// Check the undoStack only recorded one delete event.
|
||||
var undoStack = workspace.undoStack_;
|
||||
assertEquals('var_delete', undoStack[undoStack.length-1].type);
|
||||
assertNotEquals('var_delete', undoStack[undoStack.length-2].type);
|
||||
|
||||
// undo delete
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
|
||||
// redo delete
|
||||
workspace.undo(true);
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
|
||||
// redo delete, nothing should happen
|
||||
workspace.undo(true);
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_redoAndUndoDeleteVariableTwice_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
createMockBlock('name1');
|
||||
workspace.deleteVariableById('id1');
|
||||
workspace.deleteVariableById('id1');
|
||||
|
||||
// Check the undoStack only recorded one delete event.
|
||||
var undoStack = workspace.undoStack_;
|
||||
assertEquals('var_delete', undoStack[undoStack.length-1].type);
|
||||
assertEquals('delete', undoStack[undoStack.length-2].type);
|
||||
assertNotEquals('var_delete', undoStack[undoStack.length-3].type);
|
||||
|
||||
// undo delete
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name1');
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
|
||||
// redo delete
|
||||
workspace.undo(true);
|
||||
assertEquals(0, workspace.topBlocks_.length);
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
|
||||
// redo delete, nothing should happen
|
||||
workspace.undo(true);
|
||||
assertEquals(0, workspace.topBlocks_.length);
|
||||
assertNull(workspace.getVariableById('id1'));
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_NeitherVariableExists() {
|
||||
// Expect that a variable with the name, 'name2', and the generated UUID,
|
||||
// 'id2', to be created when rename is called. Undo removes this variable
|
||||
// and redo recreates it.
|
||||
undoRedoTest_setUp();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null,
|
||||
['rename_group', 'id2', 'delete_group']);
|
||||
workspace.renameVariable('name1', 'name2');
|
||||
|
||||
workspace.undo();
|
||||
assertNull(workspace.getVariableById('id2'));
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'name2', '', 'id2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_OneExists_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', '', 'id1');
|
||||
workspace.renameVariable('name1', 'name2');
|
||||
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
assertNull(workspace.getVariable('name2'));
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'name2', '', 'id1');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_OneExists_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', '', 'id1');
|
||||
createMockBlock('name1');
|
||||
workspace.renameVariable('name1', 'name2');
|
||||
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name1');
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
assertNull(workspace.getVariable('name2'));
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'name2', '', 'id1');
|
||||
undoRedoTest_checkBlockVariableName(0, 'name2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_BothExist_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
createTwoVarsEmptyType();
|
||||
workspace.renameVariable('name1', 'name2');
|
||||
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
checkVariableValues(workspace, 'name2', '', 'id2');
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'name2', '', 'id2');
|
||||
assertNull(workspace.getVariable('name1'));
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_BothExist_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
createTwoVarsEmptyType();
|
||||
createMockBlock('name1');
|
||||
createMockBlock('name2');
|
||||
workspace.renameVariable('name1', 'name2');
|
||||
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name1');
|
||||
undoRedoTest_checkBlockVariableName(1, 'name2');
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
checkVariableValues(workspace, 'name2', '', 'id2');
|
||||
|
||||
workspace.undo(true);
|
||||
undoRedoTest_checkBlockVariableName(0, 'name2');
|
||||
undoRedoTest_checkBlockVariableName(1, 'name2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_BothExistCaseChange_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
createTwoVarsEmptyType();
|
||||
workspace.renameVariable('name1', 'Name2');
|
||||
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
checkVariableValues(workspace, 'name2', '', 'id2');
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'Name2', '', 'id2');
|
||||
assertNull(workspace.getVariable('name1'));
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_BothExistCaseChange_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
createTwoVarsEmptyType();
|
||||
createMockBlock('name1');
|
||||
createMockBlock('name2');
|
||||
workspace.renameVariable('name1', 'Name2');
|
||||
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name1');
|
||||
undoRedoTest_checkBlockVariableName(1, 'name2');
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
checkVariableValues(workspace, 'name2', '', 'id2');
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'Name2', '', 'id2');
|
||||
assertNull(workspace.getVariable('name1'));
|
||||
undoRedoTest_checkBlockVariableName(0, 'Name2');
|
||||
undoRedoTest_checkBlockVariableName(1, 'Name2');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_OnlyCaseChange_NoBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', '', 'id1');
|
||||
workspace.renameVariable('name1', 'Name1');
|
||||
|
||||
workspace.undo();
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'Name1', '', 'id1');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
||||
|
||||
function test_undoRedoRenameVariable_OnlyCaseChange_WithBlocks() {
|
||||
undoRedoTest_setUp();
|
||||
workspace.createVariable('name1', '', 'id1');
|
||||
createMockBlock('name1');
|
||||
workspace.renameVariable('name1', 'Name1');
|
||||
|
||||
workspace.undo();
|
||||
undoRedoTest_checkBlockVariableName(0, 'name1');
|
||||
checkVariableValues(workspace, 'name1', '', 'id1');
|
||||
|
||||
workspace.undo(true);
|
||||
checkVariableValues(workspace, 'Name1', '', 'id1');
|
||||
undoRedoTest_checkBlockVariableName(0, 'Name1');
|
||||
undoRedoTest_tearDown();
|
||||
}
|
|
@ -23,7 +23,6 @@ goog.require('goog.testing');
|
|||
goog.require('goog.testing.MockControl');
|
||||
|
||||
var mockControl_;
|
||||
var saved_msg = Blockly.Msg.DELETE_VARIABLE;
|
||||
var workspace;
|
||||
var XML_TEXT = ['<xml xmlns="http://www.w3.org/1999/xhtml">',
|
||||
' <block type="controls_repeat_ext" inline="true" x="21" y="23">',
|
||||
|
@ -70,11 +69,6 @@ function xmlTest_setUpWithMockBlocks() {
|
|||
}
|
||||
],
|
||||
}]);
|
||||
// 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
|
||||
// expects.
|
||||
Blockly.Msg.DELETE_VARIABLE = '%1';
|
||||
}
|
||||
|
||||
function xmlTest_tearDown() {
|
||||
|
@ -85,7 +79,6 @@ function xmlTest_tearDown() {
|
|||
function xmlTest_tearDownWithMockBlocks() {
|
||||
xmlTest_tearDown();
|
||||
delete Blockly.Blocks.field_variable_test_block;
|
||||
Blockly.Msg.DELETE_VARIABLE = saved_msg;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,20 +122,6 @@ function xmlTest_checkVariableDomValues(variableDom, type, id, text) {
|
|||
assertEquals(text, variableDom.textContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 xmlTest_checkVariableValues(name, type, id) {
|
||||
var variable = workspace.getVariable(name);
|
||||
assertNotUndefined(variable);
|
||||
assertEquals(name, variable.name);
|
||||
assertEquals(type, variable.type);
|
||||
assertEquals(id, variable.getId());
|
||||
}
|
||||
|
||||
function test_textToDom() {
|
||||
var dom = Blockly.Xml.textToDom(XML_TEXT);
|
||||
assertEquals('XML tag', 'xml', dom.nodeName);
|
||||
|
@ -159,10 +138,7 @@ function test_domToText() {
|
|||
function test_domToWorkspace_BackwardCompatibility() {
|
||||
// Expect that workspace still loads without serialized variables.
|
||||
xmlTest_setUpWithMockBlocks();
|
||||
var mockGenUid = mockControl_.createMethodMock(Blockly.utils, 'genUid');
|
||||
mockGenUid().$returns('1');
|
||||
mockGenUid().$returns('1');
|
||||
mockGenUid().$replay();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1', '1']);
|
||||
try {
|
||||
var dom = Blockly.Xml.textToDom(
|
||||
'<xml>' +
|
||||
|
@ -172,7 +148,7 @@ function test_domToWorkspace_BackwardCompatibility() {
|
|||
'</xml>');
|
||||
Blockly.Xml.domToWorkspace(dom, workspace);
|
||||
assertEquals('Block count', 1, workspace.getAllBlocks().length);
|
||||
xmlTest_checkVariableValues('name1', '', '1');
|
||||
checkVariableValues(workspace, 'name1', '', '1');
|
||||
} finally {
|
||||
xmlTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
@ -195,9 +171,9 @@ function test_domToWorkspace_VariablesAtTop() {
|
|||
'</xml>');
|
||||
Blockly.Xml.domToWorkspace(dom, workspace);
|
||||
assertEquals('Block count', 1, workspace.getAllBlocks().length);
|
||||
xmlTest_checkVariableValues('name1', 'type1', 'id1');
|
||||
xmlTest_checkVariableValues('name2', 'type2', 'id2');
|
||||
xmlTest_checkVariableValues('name3', '', 'id3');
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
checkVariableValues(workspace, 'name3', '', 'id3');
|
||||
} finally {
|
||||
xmlTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
@ -309,27 +285,26 @@ function test_appendDomToWorkspace() {
|
|||
}
|
||||
|
||||
function test_blockToDom_fieldToDom_trivial() {
|
||||
xmlTest_setUpWithMockBlocks()
|
||||
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()
|
||||
xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', 'type1', 'id1',
|
||||
'name1');
|
||||
xmlTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockToDom_fieldToDom_defaultCase() {
|
||||
xmlTest_setUpWithMockBlocks()
|
||||
var mockGenUid = mockControl_.createMethodMock(Blockly.utils, 'genUid');
|
||||
mockGenUid().$returns('1');
|
||||
mockGenUid().$replay();
|
||||
xmlTest_setUpWithMockBlocks();
|
||||
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')
|
||||
xmlTest_tearDownWithMockBlocks()
|
||||
xmlTest_checkVariableFieldDomValues(resultFieldDom, 'VAR', '', '1', 'name1');
|
||||
xmlTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_blockToDom_fieldToDom_notAFieldVariable() {
|
||||
|
@ -344,19 +319,17 @@ function test_blockToDom_fieldToDom_notAFieldVariable() {
|
|||
}
|
||||
],
|
||||
}]);
|
||||
xmlTest_setUpWithMockBlocks()
|
||||
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()
|
||||
xmlTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
function test_variablesToDom_oneVariable() {
|
||||
xmlTest_setUp();
|
||||
var mockGenUid = mockControl_.createMethodMock(Blockly.utils, 'genUid');
|
||||
mockGenUid().$returns('1');
|
||||
mockGenUid().$replay();
|
||||
setUpMockMethod(mockControl_, Blockly.utils, 'genUid', null, ['1']);
|
||||
|
||||
workspace.createVariable('name1');
|
||||
var resultDom = Blockly.Xml.variablesToDom(workspace.getAllVariables());
|
||||
|
@ -392,34 +365,3 @@ function test_variablesToDom_noVariables() {
|
|||
assertEquals(1, resultDom.children.length);
|
||||
xmlTest_tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(
|
||||
'<xml xmlns="http://www.w3.org/1999/xhtml">' +
|
||||
' <block type="test_block" inline="true" x="21" y="23">' +
|
||||
' </block>' +
|
||||
'</xml>');
|
||||
var 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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue