mirror of
https://github.com/google/blockly.git
synced 2026-01-18 14:27:12 +01:00
Shared events cleanup (#4092)
* Remove temp fix for event queue cleanup. * Implementing shared setup and cleanup. * Remove unecessary restore and add comment. * Adds helper for workspace teardown * Remove unecessary restore calls in event tests
This commit is contained in:
@@ -17,14 +17,16 @@
|
||||
"defineRowBlock": true,
|
||||
"defineStackBlock": true,
|
||||
"defineStatementBlock": true,
|
||||
"createEventsFireStub": true,
|
||||
"createFireChangeListenerSpy": true,
|
||||
"createGenUidStubWithReturns": true,
|
||||
"testAWorkspace": true,
|
||||
"testHelpers" : true,
|
||||
"getCategoryJSON": true,
|
||||
"getSimpleJSON": true,
|
||||
"getXmlArray": true,
|
||||
"getCategoryJSON": true
|
||||
"sharedTestSetup": true,
|
||||
"sharedTestTeardown": true,
|
||||
"testAWorkspace": true,
|
||||
"testHelpers" : true,
|
||||
"workspaceTeardown": true
|
||||
},
|
||||
"rules": {
|
||||
"no-unused-vars": ["off"],
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
suite('Blocks', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this, {fireEventsNow: false});
|
||||
this.workspace = new Blockly.Workspace();
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
@@ -43,7 +44,7 @@ suite('Blocks', function() {
|
||||
}]);
|
||||
});
|
||||
teardown(function() {
|
||||
this.workspace.dispose();
|
||||
sharedTestTeardown.call(this);
|
||||
delete Blockly.Blocks['empty_block'];
|
||||
delete Blockly.Blocks['stack_block'];
|
||||
delete Blockly.Blocks['row_block'];
|
||||
@@ -392,8 +393,6 @@ suite('Blocks', function() {
|
||||
});
|
||||
suite('Connection Tracking', function() {
|
||||
setup(function() {
|
||||
this.workspace.dispose();
|
||||
// The new rendered workspace will get disposed by the parent teardown.
|
||||
this.workspace = Blockly.inject('blocklyDiv');
|
||||
|
||||
this.getInputs = function() {
|
||||
@@ -419,12 +418,11 @@ suite('Blocks', function() {
|
||||
chai.assert.isEmpty(this.getNext());
|
||||
chai.assert.isEmpty(this.getPrevious());
|
||||
};
|
||||
|
||||
this.clock = sinon.useFakeTimers();
|
||||
});
|
||||
teardown(function() {
|
||||
this.clock.restore();
|
||||
workspaceTeardown.call(this, this.workspace);
|
||||
});
|
||||
|
||||
suite('Deserialization', function() {
|
||||
test('Stack', function() {
|
||||
Blockly.Xml.appendDomToWorkspace(Blockly.Xml.textToDom(
|
||||
@@ -433,7 +431,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 1);
|
||||
});
|
||||
@@ -452,7 +450,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 3);
|
||||
});
|
||||
@@ -463,7 +461,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 1);
|
||||
});
|
||||
@@ -482,7 +480,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 3);
|
||||
});
|
||||
@@ -493,7 +491,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 1);
|
||||
chai.assert.equal(this.getInputs().length, 1);
|
||||
});
|
||||
@@ -512,7 +510,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 3);
|
||||
chai.assert.equal(this.getInputs().length, 3);
|
||||
});
|
||||
@@ -523,7 +521,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 1);
|
||||
chai.assert.equal(this.getInputs().length, 0);
|
||||
});
|
||||
@@ -542,7 +540,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 1);
|
||||
chai.assert.equal(this.getInputs().length, 0);
|
||||
});
|
||||
@@ -561,7 +559,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 2);
|
||||
chai.assert.equal(this.getInputs().length, 1);
|
||||
});
|
||||
@@ -572,7 +570,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 2);
|
||||
});
|
||||
@@ -591,7 +589,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 6);
|
||||
});
|
||||
@@ -602,7 +600,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 1);
|
||||
});
|
||||
@@ -621,7 +619,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 1);
|
||||
});
|
||||
@@ -640,7 +638,7 @@ suite('Blocks', function() {
|
||||
'</xml>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 2);
|
||||
chai.assert.equal(this.getNext().length, 3);
|
||||
});
|
||||
@@ -679,7 +677,7 @@ suite('Blocks', function() {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="stack_block"/>'
|
||||
), this.workspace);
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 1);
|
||||
|
||||
@@ -704,7 +702,7 @@ suite('Blocks', function() {
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 3);
|
||||
|
||||
@@ -720,7 +718,7 @@ suite('Blocks', function() {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="row_block"/>'
|
||||
), this.workspace);
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 1);
|
||||
chai.assert.equal(this.getInputs().length, 1);
|
||||
|
||||
@@ -744,7 +742,7 @@ suite('Blocks', function() {
|
||||
' </value>' +
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 3);
|
||||
chai.assert.equal(this.getInputs().length, 3);
|
||||
|
||||
@@ -768,7 +766,7 @@ suite('Blocks', function() {
|
||||
' </value>' +
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 3);
|
||||
chai.assert.equal(this.getInputs().length, 3);
|
||||
|
||||
@@ -795,7 +793,7 @@ suite('Blocks', function() {
|
||||
' </value>' +
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getOutputs().length, 3);
|
||||
chai.assert.equal(this.getInputs().length, 3);
|
||||
|
||||
@@ -820,7 +818,7 @@ suite('Blocks', function() {
|
||||
var block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
'<block type="statement_block"/>'
|
||||
), this.workspace);
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 1);
|
||||
chai.assert.equal(this.getNext().length, 2);
|
||||
|
||||
@@ -845,7 +843,7 @@ suite('Blocks', function() {
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 6);
|
||||
|
||||
@@ -870,7 +868,7 @@ suite('Blocks', function() {
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 6);
|
||||
|
||||
@@ -896,7 +894,7 @@ suite('Blocks', function() {
|
||||
'</block>'
|
||||
), this.workspace);
|
||||
this.assertConnectionsEmpty();
|
||||
this.clock.tick(1);
|
||||
this.clock.runAll();
|
||||
chai.assert.equal(this.getPrevious().length, 3);
|
||||
chai.assert.equal(this.getNext().length, 6);
|
||||
|
||||
@@ -1019,12 +1017,6 @@ suite('Blocks', function() {
|
||||
});
|
||||
});
|
||||
suite('Comments', function() {
|
||||
setup(function() {
|
||||
this.eventSpy = sinon.spy(Blockly.Events, 'fire');
|
||||
});
|
||||
teardown(function() {
|
||||
this.eventSpy.restore();
|
||||
});
|
||||
suite('Set/Get Text', function() {
|
||||
function assertCommentEvent(eventSpy, oldValue, newValue) {
|
||||
var calls = eventSpy.getCalls();
|
||||
@@ -1039,6 +1031,12 @@ suite('Blocks', function() {
|
||||
var event = calls[calls.length - 1].args[0];
|
||||
chai.assert.notEqual(event.type, Blockly.Events.BLOCK_CHANGE);
|
||||
}
|
||||
setup(function() {
|
||||
this.eventsFireSpy = sinon.spy(Blockly.Events, 'fire');
|
||||
});
|
||||
teardown(function() {
|
||||
this.eventsFireSpy.restore();
|
||||
});
|
||||
suite('Headless', function() {
|
||||
setup(function() {
|
||||
this.block = Blockly.Xml.domToBlock(Blockly.Xml.textToDom(
|
||||
@@ -1048,24 +1046,24 @@ suite('Blocks', function() {
|
||||
test('Text', function() {
|
||||
this.block.setCommentText('test text');
|
||||
chai.assert.equal(this.block.getCommentText(), 'test text');
|
||||
assertCommentEvent(this.eventSpy, null, 'test text');
|
||||
assertCommentEvent(this.eventsFireSpy, null, 'test text');
|
||||
});
|
||||
test('Text Empty', function() {
|
||||
this.block.setCommentText('');
|
||||
chai.assert.equal(this.block.getCommentText(), '');
|
||||
assertCommentEvent(this.eventSpy, null, '');
|
||||
assertCommentEvent(this.eventsFireSpy, null, '');
|
||||
});
|
||||
test('Text Null', function() {
|
||||
this.block.setCommentText(null);
|
||||
chai.assert.isNull(this.block.getCommentText());
|
||||
assertNoCommentEvent(this.eventSpy);
|
||||
assertNoCommentEvent(this.eventsFireSpy);
|
||||
});
|
||||
test('Text -> Null', function() {
|
||||
this.block.setCommentText('first text');
|
||||
|
||||
this.block.setCommentText(null);
|
||||
chai.assert.isNull(this.block.getCommentText());
|
||||
assertCommentEvent(this.eventSpy, 'first text', null);
|
||||
assertCommentEvent(this.eventsFireSpy, 'first text', null);
|
||||
});
|
||||
});
|
||||
suite('Rendered', function() {
|
||||
@@ -1084,24 +1082,24 @@ suite('Blocks', function() {
|
||||
test('Text', function() {
|
||||
this.block.setCommentText('test text');
|
||||
chai.assert.equal(this.block.getCommentText(), 'test text');
|
||||
assertCommentEvent(this.eventSpy, null, 'test text');
|
||||
assertCommentEvent(this.eventsFireSpy, null, 'test text');
|
||||
});
|
||||
test('Text Empty', function() {
|
||||
this.block.setCommentText('');
|
||||
chai.assert.equal(this.block.getCommentText(), '');
|
||||
assertCommentEvent(this.eventSpy, null, '');
|
||||
assertCommentEvent(this.eventsFireSpy, null, '');
|
||||
});
|
||||
test('Text Null', function() {
|
||||
this.block.setCommentText(null);
|
||||
chai.assert.isNull(this.block.getCommentText());
|
||||
assertNoCommentEvent(this.eventSpy);
|
||||
assertNoCommentEvent(this.eventsFireSpy);
|
||||
});
|
||||
test('Text -> Null', function() {
|
||||
this.block.setCommentText('first text');
|
||||
|
||||
this.block.setCommentText(null);
|
||||
chai.assert.isNull(this.block.getCommentText());
|
||||
assertCommentEvent(this.eventSpy, 'first text', null);
|
||||
assertCommentEvent(this.eventsFireSpy, 'first text', null);
|
||||
});
|
||||
test('Set While Visible - Editable', function() {
|
||||
this.block.setCommentText('test1');
|
||||
@@ -1110,22 +1108,21 @@ suite('Blocks', function() {
|
||||
|
||||
this.block.setCommentText('test2');
|
||||
chai.assert.equal(this.block.getCommentText(), 'test2');
|
||||
assertCommentEvent(this.eventSpy, 'test1', 'test2');
|
||||
assertCommentEvent(this.eventsFireSpy, 'test1', 'test2');
|
||||
chai.assert.equal(icon.textarea_.value, 'test2');
|
||||
});
|
||||
test('Set While Visible - NonEditable', function() {
|
||||
this.block.setCommentText('test1');
|
||||
var editableStub = sinon.stub(this.block, 'isEditable').returns(false);
|
||||
// Restored up by call to sinon.restore() in sharedTestTeardown()
|
||||
sinon.stub(this.block, 'isEditable').returns(false);
|
||||
var icon = this.block.getCommentIcon();
|
||||
icon.setVisible(true);
|
||||
|
||||
this.block.setCommentText('test2');
|
||||
chai.assert.equal(this.block.getCommentText(), 'test2');
|
||||
assertCommentEvent(this.eventSpy, 'test1', 'test2');
|
||||
assertCommentEvent(this.eventsFireSpy, 'test1', 'test2');
|
||||
chai.assert.equal(icon.paragraphElement_.firstChild.textContent,
|
||||
'test2');
|
||||
|
||||
editableStub.restore();
|
||||
});
|
||||
test('Get Text While Editing', function() {
|
||||
this.block.setCommentText('test1');
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
suite('Comments', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
Blockly.defineBlocksWithJsonArray([
|
||||
{
|
||||
"type": "empty_block",
|
||||
@@ -25,16 +26,12 @@ suite('Comments', function() {
|
||||
this.comment.computeIconLocation();
|
||||
});
|
||||
teardown(function() {
|
||||
sharedTestTeardown.call(this);
|
||||
delete Blockly.Blocks['empty_block'];
|
||||
this.workspace.dispose();
|
||||
});
|
||||
suite('Visibility and Editability', function() {
|
||||
setup(function() {
|
||||
this.comment.setText('test text');
|
||||
this.eventsStub = createEventsFireStub();
|
||||
});
|
||||
teardown(function() {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
function assertEditable(comment) {
|
||||
@@ -53,7 +50,7 @@ suite('Comments', function() {
|
||||
chai.assert.isTrue(this.comment.isVisible());
|
||||
assertEditable(this.comment);
|
||||
assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
this.eventsFireStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
{element: 'commentOpen', oldValue: false, newValue: true});
|
||||
});
|
||||
test('Not Editable', function() {
|
||||
@@ -63,7 +60,7 @@ suite('Comments', function() {
|
||||
chai.assert.isTrue(this.comment.isVisible());
|
||||
assertNotEditable(this.comment);
|
||||
assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
this.eventsFireStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
{element: 'commentOpen', oldValue: false, newValue: true});
|
||||
});
|
||||
test('Editable -> Not Editable', function() {
|
||||
@@ -73,10 +70,10 @@ suite('Comments', function() {
|
||||
this.comment.updateEditable();
|
||||
chai.assert.isTrue(this.comment.isVisible());
|
||||
assertNotEditable(this.comment);assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
this.eventsFireStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
{element: 'commentOpen', oldValue: false, newValue: true});
|
||||
assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
this.eventsFireStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
{element: 'commentOpen', oldValue: false, newValue: true});
|
||||
});
|
||||
test('Not Editable -> Editable', function() {
|
||||
@@ -88,7 +85,7 @@ suite('Comments', function() {
|
||||
chai.assert.isTrue(this.comment.isVisible());
|
||||
assertEditable(this.comment);
|
||||
assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
this.eventsFireStub, Blockly.Events.UI, this.workspace.id, this.block.id,
|
||||
{element: 'commentOpen', oldValue: false, newValue: true});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
suite('Events', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this, {fireEventsNow: false});
|
||||
this.eventsFireSpy = sinon.spy(Blockly.Events, 'fire');
|
||||
this.workspace = new Blockly.Workspace();
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
'type': 'field_variable_test_block',
|
||||
@@ -25,13 +27,9 @@ suite('Events', function() {
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sharedTestTeardown.call(this);
|
||||
delete Blockly.Blocks['field_variable_test_block'];
|
||||
delete Blockly.Blocks['simple_test_block'];
|
||||
this.workspace.dispose();
|
||||
|
||||
// Clear Blockly.Event state.
|
||||
Blockly.Events.setGroup(false);
|
||||
Blockly.Events.disabled_ = 0;
|
||||
});
|
||||
|
||||
function createSimpleTestBlock(workspace, opt_prototypeName) {
|
||||
@@ -75,9 +73,6 @@ suite('Events', function() {
|
||||
[this.TEST_BLOCK_ID, this.TEST_PARENT_ID]);
|
||||
this.block = createSimpleTestBlock(this.workspace);
|
||||
});
|
||||
teardown(function() {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
test('Block base', function() {
|
||||
var event = new Blockly.Events.BlockBase(this.block);
|
||||
@@ -232,9 +227,6 @@ suite('Events', function() {
|
||||
this.block =
|
||||
createSimpleTestBlock(this.workspace, 'field_variable_test_block');
|
||||
});
|
||||
teardown(function() {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
test('Change', function() {
|
||||
var event = new Blockly.Events.Change(
|
||||
@@ -625,18 +617,17 @@ suite('Events', function() {
|
||||
|
||||
suite('Firing', function() {
|
||||
setup(function() {
|
||||
this.eventsStub = createEventsFireStub();
|
||||
this.changeListenerSpy = createFireChangeListenerSpy(this.workspace);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
test('Block dispose triggers Delete', function() {
|
||||
try {
|
||||
var toolbox = document.getElementById('toolbox-categories');
|
||||
var workspaceSvg = Blockly.inject('blocklyDiv', {toolbox: toolbox});
|
||||
var changeListenerSpy = createFireChangeListenerSpy(workspaceSvg);
|
||||
var TEST_BLOCK_ID = 'test_block_id';
|
||||
var genUidStub = createGenUidStubWithReturns(
|
||||
[TEST_BLOCK_ID, 'test_group_id']);
|
||||
|
||||
var block = workspaceSvg.newBlock('');
|
||||
block.initSvg();
|
||||
@@ -646,9 +637,22 @@ suite('Events', function() {
|
||||
|
||||
block.dispose();
|
||||
|
||||
// Run all queued events.
|
||||
this.clock.runAll();
|
||||
|
||||
// Expect two calls to genUid: one to set the block's ID, and one for
|
||||
// the event group's ID for creating block.
|
||||
sinon.assert.calledTwice(genUidStub);
|
||||
|
||||
assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.DELETE, workspaceSvg.id,
|
||||
expectedId, {oldXml: expectedOldXml});
|
||||
this.eventsFireSpy, Blockly.Events.DELETE, workspaceSvg.id,
|
||||
expectedId, {oldXml: expectedOldXml, group: ''});
|
||||
assertLastCallEventArgEquals(
|
||||
changeListenerSpy, Blockly.Events.DELETE, workspaceSvg.id,
|
||||
expectedId, {oldXml: expectedOldXml, group: ''});
|
||||
|
||||
// Expect the workspace to not have a variable with ID 'test_block_id'.
|
||||
chai.assert.isNull(this.workspace.getVariableById(TEST_BLOCK_ID));
|
||||
} finally {
|
||||
workspaceSvg.dispose();
|
||||
}
|
||||
@@ -663,12 +667,15 @@ suite('Events', function() {
|
||||
var _ = this.workspace.newBlock('field_variable_test_block');
|
||||
var TEST_VAR_NAME = 'item'; // As defined in block's json.
|
||||
|
||||
// Run all queued events.
|
||||
this.clock.runAll();
|
||||
|
||||
// Expect three calls to genUid: one to set the block's ID, one for the event
|
||||
// group's id, and one for the variable's ID.
|
||||
// group's ID, and one for the variable's ID.
|
||||
sinon.assert.calledThrice(genUidStub);
|
||||
|
||||
// Expect two events fired: varCreate and block create.
|
||||
sinon.assert.calledTwice(this.eventsStub);
|
||||
sinon.assert.calledTwice(this.eventsFireSpy);
|
||||
// Expect both events to trigger change listener.
|
||||
sinon.assert.calledTwice(this.changeListenerSpy);
|
||||
// Both events should be on undo stack
|
||||
@@ -701,6 +708,9 @@ suite('Events', function() {
|
||||
var TEST_VAR_ID = 'test_var_id';
|
||||
var TEST_VAR_NAME = 'name1';
|
||||
|
||||
// Run all queued events.
|
||||
this.clock.runAll();
|
||||
|
||||
// Expect one call to genUid: for the event group's id
|
||||
sinon.assert.calledOnce(genUidStub);
|
||||
|
||||
@@ -710,7 +720,7 @@ suite('Events', function() {
|
||||
// 3. block create
|
||||
// 4. move (no-op, is filtered out)
|
||||
// 5. finished loading
|
||||
sinon.assert.callCount(this.eventsStub, 5);
|
||||
sinon.assert.callCount(this.eventsFireSpy, 5);
|
||||
// The first varCreate and move event should have been ignored.
|
||||
sinon.assert.callCount(this.changeListenerSpy, 3);
|
||||
// Expect two events on undo stack: varCreate and block create.
|
||||
|
||||
@@ -9,6 +9,7 @@ goog.require('Blockly.Msg');
|
||||
|
||||
suite('Procedures', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
this.workspace = new Blockly.Workspace();
|
||||
|
||||
this.callForAllTypes = function(func, startName) {
|
||||
@@ -37,7 +38,7 @@ suite('Procedures', function() {
|
||||
};
|
||||
});
|
||||
teardown(function() {
|
||||
this.workspace.dispose();
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
suite('allProcedures', function() {
|
||||
@@ -340,7 +341,6 @@ suite('Procedures', function() {
|
||||
});
|
||||
suite('Enable/Disable', function() {
|
||||
setup(function() {
|
||||
createEventsFireStub();
|
||||
var toolbox = document.getElementById('toolbox-categories');
|
||||
this.workspaceSvg = Blockly.inject('blocklyDiv', {toolbox: toolbox});
|
||||
});
|
||||
|
||||
@@ -39,10 +39,114 @@ function captureWarnings(innerFunc) {
|
||||
return msgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely disposes of Blockly workspace, logging any errors.
|
||||
* Assumes that sharedTestSetup has also been called. This should be called
|
||||
* using workspaceTeardown.call(this).
|
||||
* @param {!Blockly.Workspace} workspace The workspace to dispose.
|
||||
*/
|
||||
function workspaceTeardown(workspace) {
|
||||
try {
|
||||
this.clock.runAll(); // Run all queued setTimeout calls.
|
||||
workspace.dispose();
|
||||
this.clock.runAll(); // Run all remaining queued setTimeout calls.
|
||||
} catch (e) {
|
||||
console.error(this.currentTest.fullTitle() + '\n', e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates stub for Blockly.Events.fire that advances the clock forward after
|
||||
* the event fires so it is processed immediately instead of on a timeout.
|
||||
* @param {!SinonClock} clock The sinon clock.
|
||||
* @return {!SinonStub} The created stub.
|
||||
* @private
|
||||
*/
|
||||
function createEventsFireStubFireImmediately_(clock) {
|
||||
var stub = sinon.stub(Blockly.Events, 'fire');
|
||||
stub.callsFake(function(event) {
|
||||
// TODO(#4070) Replace the fake function content with the following code
|
||||
// that uses wrappedMethod after cleanup is added to ALL tests.
|
||||
// Calling the original method will not consistently work if other tests
|
||||
// add things to the event queue because the setTimeout call will not be
|
||||
// added to the stubbed clock (so runAll cannot be used to control).
|
||||
// // Call original method.
|
||||
// stub.wrappedMethod.call(this, ...arguments);
|
||||
// // Advance clock forward to run any queued events.
|
||||
// clock.runAll();
|
||||
//
|
||||
if (!Blockly.Events.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.FIRE_QUEUE_.push(event);
|
||||
Blockly.Events.fireNow_();
|
||||
});
|
||||
return stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared setup method that sets up fake timer for clock so that pending
|
||||
* setTimeout calls can be cleared in test teardown along with other common
|
||||
* stubs. Should be called in setup of outermost suite using
|
||||
* sharedTestSetup.call(this).
|
||||
* @param {Object<string, boolean>} options Options to enable/disable setup
|
||||
* of certain stubs.
|
||||
*/
|
||||
function sharedTestSetup(options = {}) {
|
||||
this.sharedSetupCalled_ = true;
|
||||
// Sandbox created for greater control when certain stubs are cleared.
|
||||
this.sharedSetupSandbox_ = sinon.createSandbox();
|
||||
this.clock = this.sharedSetupSandbox_.useFakeTimers();
|
||||
if (options['fireEventsNow'] === undefined || options['fireEventsNow']) {
|
||||
// Stubs event firing unless passed option "fireEventsNow: false"
|
||||
this.eventsFireStub = createEventsFireStubFireImmediately_(this.clock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared cleanup method that clears up pending setTimeout calls, disposes of
|
||||
* workspace, and resets global variables. Should be called in setup of
|
||||
* outermost suite using sharedTestTeardown.call(this).
|
||||
*/
|
||||
function sharedTestTeardown() {
|
||||
if (!this.sharedSetupCalled_) {
|
||||
console.error('"' + this.currentTest.fullTitle() +
|
||||
'" did not call sharedTestSetup');
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.workspace) {
|
||||
workspaceTeardown.call(this, this.workspace);
|
||||
this.workspace = null;
|
||||
} else {
|
||||
this.clock.runAll(); // Run all queued setTimeout calls.
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(this.currentTest.fullTitle() + '\n', e);
|
||||
} finally {
|
||||
// Clear Blockly.Event state.
|
||||
Blockly.Events.setGroup(false);
|
||||
Blockly.Events.disabled_ = 0;
|
||||
if (Blockly.Events.FIRE_QUEUE_.length) {
|
||||
// If this happens, it may mean that some previous test is missing cleanup
|
||||
// (i.e. a previous test added an event to the queue on a timeout that
|
||||
// did not use a stubbed clock).
|
||||
Blockly.Events.FIRE_QUEUE_.length = 0;
|
||||
console.warn(this.currentTest.fullTitle() +
|
||||
'" needed cleanup of Blockly.Events.FIRE_QUEUE_. This may indicate ' +
|
||||
'leakage from an earlier test');
|
||||
}
|
||||
|
||||
// Restore all stubbed methods.
|
||||
this.sharedSetupSandbox_.restore();
|
||||
sinon.restore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates stub for Blockly.utils.genUid that returns the provided id or ids.
|
||||
* Recommended to also assert that the stub is called the expected number of
|
||||
* times.
|
||||
* Recommended to also assert that the stub is called the expected number of
|
||||
* times.
|
||||
* @param {string|!Array<string>} returnIds The return values to use for the
|
||||
* created stub. If a single value is passed, then the stub always returns
|
||||
* that value.
|
||||
@@ -60,27 +164,6 @@ function createGenUidStubWithReturns(returnIds) {
|
||||
return stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates stub for Blockly.Events.fire that fires events immediately instead of
|
||||
* with timeout.
|
||||
* @return {!SinonStub} The created stub.
|
||||
*/
|
||||
function createEventsFireStub() {
|
||||
// TODO(#4064): Remove clearing of event clear here in favor of adding cleanup
|
||||
// to other tests that cause events to be added to the queue even after they
|
||||
// end.
|
||||
Blockly.Events.FIRE_QUEUE_.length = 0;
|
||||
var stub = sinon.stub(Blockly.Events, 'fire');
|
||||
stub.callsFake(function(event) {
|
||||
if (!Blockly.Events.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
Blockly.Events.FIRE_QUEUE_.push(event);
|
||||
Blockly.Events.fireNow_();
|
||||
});
|
||||
return stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates spy for workspace fireChangeListener
|
||||
* @param {!Blockly.Workspace} workspace The workspace to spy fireChangeListener
|
||||
@@ -124,7 +207,7 @@ function assertEventEquals(event, expectedType,
|
||||
|
||||
/**
|
||||
* Asserts that the event passed to the last call of the given spy has the
|
||||
* expected values. Assumes that the event is passed as the first argument.
|
||||
* expected values. Assumes that the event is passed as the first argument.
|
||||
* @param {!SinonSpy} spy The spy to use.
|
||||
* @param {string} expectedType Expected type of event fired.
|
||||
* @param {string} expectedWorkspaceId Expected workspace id of event fired.
|
||||
@@ -142,7 +225,7 @@ function assertLastCallEventArgEquals(spy, expectedType,
|
||||
|
||||
/**
|
||||
* Asserts that the event passed to the nth call of the given spy has the
|
||||
* expected values. Assumes that the event is passed as the first argument.
|
||||
* expected values. Assumes that the event is passed as the first argument.
|
||||
* @param {!SinonSpy} spy The spy to use.
|
||||
* @param {number} n Which call to check.
|
||||
* @param {string} expectedType Expected type of event fired.
|
||||
|
||||
@@ -26,7 +26,7 @@ suite("Trashcan", function() {
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
this.eventsStub = createEventsFireStub();
|
||||
sharedTestSetup.call(this);
|
||||
var options = new Blockly.Options(
|
||||
{'trashcan': true, 'maxTrashcanContents': Infinity});
|
||||
this.workspace = new Blockly.WorkspaceSvg(options);
|
||||
@@ -35,7 +35,7 @@ suite("Trashcan", function() {
|
||||
this.trashcan.svgLid_ = sinon.createStubInstance(SVGElement);
|
||||
});
|
||||
teardown(function() {
|
||||
sinon.restore();
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
suite("Events", function() {
|
||||
@@ -63,7 +63,7 @@ suite("Trashcan", function() {
|
||||
});
|
||||
test("Click without contents - fires no events", function() {
|
||||
this.trashcan.click();
|
||||
var lastFireCall = this.eventsStub.lastCall;
|
||||
var lastFireCall = this.eventsFireStub.lastCall;
|
||||
chai.assert.notExists(lastFireCall);
|
||||
});
|
||||
test("Click with contents - fires trashcanOpen", function() {
|
||||
@@ -73,7 +73,7 @@ suite("Trashcan", function() {
|
||||
var showFlyoutStub = sinon.stub(this.trashcan.flyout, "show");
|
||||
this.trashcan.click();
|
||||
assertLastCallEventArgEquals(
|
||||
this.eventsStub, Blockly.Events.UI, this.workspace.id, undefined,
|
||||
this.eventsFireStub, Blockly.Events.UI, this.workspace.id, undefined,
|
||||
{element: 'trashcanOpen', oldValue: null, newValue: true});
|
||||
sinon.assert.calledOnce(showFlyoutStub);
|
||||
});
|
||||
|
||||
@@ -8,11 +8,12 @@ goog.require('Blockly.WorkspaceComment');
|
||||
|
||||
suite('Workspace comment', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
this.workspace = new Blockly.Workspace();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.workspace.dispose();
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
suite('getTopComments(ordered=true)', function() {
|
||||
@@ -163,7 +164,6 @@ suite('Workspace comment', function() {
|
||||
|
||||
suite('Content', function() {
|
||||
setup(function() {
|
||||
createEventsFireStub();
|
||||
|
||||
this.comment = new Blockly.WorkspaceComment(
|
||||
this.workspace, 'comment text', 0, 0, 'comment id');
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
suite('WorkspaceSvg', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
var toolbox = document.getElementById('toolbox-categories');
|
||||
this.workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
@@ -26,10 +27,9 @@ suite('WorkspaceSvg', function() {
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sharedTestTeardown.call(this);
|
||||
delete Blockly.Blocks['simple_test_block'];
|
||||
delete Blockly.Blocks['test_val_in'];
|
||||
this.workspace.dispose();
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
test('appendDomToWorkspace alignment', function() {
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
|
||||
suite('Workspace', function() {
|
||||
setup(function() {
|
||||
sharedTestSetup.call(this);
|
||||
this.workspace = new Blockly.Workspace();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.workspace.dispose();
|
||||
sharedTestTeardown.call(this);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-use-before-define
|
||||
@@ -663,10 +664,6 @@ function testAWorkspace() {
|
||||
});
|
||||
|
||||
suite('Undo/Redo', function() {
|
||||
setup(function() {
|
||||
createEventsFireStub();
|
||||
});
|
||||
|
||||
function createTwoVarsDifferentTypes(workspace) {
|
||||
workspace.createVariable('name1', 'type1', 'id1');
|
||||
workspace.createVariable('name2', 'type2', 'id2');
|
||||
|
||||
Reference in New Issue
Block a user