Bug 767587 - GCLI should have a type for files; r=mratcliffe

This commit is contained in:
Joe Walker 2013-07-20 05:17:24 +01:00
parent e630aca256
commit 94ba16c7f3
22 changed files with 4915 additions and 2778 deletions

View File

@ -600,6 +600,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
return prefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
});
XPCOMUtils.defineLazyGetter(this, 'supportsString', function() {
return Cc["@mozilla.org/supports-string;1"]
.createInstance(Ci.nsISupportsString);
});
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
@ -719,7 +724,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
gcli.addCommand(commandSpec);
commands.push(commandSpec.name);
});
},
function onError(reason) {
console.error("OS.File.read(" + aFileEntry.path + ") failed.");
@ -733,7 +737,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
*/
gcli.addCommand({
name: "cmd",
get hidden() { return !prefBranch.prefHasUserValue(PREF_DIR); },
get hidden() {
return !prefBranch.prefHasUserValue(PREF_DIR);
},
description: gcli.lookup("cmdDesc")
});
@ -743,10 +749,49 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
gcli.addCommand({
name: "cmd refresh",
description: gcli.lookup("cmdRefreshDesc"),
get hidden() { return !prefBranch.prefHasUserValue(PREF_DIR); },
exec: function Command_cmdRefresh(args, context) {
get hidden() {
return !prefBranch.prefHasUserValue(PREF_DIR);
},
exec: function(args, context) {
let chromeWindow = context.environment.chromeDocument.defaultView;
CmdCommands.refreshAutoCommands(chromeWindow);
let dirName = prefBranch.getComplexValue(PREF_DIR,
Ci.nsISupportsString).data.trim();
return gcli.lookupFormat("cmdStatus", [ commands.length, dirName ]);
}
});
/**
* 'cmd setdir' command
*/
gcli.addCommand({
name: "cmd setdir",
description: gcli.lookup("cmdSetdirDesc"),
params: [
{
name: "directory",
description: gcli.lookup("cmdSetdirDirectoryDesc"),
type: {
name: "file",
filetype: "directory",
existing: "yes"
},
defaultValue: null
}
],
returnType: "string",
get hidden() {
return true; // !prefBranch.prefHasUserValue(PREF_DIR);
},
exec: function(args, context) {
supportsString.data = args.directory;
prefBranch.setComplexValue(PREF_DIR, Ci.nsISupportsString, supportsString);
let chromeWindow = context.environment.chromeDocument.defaultView;
CmdCommands.refreshAutoCommands(chromeWindow);
return gcli.lookupFormat("cmdStatus", [ commands.length, args.directory ]);
}
});
}(this));
@ -1493,7 +1538,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppCacheUtils",
params: [
{
name: "srcdir",
type: "string",
type: "string" /* {
name: "file",
filetype: "directory",
existing: "yes"
} */,
description: gcli.lookup("toolsSrcdirDir")
}
],

View File

@ -44,10 +44,14 @@ MOCHITEST_BROWSER_FILES = \
browser_cmd_screenshot.html \
browser_cmd_screenshot.js \
browser_cmd_settings.js \
browser_gcli_async.js \
browser_gcli_canon.js \
browser_gcli_cli.js \
browser_gcli_completion.js \
browser_gcli_date.js \
browser_gcli_exec.js \
browser_gcli_fail.js \
browser_gcli_file.js \
browser_gcli_focus.js \
browser_gcli_history.js \
browser_gcli_incomplete.js \

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {

View File

@ -217,10 +217,11 @@ exports.testAltCanon = function(options) {
var commandSpecs = altCanon.getCommandSpecs();
assert.is(JSON.stringify(commandSpecs),
'{"tss":{"name":"tss","params":[' +
'{"name":"str","type":"string"},' +
'{"name":"num","type":"number"},' +
'{"name":"opt","type":{"name":"selection","data":["1","2","3"]}}]}}',
'{"tss":{"name":"tss","description":"(No description)","params":[' +
'{"name":"str","type":"string","description":"(No description)"},' +
'{"name":"num","type":"number","description":"(No description)"},' +
'{"name":"opt","type":{"name":"selection","data":["1","2","3"]},"description":"(No description)"}'+
'],"isParent":false}}',
'JSON.stringify(commandSpecs)');
var remoter = function(args, context) {

View File

@ -37,26 +37,17 @@ function test() {
// var helpers = require('gclitest/helpers');
// var mockCommands = require('gclitest/mockCommands');
var cli = require('gcli/cli');
var origLogErrors = undefined;
exports.setup = function(options) {
mockCommands.setup();
origLogErrors = cli.logErrors;
cli.logErrors = false;
};
exports.shutdown = function(options) {
mockCommands.shutdown();
cli.logErrors = origLogErrors;
origLogErrors = undefined;
};
exports.testBaseline = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
// These 3 establish a baseline for comparison when we have used the
// context command
{
@ -100,7 +91,7 @@ exports.testBaseline = function(options) {
};
exports.testContext = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
// Use the 'tsn' context
{
setup: 'context tsn',

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {
@ -80,8 +90,10 @@ exports.testIncrement = function(options) {
};
exports.testInput = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
// See bug 892901
skipRemainingIf: options.isFirefox,
setup: 'tsdate 2001-01-01 1980-01-03',
check: {
input: 'tsdate 2001-01-01 1980-01-03',
@ -132,8 +144,10 @@ exports.testInput = function(options) {
};
exports.testIncrDecr = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
// See bug 892901
skipRemainingIf: options.isFirefox,
setup: 'tsdate 2001-01-01<UP>',
check: {
input: 'tsdate 2001-01-02',
@ -224,14 +238,14 @@ exports.testIncrDecr = function(options) {
message: ''
},
d2: {
value: function(d1) {
assert.is(d1.getFullYear(), 2000, 'd1 year');
assert.is(d1.getMonth(), 1, 'd1 month');
assert.is(d1.getDate(), 28, 'd1 date');
assert.is(d1.getHours(), 0, 'd1 hours');
assert.is(d1.getMinutes(), 0, 'd1 minutes');
assert.is(d1.getSeconds(), 0, 'd1 seconds');
assert.is(d1.getMilliseconds(), 0, 'd1 millis');
value: function(d2) {
assert.is(d2.getFullYear(), 2000, 'd2 year');
assert.is(d2.getMonth(), 1, 'd2 month');
assert.is(d2.getDate(), 28, 'd2 date');
assert.is(d2.getHours(), 0, 'd2 hours');
assert.is(d2.getMinutes(), 0, 'd2 minutes');
assert.is(d2.getSeconds(), 0, 'd2 seconds');
assert.is(d2.getMilliseconds(), 0, 'd2 millis');
},
arg: ' "2000-02-28"',
status: 'VALID',

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {
@ -27,22 +37,13 @@ function test() {
// var helpers = require('gclitest/helpers');
// var mockCommands = require('gclitest/mockCommands');
var cli = require('gcli/cli');
var origLogErrors = undefined;
exports.setup = function(options) {
mockCommands.setup();
origLogErrors = cli.logErrors;
cli.logErrors = false;
};
exports.shutdown = function(options) {
mockCommands.shutdown();
cli.logErrors = origLogErrors;
origLogErrors = undefined;
};
exports.testBasic = function(options) {

View File

@ -0,0 +1,848 @@
/*
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
var exports = {};
const TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFile.js</p>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.runTests(options, exports);
}).then(finish);
}
// <INJECTED SOURCE:END>
'use strict';
// var helpers = require('gclitest/helpers');
// var mockCommands = require('gclitest/mockCommands');
exports.setup = function(options) {
mockCommands.setup();
};
exports.shutdown = function(options) {
mockCommands.shutdown();
};
var local = false;
exports.testBasic = function(options) {
var isPhantomjsFromFilesystem = (!options.isHttp && options.isPhantomjs);
return helpers.audit(options, [
{
// These tests require us to be using node directly or to be in
// phantomjs connected to an allowexec enabled node server or to be in
// firefox. In short they only don't work when in phantomjs reading
// from the filesystem, but they do work in Firefox
skipRemainingIf: isPhantomjsFromFilesystem || options.isFirefox,
setup: 'tsfile open /',
check: {
input: 'tsfile open /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
setup: 'tsfile open /zxcv',
check: {
input: 'tsfile open /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVIIIII',
cursor: 17,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile open /mach_kernel',
check: {
input: 'tsfile open /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile open' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile saveas /',
check: {
input: 'tsfile saveas /',
hints: '',
markup: 'VVVVVVVVVVVVVVI',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
setup: 'tsfile saveas /zxcv',
check: {
input: 'tsfile saveas /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVVVV',
cursor: 19,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile saveas /mach_kernel',
check: {
input: 'tsfile saveas /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 26,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
setup: 'tsfile save /',
check: {
input: 'tsfile save /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile save' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
setup: 'tsfile save /zxcv',
check: {
input: 'tsfile save /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVV',
cursor: 17,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile save /mach_kernel',
check: {
input: 'tsfile save /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /',
check: {
input: 'tsfile cd /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile cd' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /zxcv',
check: {
input: 'tsfile cd /zxcv',
// hints: ' -> /dev/',
markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: true || !local,
setup: 'tsfile cd /etc/passwd',
check: {
input: 'tsfile cd /etc/passwd',
hints: ' -> /etc/pam.d/',
markup: 'VVVVVVVVVVIIIIIIIIIII',
cursor: 21,
current: 'p1',
status: 'ERROR',
message: '\'/etc/passwd\' is not a directory',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /etc/passwd',
status: 'INCOMPLETE',
message: '\'/etc/passwd\' is not a directory'
}
}
}
},
{
setup: 'tsfile mkdir /',
check: {
input: 'tsfile mkdir /',
hints: '',
markup: 'VVVVVVVVVVVVVI',
cursor: 14,
current: 'p1',
status: 'ERROR',
message: ''/' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
setup: 'tsfile mkdir /zxcv',
check: {
input: 'tsfile mkdir /zxcv',
// hints: ' -> /dev/',
markup: 'VVVVVVVVVVVVVVVVVV',
cursor: 18,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile mkdir /mach_kernel',
check: {
input: 'tsfile mkdir /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 25,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
setup: 'tsfile rm /',
check: {
input: 'tsfile rm /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile rm /zxcv',
check: {
input: 'tsfile rm /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile rm' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile rm /mach_kernel',
check: {
input: 'tsfile rm /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVV',
cursor: 22,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
}
]);
};
exports.testFirefoxBasic = function(options) {
return helpers.audit(options, [
{
// These tests are just like the ones above tailored for running in
// Firefox
skipRemainingIf: true,
// skipRemainingIf: !options.isFirefox,
skipIf: true,
setup: 'tsfile open /',
check: {
input: 'tsfile open /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
skipIf: true,
setup: 'tsfile open /zxcv',
check: {
input: 'tsfile open /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVIIIII',
cursor: 17,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile open' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile open /mach_kernel',
check: {
input: 'tsfile open /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile open' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: true,
setup: 'tsfile saveas /',
check: {
input: 'tsfile saveas /',
hints: '',
markup: 'VVVVVVVVVVVVVVI',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
skipIf: true,
setup: 'tsfile saveas /zxcv',
check: {
input: 'tsfile saveas /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVVVV',
cursor: 19,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile saveas /mach_kernel',
check: {
input: 'tsfile saveas /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 26,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile saveas' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
skipIf: true,
setup: 'tsfile save /',
check: {
input: 'tsfile save /',
hints: '',
markup: 'VVVVVVVVVVVVI',
cursor: 13,
current: 'p1',
status: 'ERROR',
message: '\'/\' is not a file',
args: {
command: { name: 'tsfile save' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' is not a file'
}
}
}
},
{
skipIf: true,
setup: 'tsfile save /zxcv',
check: {
input: 'tsfile save /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVVVVVVVV',
cursor: 17,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile save /mach_kernel',
check: {
input: 'tsfile save /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 24,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile save' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /',
check: {
input: 'tsfile cd /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile cd' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
setup: 'tsfile cd /zxcv',
check: {
input: 'tsfile cd /zxcv',
// hints: ' -> /dev/',
// markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
// status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /zxcv',
// status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: true || !local,
setup: 'tsfile cd /etc/passwd',
check: {
input: 'tsfile cd /etc/passwd',
hints: ' -> /etc/pam.d/',
markup: 'VVVVVVVVVVIIIIIIIIIII',
cursor: 21,
current: 'p1',
status: 'ERROR',
message: '\'/etc/passwd\' is not a directory',
args: {
command: { name: 'tsfile cd' },
p1: {
value: undefined,
arg: ' /etc/passwd',
status: 'INCOMPLETE',
message: '\'/etc/passwd\' is not a directory'
}
}
}
},
{
setup: 'tsfile mkdir /',
check: {
input: 'tsfile mkdir /',
hints: '',
markup: 'VVVVVVVVVVVVVI',
cursor: 14,
current: 'p1',
status: 'ERROR',
message: ''/' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /',
status: 'INCOMPLETE',
message: '\'/\' already exists'
}
}
}
},
{
setup: 'tsfile mkdir /zxcv',
check: {
input: 'tsfile mkdir /zxcv',
// hints: ' -> /dev/',
markup: 'VVVVVVVVVVVVVVVVVV',
cursor: 18,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: '/zxcv',
arg: ' /zxcv',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: !local,
setup: 'tsfile mkdir /mach_kernel',
check: {
input: 'tsfile mkdir /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVIIIIIIIIIIII',
cursor: 25,
current: 'p1',
status: 'ERROR',
message: '\'/mach_kernel\' already exists',
args: {
command: { name: 'tsfile mkdir' },
p1: {
value: undefined,
arg: ' /mach_kernel',
status: 'INCOMPLETE',
message: '\'/mach_kernel\' already exists'
}
}
}
},
{
skipIf: true,
setup: 'tsfile rm /',
check: {
input: 'tsfile rm /',
hints: '',
markup: 'VVVVVVVVVVV',
cursor: 11,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/',
arg: ' /',
status: 'VALID',
message: ''
}
}
}
},
{
skipIf: true,
setup: 'tsfile rm /zxcv',
check: {
input: 'tsfile rm /zxcv',
// hints: ' -> /etc/',
markup: 'VVVVVVVVVVIIIII',
cursor: 15,
current: 'p1',
status: 'ERROR',
message: '\'/zxcv\' doesn\'t exist',
args: {
command: { name: 'tsfile rm' },
p1: {
value: undefined,
arg: ' /zxcv',
status: 'INCOMPLETE',
message: '\'/zxcv\' doesn\'t exist'
}
}
}
},
{
skipIf: !local,
setup: 'tsfile rm /mach_kernel',
check: {
input: 'tsfile rm /mach_kernel',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVV',
cursor: 22,
current: 'p1',
status: 'VALID',
message: '',
args: {
command: { name: 'tsfile rm' },
p1: {
value: '/mach_kernel',
arg: ' /mach_kernel',
status: 'VALID',
message: ''
}
}
}
}
]);
};
// });

View File

@ -0,0 +1,57 @@
/*
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
var exports = {};
const TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFileparser.js</p>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.runTests(options, exports);
}).then(finish);
}
// <INJECTED SOURCE:END>
'use strict';
// var assert = require('test/assert');
var fileparser = require('util/fileparser');
var local = false;
exports.testGetPredictor = function(options) {
if (!options.isNode || !local) {
return;
}
var options = { filetype: 'file', existing: 'yes' };
var predictor = fileparser.getPredictor('/usr/locl/bin/nmp', options);
return predictor().then(function(replies) {
assert.is(replies[0].name,
'/usr/local/bin/npm',
'predict npm');
});
};
// });

View File

@ -0,0 +1,78 @@
/*
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {
// <INJECTED SOURCE:START>
// THIS FILE IS GENERATED FROM SOURCE IN THE GCLI PROJECT
// DO NOT EDIT IT DIRECTLY
var exports = {};
const TEST_URI = "data:text/html;charset=utf-8,<p id='gcli-input'>gcli-testFilesystem.js</p>";
function test() {
helpers.addTabWithToolbar(TEST_URI, function(options) {
return helpers.runTests(options, exports);
}).then(finish);
}
// <INJECTED SOURCE:END>
'use strict';
// var assert = require('test/assert');
// var helpers = require('gclitest/helpers');
var filesystem = require('util/filesystem');
exports.testSplit = function(options) {
if (!options.isNode) {
return;
}
helpers.arrayIs(filesystem.split('', '/'),
[ '.' ],
'split <blank>');
helpers.arrayIs(filesystem.split('a', '/'),
[ 'a' ],
'split a');
helpers.arrayIs(filesystem.split('a/b/c', '/'),
[ 'a', 'b', 'c' ],
'split a/b/c');
helpers.arrayIs(filesystem.split('/a/b/c/', '/'),
[ 'a', 'b', 'c' ],
'split a/b/c');
helpers.arrayIs(filesystem.split('/a/b///c/', '/'),
[ 'a', 'b', 'c' ],
'split a/b/c');
};
exports.testJoin = function(options) {
if (!options.isNode) {
return;
}
assert.is(filesystem.join('usr', 'local', 'bin'),
'usr/local/bin',
'join to usr/local/bin');
};
// });

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {

View File

@ -1,7 +1,17 @@
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
* Copyright 2012, Mozilla Foundation and contributors
*
* 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.
*/
// define(function(require, exports, module) {

View File

@ -48,6 +48,7 @@ exports.shutdown = function(options) {
};
exports.testRemote = function(options) {
var connected = false;
return helpers.audit(options, [
{
skipRemainingIf: !options.isHttp,
@ -65,6 +66,72 @@ exports.testRemote = function(options) {
unassigned: [ ],
}
},
{
setup: 'connect remote',
check: {
input: 'connect remote',
hints: ' [options]',
markup: 'VVVVVVVVVVVVVV',
cursor: 14,
current: 'prefix',
status: 'VALID',
options: [ ],
message: '',
predictions: [ ],
unassigned: [ ],
args: {
command: { name: 'connect' },
prefix: { value: 'remote', arg: ' remote', status: 'VALID', message: '' },
host: { value: undefined, arg: '', status: 'VALID', message: '' },
port: { value: undefined, arg: '', status: 'VALID', message: '' },
}
},
exec: {
completed: false,
error: false
},
post: function(output, data) {
connected = !output.error;
if (!connected) {
console.log('Failure from "connect remote". Run server with "node gcli server start --websocket --allowexec" to allow remote command testing');
}
}
},
{
// We do a connect-disconnect dance for 2 reasons, partly re-establishing
// a connection is a good test, and secondly it lets us have minimal
// testing on the first connection so we don't need to turn websockets
// on all the time
setup: 'disconnect remote --force',
skipRemainingIf: !connected,
check: {
input: 'disconnect remote --force',
hints: '',
markup: 'VVVVVVVVVVVVVVVVVVVVVVVVV',
cursor: 25,
current: 'force',
status: 'VALID',
message: '',
unassigned: [ ],
args: {
command: { name: 'disconnect' },
prefix: {
value: function(connection) {
assert.is(connection.prefix, 'remote', 'disconnecting remote');
},
arg: ' remote',
status: 'VALID',
message: ''
}
}
},
exec: {
output: /^Removed [0-9]* commands.$/,
completed: true,
type: 'string',
error: false
}
},
{
setup: 'connect remote',
check: {

View File

@ -35,7 +35,7 @@ function test() {
'use strict';
// var assert = require('test/assert');
var spell = require('gcli/types/spell');
var spell = require('util/spell');
exports.testSpellerSimple = function(options) {
var alternatives = Object.keys(options.window);
@ -54,5 +54,34 @@ exports.testSpellerSimple = function(options) {
assert.is(spell.correct('=========', alternatives), undefined);
};
exports.testRank = function(options) {
var distances = spell.rank('fred', [ 'banana', 'fred', 'ed', 'red', 'FRED' ]);
assert.is(distances.length, 5, 'rank length');
assert.is(distances[0].name, 'fred', 'fred name #0');
assert.is(distances[1].name, 'FRED', 'FRED name #1');
assert.is(distances[2].name, 'red', 'red name #2');
assert.is(distances[3].name, 'ed', 'ed name #3');
assert.is(distances[4].name, 'banana', 'banana name #4');
assert.is(distances[0].dist, 0, 'fred dist 0');
assert.is(distances[1].dist, 4, 'FRED dist 4');
assert.is(distances[2].dist, 10, 'red dist 10');
assert.is(distances[3].dist, 20, 'ed dist 20');
assert.is(distances[4].dist, 100, 'banana dist 100');
};
exports.testRank2 = function(options) {
var distances = spell.rank('caps', [ 'CAPS', 'false' ]);
assert.is(JSON.stringify(distances),
'[{"name":"CAPS","dist":4},{"name":"false","dist":50}]',
'spell.rank("caps", [ "CAPS", "false" ]');
};
exports.testDistancePrefix = function(options) {
assert.is(spell.distancePrefix('fred', 'freddy'), 0, 'distancePrefix fred');
assert.is(spell.distancePrefix('FRED', 'freddy'), 4, 'distancePrefix FRED');
};
// });

View File

@ -47,7 +47,7 @@ exports.shutdown = function(options) {
};
exports.testNewLine = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'echo a\\nb',
check: {
@ -72,7 +72,7 @@ exports.testNewLine = function(options) {
};
exports.testTab = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'echo a\\tb',
check: {
@ -97,7 +97,7 @@ exports.testTab = function(options) {
};
exports.testEscape = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
// What's typed is actually:
// tsrsrsr a\\ b c
@ -143,7 +143,7 @@ exports.testEscape = function(options) {
};
exports.testBlank = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'tsrsrsr a "" c',
check: {
@ -213,7 +213,7 @@ exports.testBlank = function(options) {
};
exports.testBlankWithParam = function(options) {
helpers.audit(options, [
return helpers.audit(options, [
{
setup: 'tsrsrsr a --p3',
check: {

View File

@ -30,6 +30,7 @@ let promise = (Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js",
let assert = { ok: ok, is: is, log: info };
var util = require('util/util');
var cli = require('gcli/cli');
var converters = require('gcli/converters');
@ -566,7 +567,7 @@ helpers._check = function(options, name, checks) {
if ('predictions' in checks) {
var predictionsCheck = function(actualPredictions) {
helpers._arrayIs(actualPredictions,
helpers.arrayIs(actualPredictions,
checks.predictions,
'predictions' + suffix);
};
@ -585,7 +586,7 @@ helpers._check = function(options, name, checks) {
}
if ('unassigned' in checks) {
helpers._arrayIs(helpers._actual.unassigned(options),
helpers.arrayIs(helpers._actual.unassigned(options),
checks.unassigned,
'unassigned' + suffix);
}
@ -613,7 +614,7 @@ helpers._check = function(options, name, checks) {
}
if ('options' in checks) {
helpers._arrayIs(helpers._actual.options(options),
helpers.arrayIs(helpers._actual.options(options),
checks.options,
'options' + suffix);
}
@ -718,6 +719,11 @@ helpers._exec = function(options, name, expected) {
return promise.resolve({});
}
var origLogErrors = cli.logErrors;
if (expected.error) {
cli.logErrors = false;
}
var output;
try {
output = options.display.requisition.exec({ hidden: true });
@ -726,6 +732,9 @@ helpers._exec = function(options, name, expected) {
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
util.errorHandler(ex);
if (expected.error) {
cli.logErrors = origLogErrors;
}
return promise.resolve({});
}
@ -737,10 +746,17 @@ helpers._exec = function(options, name, expected) {
if (!options.window.document.createElement) {
assert.log('skipping output tests (missing doc.createElement) for ' + name);
if (expected.error) {
cli.logErrors = origLogErrors;
}
return promise.resolve({ output: output });
}
if (!('output' in expected)) {
if (expected.error) {
cli.logErrors = origLogErrors;
}
return promise.resolve({ output: output });
}
@ -788,6 +804,9 @@ helpers._exec = function(options, name, expected) {
doTest(expected.output, actualOutput);
}
if (expected.error) {
cli.logErrors = origLogErrors;
}
return { output: output, text: actualOutput };
});
};
@ -940,17 +959,6 @@ helpers.audit = function(options, audits) {
log('- START \'' + name + '\' in ' + assert.currentTest);
}
if (audit.skipIf) {
var skip = (typeof audit.skipIf === 'function') ?
audit.skipIf(options) :
!!audit.skipIf;
if (skip) {
var reason = audit.skipIf.name ? 'due to ' + audit.skipIf.name : '';
assert.log('Skipped ' + name + ' ' + reason);
return promise.resolve(undefined);
}
}
if (audit.skipRemainingIf) {
var skipRemainingIf = (typeof audit.skipRemainingIf === 'function') ?
audit.skipRemainingIf(options) :
@ -964,6 +972,17 @@ helpers.audit = function(options, audits) {
}
}
if (audit.skipIf) {
var skip = (typeof audit.skipIf === 'function') ?
audit.skipIf(options) :
!!audit.skipIf;
if (skip) {
var reason = audit.skipIf.name ? 'due to ' + audit.skipIf.name : '';
assert.log('Skipped ' + name + ' ' + reason);
return promise.resolve(undefined);
}
}
if (skipReason != null) {
assert.log('Skipped ' + name + ' ' + skipReason);
return promise.resolve(undefined);
@ -1008,7 +1027,7 @@ helpers.audit = function(options, audits) {
/**
* Compare 2 arrays.
*/
helpers._arrayIs = function(actual, expected, message) {
helpers.arrayIs = function(actual, expected, message) {
assert.ok(Array.isArray(actual), 'actual is not an array: ' + message);
assert.ok(Array.isArray(expected), 'expected is not an array: ' + message);

View File

@ -482,6 +482,116 @@ var tsfail = {
}
};
var tsfile = {
item: 'command',
name: 'tsfile',
description: 'test file params',
};
var tsfileOpen = {
item: 'command',
name: 'tsfile open',
description: 'a file param in open mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'file',
existing: 'yes'
}
}
],
exec: createExec('tsfile open')
};
var tsfileSaveas = {
item: 'command',
name: 'tsfile saveas',
description: 'a file param in saveas mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'file',
existing: 'no'
}
}
],
exec: createExec('tsfile saveas')
};
var tsfileSave = {
item: 'command',
name: 'tsfile save',
description: 'a file param in save mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'file',
existing: 'maybe'
}
}
],
exec: createExec('tsfile save')
};
var tsfileCd = {
item: 'command',
name: 'tsfile cd',
description: 'a file param in cd mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'directory',
existing: 'yes'
}
}
],
exec: createExec('tsfile cd')
};
var tsfileMkdir = {
item: 'command',
name: 'tsfile mkdir',
description: 'a file param in mkdir mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'directory',
existing: 'no'
}
}
],
exec: createExec('tsfile mkdir')
};
var tsfileRm = {
item: 'command',
name: 'tsfile rm',
description: 'a file param in rm mode',
params: [
{
name: 'p1',
type: {
name: 'file',
filetype: 'any',
existing: 'yes'
}
}
],
exec: createExec('tsfile rm')
};
mockCommands.commands = {};
/**
@ -533,6 +643,13 @@ mockCommands.setup = function(opts) {
mockCommands.commands.tslong = canon.addCommand(tslong);
mockCommands.commands.tsdate = canon.addCommand(tsdate);
mockCommands.commands.tsfail = canon.addCommand(tsfail);
mockCommands.commands.tsfile = canon.addCommand(tsfile);
mockCommands.commands.tsfileOpen = canon.addCommand(tsfileOpen);
mockCommands.commands.tsfileSaveas = canon.addCommand(tsfileSaveas);
mockCommands.commands.tsfileSave = canon.addCommand(tsfileSave);
mockCommands.commands.tsfileCd = canon.addCommand(tsfileCd);
mockCommands.commands.tsfileMkdir = canon.addCommand(tsfileMkdir);
mockCommands.commands.tsfileRm = canon.addCommand(tsfileRm);
};
mockCommands.shutdown = function(opts) {
@ -564,6 +681,13 @@ mockCommands.shutdown = function(opts) {
canon.removeCommand(tslong);
canon.removeCommand(tsdate);
canon.removeCommand(tsfail);
canon.removeCommand(tsfile);
canon.removeCommand(tsfileOpen);
canon.removeCommand(tsfileSaveas);
canon.removeCommand(tsfileSave);
canon.removeCommand(tsfileCd);
canon.removeCommand(tsfileMkdir);
canon.removeCommand(tsfileRm);
types.removeType(mockCommands.optionType);
types.removeType(mockCommands.optionValue);

View File

@ -47,6 +47,30 @@ cliUnusedArg=Too many arguments
# options that are available to the current command.
cliOptions=Available Options
# LOCALIZATION NOTE (fileErrNotExists): Error message given when a file
# argument points to a file that does not exist, but should (e.g. for use with
# File->Open) %1$S is a filename
fileErrNotExists='%1$S' doesn't exist
# LOCALIZATION NOTE (fileErrExists): Error message given when a file argument
# points to a file that exists, but should not (e.g. for use with File->Save
# As) %1$S is a filename
fileErrExists='%1$S' already exists
# LOCALIZATION NOTE (fileErrIsNotFile): Error message given when a file
# argument points to a non-file, when a file is needed. %1$S is a filename
fileErrIsNotFile='%1$S' is not a file
# LOCALIZATION NOTE (fileErrIsNotDirectory): Error message given when a file
# argument points to a non-directory, when a directory is needed (e.g. for use
# with 'cd') %1$S is a filename
fileErrIsNotDirectory='%1$S' is not a directory
# LOCALIZATION NOTE (fileErrDoesntMatch): Error message given when a file
# argument does not match the specified regular expression %1$S is a filename
# %2$S is a regular expression
fileErrDoesntMatch='%1$S' does not match '%2$S'
# LOCALIZATION NOTE (fieldSelectionSelect): When a command has a parameter
# that has a number of pre-defined options the user interface presents these
# in a drop-down menu, where the first 'option' is an indicator that a

View File

@ -504,6 +504,21 @@ cmdDesc=Manipulate the commands
# name, which is why it should be as short as possible.
cmdRefreshDesc=Re-read mozcmd directory
# LOCALIZATION NOTE (cmdStatus) When the we load new commands from mozcmd
# directory, we report on how many we loaded. %1$S is a count of the number
# of loaded commands, and %2$S is the directory we loaded from.
cmdStatus=Read %1$S commands from '%2$S'
# LOCALIZATION NOTE (cmdSetdirDesc)
cmdSetdirDesc=Setup a mozcmd directory
# LOCALIZATION NOTE (cmdSetdirManual)
cmdSetdirManual=A 'mozcmd' directory is an easy way to create new custom commands for the Firefox command line. For more information see the <a href="https://developer.mozilla.org/en-US/docs/Tools/GCLI/Customization">MDN documentation</a>.
# LOCALIZATION NOTE (cmdSetdirDirectoryDesc) The description of the directory
# parameter to the 'cmd setdir' command.
cmdSetdirDirectoryDesc=Directory containing .mozcmd files
# LOCALIZATION NOTE (addonDesc) A very short description of the 'addon'
# command. This string is designed to be shown in a menu alongside the command
# name, which is why it should be as short as possible.

File diff suppressed because it is too large Load Diff