diff --git a/tests/jsunit/generator_test.js b/tests/jsunit/generator_test.js
deleted file mode 100644
index b7187991b..000000000
--- a/tests/jsunit/generator_test.js
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * @license
- * Copyright 2012 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-'use strict';
-
-goog.require('Blockly.Dart');
-goog.require('Blockly.JavaScript');
-goog.require('Blockly.Lua');
-goog.require('Blockly.PHP');
-goog.require('Blockly.Python');
-
-var workspace;
-
-function defineGeneratorTestBlocks() {
- Blockly.defineBlocksWithJsonArray([{
- "type": "stack_block",
- "message0": "",
- "previousStatement": null,
- "nextStatement": null
- },
- {
- "type": "row_block",
- "message0": "%1",
- "args0": [
- {
- "type": "input_value",
- "name": "INPUT"
- }
- ],
- "output": null,
- "nextStatement": null
- },
- {
- "type": "controls_repeat_ext",
- "message0": "Repeat Loop",
- "message1": "%1",
- "args1": [{
- "type": "input_statement",
- "name": "DO"
- }],
- "previousStatement": null,
- "nextStatement": null
- }]);
-}
-
-function undefineGeneratorTestBlocks() {
- delete Blockly.Blocks['stack_block'];
- delete Blockly.Blocks['row_block'];
-}
-
-function generatorTest_setUp() {
- defineGeneratorTestBlocks();
- workspace = new Blockly.Workspace();
-}
-
-function generatorTest_tearDown() {
- undefineGeneratorTestBlocks();
- workspace.dispose();
-}
-
-function blockToCodeTestSetup(generator) {
- var row_block = workspace.newBlock('row_block');
- var stack_block = workspace.newBlock('stack_block');
-
- generator.row_block = function(block){return 'row_block'};
- generator.stack_block = function(block){return 'stack_block'};
- row_block.nextConnection.connect(stack_block.previousConnection);
- return row_block;
-}
-
-function blockToCodeTest(generator, opt_thisOnly) {
- var row_block = blockToCodeTestSetup(generator);
- return generator.blockToCode(row_block, opt_thisOnly);
-}
-
-function disabledBlockTest(generator, opt_thisOnly) {
- var row_block = blockToCodeTestSetup(generator);
- row_block.disabled=true;
- return generator.blockToCode(row_block, opt_thisOnly);
-}
-
-function nestedLoopTest(generator, opt_thisOnly) {
- Blockly.Msg['CONTROLS_REPEAT_TITLE'] = 'repeat %1 times';
- var blockA = workspace.newBlock('controls_repeat_ext');
- var blockB = workspace.newBlock('controls_repeat_ext');
- var blockC = workspace.newBlock('controls_repeat_ext');
- generator.controls_repeat_ext = getControlRepeatFunc(generator);
-
- blockA.getInput('DO').connection.connect(blockB.previousConnection);
- blockA.nextConnection.connect(blockC.previousConnection);
- return generator.blockToCode(blockA, opt_thisOnly);
-}
-
-function getControlRepeatFunc(generator) {
- return function(block){
- return '{' + generator.statementToCode(block, 'DO') + '}';
- };
-}
-
-function test_blockToCodeOnAllGeneartors() {
- generatorTest_setUp();
-
- assertEquals(blockToCodeTest(Blockly.Dart, true), 'row_block');
- assertEquals(blockToCodeTest(Blockly.Dart, false), 'row_blockstack_block');
-
- assertEquals(blockToCodeTest(Blockly.JavaScript, true), 'row_block');
- assertEquals(blockToCodeTest(Blockly.JavaScript, false), 'row_blockstack_block');
-
- assertEquals(blockToCodeTest(Blockly.Lua, true), 'row_block');
- assertEquals(blockToCodeTest(Blockly.Lua, false), 'row_blockstack_block');
-
- assertEquals(blockToCodeTest(Blockly.PHP, true), 'row_block');
- assertEquals(blockToCodeTest(Blockly.PHP, false), 'row_blockstack_block');
-
- assertEquals(blockToCodeTest(Blockly.Python, true), 'row_block');
- assertEquals(blockToCodeTest(Blockly.Python, false), 'row_blockstack_block');
-
- generatorTest_tearDown();
-}
-
-function test_disabledBlockToCode() {
- generatorTest_setUp();
-
- assertEquals(disabledBlockTest(Blockly.Dart, true), '');
- assertEquals(disabledBlockTest(Blockly.Dart, false), 'stack_block');
-
- assertEquals(disabledBlockTest(Blockly.JavaScript, true), '');
- assertEquals(disabledBlockTest(Blockly.JavaScript, false), 'stack_block');
-
- assertEquals(disabledBlockTest(Blockly.Lua, true), '');
- assertEquals(disabledBlockTest(Blockly.Lua, false), 'stack_block');
-
- assertEquals(disabledBlockTest(Blockly.PHP, true), '');
- assertEquals(disabledBlockTest(Blockly.PHP, false), 'stack_block');
-
- assertEquals(disabledBlockTest(Blockly.Python, true), '');
- assertEquals(disabledBlockTest(Blockly.Python, false), 'stack_block');
-
- generatorTest_tearDown();
-}
-
-// { {}} represents a nested block
-//{ {}}{} represents a nested block with a block after it
-function test_nestedLoopBlockToCode() {
- generatorTest_setUp();
-
- assertEquals(nestedLoopTest(Blockly.Dart, true), '{ {}}');
- assertEquals(nestedLoopTest(Blockly.Dart, false), '{ {}}{}');
-
- assertEquals(nestedLoopTest(Blockly.JavaScript, true), '{ {}}');
- assertEquals(nestedLoopTest(Blockly.JavaScript, false), '{ {}}{}');
-
- assertEquals(nestedLoopTest(Blockly.Lua, true), '{ {}}');
- assertEquals(nestedLoopTest(Blockly.Lua, false), '{ {}}{}');
-
- assertEquals(nestedLoopTest(Blockly.PHP, true), '{ {}}');
- assertEquals(nestedLoopTest(Blockly.PHP, false), '{ {}}{}');
-
- assertEquals(nestedLoopTest(Blockly.Python, true), '{ {}}');
- assertEquals(nestedLoopTest(Blockly.Python, false), '{ {}}{}');
-
- generatorTest_tearDown();
-}
-
-function test_prefix() {
- var generator = new Blockly.Generator('INTERCAL');
- assertEquals('Prefix nothing.', '', generator.prefixLines('', ''));
- assertEquals('Prefix a word.', '@Hello', generator.prefixLines('Hello', '@'));
- assertEquals('Prefix one line.', '12Hello\n', generator.prefixLines('Hello\n', '12'));
- assertEquals('Prefix two lines.', '***Hello\n***World\n', generator.prefixLines('Hello\nWorld\n', '***'));
-}
\ No newline at end of file
diff --git a/tests/jsunit/index.html b/tests/jsunit/index.html
index feb2d2e93..38ad75f9a 100644
--- a/tests/jsunit/index.html
+++ b/tests/jsunit/index.html
@@ -17,8 +17,7 @@
-
-
+
diff --git a/tests/mocha/generator_test.js b/tests/mocha/generator_test.js
new file mode 100644
index 000000000..cf91990ea
--- /dev/null
+++ b/tests/mocha/generator_test.js
@@ -0,0 +1,158 @@
+/**
+ * @license
+ * Copyright 2020 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+goog.require('Blockly.Dart');
+goog.require('Blockly.JavaScript');
+goog.require('Blockly.Lua');
+goog.require('Blockly.PHP');
+goog.require('Blockly.Python');
+
+suite('Generator', function() {
+ setup(function() {
+ this.workspace = new Blockly.Workspace();
+ });
+
+ teardown(function() {
+ this.workspace.dispose();
+ });
+
+ suite('prefix', function() {
+ setup(function() {
+ this.generator = new Blockly.Generator('INTERCAL');
+ });
+
+ test('Nothing', function() {
+ chai.assert.equal(this.generator.prefixLines('', ''), '');
+ });
+
+ test('One word', function() {
+ chai.assert.equal(this.generator.prefixLines('Hello', '@'), '@Hello') ;
+ });
+
+ test('One line', function() {
+ chai.assert.equal(this.generator.prefixLines('Hello\n', '12'), '12Hello\n');
+ });
+
+ test('Two lines', function() {
+ chai.assert.equal(this.generator.prefixLines('Hello\nWorld\n', '***'), '***Hello\n***World\n');
+ });
+ });
+
+ suite('blockToCode', function() {
+ 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,
+ "nextStatement": null
+ }]);
+ var rowBlock = this.workspace.newBlock('row_block');
+ var stackBlock = this.workspace.newBlock('stack_block');
+
+ this.blockToCodeTest = function(
+ generator, blockDisabled, opt_thisOnly,
+ expectedCode, opt_message) {
+ generator.row_block = function(_){return 'row_block';};
+ generator.stack_block = function(_){return 'stack_block';};
+ rowBlock.nextConnection.connect(stackBlock.previousConnection);
+ rowBlock.disabled = blockDisabled;
+
+ var code = generator.blockToCode(rowBlock, opt_thisOnly);
+ chai.assert.equal(code, expectedCode, opt_message);
+ };
+ });
+
+ teardown(function() {
+ delete Blockly.Blocks['stack_block'];
+ delete Blockly.Blocks['row_block'];
+ });
+
+ var testCase = [
+ [Blockly.Dart, 'Dart'],
+ [Blockly.JavaScript, 'JavaScript'],
+ [Blockly.Lua, 'Lua'],
+ [Blockly.PHP, 'PHP'],
+ [Blockly.Python, 'Python']];
+
+ suite('Trivial', function() {
+ testCase.forEach(function(testCase) {
+ var generator = testCase[0];
+ var name = testCase[1];
+ test(name, function() {
+ this.blockToCodeTest(generator, false, true, 'row_block');
+ this.blockToCodeTest(
+ generator, false, false, 'row_blockstack_block', 'thisOnly=false');
+ });
+ });
+ });
+
+ suite('Disabled block', function() {
+ testCase.forEach(function(testCase) {
+ var generator = testCase[0];
+ var name = testCase[1];
+ test(name, function() {
+ this.blockToCodeTest(generator, true, true, '');
+ this.blockToCodeTest(generator, true, false, 'stack_block', 'thisOnly=false');
+ });
+ });
+ });
+
+ suite('Nested block', function() {
+ setup(function() {
+ Blockly.defineBlocksWithJsonArray([ {
+ "type": "test_loop_block",
+ "message0": "Repeat Loop",
+ "message1": "%1",
+ "args1": [{
+ "type": "input_statement",
+ "name": "DO"
+ }],
+ "previousStatement": null,
+ "nextStatement": null
+ }]);
+ var blockA = this.workspace.newBlock('test_loop_block');
+ var blockB = this.workspace.newBlock('test_loop_block');
+ var blockC = this.workspace.newBlock('test_loop_block');
+ this.loopTest = function(
+ generator, opt_thisOnly, expectedCode, opt_message) {
+ generator.test_loop_block = function(block){
+ return '{' + generator.statementToCode(block, 'DO') + '}';
+ };
+ blockA.getInput('DO').connection.connect(blockB.previousConnection);
+ blockA.nextConnection.connect(blockC.previousConnection);
+
+ var code = generator.blockToCode(blockA, opt_thisOnly);
+ chai.assert.equal(code, expectedCode, opt_message);
+ };
+ });
+
+ teardown(function() {
+ delete Blockly.Blocks['test_loop_block'];
+ });
+
+ testCase.forEach(function(testCase) {
+ var generator = testCase[0];
+ var name = testCase[1];
+ test(name, function() {
+ this.loopTest(generator, true, '{ {}}');
+ this.loopTest(generator, false, '{ {}}{}', 'thisOnly=false');
+ });
+ });
+ });
+ });
+});
diff --git a/tests/mocha/index.html b/tests/mocha/index.html
index c3f0e03c9..09d2e7cdf 100644
--- a/tests/mocha/index.html
+++ b/tests/mocha/index.html
@@ -6,6 +6,11 @@
+
+
+
+
+
@@ -47,6 +52,7 @@
+