Permalink
Browse files

Merge branch 'master' into asynctypes-685526

Conflicts:
	lib/gclitest/testCli.js
	lib/gclitest/testKeyboard.js
	lib/gclitest/testTooltip.js
  • Loading branch information...
2 parents 502dcb6 + 019115f commit 5784f9410a2eba9396b9965fb2beb21fbab0fa9e @joewalker joewalker committed Feb 25, 2013
@@ -98,7 +98,7 @@ var gcliTwonums = {
{
name: 'p2',
defaultValue: 8,
- type: { name: 'number', min: -20, max: 42, step: 5 },
+ type: { name: 'number', allowFloat: true, min: -20, max: 42, step: 5 },
description: 'Second param'
},
{
@@ -81,6 +81,10 @@ var i18n = {
// the smallest allowed number, this error message is displayed.
typesNumberMin: '%1$S is smaller than minimum allowed: %2$S.',
+ // When the command line is passed a number, but the number has a decimal
+ // part and floats are not allowed.
+ typesNumberNotInt: 'Can\'t convert "%S" to an integer.',
+
// When the command line is passed an option with a limited number of
// correct values, but the passed value is not one of them, this error
// message is displayed.
@@ -300,7 +304,7 @@ var i18n = {
// to explain the command line, and is shown each time it is opened until
// the user clicks the 'Got it!' button.
// This string is the opening paragraph of the intro text.
- introTextOpening: 'The Firefox command line is designed for developers. It focuses on speed of input over JavaScript syntax and a rich display over monospace output.',
+ introTextOpening: 'This command line is designed for developers. It focuses on speed of input over JavaScript syntax and a rich display over monospace output.',
// For information about the 'intro text' see introTextOpening.
// The second paragraph is in 2 sections, the first section points the user
@@ -82,13 +82,23 @@ exports.StringType = StringType;
/**
- * We don't currently plan to distinguish between integers and floats
+ * We distinguish between integers and floats with the _allowFloat flag.
*/
function NumberType(typeSpec) {
+ // Default to integer values
+ this._allowFloat = !!typeSpec.allowFloat;
+
if (typeSpec) {
this._min = typeSpec.min;
this._max = typeSpec.max;
this._step = typeSpec.step || 1;
+
+ if (!this._allowFloat &&
+ (this._isFloat(this._min) ||
+ this._isFloat(this._max) ||
+ this._isFloat(this._step))) {
+ throw new Error('allowFloat is false, but non-integer values given in type spec');
+ }
}
else {
this._step = 1;
@@ -133,7 +143,19 @@ NumberType.prototype.parse = function(arg) {
return Promise.resolve(new Conversion(undefined, arg, Status.INCOMPLETE, ''));
}
- var value = parseInt(arg.text, 10);
+ if (!this._allowFloat && (arg.text.indexOf('.') !== -1)) {
+ var message = l10n.lookupFormat('typesNumberNotInt', [ arg.text ]);
+ return Promise.resolve(new Conversion(undefined, arg, Status.ERROR, message));
+ }
+
+ var value;
+ if (this._allowFloat) {
+ value = parseFloat(arg.text);
+ }
+ else {
+ value = parseInt(arg.text, 10);
+ }
+
if (isNaN(value)) {
var message = l10n.lookupFormat('typesNumberNan', [ arg.text ]);
return Promise.resolve(new Conversion(undefined, arg, Status.ERROR, message));
@@ -195,6 +217,14 @@ NumberType.prototype._boundsCheck = function(value) {
return value;
};
+/**
+ * Return true if the given value is a finite number and not an integer, else
+ * return false.
+ */
+NumberType.prototype._isFloat = function(value) {
+ return ((typeof value === 'number') && isFinite(value) && (value % 1 !== 0));
+};
+
NumberType.prototype.name = 'number';
exports.NumberType = NumberType;
@@ -46,6 +46,7 @@ mockCommands.setup = function(opts) {
canon.addCommand(mockCommands.tsb);
canon.addCommand(mockCommands.tss);
canon.addCommand(mockCommands.tsu);
+ canon.addCommand(mockCommands.tsf);
canon.addCommand(mockCommands.tsn);
canon.addCommand(mockCommands.tsnDif);
canon.addCommand(mockCommands.tsnExt);
@@ -73,6 +74,7 @@ mockCommands.shutdown = function(opts) {
canon.removeCommand(mockCommands.tsb);
canon.removeCommand(mockCommands.tss);
canon.removeCommand(mockCommands.tsu);
+ canon.removeCommand(mockCommands.tsf);
canon.removeCommand(mockCommands.tsn);
canon.removeCommand(mockCommands.tsnDif);
canon.removeCommand(mockCommands.tsnExt);
@@ -220,6 +222,12 @@ mockCommands.tsu = {
exec: createExec('tsu')
};
+mockCommands.tsf = {
+ name: 'tsf',
+ params: [ { name: 'num', type: { name: 'number', allowFloat: true, max: 11.5, min: -6.5, step: 1.5 } } ],
+ exec: createExec('tsf')
+};
+
mockCommands.tsn = {
name: 'tsn'
};
@@ -677,7 +677,7 @@ exports.testSingleNumber = function(options) {
unassigned: [ ],
args: {
command: { name: 'tsu' },
- num: { value: 1, arg: ' 1', status: 'VALID', message: '' },
+ num: { value: 1, arg: ' 1', status: 'VALID', message: '' }
}
}
},
@@ -703,6 +703,154 @@ exports.testSingleNumber = function(options) {
}
}
}
+ },
+ {
+ setup: 'tsu 1.5',
+ check: {
+ input: 'tsu 1.5',
+ hints: '',
+ markup: 'VVVVEEE',
+ cursor: 7,
+ current: 'num',
+ status: 'ERROR',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsu' },
+ num: {
+ value: undefined,
+ arg: ' 1.5',
+ status: 'ERROR',
+ message: 'Can\'t convert "1.5" to an integer.'
+ }
+ }
+ }
+ }
+ ]);
+};
+
+exports.testSingleFloat = function(options) {
+ return helpers.audit(options, [
+ {
+ setup: 'tsf',
+ check: {
+ input: 'tsf',
+ hints: ' <num>',
+ markup: 'VVV',
+ cursor: 3,
+ current: '__command',
+ status: 'ERROR',
+ error: '',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsf' },
+ num: {
+ value: undefined,
+ arg: '',
+ status: 'INCOMPLETE',
+ message: ''
+ }
+ }
+ }
+ },
+ {
+ setup: 'tsf 1',
+ check: {
+ input: 'tsf 1',
+ hints: '',
+ markup: 'VVVVV',
+ cursor: 5,
+ current: 'num',
+ status: 'VALID',
+ error: '',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsf' },
+ num: { value: 1, arg: ' 1', status: 'VALID', message: '' }
+ }
+ }
+ },
+ {
+ setup: 'tsf 1.',
+ check: {
+ input: 'tsf 1.',
+ hints: '',
+ markup: 'VVVVVV',
+ cursor: 6,
+ current: 'num',
+ status: 'VALID',
+ error: '',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsf' },
+ num: { value: 1, arg: ' 1.', status: 'VALID', message: '' }
+ }
+ }
+ },
+ {
+ setup: 'tsf 1.5',
+ check: {
+ input: 'tsf 1.5',
+ hints: '',
+ markup: 'VVVVVVV',
+ cursor: 7,
+ current: 'num',
+ status: 'VALID',
+ error: '',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsf' },
+ num: { value: 1.5, arg: ' 1.5', status: 'VALID', message: '' }
+ }
+ }
+ },
+ {
+ setup: 'tsf 1.5x',
+ check: {
+ input: 'tsf 1.5x',
+ hints: '',
+ markup: 'VVVVVVVV',
+ cursor: 8,
+ current: 'num',
+ status: 'VALID',
+ error: '',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsf' },
+ num: { value: 1.5, arg: ' 1.5x', status: 'VALID', message: '' }
+ }
+ }
+ },
+ {
+ name: 'tsf x (cursor=4)',
+ setup: function() {
+ return helpers.setInput(options, 'tsf x', 4);
+ },
+ check: {
+ input: 'tsf x',
+ hints: '',
+ markup: 'VVVVE',
+ cursor: 4,
+ current: 'num',
+ status: 'ERROR',
+ error: 'Can\'t convert "x" to a number.',
+ predictions: [ ],
+ unassigned: [ ],
+ args: {
+ command: { name: 'tsf' },
+ num: {
+ value: undefined,
+ arg: ' x',
+ status: 'ERROR',
+ message: 'Can\'t convert "x" to a number.'
+ }
+ }
+ }
}
]);
};
Oops, something went wrong.

0 comments on commit 5784f94

Please sign in to comment.