Add jsunit->chai assert converters, and block tests

This commit is contained in:
Rachel Fenichel
2018-12-07 16:18:14 -08:00
parent 376bed8c46
commit e27f58ada7
4 changed files with 335 additions and 77 deletions

182
tests/mocha/block_test.js Normal file
View File

@@ -0,0 +1,182 @@
// Declare some globals to make eslint happier.
// TODO: make an eslint config that applies to this directory and put this
// configuration in that file, instead of inline.
/* global suite, test, chai, setup, teardown */
/* global assertFalse, assertTrue, assertNull, assertEquals */
suite('Blocks', function() {
suite('Unplug', function() {
function assertUnpluggedNoheal(blocks) {
// A has nothing connected to it.
assertEquals(0, blocks.A.getChildren().length);
// B and C are still connected.
assertEquals(blocks.B, blocks.C.getParent());
// B is the top of its stack.
assertNull(blocks.B.getParent());
}
function assertUnpluggedHealed(blocks) {
// A and C are connected.
assertEquals(1, blocks.A.getChildren().length);
assertEquals(blocks.A, blocks.C.getParent());
// B has nothing connected to it.
assertEquals(0, blocks.B.getChildren().length);
// B is the top of its stack.
assertNull(blocks.B.getParent());
}
setup(function() {
Blockly.defineBlocksWithJsonArray([{
"type": "stack_block",
"message0": "",
"previousStatement": null,
"nextStatement": null
},
{
"type": "row_block",
"message0": "%1",
"args0": [
{
"type": "input_value",
"name": "INPUT"
}
],
"output": null
}]);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
delete Blockly.Blocks['stack_block'];
delete Blockly.Blocks['row_block'];
this.workspace.dispose();
});
suite('Row', function() {
setup(function() {
var blockA = this.workspace.newBlock('row_block');
var blockB = this.workspace.newBlock('row_block');
var blockC = this.workspace.newBlock('row_block');
blockA.inputList[0].connection.connect(blockB.outputConnection);
blockB.inputList[0].connection.connect(blockC.outputConnection);
assertEquals(blockB, blockC.getParent());
this.blocks = {
A: blockA,
B: blockB,
C: blockC
};
});
test('Don\'t heal', function() {
this.blocks.B.unplug(false);
assertUnpluggedNoheal(this.blocks);
});
test('Heal', function() {
this.blocks.B.unplug(true);
// Each block has only one input, and the types work.
assertUnpluggedHealed(this.blocks);
});
test('Heal with bad checks', function() {
var blocks = this.blocks;
// A and C can't connect, but both can connect to B.
blocks.A.inputList[0].connection.setCheck('type1');
blocks.C.outputConnection.setCheck('type2');
// Each block has only one input, but the types don't work.
blocks.B.unplug(true);
assertUnpluggedNoheal(blocks);
});
test('Parent has multiple inputs', function() {
var blocks = this.blocks;
// Add extra input to parent
blocks.A.appendValueInput("INPUT").setCheck(null);
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
});
test('Middle block has multiple inputs', function() {
var blocks = this.blocks;
// Add extra input to middle block
blocks.B.appendValueInput("INPUT").setCheck(null);
blocks.B.unplug(true);
assertUnpluggedNoheal(blocks);
});
test('Child block has multiple inputs', function() {
var blocks = this.blocks;
// Add extra input to child block
blocks.C.appendValueInput("INPUT").setCheck(null);
// Child block input count doesn't matter.
blocks.B.unplug(true);
assertUnpluggedHealed(blocks);
});
});
suite('Stack', function() {
setup(function() {
var blockA = this.workspace.newBlock('stack_block');
var blockB = this.workspace.newBlock('stack_block');
var blockC = this.workspace.newBlock('stack_block');
blockA.nextConnection.connect(blockB.previousConnection);
blockB.nextConnection.connect(blockC.previousConnection);
assertEquals(blockB, blockC.getParent());
this.blocks = {
A: blockA,
B: blockB,
C: blockC
};
});
test('Don\'t heal', function() {
this.blocks.B.unplug();
assertUnpluggedNoheal(this.blocks);
});
test('Heal', function() {
this.blocks.B.unplug(true);
assertUnpluggedHealed(this.blocks);
});
test('Heal with bad checks', function() {
var blocks = this.blocks;
// A and C can't connect, but both can connect to B.
blocks.A.nextConnection.setCheck('type1');
blocks.C.previousConnection.setCheck('type2');
// The types don't work.
blocks.B.unplug(true);
// Stack blocks unplug before checking whether the types match.
// TODO (#1994): Check types before unplugging.
// A has nothing connected to it.
assertEquals(0, blocks.A.getChildren().length);
// B has nothing connected to it.
assertEquals(0, blocks.B.getChildren().length);
// C has nothing connected to it.
assertEquals(0, blocks.C.getChildren().length);
// A is the top of its stack.
assertNull(blocks.A.getParent());
// B is the top of its stack.
assertNull(blocks.B.getParent());
// C is the top of its stack.
assertNull(blocks.C.getParent());
});
});
});
});

View File

@@ -17,6 +17,8 @@
ui: 'tdd'
});
</script>
<script src="test_helpers.js"></script>
<script src="block_test.js"></script>
<script src="utils_test.js"></script>
<script>

View File

@@ -0,0 +1,73 @@
function _argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) {
return args.length == expectedNumberOfNonCommentArgs + 1;
}
function _commentArg(expectedNumberOfNonCommentArgs, args) {
if (_argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) {
return args[0];
}
return null;
}
function _nonCommentArg(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) {
return _argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ?
args[desiredNonCommentArgIndex] :
args[desiredNonCommentArgIndex - 1];
}
function _validateArguments(expectedNumberOfNonCommentArgs, args) {
if (!( args.length == expectedNumberOfNonCommentArgs ||
(args.length == expectedNumberOfNonCommentArgs + 1 && (typeof(args[0]) == 'string') || args[0] == null))) {
throw new Error('Incorrect arguments passed to assert function');
}
}
/**
* Converts from JSUnit assertEquals to chai.assert.equal.
*/
function assertEquals() {
_validateArguments(2, arguments);
var var1 = _nonCommentArg(1, 2, arguments);
var var2 = _nonCommentArg(2, 2, arguments);
var comment = _commentArg(2, arguments);
chai.assert.equal(var1, var2, comment);
}
/**
* Converts from JSUnit assertTrue to chai.assert.isTrue.
*/
function assertTrue() {
_validateArguments(1, arguments);
var commentArg = _commentArg(1, arguments);
var booleanValue = _nonCommentArg(1, 1, arguments);
if (typeof(booleanValue) != 'boolean') {
throw new Error('Bad argument to assertTrue(boolean)');
}
chai.assert.isTrue(booleanValue, commentArg);
}
/**
* Converts from JSUnit assertFalse to chai.assert.isNotTrue.
*/
function assertFalse() {
_validateArguments(1, arguments);
var commentArg = _commentArg(1, arguments);
var booleanValue = _nonCommentArg(1, 1, arguments);
if (typeof(booleanValue) != 'boolean') {
throw new Error('Bad argument to assertFalse(boolean)');
}
chai.assert.isNotTrue(booleanValue, commentArg);
}
/**
* Converts from JSUnit assertNull to chai.assert.isNull.
*/
function assertNull() {
_validateArguments(1, arguments);
var commentArg = _commentArg(1, arguments);
var val = _nonCommentArg(1, 1, arguments);
chai.assert.isNull(val, commentArg);
}

View File

@@ -1,3 +1,9 @@
// Declare some globals to make eslint happier.
// TODO: make an eslint config that applies to this directory and put this
// configuration in that file, instead of inline.
/* global suite, test, chai, assertFalse, assertTrue, assertEquals */
// var assert = require('assert');
// describe('Array', function() {
// describe('#indexOf()', function() {
@@ -7,94 +13,91 @@
// });
// });
suite('Utils', function() {
test('genUid', function() {
var uuids = {};
chai.assert.equal([1,2,3].indexOf(4), -1);
for (var i = 0; i < 1000; i++) {
var uuid = Blockly.utils.genUid();
chai.assert.isTrue(uuid in uuids, 'UUID different: ' + uuid);
chai.assert.isFalse(uuid in uuids, 'UUID different: ' + uuid);
uuids[uuid] = true;
}
});
test('addClass', function() {
var p = document.createElement('p');
Blockly.utils.addClass(p, 'one');
assertEquals('Adding "one"', 'one', p.className);
Blockly.utils.addClass(p, 'one');
assertEquals('Adding duplicate "one"', 'one', p.className);
Blockly.utils.addClass(p, 'two');
assertEquals('Adding "two"', 'one two', p.className);
Blockly.utils.addClass(p, 'two');
assertEquals('Adding duplicate "two"', 'one two', p.className);
Blockly.utils.addClass(p, 'three');
assertEquals('Adding "three"', 'one two three', p.className);
});
test('hasClass', function() {
var p = document.createElement('p');
p.className = ' one three two three ';
assertTrue('Has "one"', Blockly.utils.hasClass(p, 'one'));
assertTrue('Has "two"', Blockly.utils.hasClass(p, 'two'));
assertTrue('Has "three"', Blockly.utils.hasClass(p, 'three'));
assertFalse('Has no "four"', Blockly.utils.hasClass(p, 'four'));
assertFalse('Has no "t"', Blockly.utils.hasClass(p, 't'));
});
// function test_addClass() {
// var p = document.createElement('p');
// Blockly.utils.addClass(p, 'one');
// assertEquals('Adding "one"', 'one', p.className);
// Blockly.utils.addClass(p, 'one');
// assertEquals('Adding duplicate "one"', 'one', p.className);
// Blockly.utils.addClass(p, 'two');
// assertEquals('Adding "two"', 'one two', p.className);
// Blockly.utils.addClass(p, 'two');
// assertEquals('Adding duplicate "two"', 'one two', p.className);
// Blockly.utils.addClass(p, 'three');
// assertEquals('Adding "three"', 'one two three', p.className);
// }
test('removeClass', function() {
var p = document.createElement('p');
p.className = ' one three two three ';
Blockly.utils.removeClass(p, 'two');
assertEquals('Removing "two"', 'one three three', p.className);
Blockly.utils.removeClass(p, 'four');
assertEquals('Removing "four"', 'one three three', p.className);
Blockly.utils.removeClass(p, 'three');
assertEquals('Removing "three"', 'one', p.className);
Blockly.utils.removeClass(p, 'ne');
assertEquals('Removing "ne"', 'one', p.className);
Blockly.utils.removeClass(p, 'one');
assertEquals('Removing "one"', '', p.className);
Blockly.utils.removeClass(p, 'zero');
assertEquals('Removing "zero"', '', p.className);
});
// function test_hasClass() {
// var p = document.createElement('p');
// p.className = ' one three two three ';
// assertTrue('Has "one"', Blockly.utils.hasClass(p, 'one'));
// assertTrue('Has "two"', Blockly.utils.hasClass(p, 'two'));
// assertTrue('Has "three"', Blockly.utils.hasClass(p, 'three'));
// assertFalse('Has no "four"', Blockly.utils.hasClass(p, 'four'));
// assertFalse('Has no "t"', Blockly.utils.hasClass(p, 't'));
// }
// function test_removeClass() {
// var p = document.createElement('p');
// p.className = ' one three two three ';
// Blockly.utils.removeClass(p, 'two');
// assertEquals('Removing "two"', 'one three three', p.className);
// Blockly.utils.removeClass(p, 'four');
// assertEquals('Removing "four"', 'one three three', p.className);
// Blockly.utils.removeClass(p, 'three');
// assertEquals('Removing "three"', 'one', p.className);
// Blockly.utils.removeClass(p, 'ne');
// assertEquals('Removing "ne"', 'one', p.className);
// Blockly.utils.removeClass(p, 'one');
// assertEquals('Removing "one"', '', p.className);
// Blockly.utils.removeClass(p, 'zero');
// assertEquals('Removing "zero"', '', p.className);
// }
// function test_shortestStringLength() {
// var len = Blockly.utils.shortestStringLength('one,two,three,four,five'.split(','));
// assertEquals('Length of "one"', 3, len);
// len = Blockly.utils.shortestStringLength('one,two,three,four,five,'.split(','));
// assertEquals('Length of ""', 0, len);
// len = Blockly.utils.shortestStringLength(['Hello World']);
// assertEquals('List of one', 11, len);
// len = Blockly.utils.shortestStringLength([]);
// assertEquals('Empty list', 0, len);
// }
// function test_commonWordPrefix() {
// var len = Blockly.utils.commonWordPrefix('one,two,three,four,five'.split(','));
// assertEquals('No prefix', 0, len);
// len = Blockly.utils.commonWordPrefix('Xone,Xtwo,Xthree,Xfour,Xfive'.split(','));
// assertEquals('No word prefix', 0, len);
// len = Blockly.utils.commonWordPrefix('abc de,abc de,abc de,abc de'.split(','));
// assertEquals('Full equality', 6, len);
// len = Blockly.utils.commonWordPrefix('abc deX,abc deY'.split(','));
// assertEquals('One word prefix', 4, len);
// len = Blockly.utils.commonWordPrefix('abc de,abc deY'.split(','));
// assertEquals('Overflow no', 4, len);
// len = Blockly.utils.commonWordPrefix('abc de,abc de Y'.split(','));
// assertEquals('Overflow yes', 6, len);
// len = Blockly.utils.commonWordPrefix(['Hello World']);
// assertEquals('List of one', 11, len);
// len = Blockly.utils.commonWordPrefix([]);
// assertEquals('Empty list', 0, len);
// len = Blockly.utils.commonWordPrefix('turn&nbsp;left,turn&nbsp;right'.split(','));
// assertEquals('No prefix due to &amp;nbsp;', 0, len);
// len = Blockly.utils.commonWordPrefix('turn\u00A0left,turn\u00A0right'.split(','));
// assertEquals('No prefix due to \\u00A0', 0, len);
// }
test('shortest string length', function() {
var len = Blockly.utils.shortestStringLength('one,two,three,four,five'.split(','));
assertEquals('Length of "one"', 3, len);
len = Blockly.utils.shortestStringLength('one,two,three,four,five,'.split(','));
assertEquals('Length of ""', 0, len);
len = Blockly.utils.shortestStringLength(['Hello World']);
assertEquals('List of one', 11, len);
len = Blockly.utils.shortestStringLength([]);
assertEquals('Empty list', 0, len);
});
test('comment word prefix', function() {
var len = Blockly.utils.commonWordPrefix('one,two,three,four,five'.split(','));
assertEquals('No prefix', 0, len);
len = Blockly.utils.commonWordPrefix('Xone,Xtwo,Xthree,Xfour,Xfive'.split(','));
assertEquals('No word prefix', 0, len);
len = Blockly.utils.commonWordPrefix('abc de,abc de,abc de,abc de'.split(','));
assertEquals('Full equality', 6, len);
len = Blockly.utils.commonWordPrefix('abc deX,abc deY'.split(','));
assertEquals('One word prefix', 4, len);
len = Blockly.utils.commonWordPrefix('abc de,abc deY'.split(','));
assertEquals('Overflow no', 4, len);
len = Blockly.utils.commonWordPrefix('abc de,abc de Y'.split(','));
assertEquals('Overflow yes', 6, len);
len = Blockly.utils.commonWordPrefix(['Hello World']);
assertEquals('List of one', 11, len);
len = Blockly.utils.commonWordPrefix([]);
assertEquals('Empty list', 0, len);
len = Blockly.utils.commonWordPrefix('turn&nbsp;left,turn&nbsp;right'.split(','));
assertEquals('No prefix due to &amp;nbsp;', 0, len);
len = Blockly.utils.commonWordPrefix('turn\u00A0left,turn\u00A0right'.split(','));
assertEquals('No prefix due to \\u00A0', 0, len);
});
});
// function test_commonWordSuffix() {
// var len = Blockly.utils.commonWordSuffix('one,two,three,four,five'.split(','));
// assertEquals('No prefix', 0, len);
@@ -263,5 +266,3 @@ suite('Utils', function() {
// assertEquals('360', 360, Blockly.utils.toDegrees(4 * quarter));
// assertEquals('450', 360 + 90, Blockly.utils.toDegrees(5 * quarter));
// }
});