mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-09 05:14:24 +00:00
Bug 874821 - Enable better remote gcli testing; r=mratcliffe
This commit is contained in:
parent
70d15618e2
commit
57536173c7
@ -57,6 +57,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_gcli_keyboard3.js \
|
||||
browser_gcli_menu.js \
|
||||
browser_gcli_node.js \
|
||||
browser_gcli_remote.js \
|
||||
browser_gcli_resource.js \
|
||||
browser_gcli_scratchpad.js \
|
||||
browser_gcli_spell.js \
|
||||
|
462
browser/devtools/commandline/test/browser_gcli_remote.js
Normal file
462
browser/devtools/commandline/test/browser_gcli_remote.js
Normal file
@ -0,0 +1,462 @@
|
||||
/*
|
||||
* 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-testRemote.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 mockCommands = require('gclitest/mockCommands');
|
||||
|
||||
exports.setup = function(options) {
|
||||
mockCommands.setup();
|
||||
};
|
||||
|
||||
exports.shutdown = function(options) {
|
||||
mockCommands.shutdown();
|
||||
};
|
||||
|
||||
exports.testRemote = function(options) {
|
||||
return helpers.audit(options, [
|
||||
{
|
||||
skipRemainingIf: !options.isHttp,
|
||||
setup: 'remote ',
|
||||
check: {
|
||||
input: 'remote ',
|
||||
hints: '',
|
||||
markup: 'EEEEEEV',
|
||||
cursor: 7,
|
||||
current: '__command',
|
||||
status: 'ERROR',
|
||||
options: [ ],
|
||||
message: 'Can\'t use \'remote\'.',
|
||||
predictions: [ ],
|
||||
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: {
|
||||
output: /^Added [0-9]* commands.$/,
|
||||
completed: false,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote ',
|
||||
check: {
|
||||
input: 'remote ',
|
||||
hints: '',
|
||||
markup: 'IIIIIIV',
|
||||
cursor: 7,
|
||||
current: '__command',
|
||||
status: 'ERROR',
|
||||
optionsIncludes: [
|
||||
'remote', 'remote cd', 'remote context', 'remote echo',
|
||||
'remote exec', 'remote exit', 'remote firefox', 'remote help',
|
||||
'remote intro', 'remote make'
|
||||
],
|
||||
message: '',
|
||||
predictions: [ 'remote' ],
|
||||
unassigned: [ ],
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote echo hello world',
|
||||
check: {
|
||||
input: 'remote echo hello world',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVVVVVVVVVVV',
|
||||
cursor: 23,
|
||||
current: 'message',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'remote echo' },
|
||||
message: {
|
||||
value: 'hello world',
|
||||
arg: ' hello world',
|
||||
status: 'VALID',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'hello world',
|
||||
completed: false,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote exec ls',
|
||||
check: {
|
||||
input: 'remote exec ls',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVV',
|
||||
cursor: 14,
|
||||
current: 'command',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: {
|
||||
value: 'ls',
|
||||
arg: ' ls',
|
||||
status: 'VALID',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
// output: '', We can't rely on the contents of the FS
|
||||
completed: false,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote sleep mistake',
|
||||
check: {
|
||||
input: 'remote sleep mistake',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVEEEEEEE',
|
||||
cursor: 20,
|
||||
current: 'length',
|
||||
status: 'ERROR',
|
||||
options: [ ],
|
||||
message: 'Can\'t convert "mistake" to a number.',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'remote sleep' },
|
||||
length: {
|
||||
value: undefined,
|
||||
arg: ' mistake',
|
||||
status: 'ERROR',
|
||||
message: 'Can\'t convert "mistake" to a number.'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote sleep 1',
|
||||
check: {
|
||||
input: 'remote sleep 1',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVV',
|
||||
cursor: 14,
|
||||
current: 'length',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'remote sleep' },
|
||||
length: { value: 1, arg: ' 1', status: 'VALID', message: '' }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Done',
|
||||
completed: false,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote help ',
|
||||
skipIf: true, // The help command is not remotable
|
||||
check: {
|
||||
input: 'remote help ',
|
||||
hints: '[search]',
|
||||
markup: 'VVVVVVVVVVVV',
|
||||
cursor: 12,
|
||||
current: 'search',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'remote help' },
|
||||
search: {
|
||||
value: undefined,
|
||||
arg: '',
|
||||
status: 'VALID',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: '',
|
||||
completed: false,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'remote intro',
|
||||
check: {
|
||||
input: 'remote intro',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVV',
|
||||
cursor: 12,
|
||||
current: '__command',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'remote intro' }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/^This command line/,
|
||||
/F1\/Escape/
|
||||
],
|
||||
completed: false,
|
||||
type: 'intro',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'context remote',
|
||||
check: {
|
||||
input: 'context remote',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVV',
|
||||
cursor: 14,
|
||||
current: 'prefix',
|
||||
status: 'VALID',
|
||||
optionsContains: [ 'remote', 'remote cd', 'remote echo', 'remote exec', 'remote exit', 'remote firefox', 'remote help', 'remote intro', 'remote make' ],
|
||||
message: '',
|
||||
predictionsContains: [ 'remote', 'remote cd', 'remote echo', 'remote exec', 'remote exit', 'remote firefox', 'remote help', 'remote intro', 'remote make', 'remote pref' ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'context' },
|
||||
prefix: {
|
||||
/*value:[object Object],*/
|
||||
arg: ' remote',
|
||||
status: 'VALID',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Using remote as a command prefix',
|
||||
completed: true,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'exec ls',
|
||||
check: {
|
||||
input: 'exec ls',
|
||||
hints: '',
|
||||
markup: 'VVVVVVV',
|
||||
cursor: 7,
|
||||
current: 'command',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { value: 'ls', arg: ' ls', status: 'VALID', message: '' },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
// output: '', We can't rely on the contents of the filesystem
|
||||
completed: false,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'echo hello world',
|
||||
check: {
|
||||
input: 'echo hello world',
|
||||
hints: '',
|
||||
markup: 'VVVVVVVVVVVVVVVV',
|
||||
cursor: 16,
|
||||
current: 'message',
|
||||
status: 'VALID',
|
||||
options: [ ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'remote echo' },
|
||||
message: {
|
||||
value: 'hello world',
|
||||
arg: ' hello world',
|
||||
status: 'VALID',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: /^hello world$/,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'context',
|
||||
check: {
|
||||
input: 'context',
|
||||
hints: ' [prefix]',
|
||||
markup: 'VVVVVVV',
|
||||
cursor: 7,
|
||||
current: '__command',
|
||||
status: 'VALID',
|
||||
optionsContains: [ 'remote', 'remote cd', 'remote echo', 'remote exec', 'remote exit', 'remote firefox', 'remote help', 'remote intro', 'remote make' ],
|
||||
message: '',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'context' },
|
||||
prefix: { value: undefined, arg: '', status: 'VALID', message: '' }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: 'Command prefix is unset',
|
||||
completed: true,
|
||||
type: 'string',
|
||||
error: false
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'disconnect ',
|
||||
check: {
|
||||
input: 'disconnect ',
|
||||
hints: 'remote',
|
||||
markup: 'VVVVVVVVVVV',
|
||||
cursor: 11,
|
||||
current: 'prefix',
|
||||
status: 'ERROR',
|
||||
options: [ 'remote' ],
|
||||
message: '',
|
||||
predictions: [ 'remote' ],
|
||||
unassigned: [ ],
|
||||
args: {
|
||||
command: { name: 'disconnect' },
|
||||
prefix: {
|
||||
value: undefined,
|
||||
arg: '',
|
||||
status: 'INCOMPLETE',
|
||||
message: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
setup: 'disconnect remote --force',
|
||||
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: 'remote ',
|
||||
check: {
|
||||
input: 'remote ',
|
||||
hints: '',
|
||||
markup: 'EEEEEEV',
|
||||
cursor: 7,
|
||||
current: '__command',
|
||||
status: 'ERROR',
|
||||
options: [ ],
|
||||
message: 'Can\'t use \'remote\'.',
|
||||
predictions: [ ],
|
||||
unassigned: [ ],
|
||||
}
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
// });
|
||||
|
@ -226,7 +226,7 @@ helpers._actual = {
|
||||
.replace(/ $/, '');
|
||||
};
|
||||
|
||||
var promisedJoin = util.promised(join);
|
||||
var promisedJoin = Promise.promised(join);
|
||||
return promisedJoin(templateData.directTabText,
|
||||
templateData.emptyParameters,
|
||||
templateData.arrowTabText);
|
||||
@ -314,12 +314,12 @@ helpers._createDebugCheck = function(options) {
|
||||
var hintsPromise = helpers._actual.hints(options);
|
||||
var predictionsPromise = helpers._actual.predictions(options);
|
||||
|
||||
return util.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
return Promise.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
var hints = values[0];
|
||||
var predictions = values[1];
|
||||
var output = '';
|
||||
|
||||
output += 'helpers.audit(options, [\n';
|
||||
output += 'return helpers.audit(options, [\n';
|
||||
output += ' {\n';
|
||||
|
||||
if (cursor === input.length) {
|
||||
@ -627,13 +627,14 @@ helpers._check = function(options, name, checks) {
|
||||
Object.keys(checks.args).forEach(function(paramName) {
|
||||
var check = checks.args[paramName];
|
||||
|
||||
var assignment;
|
||||
if (paramName === 'command') {
|
||||
// We allow an 'argument' called 'command' to be the command itself, but
|
||||
// what if the command has a parameter called 'command' (for example, an
|
||||
// 'exec' command)? We default to using the parameter because checking
|
||||
// the command value is less useful
|
||||
var assignment = requisition.getAssignment(paramName);
|
||||
if (assignment == null && paramName === 'command') {
|
||||
assignment = requisition.commandAssignment;
|
||||
}
|
||||
else {
|
||||
assignment = requisition.getAssignment(paramName);
|
||||
}
|
||||
|
||||
if (assignment == null) {
|
||||
assert.ok(false, 'Unknown arg: ' + paramName + suffix);
|
||||
@ -641,9 +642,19 @@ helpers._check = function(options, name, checks) {
|
||||
}
|
||||
|
||||
if ('value' in check) {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
if (typeof check.value === 'function') {
|
||||
try {
|
||||
check.value(assignment.value);
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, '' + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
if ('name' in check) {
|
||||
@ -689,7 +700,7 @@ helpers._check = function(options, name, checks) {
|
||||
});
|
||||
}
|
||||
|
||||
return util.all(outstanding).then(function() {
|
||||
return Promise.all(outstanding).then(function() {
|
||||
// Ensure the promise resolves to nothing
|
||||
return undefined;
|
||||
});
|
||||
@ -707,7 +718,16 @@ helpers._exec = function(options, name, expected) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
var output = options.display.requisition.exec({ hidden: true });
|
||||
var output;
|
||||
try {
|
||||
output = options.display.requisition.exec({ hidden: true });
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
|
||||
util.errorHandler(ex);
|
||||
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
if ('completed' in expected) {
|
||||
assert.is(output.completed,
|
||||
@ -725,9 +745,6 @@ helpers._exec = function(options, name, expected) {
|
||||
}
|
||||
|
||||
var checkOutput = function() {
|
||||
var div = options.window.document.createElement('div');
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
|
||||
if ('type' in expected) {
|
||||
assert.is(output.type,
|
||||
expected.type,
|
||||
@ -740,20 +757,20 @@ helpers._exec = function(options, name, expected) {
|
||||
'output.error for: ' + name);
|
||||
}
|
||||
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
var convertPromise = converters.convert(output.data, output.type, 'dom',
|
||||
conversionContext);
|
||||
return convertPromise.then(function(node) {
|
||||
div.appendChild(node);
|
||||
var actualOutput = div.textContent.trim();
|
||||
var actualOutput = node.textContent.trim();
|
||||
|
||||
var doTest = function(match, against) {
|
||||
if (match.test(against)) {
|
||||
assert.ok(true, 'html output for ' + name + ' should match ' +
|
||||
match.source);
|
||||
assert.ok(true, 'html output for ' + name + ' should match /' +
|
||||
match.source + '/');
|
||||
} else {
|
||||
assert.ok(false, 'html output for ' + name + ' should match ' +
|
||||
assert.ok(false, 'html output for ' + name + ' should match /' +
|
||||
match.source +
|
||||
'. Actual textContent: "' + against + '"');
|
||||
'/. Actual textContent: "' + against + '"');
|
||||
}
|
||||
};
|
||||
|
||||
@ -810,11 +827,13 @@ var totalResponseTime = 0;
|
||||
var averageOver = 0;
|
||||
var maxResponseTime = 0;
|
||||
var maxResponseCulprit = undefined;
|
||||
var start = undefined;
|
||||
|
||||
/**
|
||||
* Restart the stats collection process
|
||||
*/
|
||||
helpers.resetResponseTimes = function() {
|
||||
start = new Date().getTime();
|
||||
totalResponseTime = 0;
|
||||
averageOver = 0;
|
||||
maxResponseTime = 0;
|
||||
@ -849,6 +868,20 @@ Object.defineProperty(helpers, 'maxResponseCulprit', {
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Quick summary of the times
|
||||
*/
|
||||
Object.defineProperty(helpers, 'timingSummary', {
|
||||
get: function() {
|
||||
var elapsed = (new Date().getTime() - start) / 1000;
|
||||
return 'Total ' + elapsed + 's, ' +
|
||||
'ave response ' + helpers.averageResponseTime + 'ms, ' +
|
||||
'max response ' + helpers.maxResponseTime + 'ms ' +
|
||||
'from \'' + helpers.maxResponseCulprit + '\'';
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* A way of turning a set of tests into something more declarative, this helps
|
||||
* to allow tests to be asynchronous.
|
||||
|
@ -226,7 +226,7 @@ helpers._actual = {
|
||||
.replace(/ $/, '');
|
||||
};
|
||||
|
||||
var promisedJoin = util.promised(join);
|
||||
var promisedJoin = Promise.promised(join);
|
||||
return promisedJoin(templateData.directTabText,
|
||||
templateData.emptyParameters,
|
||||
templateData.arrowTabText);
|
||||
@ -314,12 +314,12 @@ helpers._createDebugCheck = function(options) {
|
||||
var hintsPromise = helpers._actual.hints(options);
|
||||
var predictionsPromise = helpers._actual.predictions(options);
|
||||
|
||||
return util.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
return Promise.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
var hints = values[0];
|
||||
var predictions = values[1];
|
||||
var output = '';
|
||||
|
||||
output += 'helpers.audit(options, [\n';
|
||||
output += 'return helpers.audit(options, [\n';
|
||||
output += ' {\n';
|
||||
|
||||
if (cursor === input.length) {
|
||||
@ -627,13 +627,14 @@ helpers._check = function(options, name, checks) {
|
||||
Object.keys(checks.args).forEach(function(paramName) {
|
||||
var check = checks.args[paramName];
|
||||
|
||||
var assignment;
|
||||
if (paramName === 'command') {
|
||||
// We allow an 'argument' called 'command' to be the command itself, but
|
||||
// what if the command has a parameter called 'command' (for example, an
|
||||
// 'exec' command)? We default to using the parameter because checking
|
||||
// the command value is less useful
|
||||
var assignment = requisition.getAssignment(paramName);
|
||||
if (assignment == null && paramName === 'command') {
|
||||
assignment = requisition.commandAssignment;
|
||||
}
|
||||
else {
|
||||
assignment = requisition.getAssignment(paramName);
|
||||
}
|
||||
|
||||
if (assignment == null) {
|
||||
assert.ok(false, 'Unknown arg: ' + paramName + suffix);
|
||||
@ -641,9 +642,19 @@ helpers._check = function(options, name, checks) {
|
||||
}
|
||||
|
||||
if ('value' in check) {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
if (typeof check.value === 'function') {
|
||||
try {
|
||||
check.value(assignment.value);
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, '' + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
if ('name' in check) {
|
||||
@ -689,7 +700,7 @@ helpers._check = function(options, name, checks) {
|
||||
});
|
||||
}
|
||||
|
||||
return util.all(outstanding).then(function() {
|
||||
return Promise.all(outstanding).then(function() {
|
||||
// Ensure the promise resolves to nothing
|
||||
return undefined;
|
||||
});
|
||||
@ -707,7 +718,16 @@ helpers._exec = function(options, name, expected) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
var output = options.display.requisition.exec({ hidden: true });
|
||||
var output;
|
||||
try {
|
||||
output = options.display.requisition.exec({ hidden: true });
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
|
||||
util.errorHandler(ex);
|
||||
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
if ('completed' in expected) {
|
||||
assert.is(output.completed,
|
||||
@ -725,9 +745,6 @@ helpers._exec = function(options, name, expected) {
|
||||
}
|
||||
|
||||
var checkOutput = function() {
|
||||
var div = options.window.document.createElement('div');
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
|
||||
if ('type' in expected) {
|
||||
assert.is(output.type,
|
||||
expected.type,
|
||||
@ -740,20 +757,20 @@ helpers._exec = function(options, name, expected) {
|
||||
'output.error for: ' + name);
|
||||
}
|
||||
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
var convertPromise = converters.convert(output.data, output.type, 'dom',
|
||||
conversionContext);
|
||||
return convertPromise.then(function(node) {
|
||||
div.appendChild(node);
|
||||
var actualOutput = div.textContent.trim();
|
||||
var actualOutput = node.textContent.trim();
|
||||
|
||||
var doTest = function(match, against) {
|
||||
if (match.test(against)) {
|
||||
assert.ok(true, 'html output for ' + name + ' should match ' +
|
||||
match.source);
|
||||
assert.ok(true, 'html output for ' + name + ' should match /' +
|
||||
match.source + '/');
|
||||
} else {
|
||||
assert.ok(false, 'html output for ' + name + ' should match ' +
|
||||
assert.ok(false, 'html output for ' + name + ' should match /' +
|
||||
match.source +
|
||||
'. Actual textContent: "' + against + '"');
|
||||
'/. Actual textContent: "' + against + '"');
|
||||
}
|
||||
};
|
||||
|
||||
@ -810,11 +827,13 @@ var totalResponseTime = 0;
|
||||
var averageOver = 0;
|
||||
var maxResponseTime = 0;
|
||||
var maxResponseCulprit = undefined;
|
||||
var start = undefined;
|
||||
|
||||
/**
|
||||
* Restart the stats collection process
|
||||
*/
|
||||
helpers.resetResponseTimes = function() {
|
||||
start = new Date().getTime();
|
||||
totalResponseTime = 0;
|
||||
averageOver = 0;
|
||||
maxResponseTime = 0;
|
||||
@ -849,6 +868,20 @@ Object.defineProperty(helpers, 'maxResponseCulprit', {
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Quick summary of the times
|
||||
*/
|
||||
Object.defineProperty(helpers, 'timingSummary', {
|
||||
get: function() {
|
||||
var elapsed = (new Date().getTime() - start) / 1000;
|
||||
return 'Total ' + elapsed + 's, ' +
|
||||
'ave response ' + helpers.averageResponseTime + 'ms, ' +
|
||||
'max response ' + helpers.maxResponseTime + 'ms ' +
|
||||
'from \'' + helpers.maxResponseCulprit + '\'';
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* A way of turning a set of tests into something more declarative, this helps
|
||||
* to allow tests to be asynchronous.
|
||||
|
@ -226,7 +226,7 @@ helpers._actual = {
|
||||
.replace(/ $/, '');
|
||||
};
|
||||
|
||||
var promisedJoin = util.promised(join);
|
||||
var promisedJoin = Promise.promised(join);
|
||||
return promisedJoin(templateData.directTabText,
|
||||
templateData.emptyParameters,
|
||||
templateData.arrowTabText);
|
||||
@ -314,12 +314,12 @@ helpers._createDebugCheck = function(options) {
|
||||
var hintsPromise = helpers._actual.hints(options);
|
||||
var predictionsPromise = helpers._actual.predictions(options);
|
||||
|
||||
return util.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
return Promise.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
var hints = values[0];
|
||||
var predictions = values[1];
|
||||
var output = '';
|
||||
|
||||
output += 'helpers.audit(options, [\n';
|
||||
output += 'return helpers.audit(options, [\n';
|
||||
output += ' {\n';
|
||||
|
||||
if (cursor === input.length) {
|
||||
@ -627,13 +627,14 @@ helpers._check = function(options, name, checks) {
|
||||
Object.keys(checks.args).forEach(function(paramName) {
|
||||
var check = checks.args[paramName];
|
||||
|
||||
var assignment;
|
||||
if (paramName === 'command') {
|
||||
// We allow an 'argument' called 'command' to be the command itself, but
|
||||
// what if the command has a parameter called 'command' (for example, an
|
||||
// 'exec' command)? We default to using the parameter because checking
|
||||
// the command value is less useful
|
||||
var assignment = requisition.getAssignment(paramName);
|
||||
if (assignment == null && paramName === 'command') {
|
||||
assignment = requisition.commandAssignment;
|
||||
}
|
||||
else {
|
||||
assignment = requisition.getAssignment(paramName);
|
||||
}
|
||||
|
||||
if (assignment == null) {
|
||||
assert.ok(false, 'Unknown arg: ' + paramName + suffix);
|
||||
@ -641,9 +642,19 @@ helpers._check = function(options, name, checks) {
|
||||
}
|
||||
|
||||
if ('value' in check) {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
if (typeof check.value === 'function') {
|
||||
try {
|
||||
check.value(assignment.value);
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, '' + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
if ('name' in check) {
|
||||
@ -689,7 +700,7 @@ helpers._check = function(options, name, checks) {
|
||||
});
|
||||
}
|
||||
|
||||
return util.all(outstanding).then(function() {
|
||||
return Promise.all(outstanding).then(function() {
|
||||
// Ensure the promise resolves to nothing
|
||||
return undefined;
|
||||
});
|
||||
@ -707,7 +718,16 @@ helpers._exec = function(options, name, expected) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
var output = options.display.requisition.exec({ hidden: true });
|
||||
var output;
|
||||
try {
|
||||
output = options.display.requisition.exec({ hidden: true });
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
|
||||
util.errorHandler(ex);
|
||||
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
if ('completed' in expected) {
|
||||
assert.is(output.completed,
|
||||
@ -725,9 +745,6 @@ helpers._exec = function(options, name, expected) {
|
||||
}
|
||||
|
||||
var checkOutput = function() {
|
||||
var div = options.window.document.createElement('div');
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
|
||||
if ('type' in expected) {
|
||||
assert.is(output.type,
|
||||
expected.type,
|
||||
@ -740,20 +757,20 @@ helpers._exec = function(options, name, expected) {
|
||||
'output.error for: ' + name);
|
||||
}
|
||||
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
var convertPromise = converters.convert(output.data, output.type, 'dom',
|
||||
conversionContext);
|
||||
return convertPromise.then(function(node) {
|
||||
div.appendChild(node);
|
||||
var actualOutput = div.textContent.trim();
|
||||
var actualOutput = node.textContent.trim();
|
||||
|
||||
var doTest = function(match, against) {
|
||||
if (match.test(against)) {
|
||||
assert.ok(true, 'html output for ' + name + ' should match ' +
|
||||
match.source);
|
||||
assert.ok(true, 'html output for ' + name + ' should match /' +
|
||||
match.source + '/');
|
||||
} else {
|
||||
assert.ok(false, 'html output for ' + name + ' should match ' +
|
||||
assert.ok(false, 'html output for ' + name + ' should match /' +
|
||||
match.source +
|
||||
'. Actual textContent: "' + against + '"');
|
||||
'/. Actual textContent: "' + against + '"');
|
||||
}
|
||||
};
|
||||
|
||||
@ -810,11 +827,13 @@ var totalResponseTime = 0;
|
||||
var averageOver = 0;
|
||||
var maxResponseTime = 0;
|
||||
var maxResponseCulprit = undefined;
|
||||
var start = undefined;
|
||||
|
||||
/**
|
||||
* Restart the stats collection process
|
||||
*/
|
||||
helpers.resetResponseTimes = function() {
|
||||
start = new Date().getTime();
|
||||
totalResponseTime = 0;
|
||||
averageOver = 0;
|
||||
maxResponseTime = 0;
|
||||
@ -849,6 +868,20 @@ Object.defineProperty(helpers, 'maxResponseCulprit', {
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Quick summary of the times
|
||||
*/
|
||||
Object.defineProperty(helpers, 'timingSummary', {
|
||||
get: function() {
|
||||
var elapsed = (new Date().getTime() - start) / 1000;
|
||||
return 'Total ' + elapsed + 's, ' +
|
||||
'ave response ' + helpers.averageResponseTime + 'ms, ' +
|
||||
'max response ' + helpers.maxResponseTime + 'ms ' +
|
||||
'from \'' + helpers.maxResponseCulprit + '\'';
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* A way of turning a set of tests into something more declarative, this helps
|
||||
* to allow tests to be asynchronous.
|
||||
|
@ -24,7 +24,7 @@ let require = (Cu.import("resource://gre/modules/devtools/Require.jsm", {})).req
|
||||
Components.utils.import("resource://gre/modules/devtools/gcli.jsm", {});
|
||||
|
||||
let console = (Cu.import("resource://gre/modules/devtools/Console.jsm", {})).console;
|
||||
let TargetFactory = (Cu.import("resource:///modules/devtools/gDevTools.jsm", {})).devtools.TargetFactory;
|
||||
let TargetFactory = (Cu.import("resource://gre/modules/devtools/Loader.jsm", {})).devtools.TargetFactory;
|
||||
|
||||
let Promise = (Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {})).Promise;
|
||||
let assert = { ok: ok, is: is, log: info };
|
||||
@ -226,7 +226,7 @@ helpers._actual = {
|
||||
.replace(/ $/, '');
|
||||
};
|
||||
|
||||
var promisedJoin = util.promised(join);
|
||||
var promisedJoin = Promise.promised(join);
|
||||
return promisedJoin(templateData.directTabText,
|
||||
templateData.emptyParameters,
|
||||
templateData.arrowTabText);
|
||||
@ -314,12 +314,12 @@ helpers._createDebugCheck = function(options) {
|
||||
var hintsPromise = helpers._actual.hints(options);
|
||||
var predictionsPromise = helpers._actual.predictions(options);
|
||||
|
||||
return util.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
return Promise.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
var hints = values[0];
|
||||
var predictions = values[1];
|
||||
var output = '';
|
||||
|
||||
output += 'helpers.audit(options, [\n';
|
||||
output += 'return helpers.audit(options, [\n';
|
||||
output += ' {\n';
|
||||
|
||||
if (cursor === input.length) {
|
||||
@ -627,13 +627,14 @@ helpers._check = function(options, name, checks) {
|
||||
Object.keys(checks.args).forEach(function(paramName) {
|
||||
var check = checks.args[paramName];
|
||||
|
||||
var assignment;
|
||||
if (paramName === 'command') {
|
||||
// We allow an 'argument' called 'command' to be the command itself, but
|
||||
// what if the command has a parameter called 'command' (for example, an
|
||||
// 'exec' command)? We default to using the parameter because checking
|
||||
// the command value is less useful
|
||||
var assignment = requisition.getAssignment(paramName);
|
||||
if (assignment == null && paramName === 'command') {
|
||||
assignment = requisition.commandAssignment;
|
||||
}
|
||||
else {
|
||||
assignment = requisition.getAssignment(paramName);
|
||||
}
|
||||
|
||||
if (assignment == null) {
|
||||
assert.ok(false, 'Unknown arg: ' + paramName + suffix);
|
||||
@ -641,9 +642,19 @@ helpers._check = function(options, name, checks) {
|
||||
}
|
||||
|
||||
if ('value' in check) {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
if (typeof check.value === 'function') {
|
||||
try {
|
||||
check.value(assignment.value);
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, '' + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
if ('name' in check) {
|
||||
@ -689,7 +700,7 @@ helpers._check = function(options, name, checks) {
|
||||
});
|
||||
}
|
||||
|
||||
return util.all(outstanding).then(function() {
|
||||
return Promise.all(outstanding).then(function() {
|
||||
// Ensure the promise resolves to nothing
|
||||
return undefined;
|
||||
});
|
||||
@ -707,7 +718,16 @@ helpers._exec = function(options, name, expected) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
var output = options.display.requisition.exec({ hidden: true });
|
||||
var output;
|
||||
try {
|
||||
output = options.display.requisition.exec({ hidden: true });
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
|
||||
util.errorHandler(ex);
|
||||
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
if ('completed' in expected) {
|
||||
assert.is(output.completed,
|
||||
@ -725,9 +745,6 @@ helpers._exec = function(options, name, expected) {
|
||||
}
|
||||
|
||||
var checkOutput = function() {
|
||||
var div = options.window.document.createElement('div');
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
|
||||
if ('type' in expected) {
|
||||
assert.is(output.type,
|
||||
expected.type,
|
||||
@ -740,20 +757,20 @@ helpers._exec = function(options, name, expected) {
|
||||
'output.error for: ' + name);
|
||||
}
|
||||
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
var convertPromise = converters.convert(output.data, output.type, 'dom',
|
||||
conversionContext);
|
||||
return convertPromise.then(function(node) {
|
||||
div.appendChild(node);
|
||||
var actualOutput = div.textContent.trim();
|
||||
var actualOutput = node.textContent.trim();
|
||||
|
||||
var doTest = function(match, against) {
|
||||
if (match.test(against)) {
|
||||
assert.ok(true, 'html output for ' + name + ' should match ' +
|
||||
match.source);
|
||||
assert.ok(true, 'html output for ' + name + ' should match /' +
|
||||
match.source + '/');
|
||||
} else {
|
||||
assert.ok(false, 'html output for ' + name + ' should match ' +
|
||||
assert.ok(false, 'html output for ' + name + ' should match /' +
|
||||
match.source +
|
||||
'. Actual textContent: "' + against + '"');
|
||||
'/. Actual textContent: "' + against + '"');
|
||||
}
|
||||
};
|
||||
|
||||
@ -810,11 +827,13 @@ var totalResponseTime = 0;
|
||||
var averageOver = 0;
|
||||
var maxResponseTime = 0;
|
||||
var maxResponseCulprit = undefined;
|
||||
var start = undefined;
|
||||
|
||||
/**
|
||||
* Restart the stats collection process
|
||||
*/
|
||||
helpers.resetResponseTimes = function() {
|
||||
start = new Date().getTime();
|
||||
totalResponseTime = 0;
|
||||
averageOver = 0;
|
||||
maxResponseTime = 0;
|
||||
@ -849,6 +868,20 @@ Object.defineProperty(helpers, 'maxResponseCulprit', {
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Quick summary of the times
|
||||
*/
|
||||
Object.defineProperty(helpers, 'timingSummary', {
|
||||
get: function() {
|
||||
var elapsed = (new Date().getTime() - start) / 1000;
|
||||
return 'Total ' + elapsed + 's, ' +
|
||||
'ave response ' + helpers.averageResponseTime + 'ms, ' +
|
||||
'max response ' + helpers.maxResponseTime + 'ms ' +
|
||||
'from \'' + helpers.maxResponseCulprit + '\'';
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* A way of turning a set of tests into something more declarative, this helps
|
||||
* to allow tests to be asynchronous.
|
||||
|
@ -226,7 +226,7 @@ helpers._actual = {
|
||||
.replace(/ $/, '');
|
||||
};
|
||||
|
||||
var promisedJoin = util.promised(join);
|
||||
var promisedJoin = Promise.promised(join);
|
||||
return promisedJoin(templateData.directTabText,
|
||||
templateData.emptyParameters,
|
||||
templateData.arrowTabText);
|
||||
@ -314,12 +314,12 @@ helpers._createDebugCheck = function(options) {
|
||||
var hintsPromise = helpers._actual.hints(options);
|
||||
var predictionsPromise = helpers._actual.predictions(options);
|
||||
|
||||
return util.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
return Promise.all(hintsPromise, predictionsPromise).then(function(values) {
|
||||
var hints = values[0];
|
||||
var predictions = values[1];
|
||||
var output = '';
|
||||
|
||||
output += 'helpers.audit(options, [\n';
|
||||
output += 'return helpers.audit(options, [\n';
|
||||
output += ' {\n';
|
||||
|
||||
if (cursor === input.length) {
|
||||
@ -627,13 +627,14 @@ helpers._check = function(options, name, checks) {
|
||||
Object.keys(checks.args).forEach(function(paramName) {
|
||||
var check = checks.args[paramName];
|
||||
|
||||
var assignment;
|
||||
if (paramName === 'command') {
|
||||
// We allow an 'argument' called 'command' to be the command itself, but
|
||||
// what if the command has a parameter called 'command' (for example, an
|
||||
// 'exec' command)? We default to using the parameter because checking
|
||||
// the command value is less useful
|
||||
var assignment = requisition.getAssignment(paramName);
|
||||
if (assignment == null && paramName === 'command') {
|
||||
assignment = requisition.commandAssignment;
|
||||
}
|
||||
else {
|
||||
assignment = requisition.getAssignment(paramName);
|
||||
}
|
||||
|
||||
if (assignment == null) {
|
||||
assert.ok(false, 'Unknown arg: ' + paramName + suffix);
|
||||
@ -641,9 +642,19 @@ helpers._check = function(options, name, checks) {
|
||||
}
|
||||
|
||||
if ('value' in check) {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
if (typeof check.value === 'function') {
|
||||
try {
|
||||
check.value(assignment.value);
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, '' + ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert.is(assignment.value,
|
||||
check.value,
|
||||
'arg.' + paramName + '.value' + suffix);
|
||||
}
|
||||
}
|
||||
|
||||
if ('name' in check) {
|
||||
@ -689,7 +700,7 @@ helpers._check = function(options, name, checks) {
|
||||
});
|
||||
}
|
||||
|
||||
return util.all(outstanding).then(function() {
|
||||
return Promise.all(outstanding).then(function() {
|
||||
// Ensure the promise resolves to nothing
|
||||
return undefined;
|
||||
});
|
||||
@ -707,7 +718,16 @@ helpers._exec = function(options, name, expected) {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
var output = options.display.requisition.exec({ hidden: true });
|
||||
var output;
|
||||
try {
|
||||
output = options.display.requisition.exec({ hidden: true });
|
||||
}
|
||||
catch (ex) {
|
||||
assert.ok(false, 'Failure executing \'' + name + '\': ' + ex);
|
||||
util.errorHandler(ex);
|
||||
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
if ('completed' in expected) {
|
||||
assert.is(output.completed,
|
||||
@ -725,9 +745,6 @@ helpers._exec = function(options, name, expected) {
|
||||
}
|
||||
|
||||
var checkOutput = function() {
|
||||
var div = options.window.document.createElement('div');
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
|
||||
if ('type' in expected) {
|
||||
assert.is(output.type,
|
||||
expected.type,
|
||||
@ -740,20 +757,20 @@ helpers._exec = function(options, name, expected) {
|
||||
'output.error for: ' + name);
|
||||
}
|
||||
|
||||
var conversionContext = options.display.requisition.conversionContext;
|
||||
var convertPromise = converters.convert(output.data, output.type, 'dom',
|
||||
conversionContext);
|
||||
return convertPromise.then(function(node) {
|
||||
div.appendChild(node);
|
||||
var actualOutput = div.textContent.trim();
|
||||
var actualOutput = node.textContent.trim();
|
||||
|
||||
var doTest = function(match, against) {
|
||||
if (match.test(against)) {
|
||||
assert.ok(true, 'html output for ' + name + ' should match ' +
|
||||
match.source);
|
||||
assert.ok(true, 'html output for ' + name + ' should match /' +
|
||||
match.source + '/');
|
||||
} else {
|
||||
assert.ok(false, 'html output for ' + name + ' should match ' +
|
||||
assert.ok(false, 'html output for ' + name + ' should match /' +
|
||||
match.source +
|
||||
'. Actual textContent: "' + against + '"');
|
||||
'/. Actual textContent: "' + against + '"');
|
||||
}
|
||||
};
|
||||
|
||||
@ -810,11 +827,13 @@ var totalResponseTime = 0;
|
||||
var averageOver = 0;
|
||||
var maxResponseTime = 0;
|
||||
var maxResponseCulprit = undefined;
|
||||
var start = undefined;
|
||||
|
||||
/**
|
||||
* Restart the stats collection process
|
||||
*/
|
||||
helpers.resetResponseTimes = function() {
|
||||
start = new Date().getTime();
|
||||
totalResponseTime = 0;
|
||||
averageOver = 0;
|
||||
maxResponseTime = 0;
|
||||
@ -849,6 +868,20 @@ Object.defineProperty(helpers, 'maxResponseCulprit', {
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Quick summary of the times
|
||||
*/
|
||||
Object.defineProperty(helpers, 'timingSummary', {
|
||||
get: function() {
|
||||
var elapsed = (new Date().getTime() - start) / 1000;
|
||||
return 'Total ' + elapsed + 's, ' +
|
||||
'ave response ' + helpers.averageResponseTime + 'ms, ' +
|
||||
'max response ' + helpers.maxResponseTime + 'ms ' +
|
||||
'from \'' + helpers.maxResponseCulprit + '\'';
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* A way of turning a set of tests into something more declarative, this helps
|
||||
* to allow tests to be asynchronous.
|
||||
|
@ -306,10 +306,21 @@ disconnectManual=Connect to the server, creating local versions of the commands
|
||||
# short as possible.
|
||||
disconnectPrefixDesc=Parent prefix for imported commands
|
||||
|
||||
# LOCALIZATION NOTE (disconnectForceDesc): A short description of the 'force'
|
||||
# parameter to the 'disconnect' command. This string is designed to be shown
|
||||
# in a dialog with restricted space, which is why it should be as short as
|
||||
# possible.
|
||||
disconnectForceDesc=Ignore outstanding requests
|
||||
|
||||
# LOCALIZATION NOTE (disconnectReply): The output of the 'disconnect' command,
|
||||
# telling the user what it's done.
|
||||
disconnectReply=Removed %S commands.
|
||||
|
||||
# LOCALIZATION NOTE (disconnectOutstanding): An error message displayed when
|
||||
# the user attempts to disconnect before all requests have completed. %1$S is
|
||||
# a list of commands which are incomplete
|
||||
disconnectOutstanding=Outstanding requests (%1$S)
|
||||
|
||||
# LOCALIZATION NOTE (prefDesc): A very short description of the 'pref'
|
||||
# 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. See prefManual for a
|
||||
|
@ -104,7 +104,7 @@ var mozl10n = {};
|
||||
|
||||
})(mozl10n);
|
||||
|
||||
define('gcli/index', ['require', 'exports', 'module' , 'gcli/types/basic', 'gcli/types/selection', 'gcli/types/command', 'gcli/types/date', 'gcli/types/javascript', 'gcli/types/node', 'gcli/types/resource', 'gcli/types/setting', 'gcli/settings', 'gcli/ui/intro', 'gcli/ui/focus', 'gcli/ui/fields/basic', 'gcli/ui/fields/javascript', 'gcli/ui/fields/selection', 'gcli/commands/connect', 'gcli/commands/context', 'gcli/commands/help', 'gcli/commands/pref', 'gcli/canon', 'gcli/converters', 'gcli/types', 'gcli/ui/ffdisplay'], function(require, exports, module) {
|
||||
define('gcli/index', ['require', 'exports', 'module' , 'gcli/types/basic', 'gcli/types/selection', 'gcli/types/command', 'gcli/types/date', 'gcli/types/javascript', 'gcli/types/node', 'gcli/types/resource', 'gcli/types/setting', 'gcli/settings', 'gcli/ui/intro', 'gcli/ui/focus', 'gcli/ui/fields/basic', 'gcli/ui/fields/javascript', 'gcli/ui/fields/selection', 'gcli/commands/connect', 'gcli/commands/context', 'gcli/commands/help', 'gcli/commands/pref', 'gcli/canon', 'gcli/converters', 'gcli/ui/ffdisplay'], function(require, exports, module) {
|
||||
|
||||
'use strict';
|
||||
|
||||
@ -143,9 +143,6 @@ define('gcli/index', ['require', 'exports', 'module' , 'gcli/types/basic', 'gcli
|
||||
exports.removeCommand = require('gcli/canon').removeCommand;
|
||||
exports.addConverter = require('gcli/converters').addConverter;
|
||||
exports.removeConverter = require('gcli/converters').removeConverter;
|
||||
exports.addType = require('gcli/types').addType;
|
||||
exports.removeType = require('gcli/types').removeType;
|
||||
|
||||
exports.lookup = mozl10n.lookup;
|
||||
exports.lookupFormat = mozl10n.lookupFormat;
|
||||
|
||||
@ -624,7 +621,7 @@ ArrayType.prototype.parse = function(arg, context) {
|
||||
}.bind(this);
|
||||
|
||||
var conversionPromises = arg.getArguments().map(subArgParse);
|
||||
return util.all(conversionPromises).then(function(conversions) {
|
||||
return Promise.all(conversionPromises).then(function(conversions) {
|
||||
return new ArrayConversion(conversions, arg);
|
||||
});
|
||||
};
|
||||
@ -657,15 +654,17 @@ exports.ArrayType = ArrayType;
|
||||
|
||||
define('util/promise', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var imported = {};
|
||||
Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js",
|
||||
imported);
|
||||
var imported = {};
|
||||
Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js",
|
||||
imported);
|
||||
|
||||
exports.defer = imported.Promise.defer;
|
||||
exports.resolve = imported.Promise.resolve;
|
||||
exports.reject = imported.Promise.reject;
|
||||
exports.defer = imported.Promise.defer;
|
||||
exports.resolve = imported.Promise.resolve;
|
||||
exports.reject = imported.Promise.reject;
|
||||
exports.promised = imported.Promise.promised;
|
||||
exports.all = imported.Promise.all;
|
||||
|
||||
});
|
||||
/*
|
||||
@ -906,65 +905,6 @@ exports.createEvent = function(name) {
|
||||
|
||||
var Promise = require('util/promise');
|
||||
|
||||
/**
|
||||
* Implementation of 'promised', while we wait for bug 790195 to be fixed.
|
||||
* @see Consuming promises in https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/core/promise.html
|
||||
* @see https://bugzilla.mozilla.org/show_bug.cgi?id=790195
|
||||
* @see https://github.com/mozilla/addon-sdk/blob/master/packages/api-utils/lib/promise.js#L179
|
||||
*/
|
||||
exports.promised = (function() {
|
||||
// Note: Define shortcuts and utility functions here in order to avoid
|
||||
// slower property accesses and unnecessary closure creations on each
|
||||
// call of this popular function.
|
||||
|
||||
var call = Function.call;
|
||||
var concat = Array.prototype.concat;
|
||||
|
||||
// Utility function that does following:
|
||||
// execute([ f, self, args...]) => f.apply(self, args)
|
||||
function execute(args) { return call.apply(call, args); }
|
||||
|
||||
// Utility function that takes promise of `a` array and maybe promise `b`
|
||||
// as arguments and returns promise for `a.concat(b)`.
|
||||
function promisedConcat(promises, unknown) {
|
||||
return promises.then(function(values) {
|
||||
return Promise.resolve(unknown).then(function(value) {
|
||||
return values.concat([ value ]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return function promised(f, prototype) {
|
||||
/**
|
||||
Returns a wrapped `f`, which when called returns a promise that resolves to
|
||||
`f(...)` passing all the given arguments to it, which by the way may be
|
||||
promises. Optionally second `prototype` argument may be provided to be used
|
||||
a prototype for a returned promise.
|
||||
|
||||
## Example
|
||||
|
||||
var promise = promised(Array)(1, promise(2), promise(3))
|
||||
promise.then(console.log) // => [ 1, 2, 3 ]
|
||||
**/
|
||||
|
||||
return function promised() {
|
||||
// create array of [ f, this, args... ]
|
||||
return concat.apply([ f, this ], arguments).
|
||||
// reduce it via `promisedConcat` to get promised array of fulfillments
|
||||
reduce(promisedConcat, Promise.resolve([], prototype)).
|
||||
// finally map that to promise of `f.apply(this, args...)`
|
||||
then(execute);
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Convert an array of promises to a single promise, which is resolved (with an
|
||||
* array containing resolved values) only when all the component promises are
|
||||
* resolved.
|
||||
*/
|
||||
exports.all = exports.promised(Array);
|
||||
|
||||
/**
|
||||
* Utility to convert a resolved promise to a concrete value.
|
||||
* Warning: This is something of an experiment. The alternative of mixing
|
||||
@ -995,8 +935,10 @@ exports.synchronize = function(promise) {
|
||||
};
|
||||
|
||||
/**
|
||||
* promiseMap is roughly like Array.map except that the action is taken to be
|
||||
* something that completes asynchronously, returning a promise.
|
||||
* promiseEach is roughly like Array.forEach except that the action is taken to
|
||||
* be something that completes asynchronously, returning a promise, so we wait
|
||||
* for the action to complete for each array element before moving onto the
|
||||
* next.
|
||||
* @param array An array of objects to enumerate
|
||||
* @param action A function to call for each member of the array
|
||||
* @param scope Optional object to use as 'this' for the function calls
|
||||
@ -1010,23 +952,26 @@ exports.promiseEach = function(array, action, scope) {
|
||||
}
|
||||
|
||||
var deferred = Promise.defer();
|
||||
var replies = [];
|
||||
|
||||
var callNext = function(index) {
|
||||
var replies = [];
|
||||
var promiseReply = action.call(scope, array[index]);
|
||||
Promise.resolve(promiseReply).then(function(reply) {
|
||||
var onSuccess = function(reply) {
|
||||
replies[index] = reply;
|
||||
|
||||
var nextIndex = index + 1;
|
||||
if (nextIndex >= array.length) {
|
||||
if (index + 1 >= array.length) {
|
||||
deferred.resolve(replies);
|
||||
}
|
||||
else {
|
||||
callNext(nextIndex);
|
||||
callNext(index + 1);
|
||||
}
|
||||
}).then(null, function(ex) {
|
||||
};
|
||||
|
||||
var onFailure = function(ex) {
|
||||
deferred.reject(ex);
|
||||
});
|
||||
};
|
||||
|
||||
var reply = action.call(scope, array[index], index, array);
|
||||
Promise.resolve(reply).then(onSuccess).then(null, onFailure);
|
||||
};
|
||||
|
||||
callNext(0);
|
||||
@ -3867,6 +3812,10 @@ Canon.prototype.addProxyCommands = function(prefix, commandSpecs, remoter, to) {
|
||||
names.forEach(function(name) {
|
||||
var commandSpec = commandSpecs[name];
|
||||
|
||||
if (commandSpec.noRemote) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!commandSpec.isParent) {
|
||||
commandSpec.exec = function(args, context) {
|
||||
context.commandName = name;
|
||||
@ -6777,7 +6726,7 @@ Requisition.prototype.complete = function(cursor, predictionChoice) {
|
||||
outstanding.push(promise);
|
||||
}
|
||||
|
||||
return util.all(outstanding).then(function() {
|
||||
return Promise.all(outstanding).then(function() {
|
||||
this.onTextChange();
|
||||
this.onTextChange.resumeFire();
|
||||
}.bind(this));
|
||||
@ -7594,19 +7543,19 @@ Requisition.prototype._assign = function(args) {
|
||||
|
||||
if (!this.commandAssignment.value) {
|
||||
this._addUnassignedArgs(args);
|
||||
return util.all(outstanding);
|
||||
return Promise.all(outstanding);
|
||||
}
|
||||
|
||||
if (args.length === 0) {
|
||||
this.setBlankArguments();
|
||||
return util.all(outstanding);
|
||||
return Promise.all(outstanding);
|
||||
}
|
||||
|
||||
// Create an error if the command does not take parameters, but we have
|
||||
// been given them ...
|
||||
if (this.assignmentCount === 0) {
|
||||
this._addUnassignedArgs(args);
|
||||
return util.all(outstanding);
|
||||
return Promise.all(outstanding);
|
||||
}
|
||||
|
||||
// Special case: if there is only 1 parameter, and that's of type
|
||||
@ -7616,7 +7565,7 @@ Requisition.prototype._assign = function(args) {
|
||||
if (assignment.param.type.name === 'string') {
|
||||
var arg = (args.length === 1) ? args[0] : new MergedArgument(args);
|
||||
outstanding.push(this.setAssignment(assignment, arg, noArgUp));
|
||||
return util.all(outstanding);
|
||||
return Promise.all(outstanding);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7723,7 +7672,7 @@ Requisition.prototype._assign = function(args) {
|
||||
// What's left is can't be assigned, but we need to extract
|
||||
this._addUnassignedArgs(args);
|
||||
|
||||
return util.all(outstanding);
|
||||
return Promise.all(outstanding);
|
||||
};
|
||||
|
||||
exports.Requisition = Requisition;
|
||||
@ -9555,10 +9504,12 @@ var connect = {
|
||||
createRemoter: function(prefix, connection) {
|
||||
return function(cmdArgs, context) {
|
||||
var typed = context.typed;
|
||||
if (typed.indexOf(prefix) !== 0) {
|
||||
throw new Error("Missing prefix");
|
||||
|
||||
// If we've been called using a 'context' then there will be no prefix
|
||||
// otherwise we need to remove it
|
||||
if (typed.indexOf(prefix) === 0) {
|
||||
typed = typed.substring(prefix.length).replace(/^ */, "");
|
||||
}
|
||||
typed = typed.substring(prefix.length).replace(/^ */, "");
|
||||
|
||||
return connection.execute(typed, cmdArgs).then(function(reply) {
|
||||
var typedData = context.typedData(reply.type, reply.data);
|
||||
@ -9598,12 +9549,19 @@ var disconnect = {
|
||||
name: 'prefix',
|
||||
type: 'connection',
|
||||
description: l10n.lookup('disconnectPrefixDesc'),
|
||||
},
|
||||
{
|
||||
name: 'force',
|
||||
type: 'boolean',
|
||||
description: l10n.lookup('disconnectForceDesc'),
|
||||
hidden: connector.disconnectSupportsForce,
|
||||
option: true
|
||||
}
|
||||
],
|
||||
returnType: 'string',
|
||||
|
||||
exec: function(args, context) {
|
||||
return args.prefix.disconnect().then(function() {
|
||||
return args.prefix.disconnect(args.force).then(function() {
|
||||
var removed = canon.removeProxyCommands(args.prefix.prefix);
|
||||
delete connections[args.prefix.prefix];
|
||||
return l10n.lookupFormat('disconnectReply', [ removed.length ]);
|
||||
@ -9647,13 +9605,15 @@ exports.shutdown = function() {
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
define('util/connect/connector', ['require', 'exports', 'module' ], function(require, exports, module) {
|
||||
define('util/connect/connector', ['require', 'exports', 'module' , 'util/promise'], function(require, exports, module) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var debuggerSocketConnect = Components.utils.import('resource://gre/modules/devtools/dbg-client.jsm', {}).debuggerSocketConnect;
|
||||
var DebuggerClient = Components.utils.import('resource://gre/modules/devtools/dbg-client.jsm', {}).DebuggerClient;
|
||||
|
||||
var Promise = require('util/promise');
|
||||
|
||||
/**
|
||||
* What port should we use by default?
|
||||
*/
|
||||
@ -9740,33 +9700,13 @@ Connection.prototype.getCommandSpecs = function() {
|
||||
/**
|
||||
* Send an execute request. Replies are handled by the setup in connect()
|
||||
*/
|
||||
Connection.prototype.execute = function(typed, cmdArgs) {
|
||||
var deferred = Promise.defer();
|
||||
|
||||
var request = {
|
||||
to: this.actor,
|
||||
type: 'execute',
|
||||
typed: typed,
|
||||
args: cmdArgs
|
||||
};
|
||||
|
||||
this.client.request(request, function(response) {
|
||||
deferred.resolve(response.reply);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an execute request.
|
||||
*/
|
||||
Connection.prototype.execute = function(typed, cmdArgs) {
|
||||
var request = new Request(this.actor, typed, cmdArgs);
|
||||
this.requests[request.json.id] = request;
|
||||
this.requests[request.json.requestId] = request;
|
||||
|
||||
this.client.request(request.json, function(response) {
|
||||
var request = this.requests[response.id];
|
||||
delete this.requests[response.id];
|
||||
var request = this.requests[response.requestId];
|
||||
delete this.requests[response.requestId];
|
||||
|
||||
request.complete(response.error, response.type, response.data);
|
||||
}.bind(this));
|
||||
@ -9774,10 +9714,12 @@ Connection.prototype.execute = function(typed, cmdArgs) {
|
||||
return request.promise;
|
||||
};
|
||||
|
||||
exports.disconnectSupportsForce = false;
|
||||
|
||||
/**
|
||||
* Kill this connection
|
||||
*/
|
||||
Connection.prototype.disconnect = function() {
|
||||
Connection.prototype.disconnect = function(force) {
|
||||
var deferred = Promise.defer();
|
||||
|
||||
this.client.close(function() {
|
||||
@ -9797,7 +9739,7 @@ function Request(actor, typed, args) {
|
||||
type: 'execute',
|
||||
typed: typed,
|
||||
args: args,
|
||||
id: Request._nextRequestId++,
|
||||
requestId: 'id-' + Request._nextRequestId++,
|
||||
};
|
||||
|
||||
this._deferred = Promise.defer();
|
||||
@ -9861,6 +9803,7 @@ var contextCmdSpec = {
|
||||
}
|
||||
],
|
||||
returnType: 'string',
|
||||
noRemote: true,
|
||||
exec: function echo(args, context) {
|
||||
// Do not copy this code
|
||||
var requisition = context.__dlhjshfw;
|
||||
@ -10214,6 +10157,17 @@ var terminalDomConverter = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a terminal object to a string
|
||||
*/
|
||||
var terminalStringConverter = {
|
||||
from: 'terminal',
|
||||
to: 'string',
|
||||
exec: function(data, context) {
|
||||
return Array.isArray(data) ? data.join('') : '' + data;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Several converters are just data.toString inside a 'p' element
|
||||
*/
|
||||
@ -10393,6 +10347,7 @@ exports.convert = function(data, from, to, conversionContext) {
|
||||
exports.addConverter(viewDomConverter);
|
||||
exports.addConverter(viewStringConverter);
|
||||
exports.addConverter(terminalDomConverter);
|
||||
exports.addConverter(terminalStringConverter);
|
||||
exports.addConverter(stringDomConverter);
|
||||
exports.addConverter(numberDomConverter);
|
||||
exports.addConverter(booleanDomConverter);
|
||||
|
@ -55,15 +55,17 @@ GcliActor.prototype.execute = function(request) {
|
||||
contentWindow.document);
|
||||
|
||||
let requisition = new Requisition(environment);
|
||||
let outputPromise = requisition.updateExec(request.typed);
|
||||
let output = util.synchronize(outputPromise);
|
||||
|
||||
return {
|
||||
id: request.id,
|
||||
data: output.data,
|
||||
type: output.type,
|
||||
error: output.error
|
||||
};
|
||||
requisition.updateExec(request.typed).then(output => {
|
||||
return output.promise.then(() => {
|
||||
this.connection.send({
|
||||
from: this.actorID,
|
||||
requestId: request.requestId,
|
||||
data: output.data,
|
||||
type: output.type,
|
||||
error: output.error
|
||||
});
|
||||
});
|
||||
}).then(null, console.error);
|
||||
};
|
||||
|
||||
GcliActor.prototype.requestTypes = {
|
||||
|
Loading…
Reference in New Issue
Block a user