diff --git a/blocks/variables_dynamic.js b/blocks/variables_dynamic.js index 5d523f7e3..78598068b 100644 --- a/blocks/variables_dynamic.js +++ b/blocks/variables_dynamic.js @@ -98,11 +98,11 @@ Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MI */ customContextMenu: function(options) { // Getter blocks have the option to create a setter block, and vice versa. - if(this.isInFlyout){ + if (this.isInFlyout) { return; } - var opposite_type ; - var contextMenuMsg ; + var opposite_type; + var contextMenuMsg; if (this.type == 'variables_get_dynamic') { opposite_type = 'variables_set_dynamic'; contextMenuMsg = Blockly.Msg.VARIABLES_GET_CREATE_SET; @@ -124,8 +124,8 @@ Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MI options.push(option); }, onchange: function() { - var name = this.getFieldValue('VAR'); - var variableModel = this.workspace.getVariable(name); + var id = this.getFieldValue('VAR'); + var variableModel = this.workspace.getVariableById(id); if (this.type == 'variables_get_dynamic') { this.outputConnection.setCheck(variableModel.type); } else { diff --git a/core/extensions.js b/core/extensions.js index 1ce582cc1..774233c8d 100644 --- a/core/extensions.js +++ b/core/extensions.js @@ -74,6 +74,9 @@ Blockly.Extensions.register = function(name, initFn) { * registered. */ Blockly.Extensions.registerMixin = function(name, mixinObj) { + if (!goog.isObject(mixinObj)){ + throw new Error('Error: Mixin "' + name + '" must be a object'); + } Blockly.Extensions.register(name, function() { this.mixin(mixinObj); }); diff --git a/core/flyout_base.js b/core/flyout_base.js index 29ca24d18..6ee69aa30 100644 --- a/core/flyout_base.js +++ b/core/flyout_base.js @@ -269,6 +269,9 @@ Blockly.Flyout.prototype.init = function(targetWorkspace) { this.workspace_.renameVariableById = this.targetWorkspace_.renameVariableById.bind(this.targetWorkspace_); + + this.workspace_.getVariableTypes = + this.targetWorkspace_.getVariableTypes.bind(this.targetWorkspace_); }; /** diff --git a/core/variable_map.js b/core/variable_map.js index 5081db09a..0995d4fdd 100644 --- a/core/variable_map.js +++ b/core/variable_map.js @@ -247,11 +247,21 @@ Blockly.VariableMap.prototype.getVariablesOfType = function(type) { }; /** - * Return all variable types. + * Return all variable types. This list always contains the empty string. * @return {!Array.} List of variable types. */ Blockly.VariableMap.prototype.getVariableTypes = function() { - return Object.keys(this.variableMap_); + var types = Object.keys(this.variableMap_); + var hasEmpty = false; + for (var i = 0; i < types.length; i++) { + if (types[i] == '') { + hasEmpty = true; + } + } + if (!hasEmpty) { + types.push(''); + } + return types; }; /** diff --git a/tests/generators/unittest_dart.js b/tests/generators/unittest_dart.js index 75b165df4..97e6ae466 100644 --- a/tests/generators/unittest_dart.js +++ b/tests/generators/unittest_dart.js @@ -62,13 +62,10 @@ Blockly.Dart['unittest_main'] = function(block) { // Run tests (unindented). code += Blockly.Dart.statementToCode(block, 'DO') .replace(/^ /, '').replace(/\n /g, '\n'); - var reportVar = Blockly.Dart.variableDB_.getDistinctName( - 'report', Blockly.Variables.NAME_TYPE); - code += 'String ' + reportVar + ' = ' + functionName + '();\n'; + // Print the report to the console (that's where errors will go anyway). + code += 'print(' + functionName + '());\n'; // Destroy results. code += resultsVar + ' = null;\n'; - // Print the report to the console (that's where errors will go anyway). - code += 'print(' + reportVar + ');\n'; return code; }; @@ -143,8 +140,7 @@ Blockly.Dart['unittest_fail'] = function(block) { // Always assert an error. var resultsVar = Blockly.Dart.variableDB_.getName('unittestResults', Blockly.Variables.NAME_TYPE); - var message = Blockly.Dart.valueToCode(block, 'MESSAGE', - Blockly.Dart.ORDER_NONE) || ''; + var message = Blockly.Dart.quote_(block.getFieldValue('MESSAGE')); var functionName = Blockly.Dart.provideFunction_( 'unittest_fail', [ 'void ' + Blockly.Dart.FUNCTION_NAME_PLACEHOLDER_ + diff --git a/tests/generators/unittest_javascript.js b/tests/generators/unittest_javascript.js index db9d62ff1..9fda5be30 100644 --- a/tests/generators/unittest_javascript.js +++ b/tests/generators/unittest_javascript.js @@ -63,13 +63,10 @@ Blockly.JavaScript['unittest_main'] = function(block) { // Run tests (unindented). code += Blockly.JavaScript.statementToCode(block, 'DO') .replace(/^ /, '').replace(/\n /g, '\n'); - var reportVar = Blockly.JavaScript.variableDB_.getDistinctName( - 'report', Blockly.Variables.NAME_TYPE); - code += 'var ' + reportVar + ' = ' + functionName + '();\n'; + // Send the report to the console (that's where errors will go anyway). + code += 'console.log(' + functionName + '());\n'; // Destroy results. code += resultsVar + ' = null;\n'; - // Send the report to the console (that's where errors will go anyway). - code += 'console.log(' + reportVar + ');\n'; return code; }; @@ -147,8 +144,7 @@ Blockly.JavaScript['unittest_fail'] = function(block) { // Always assert an error. var resultsVar = Blockly.JavaScript.variableDB_.getName('unittestResults', Blockly.Variables.NAME_TYPE); - var message = Blockly.JavaScript.valueToCode(block, 'MESSAGE', - Blockly.JavaScript.ORDER_NONE) || ''; + var message = Blockly.JavaScript.quote_(block.getFieldValue('MESSAGE')); var functionName = Blockly.JavaScript.provideFunction_( 'unittest_fail', [ 'function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + diff --git a/tests/generators/unittest_lua.js b/tests/generators/unittest_lua.js index d687b091b..73c5dbe0d 100644 --- a/tests/generators/unittest_lua.js +++ b/tests/generators/unittest_lua.js @@ -61,13 +61,10 @@ Blockly.Lua['unittest_main'] = function(block) { // Run tests (unindented). code += Blockly.Lua.statementToCode(block, 'DO') .replace(/^ /, '').replace(/\n /g, '\n'); - var reportVar = Blockly.Lua.variableDB_.getDistinctName( - 'report', Blockly.Variables.NAME_TYPE); - code += reportVar + ' = ' + functionName + '()\n'; + // Print the report. + code += 'print(' + functionName + '())\n'; // Destroy results. code += resultsVar + ' = nil\n'; - // Print the report. - code += 'print(' + reportVar + ')\n'; return code; }; @@ -153,8 +150,7 @@ Blockly.Lua['unittest_fail'] = function(block) { // Always assert an error. var resultsVar = Blockly.Lua.variableDB_.getName('unittestResults', Blockly.Variables.NAME_TYPE); - var message = Blockly.Lua.valueToCode(block, 'MESSAGE', - Blockly.Lua.ORDER_NONE) || ''; + var message = Blockly.Lua.quote_(block.getFieldValue('MESSAGE')); var functionName = Blockly.Lua.provideFunction_( 'unittest_fail', ['function ' + Blockly.Lua.FUNCTION_NAME_PLACEHOLDER_ + '(message)', diff --git a/tests/generators/unittest_php.js b/tests/generators/unittest_php.js index 28e6b2799..528e5971d 100644 --- a/tests/generators/unittest_php.js +++ b/tests/generators/unittest_php.js @@ -25,147 +25,124 @@ 'use strict'; Blockly.PHP['unittest_main'] = function(block) { - // Container for unit tests. - var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults', - Blockly.Variables.NAME_TYPE); - var functionName = Blockly.PHP.provideFunction_( - 'unittest_report', - [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {', - 'global ' + resultsVar + ';', - ' // Create test report.', - ' $report = array();', - ' $summary = array();', - ' $fails = 0;', - ' for ($x = 0; $x < count(' + resultsVar + '); $x++) {', - ' if (' + resultsVar + '[$x][0]) {', - ' array_push($summary, ".");', - ' } else {', - ' array_push($summary, "F");', - ' $fails++;', - ' array_push($report,"");', - ' array_push($report, "FAIL: " . ' + resultsVar + '[$x][2]);', - ' array_push($report, ' + resultsVar + '[$x][1]);', - ' }', - ' }', - ' array_unshift($report, implode("",$summary));', - ' array_push($report, "");', - ' array_push($report, "Number of tests run: " . count(' + resultsVar + '));', - ' array_push($report, "");', - ' if ($fails) {', - ' array_push($report, "FAILED (failures=" . $fails + ")");', - ' } else {', - ' array_push($report, "OK");', - ' }', - ' return implode("\\n", $report);', - '}']); - // Setup global to hold test results. - var code = resultsVar + ' = array();\n'; - // Run tests (unindented). - code += Blockly.PHP.statementToCode(block, 'DO') - .replace(/^ /, '').replace(/\n /g, '\n'); - var reportVar = Blockly.PHP.variableDB_.getDistinctName( - 'report', Blockly.Variables.NAME_TYPE); - code += reportVar + ' = ' + functionName + '();\n'; - // Destroy results. - code += resultsVar + ' = null;\n'; - // Send the report to the console (that's where errors will go anyway). - code += 'print(' + reportVar + ');\n'; - return code; + // Container for unit tests. + var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults', + Blockly.Variables.NAME_TYPE); + var functionName = Blockly.PHP.provideFunction_( + 'unittest_report', + [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + '() {', + ' global ' + resultsVar + ';', + ' // Create test report.', + ' $report = array();', + ' $summary = array();', + ' $fails = 0;', + ' for ($x = 0; $x < count(' + resultsVar + '); $x++) {', + ' if (' + resultsVar + '[$x][0]) {', + ' array_push($summary, ".");', + ' } else {', + ' array_push($summary, "F");', + ' $fails++;', + ' array_push($report, "");', + ' array_push($report, "FAIL: " . ' + resultsVar + '[$x][2]);', + ' array_push($report, ' + resultsVar + '[$x][1]);', + ' }', + ' }', + ' array_unshift($report, implode("", $summary));', + ' array_push($report, "");', + ' array_push($report, "Number of tests run: " . count(' + resultsVar + '));', + ' array_push($report, "");', + ' if ($fails) {', + ' array_push($report, "FAILED (failures=" . $fails + ")");', + ' } else {', + ' array_push($report, "OK");', + ' }', + ' return implode("\\n", $report);', + '}']); + // Setup global to hold test results. + var code = resultsVar + ' = array();\n'; + // Run tests (unindented). + code += Blockly.PHP.statementToCode(block, 'DO') + .replace(/^ /, '').replace(/\n /g, '\n'); + // Send the report to the console (that's where errors will go anyway). + code += 'print(' + functionName + '());\n'; + // Destroy results. + code += resultsVar + ' = null;\n'; + return code; }; Blockly.PHP['unittest_main'].defineAssert_ = function(block) { - var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults', - Blockly.Variables.NAME_TYPE); - var functionName = Blockly.PHP.provideFunction_( - 'assertEquals', - [' function equals($a, $b) {', - ' if ($a === $b) {', - ' return true;', - ' } else if ((is_numeric($a)) && (is_numeric($b)) &&', - ' (round($a,15) == round($b,15))) {', - ' return true;', - ' } else if (is_array($a) && is_array($b)) {', - ' if (count($a) != count($b)) {', - ' return false;', - ' }', - ' for ($i = 0; $i < count($a); $i++) {', - ' if (!equals($a[$i], $b[$i])) {', - ' return false;', - ' }', - ' }', - ' return true;', - ' }', - ' return false;', - ' }', - 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + - '($actual, $expected, $message) {', - 'global ' + resultsVar + ';', - ' // Asserts that a value equals another value.', - ' if (!is_array(' + resultsVar + ')) {', - ' throw new Exception("Orphaned assert: " . $message);', - ' }', - ' if (equals($actual, $expected)) {', - ' array_push(' + resultsVar + ', [true, "OK", $message]);', - ' } else {', - ' $expected = is_array($expected) ? implode(" ", $expected) : ' + - '$expected;', - ' $actual = is_array($actual) ? implode(" ", $actual) : ' + - '$actual;', - ' array_push(' + resultsVar + ', [false, ' + - '"Expected: " . $expected . "\\nActual: " . $actual, $message]);', - ' }', - '}']); - return functionName; + var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults', + Blockly.Variables.NAME_TYPE); + var functionName = Blockly.PHP.provideFunction_( + 'assertEquals', + ['function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + '($actual, $expected, $message) {', + ' global ' + resultsVar + ';', + ' // Asserts that a value equals another value.', + ' if (!is_array(' + resultsVar + ')) {', + ' throw new Exception("Orphaned assert: " . $message);', + ' }', + ' if ($actual == $expected) {', + ' array_push(' + resultsVar + ', [true, "OK", $message]);', + ' } else {', + ' $expected = is_array($expected) ? implode(" ", $expected) : ' + + '$expected;', + ' $actual = is_array($actual) ? implode(" ", $actual) : ' + + '$actual;', + ' array_push(' + resultsVar + ', [false, ' + + '"Expected: " . $expected . "\\nActual: " . $actual, $message]);', + ' }', + '}']); + return functionName; }; Blockly.PHP['unittest_assertequals'] = function(block) { - // Asserts that a value equals another value. - var message = Blockly.PHP.valueToCode(block, 'MESSAGE', - Blockly.PHP.ORDER_NONE) || ''; - var actual = Blockly.PHP.valueToCode(block, 'ACTUAL', - Blockly.PHP.ORDER_COMMA) || 'null'; - var expected = Blockly.PHP.valueToCode(block, 'EXPECTED', - Blockly.PHP.ORDER_COMMA) || 'null'; - return Blockly.PHP['unittest_main'].defineAssert_() + - '(' + actual + ', ' + expected + ', ' + message + ');\n'; + // Asserts that a value equals another value. + var message = Blockly.PHP.valueToCode(block, 'MESSAGE', + Blockly.PHP.ORDER_NONE) || ''; + var actual = Blockly.PHP.valueToCode(block, 'ACTUAL', + Blockly.PHP.ORDER_COMMA) || 'null'; + var expected = Blockly.PHP.valueToCode(block, 'EXPECTED', + Blockly.PHP.ORDER_COMMA) || 'null'; + return Blockly.PHP['unittest_main'].defineAssert_() + + '(' + actual + ', ' + expected + ', ' + message + ');\n'; }; Blockly.PHP['unittest_assertvalue'] = function(block) { - // Asserts that a value is true, false, or null. - var message = Blockly.PHP.valueToCode(block, 'MESSAGE', - Blockly.PHP.ORDER_NONE) || ''; - var actual = Blockly.PHP.valueToCode(block, 'ACTUAL', - Blockly.PHP.ORDER_COMMA) || 'null'; - var expected = block.getFieldValue('EXPECTED'); - if (expected == 'TRUE') { - expected = 'true'; - } else if (expected == 'FALSE') { - expected = 'false'; - } else if (expected == 'NULL') { - expected = 'null'; - } - return Blockly.PHP['unittest_main'].defineAssert_() + - '(' + actual + ', ' + expected + ', ' + message + ');\n'; + // Asserts that a value is true, false, or null. + var message = Blockly.PHP.valueToCode(block, 'MESSAGE', + Blockly.PHP.ORDER_NONE) || ''; + var actual = Blockly.PHP.valueToCode(block, 'ACTUAL', + Blockly.PHP.ORDER_COMMA) || 'null'; + var expected = block.getFieldValue('EXPECTED'); + if (expected == 'TRUE') { + expected = 'true'; + } else if (expected == 'FALSE') { + expected = 'false'; + } else if (expected == 'NULL') { + expected = 'null'; + } + return Blockly.PHP['unittest_main'].defineAssert_() + + '(' + actual + ', ' + expected + ', ' + message + ');\n'; }; Blockly.PHP['unittest_fail'] = function(block) { - // Always assert an error. - var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults', - Blockly.Variables.NAME_TYPE); - var message = Blockly.PHP.valueToCode(block, 'MESSAGE', - Blockly.PHP.ORDER_NONE) || ''; - var functionName = Blockly.PHP.provideFunction_( - 'unittest_fail', - [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + - '($message) {', - 'global ' + resultsVar + ';', - ' // Always assert an error.', - ' if (!' + resultsVar + ') {', - ' throw new Exception("Orphaned assert fail: " . $message);', - ' }', - ' array_push(' + resultsVar + ', [false, "Fail.", $message]);', - '}']); - return functionName + '(' + message + ');\n'; + // Always assert an error. + var resultsVar = Blockly.PHP.variableDB_.getName('unittestResults', + Blockly.Variables.NAME_TYPE); + var message = Blockly.PHP.quote_(block.getFieldValue('MESSAGE')); + var functionName = Blockly.PHP.provideFunction_( + 'unittest_fail', + [ 'function ' + Blockly.PHP.FUNCTION_NAME_PLACEHOLDER_ + + '($message) {', + ' global ' + resultsVar + ';', + ' // Always assert an error.', + ' if (!' + resultsVar + ') {', + ' throw new Exception("Orphaned assert fail: " . $message);', + ' }', + ' array_push(' + resultsVar + ', [false, "Fail.", $message]);', + '}']); + return functionName + '(' + message + ');\n'; }; Blockly.PHP['unittest_adjustindex'] = function(block) { diff --git a/tests/generators/unittest_python.js b/tests/generators/unittest_python.js index 7fbe313b1..5e00e26be 100644 --- a/tests/generators/unittest_python.js +++ b/tests/generators/unittest_python.js @@ -59,13 +59,10 @@ Blockly.Python['unittest_main'] = function(block) { // Run tests (unindented). code += Blockly.Python.statementToCode(block, 'DO') .replace(/^ /, '').replace(/\n /g, '\n'); - var reportVar = Blockly.Python.variableDB_.getDistinctName( - 'report', Blockly.Variables.NAME_TYPE); - code += reportVar + ' = ' + functionName + '()\n'; + // Print the report. + code += 'print(' + functionName + '())\n'; // Destroy results. code += resultsVar + ' = None\n'; - // Print the report. - code += 'print(' + reportVar + ')\n'; return code; }; @@ -121,8 +118,7 @@ Blockly.Python['unittest_fail'] = function(block) { // Always assert an error. var resultsVar = Blockly.Python.variableDB_.getName('unittestResults', Blockly.Variables.NAME_TYPE); - var message = Blockly.Python.valueToCode(block, 'MESSAGE', - Blockly.Python.ORDER_NONE) || ''; + var message = Blockly.Python.quote_(block.getFieldValue('MESSAGE')); var functionName = Blockly.Python.provideFunction_( 'fail', ['def ' + Blockly.Python.FUNCTION_NAME_PLACEHOLDER_ + '(message):', diff --git a/tests/jsunit/field_variable_test.js b/tests/jsunit/field_variable_test.js index 6d3ef9d66..bc36b7d69 100644 --- a/tests/jsunit/field_variable_test.js +++ b/tests/jsunit/field_variable_test.js @@ -175,7 +175,8 @@ function test_fieldVariable_getVariableTypes_nullVariableTypes() { fieldVariable.variableTypes = null; var resultTypes = fieldVariable.getVariableTypes_(); - isEqualArrays(resultTypes, ['type1', 'type2']); + // The empty string is always one of the options. + isEqualArrays(resultTypes, ['type1', 'type2', '']); workspace.dispose(); } diff --git a/tests/jsunit/variable_map_test.js b/tests/jsunit/variable_map_test.js index 568ce0b0d..3ccf674e2 100644 --- a/tests/jsunit/variable_map_test.js +++ b/tests/jsunit/variable_map_test.js @@ -269,14 +269,16 @@ function test_getVariableTypes_Trivial() { variable_map.createVariable('name3', 'type2', 'id3'); variable_map.createVariable('name4', 'type3', 'id4'); var result_array = variable_map.getVariableTypes(); - isEqualArrays(['type1', 'type2', 'type3'], result_array); + // The empty string is always an option. + isEqualArrays(['type1', 'type2', 'type3', ''], result_array); variableMapTest_tearDown(); } function test_getVariableTypes_None() { variableMapTest_setUp(); + // The empty string is always an option. var result_array = variable_map.getVariableTypes(); - isEqualArrays([], result_array); + isEqualArrays([''], result_array); variableMapTest_tearDown(); }