From 211d97305450fb25cb7edd3fdb1e7f44b4d8a695 Mon Sep 17 00:00:00 2001 From: Andrew n marshall Date: Tue, 17 Jan 2017 15:39:59 -0800 Subject: [PATCH] FieldNumber & FieldAngle: Default value "0" (#832) FieldNumber and FieldAngle previously accepted "undefined" as values, if not defined in JSON. This catches these and uses "0" for any NaN value. The constructor value parameter is now optional. Includes tests. --- core/field_angle.js | 9 +++-- core/field_number.js | 16 ++++---- tests/jsunit/field_angle_test.js | 39 +++++++++++++++++++ tests/jsunit/field_number_test.js | 63 +++++++++++++++++++++++++++++++ tests/jsunit/index.html | 2 + 5 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 tests/jsunit/field_angle_test.js create mode 100644 tests/jsunit/field_number_test.js diff --git a/core/field_angle.js b/core/field_angle.js index 92d5a8c92..c5534ff0e 100644 --- a/core/field_angle.js +++ b/core/field_angle.js @@ -33,7 +33,8 @@ goog.require('goog.userAgent'); /** * Class for an editable angle field. - * @param {string} text The initial content of the field. + * @param {(string|number)=} opt_value The initial content of the field. The + * value should cast to a number, and if it does not, "0" will be used. * @param {Function=} opt_validator An optional function that is called * to validate any constraints on what the user entered. Takes the new * text as an argument and returns the accepted text or null to abort @@ -41,12 +42,14 @@ goog.require('goog.userAgent'); * @extends {Blockly.FieldTextInput} * @constructor */ -Blockly.FieldAngle = function(text, opt_validator) { +Blockly.FieldAngle = function(opt_value, opt_validator) { // Add degree symbol: "360°" (LTR) or "°360" (RTL) this.symbol_ = Blockly.utils.createSvgElement('tspan', {}, null); this.symbol_.appendChild(document.createTextNode('\u00B0')); - Blockly.FieldAngle.superClass_.constructor.call(this, text, opt_validator); + opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : "0"; + Blockly.FieldAngle.superClass_.constructor.call( + this, opt_value, opt_validator); }; goog.inherits(Blockly.FieldAngle, Blockly.FieldTextInput); diff --git a/core/field_number.js b/core/field_number.js index f72e7f053..6de97de0f 100644 --- a/core/field_number.js +++ b/core/field_number.js @@ -31,10 +31,11 @@ goog.require('goog.math'); /** * Class for an editable number field. - * @param {number|string} value The initial content of the field. - * @param {number|string|undefined} opt_min Minimum value. - * @param {number|string|undefined} opt_max Maximum value. - * @param {number|string|undefined} opt_precision Precision for value. + * @param {(string|number)=} value The initial content of the field. The value + * should cast to a number, and if it does not, "0" will be used. + * @param {(string|number)=} opt_min Minimum value. + * @param {(string|number)=} opt_max Maximum value. + * @param {(string|number)=} opt_precision Precision for value. * @param {Function=} opt_validator An optional function that is called * to validate any constraints on what the user entered. Takes the new * text as an argument and returns either the accepted text, a replacement @@ -43,9 +44,10 @@ goog.require('goog.math'); * @constructor */ Blockly.FieldNumber = - function(value, opt_min, opt_max, opt_precision, opt_validator) { - value = String(value); - Blockly.FieldNumber.superClass_.constructor.call(this, value, opt_validator); + function(opt_value, opt_min, opt_max, opt_precision, opt_validator) { + opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : "0"; + Blockly.FieldNumber.superClass_.constructor.call( + this, opt_value, opt_validator); this.setConstraints(opt_min, opt_max, opt_precision); }; goog.inherits(Blockly.FieldNumber, Blockly.FieldTextInput); diff --git a/tests/jsunit/field_angle_test.js b/tests/jsunit/field_angle_test.js new file mode 100644 index 000000000..7ffd1203f --- /dev/null +++ b/tests/jsunit/field_angle_test.js @@ -0,0 +1,39 @@ +/** + * @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.FieldAngle + * @author Anm@anm.me (Andrew n marshall) + */ +'use strict'; + +function test_fieldangle_constructor() { + assertEquals(new Blockly.FieldAngle().getValue(), "0"); + assertEquals(new Blockly.FieldAngle(null).getValue(), "0"); + assertEquals(new Blockly.FieldAngle(undefined).getValue(), "0"); + assertEquals(new Blockly.FieldAngle(1).getValue(), "1"); + assertEquals(new Blockly.FieldAngle(1.5).getValue(), "1.5"); + assertEquals(new Blockly.FieldAngle("2").getValue(), "2"); + assertEquals(new Blockly.FieldAngle("2.5").getValue(), "2.5"); + + // Bad values + assertEquals(new Blockly.FieldAngle("bad").getValue(), "0"); + assertEquals(new Blockly.FieldAngle(NaN).getValue(), "0"); +} diff --git a/tests/jsunit/field_number_test.js b/tests/jsunit/field_number_test.js new file mode 100644 index 000000000..10764d43b --- /dev/null +++ b/tests/jsunit/field_number_test.js @@ -0,0 +1,63 @@ +/** + * @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.FieldNumber + * @author Anm@anm.me (Andrew n marshall) + */ +'use strict'; + +function test_fieldnumber_constructor() { + // No arguments + var field = new Blockly.FieldNumber(); + assertEquals(field.getValue(), "0"); + assertEquals(field.min_, -Infinity); + assertEquals(field.max_, Infinity); + assertEquals(field.precision_, 0); + + // Numeric values + field = new Blockly.FieldNumber(1); + assertEquals(field.getValue(), "1"); + field = new Blockly.FieldNumber(1.5); + assertEquals(field.getValue(), "1.5"); + + // String value + field = new Blockly.FieldNumber("2"); + assertEquals(field.getValue(), "2"); + field = new Blockly.FieldNumber("2.5"); + assertEquals(field.getValue(), "2.5"); + + // All values + field = new Blockly.FieldNumber( + /* value */ 0, + /* min */ -128, + /* max */ 127, + /* precision */ 1); + assertEquals(field.getValue(), "0"); + assertEquals(field.min_, -128); + assertEquals(field.max_, 127); + assertEquals(field.precision_, 1); + + // Bad value defaults to "0" + field = new Blockly.FieldNumber("bad"); + assertEquals(field.getValue(), "0"); + field = new Blockly.FieldNumber(NaN); + assertEquals(field.getValue(), "0"); +} diff --git a/tests/jsunit/index.html b/tests/jsunit/index.html index 738bf985b..77fd8ad69 100644 --- a/tests/jsunit/index.html +++ b/tests/jsunit/index.html @@ -10,6 +10,8 @@ + +