gecko/browser/devtools/shared/test/browser_gcli_web.js

4000 lines
110 KiB
JavaScript
Executable File

/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
/*
*
*
*
*
*
*
*
*********************************** WARNING ***********************************
*
* Do not edit this file without understanding where it comes from,
* Your changes are likely to be overwritten without warning.
*
* This test file is generated using a level 25 wizard spell cast on the
* test files that run in the browser as part of GCLI's test suite.
* For details of how to cast the spell, see GCLI's gcli.js
*
* For more information on GCLI see:
* - https://github.com/mozilla/gcli/blob/master/docs/index.md
* - https://wiki.mozilla.org/DevTools/Features/GCLI
*
* The original source for this file is:
* https://github.com/mozilla/gcli/
*
*******************************************************************************
*
*
*
*
*
*
*
*
*
*/
///////////////////////////////////////////////////////////////////////////////
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/index', ['require', 'exports', 'module' , 'gclitest/suite'], function(require, exports, module) {
var examiner = require('gclitest/suite').examiner;
// A minimum fake dom to get us through the JS tests
var fakeWindow = {
isFake: true,
document: { title: 'Fake DOM' }
};
fakeWindow.window = fakeWindow;
examiner.defaultOptions = {
window: fakeWindow,
hideExec: true
};
/**
* A simple proxy to examiner.run, for convenience - this is run from the
* top level.
* @param options Lookup of options that customize test running. Includes:
* - window (default=undefined) A reference to the DOM window. If left
* undefined then a reduced set of tests will run.
* - isNode (default=false) Are we running under NodeJS, specifically, are we
* using JSDom, which isn't a 100% complete DOM implementation.
* Some tests are skipped when using NodeJS.
* - display (default=undefined) A reference to a Display implementation.
* A reduced set of tests will run if left undefined
* - detailedResultLog (default=false) do we output a test summary to
* |console.log| on test completion.
* - hideExec (default=false) Set the |hidden| property in calls to
* |requisition.exec()| which prevents the display from becoming messed up,
* however use of hideExec restricts the set of tests that are run
*/
exports.run = function(options) {
examiner.run(options || {});
// A better set of default than those specified above, come from the set
// that are passed to run().
examiner.defaultOptions = {
window: options.window,
display: options.display,
hideExec: options.hideExec
};
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/suite', ['require', 'exports', 'module' , 'gcli/index', 'test/examiner', 'gclitest/testCli', 'gclitest/testCompletion', 'gclitest/testExec', 'gclitest/testHelp', 'gclitest/testHistory', 'gclitest/testInputter', 'gclitest/testJs', 'gclitest/testKeyboard', 'gclitest/testPref', 'gclitest/testRequire', 'gclitest/testResource', 'gclitest/testScratchpad', 'gclitest/testSettings', 'gclitest/testSpell', 'gclitest/testSplit', 'gclitest/testTokenize', 'gclitest/testTooltip', 'gclitest/testTypes', 'gclitest/testUtil'], function(require, exports, module) {
// We need to make sure GCLI is initialized before we begin testing it
require('gcli/index');
var examiner = require('test/examiner');
// It's tempting to want to unify these strings and make addSuite() do the
// call to require(), however that breaks the build system which looks for
// the strings passed to require
examiner.addSuite('gclitest/testCli', require('gclitest/testCli'));
examiner.addSuite('gclitest/testCompletion', require('gclitest/testCompletion'));
examiner.addSuite('gclitest/testExec', require('gclitest/testExec'));
examiner.addSuite('gclitest/testHelp', require('gclitest/testHelp'));
examiner.addSuite('gclitest/testHistory', require('gclitest/testHistory'));
examiner.addSuite('gclitest/testInputter', require('gclitest/testInputter'));
examiner.addSuite('gclitest/testJs', require('gclitest/testJs'));
examiner.addSuite('gclitest/testKeyboard', require('gclitest/testKeyboard'));
examiner.addSuite('gclitest/testPref', require('gclitest/testPref'));
examiner.addSuite('gclitest/testRequire', require('gclitest/testRequire'));
examiner.addSuite('gclitest/testResource', require('gclitest/testResource'));
examiner.addSuite('gclitest/testScratchpad', require('gclitest/testScratchpad'));
examiner.addSuite('gclitest/testSettings', require('gclitest/testSettings'));
examiner.addSuite('gclitest/testSpell', require('gclitest/testSpell'));
examiner.addSuite('gclitest/testSplit', require('gclitest/testSplit'));
examiner.addSuite('gclitest/testTokenize', require('gclitest/testTokenize'));
examiner.addSuite('gclitest/testTooltip', require('gclitest/testTooltip'));
examiner.addSuite('gclitest/testTypes', require('gclitest/testTypes'));
examiner.addSuite('gclitest/testUtil', require('gclitest/testUtil'));
exports.examiner = examiner;
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('test/examiner', ['require', 'exports', 'module' , 'test/assert'], function(require, exports, module) {
var examiner = exports;
var assert = require('test/assert');
/**
* Test harness data
*/
examiner.suites = {};
/**
* The gap between tests when running async
*/
var delay = 10;
var stati = {
notrun: { index: 0, name: 'Skipped' },
executing: { index: 1, name: 'Executing' },
asynchronous: { index: 2, name: 'Waiting' },
pass: { index: 3, name: 'Pass' },
fail: { index: 4, name: 'Fail' }
};
/**
* Add a test suite. Generally used like:
* test.addSuite('foo', require('path/to/foo'));
*/
examiner.addSuite = function(name, suite) {
examiner.suites[name] = new Suite(name, suite);
};
/**
* When run from an command, there are some options that we can't (and
* shouldn't) specify, so we allow a set of default options, which are merged
* with the specified options in |run()|.
*/
examiner.defaultOptions = {};
/**
* Add properties to |options| from |examiner.defaultOptions| when |options|
* does not have a value for a given name.
*/
function mergeDefaultOptions(options) {
Object.keys(examiner.defaultOptions).forEach(function(name) {
if (options[name] == null) {
options[name] = examiner.defaultOptions[name];
}
});
}
/**
* Run the tests defined in the test suite synchronously
*/
examiner.run = function(options) {
mergeDefaultOptions(options);
Object.keys(examiner.suites).forEach(function(suiteName) {
var suite = examiner.suites[suiteName];
suite.run(options);
}.bind(this));
if (options.detailedResultLog) {
examiner.detailedResultLog();
}
else {
console.log('Completed test suite');
}
return examiner.suites;
};
/**
* Run all the tests asynchronously
*/
examiner.runAsync = function(options, callback) {
mergeDefaultOptions(options);
this._runAsyncInternal(0, options, callback);
};
/**
* Run all the test suits asynchronously
*/
examiner._runAsyncInternal = function(i, options, callback) {
if (i >= Object.keys(examiner.suites).length) {
if (typeof callback === 'function') {
callback();
}
return;
}
var suiteName = Object.keys(examiner.suites)[i];
examiner.suites[suiteName].runAsync(options, function() {
setTimeout(function() {
examiner._runAsyncInternal(i + 1, options, callback);
}.bind(this), delay);
}.bind(this));
};
/**
* Create a JSON object suitable for serialization
*/
examiner.toRemote = function() {
return {
suites: Object.keys(examiner.suites).map(function(suiteName) {
return examiner.suites[suiteName].toRemote();
}.bind(this)),
summary: {
checks: this.checks,
status: this.status
}
};
};
/**
* The number of checks in this set of test suites is the sum of the checks in
* the test suites.
*/
Object.defineProperty(examiner, 'checks', {
get: function() {
return Object.keys(examiner.suites).reduce(function(current, suiteName) {
return current + examiner.suites[suiteName].checks;
}.bind(this), 0);
},
enumerable: true
});
/**
* The status of this set of test suites is the worst of the statuses of the
* contained test suites.
*/
Object.defineProperty(examiner, 'status', {
get: function() {
return Object.keys(examiner.suites).reduce(function(status, suiteName) {
var suiteStatus = examiner.suites[suiteName].status;
return status.index > suiteStatus.index ? status : suiteStatus;
}.bind(this), stati.notrun);
},
enumerable: true
});
/**
* Output a test summary to console.log
*/
examiner.detailedResultLog = function() {
Object.keys(this.suites).forEach(function(suiteName) {
var suite = examiner.suites[suiteName];
console.log(suite.name + ': ' + suite.status.name + ' (funcs=' +
Object.keys(suite.tests).length +
', checks=' + suite.checks + ')');
Object.keys(suite.tests).forEach(function(testName) {
var test = suite.tests[testName];
if (test.status !== stati.pass || test.failures.length !== 0) {
console.log('- ' + test.name + ': ' + test.status.name);
test.failures.forEach(function(failure) {
console.log(' - ' + failure.message);
if (failure.params) {
console.log(' - P1: ' + failure.p1);
console.log(' - P2: ' + failure.p2);
}
}.bind(this));
}
}.bind(this));
}.bind(this));
console.log();
console.log('Summary: ' + this.status.name + ' (' + this.checks + ' checks)');
};
/**
* A suite is a group of tests
*/
function Suite(suiteName, suite) {
this.name = suiteName.replace(/gclitest\//, '');
this.suite = suite;
this.tests = {};
Object.keys(suite).forEach(function(testName) {
if (testName !== 'setup' && testName !== 'shutdown') {
var test = new Test(this, testName, suite[testName]);
this.tests[testName] = test;
}
}.bind(this));
}
/**
* Run all the tests in this suite synchronously
*/
Suite.prototype.run = function(options) {
if (!this._setup(options)) {
return;
}
Object.keys(this.tests).forEach(function(testName) {
var test = this.tests[testName];
test.run(options);
}.bind(this));
this._shutdown(options);
};
/**
* Run all the tests in this suite asynchronously
*/
Suite.prototype.runAsync = function(options, callback) {
if (!this._setup(options)) {
if (typeof callback === 'function') {
callback();
}
return;
}
this._runAsyncInternal(0, options, function() {
this._shutdown(options);
if (typeof callback === 'function') {
callback();
}
}.bind(this));
};
/**
* Function used by the async runners that can handle async recursion.
*/
Suite.prototype._runAsyncInternal = function(i, options, callback) {
if (i >= Object.keys(this.tests).length) {
if (typeof callback === 'function') {
callback();
}
return;
}
var testName = Object.keys(this.tests)[i];
this.tests[testName].runAsync(options, function() {
setTimeout(function() {
this._runAsyncInternal(i + 1, options, callback);
}.bind(this), delay);
}.bind(this));
};
/**
* Create a JSON object suitable for serialization
*/
Suite.prototype.toRemote = function() {
return {
name: this.name,
tests: Object.keys(this.tests).map(function(testName) {
return this.tests[testName].toRemote();
}.bind(this))
};
};
/**
* The number of checks in this suite is the sum of the checks in the contained
* tests.
*/
Object.defineProperty(Suite.prototype, 'checks', {
get: function() {
return Object.keys(this.tests).reduce(function(prevChecks, testName) {
return prevChecks + this.tests[testName].checks;
}.bind(this), 0);
},
enumerable: true
});
/**
* The status of a test suite is the worst of the statuses of the contained
* tests.
*/
Object.defineProperty(Suite.prototype, 'status', {
get: function() {
return Object.keys(this.tests).reduce(function(prevStatus, testName) {
var suiteStatus = this.tests[testName].status;
return prevStatus.index > suiteStatus.index ? prevStatus : suiteStatus;
}.bind(this), stati.notrun);
},
enumerable: true
});
/**
* Defensively setup the test suite
*/
Suite.prototype._setup = function(options) {
if (typeof this.suite.setup !== 'function') {
return true;
}
try {
this.suite.setup(options);
return true;
}
catch (ex) {
this._logToAllTests('' + ex);
console.error(ex);
if (ex.stack) {
console.error(ex.stack);
}
return false;
}
};
/**
* Defensively shutdown the test suite
*/
Suite.prototype._shutdown = function(options) {
if (typeof this.suite.shutdown !== 'function') {
return true;
}
try {
this.suite.shutdown(options);
return true;
}
catch (ex) {
this._logToAllTests('' + ex);
console.error(ex);
if (ex.stack) {
console.error(ex.stack);
}
return false;
}
};
/**
* Something has gone wrong that affects all tests in this Suite
*/
Suite.prototype._logToAllTests = function(message) {
var priorCurrentTest = assert.currentTest;
Object.keys(this.tests).forEach(function(testName) {
assert.currentTest = this.tests[testName];
assert.ok(false, message);
}.bind(this));
assert.currentTest = priorCurrentTest;
};
/**
* A test represents data about a single test function
*/
function Test(suite, name, func) {
this.suite = suite;
this.name = name;
this.func = func;
this.title = name.replace(/^test/, '').replace(/([A-Z])/g, ' $1');
this.failures = [];
this.status = stati.notrun;
this.checks = 0;
}
/**
* Run just a single test
*/
Test.prototype.run = function(options) {
assert.currentTest = this;
this.status = stati.executing;
this.failures = [];
this.checks = 0;
try {
this.func.apply(this.suite, [ options ]);
}
catch (ex) {
assert.ok(false, '' + ex);
console.error(ex);
if ((options.isNode || options.isFirefox) && ex.stack) {
console.error(ex.stack);
}
}
if (this.status === stati.executing) {
this.status = stati.pass;
}
assert.currentTest = null;
};
/**
* Run all the tests in this suite asynchronously
*/
Test.prototype.runAsync = function(options, callback) {
setTimeout(function() {
this.run(options);
if (typeof callback === 'function') {
callback();
}
}.bind(this), delay);
};
/**
* Create a JSON object suitable for serialization
*/
Test.prototype.toRemote = function() {
return {
name: this.name,
title: this.title,
status: this.status,
failures: this.failures,
checks: this.checks
};
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('test/assert', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.ok = ok;
exports.is = is;
exports.log = info;
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testCli', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gclitest/mockCommands', 'test/assert'], function(require, exports, module) {
var Requisition = require('gcli/cli').Requisition;
var Status = require('gcli/types').Status;
var mockCommands = require('gclitest/mockCommands');
var test = require('test/assert');
exports.setup = function() {
mockCommands.setup();
};
exports.shutdown = function() {
mockCommands.shutdown();
};
var assign1;
var assign2;
var assignC;
var requ;
var debug = false;
var status;
var statuses;
function update(input) {
if (!requ) {
requ = new Requisition();
}
requ.update(input.typed);
if (debug) {
console.log('####### TEST: typed="' + input.typed +
'" cur=' + input.cursor.start +
' cli=', requ);
}
status = requ.getStatus();
assignC = requ.getAssignmentAt(input.cursor.start);
statuses = requ.getInputStatusMarkup(input.cursor.start).map(function(s) {
return Array(s.string.length + 1).join(s.status.toString()[0]);
}).join('');
if (requ.commandAssignment.value) {
assign1 = requ.getAssignment(0);
assign2 = requ.getAssignment(1);
}
else {
assign1 = undefined;
assign2 = undefined;
}
}
function verifyPredictionsContains(name, predictions) {
return predictions.every(function(prediction) {
return name === prediction.name;
}, this);
}
exports.testBlank = function() {
update({ typed: '', cursor: { start: 0, end: 0 } });
test.is( '', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is(undefined, requ.commandAssignment.value);
update({ typed: ' ', cursor: { start: 1, end: 1 } });
test.is( 'V', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is(undefined, requ.commandAssignment.value);
update({ typed: ' ', cursor: { start: 0, end: 0 } });
test.is( 'V', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is(undefined, requ.commandAssignment.value);
};
exports.testIncompleteMultiMatch = function() {
update({ typed: 't', cursor: { start: 1, end: 1 } });
test.is( 'I', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.ok(assignC.getPredictions().length > 0);
verifyPredictionsContains('tsv', assignC.getPredictions());
verifyPredictionsContains('tsr', assignC.getPredictions());
test.is(undefined, requ.commandAssignment.value);
};
exports.testIncompleteSingleMatch = function() {
update({ typed: 'tselar', cursor: { start: 6, end: 6 } });
test.is( 'IIIIII', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is(1, assignC.getPredictions().length);
test.is('tselarr', assignC.getPredictions()[0].name);
test.is(undefined, requ.commandAssignment.value);
};
exports.testTsv = function() {
update({ typed: 'tsv', cursor: { start: 3, end: 3 } });
test.is( 'VVV', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is('tsv', requ.commandAssignment.value.name);
update({ typed: 'tsv ', cursor: { start: 4, end: 4 } });
test.is( 'VVVV', statuses);
test.is(Status.ERROR, status);
test.is(0, assignC.paramIndex);
test.is('tsv', requ.commandAssignment.value.name);
update({ typed: 'tsv ', cursor: { start: 2, end: 2 } });
test.is( 'VVVV', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is('tsv', requ.commandAssignment.value.name);
update({ typed: 'tsv o', cursor: { start: 5, end: 5 } });
test.is( 'VVVVI', statuses);
test.is(Status.ERROR, status);
test.is(0, assignC.paramIndex);
test.ok(assignC.getPredictions().length >= 2);
test.is(mockCommands.option1, assignC.getPredictions()[0].value);
test.is(mockCommands.option2, assignC.getPredictions()[1].value);
test.is('tsv', requ.commandAssignment.value.name);
test.is('o', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsv option', cursor: { start: 10, end: 10 } });
test.is( 'VVVVIIIIII', statuses);
test.is(Status.ERROR, status);
test.is(0, assignC.paramIndex);
test.ok(assignC.getPredictions().length >= 2);
test.is(mockCommands.option1, assignC.getPredictions()[0].value);
test.is(mockCommands.option2, assignC.getPredictions()[1].value);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsv option', cursor: { start: 1, end: 1 } });
test.is( 'VVVVEEEEEE', statuses);
test.is(Status.ERROR, status);
test.is(-1, assignC.paramIndex);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsv option ', cursor: { start: 11, end: 11 } });
test.is( 'VVVVEEEEEEV', statuses);
test.is(Status.ERROR, status);
test.is(1, assignC.paramIndex);
test.is(0, assignC.getPredictions().length);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsv option1', cursor: { start: 11, end: 11 } });
test.is( 'VVVVVVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option1', assign1.arg.text);
test.is(mockCommands.option1, assign1.value);
test.is(0, assignC.paramIndex);
update({ typed: 'tsv option1 ', cursor: { start: 12, end: 12 } });
test.is( 'VVVVVVVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option1', assign1.arg.text);
test.is(mockCommands.option1, assign1.value);
test.is(1, assignC.paramIndex);
update({ typed: 'tsv option1 6', cursor: { start: 13, end: 13 } });
test.is( 'VVVVVVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option1', assign1.arg.text);
test.is(mockCommands.option1, assign1.value);
test.is('6', assign2.arg.text);
test.is('6', assign2.value);
test.is('string', typeof assign2.value);
test.is(1, assignC.paramIndex);
update({ typed: 'tsv option2 6', cursor: { start: 13, end: 13 } });
test.is( 'VVVVVVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsv', requ.commandAssignment.value.name);
test.is('option2', assign1.arg.text);
test.is(mockCommands.option2, assign1.value);
test.is('6', assign2.arg.text);
test.is(6, assign2.value);
test.is('number', typeof assign2.value);
test.is(1, assignC.paramIndex);
};
exports.testInvalid = function() {
update({ typed: 'zxjq', cursor: { start: 4, end: 4 } });
test.is( 'EEEE', statuses);
test.is('zxjq', requ.commandAssignment.arg.text);
test.is('', requ._unassigned.arg.text);
test.is(-1, assignC.paramIndex);
update({ typed: 'zxjq ', cursor: { start: 5, end: 5 } });
test.is( 'EEEEV', statuses);
test.is('zxjq', requ.commandAssignment.arg.text);
test.is('', requ._unassigned.arg.text);
test.is(-1, assignC.paramIndex);
update({ typed: 'zxjq one', cursor: { start: 8, end: 8 } });
test.is( 'EEEEVEEE', statuses);
test.is('zxjq', requ.commandAssignment.arg.text);
test.is('one', requ._unassigned.arg.text);
};
exports.testSingleString = function() {
update({ typed: 'tsr', cursor: { start: 3, end: 3 } });
test.is( 'VVV', statuses);
test.is(Status.ERROR, status);
test.is('tsr', requ.commandAssignment.value.name);
test.ok(assign1.arg.isBlank());
test.is(undefined, assign1.value);
test.is(undefined, assign2);
update({ typed: 'tsr ', cursor: { start: 4, end: 4 } });
test.is( 'VVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsr', requ.commandAssignment.value.name);
test.ok(assign1.arg.isBlank());
test.is(undefined, assign1.value);
test.is(undefined, assign2);
update({ typed: 'tsr h', cursor: { start: 5, end: 5 } });
test.is( 'VVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsr', requ.commandAssignment.value.name);
test.is('h', assign1.arg.text);
test.is('h', assign1.value);
update({ typed: 'tsr "h h"', cursor: { start: 9, end: 9 } });
test.is( 'VVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsr', requ.commandAssignment.value.name);
test.is('h h', assign1.arg.text);
test.is('h h', assign1.value);
update({ typed: 'tsr h h h', cursor: { start: 9, end: 9 } });
test.is( 'VVVVVVVVV', statuses);
test.is('tsr', requ.commandAssignment.value.name);
test.is('h h h', assign1.arg.text);
test.is('h h h', assign1.value);
};
exports.testSingleNumber = function() {
update({ typed: 'tsu', cursor: { start: 3, end: 3 } });
test.is( 'VVV', statuses);
test.is(Status.ERROR, status);
test.is('tsu', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsu ', cursor: { start: 4, end: 4 } });
test.is( 'VVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsu', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsu 1', cursor: { start: 5, end: 5 } });
test.is( 'VVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsu', requ.commandAssignment.value.name);
test.is('1', assign1.arg.text);
test.is(1, assign1.value);
test.is('number', typeof assign1.value);
update({ typed: 'tsu x', cursor: { start: 5, end: 5 } });
test.is( 'VVVVE', statuses);
test.is(Status.ERROR, status);
test.is('tsu', requ.commandAssignment.value.name);
test.is('x', assign1.arg.text);
test.is(undefined, assign1.value);
};
exports.testElement = function(options) {
update({ typed: 'tse', cursor: { start: 3, end: 3 } });
test.is( 'VVV', statuses);
test.is(Status.ERROR, status);
test.is('tse', requ.commandAssignment.value.name);
test.ok(assign1.arg.isBlank());
test.is(undefined, assign1.value);
update({ typed: 'tse :root', cursor: { start: 9, end: 9 } });
test.is( 'VVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tse', requ.commandAssignment.value.name);
test.is(':root', assign1.arg.text);
if (!options.window.isFake) {
test.is(options.window.document.documentElement, assign1.value);
}
if (!options.window.isFake) {
var inputElement = options.window.document.getElementById('gcli-input');
if (inputElement) {
update({ typed: 'tse #gcli-input', cursor: { start: 15, end: 15 } });
test.is( 'VVVVVVVVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tse', requ.commandAssignment.value.name);
test.is('#gcli-input', assign1.arg.text);
test.is(inputElement, assign1.value);
}
else {
test.log('Skipping test that assumes gcli on the web');
}
}
update({ typed: 'tse #gcli-nomatch', cursor: { start: 17, end: 17 } });
// This is somewhat debatable because this input can't be corrected simply
// by typing so it's and error rather than incomplete, however without
// digging into the CSS engine we can't tell that so we default to incomplete
test.is( 'VVVVIIIIIIIIIIIII', statuses);
test.is(Status.ERROR, status);
test.is('tse', requ.commandAssignment.value.name);
test.is('#gcli-nomatch', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tse #', cursor: { start: 5, end: 5 } });
test.is( 'VVVVE', statuses);
test.is(Status.ERROR, status);
test.is('tse', requ.commandAssignment.value.name);
test.is('#', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tse .', cursor: { start: 5, end: 5 } });
test.is( 'VVVVE', statuses);
test.is(Status.ERROR, status);
test.is('tse', requ.commandAssignment.value.name);
test.is('.', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tse *', cursor: { start: 5, end: 5 } });
test.is( 'VVVVE', statuses);
test.is(Status.ERROR, status);
test.is('tse', requ.commandAssignment.value.name);
test.is('*', assign1.arg.text);
test.is(undefined, assign1.value);
};
exports.testNestedCommand = function() {
update({ typed: 'tsn', cursor: { start: 3, end: 3 } });
test.is( 'III', statuses);
test.is(Status.ERROR, status);
test.is('tsn', requ.commandAssignment.arg.text);
test.is(undefined, assign1);
update({ typed: 'tsn ', cursor: { start: 4, end: 4 } });
test.is( 'IIIV', statuses);
test.is(Status.ERROR, status);
test.is('tsn', requ.commandAssignment.arg.text);
test.is(undefined, assign1);
update({ typed: 'tsn x', cursor: { start: 5, end: 5 } });
// Commented out while we try out fuzzy matching
// test.is( 'EEEVE', statuses);
test.is(Status.ERROR, status);
test.is('tsn x', requ.commandAssignment.arg.text);
test.is(undefined, assign1);
update({ typed: 'tsn dif', cursor: { start: 7, end: 7 } });
test.is( 'VVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsn dif', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsn dif ', cursor: { start: 8, end: 8 } });
test.is( 'VVVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsn dif', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsn dif x', cursor: { start: 9, end: 9 } });
test.is( 'VVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsn dif', requ.commandAssignment.value.name);
test.is('x', assign1.arg.text);
test.is('x', assign1.value);
update({ typed: 'tsn ext', cursor: { start: 7, end: 7 } });
test.is( 'VVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsn ext', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsn exte', cursor: { start: 8, end: 8 } });
test.is( 'VVVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsn exte', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsn exten', cursor: { start: 9, end: 9 } });
test.is( 'VVVVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsn exten', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'tsn extend', cursor: { start: 10, end: 10 } });
test.is( 'VVVVVVVVVV', statuses);
test.is(Status.ERROR, status);
test.is('tsn extend', requ.commandAssignment.value.name);
test.is('', assign1.arg.text);
test.is(undefined, assign1.value);
update({ typed: 'ts ', cursor: { start: 3, end: 3 } });
test.is( 'EEV', statuses);
test.is(Status.ERROR, status);
test.is('ts', requ.commandAssignment.arg.text);
test.is(undefined, assign1);
};
// From Bug 664203
exports.testDeeplyNested = function() {
update({ typed: 'tsn deep down nested cmd', cursor: { start: 24, end: 24 } });
test.is( 'VVVVVVVVVVVVVVVVVVVVVVVV', statuses);
test.is(Status.VALID, status);
test.is('tsn deep down nested cmd', requ.commandAssignment.value.name);
test.is(undefined, assign1);
update({ typed: 'tsn deep down nested', cursor: { start: 20, end: 20 } });
test.is( 'IIIVIIIIVIIIIVIIIIII', statuses);
test.is(Status.ERROR, status);
test.is('tsn deep down nested', requ.commandAssignment.value.name);
test.is(undefined, assign1);
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/mockCommands', ['require', 'exports', 'module' , 'gcli/canon', 'gcli/util', 'gcli/types/selection', 'gcli/types/basic', 'gcli/types'], function(require, exports, module) {
var canon = require('gcli/canon');
var util = require('gcli/util');
var SelectionType = require('gcli/types/selection').SelectionType;
var DeferredType = require('gcli/types/basic').DeferredType;
var types = require('gcli/types');
/**
* Registration and de-registration.
*/
exports.setup = function() {
// setup/shutdown need to register/unregister types, however that means we
// need to re-initialize exports.option1 and exports.option2 with the
// actual types
exports.option1.type = types.getType('string');
exports.option2.type = types.getType('number');
types.registerType(exports.optionType);
types.registerType(exports.optionValue);
canon.addCommand(exports.tsv);
canon.addCommand(exports.tsr);
canon.addCommand(exports.tse);
canon.addCommand(exports.tsj);
canon.addCommand(exports.tsb);
canon.addCommand(exports.tss);
canon.addCommand(exports.tsu);
canon.addCommand(exports.tsn);
canon.addCommand(exports.tsnDif);
canon.addCommand(exports.tsnExt);
canon.addCommand(exports.tsnExte);
canon.addCommand(exports.tsnExten);
canon.addCommand(exports.tsnExtend);
canon.addCommand(exports.tsnDeep);
canon.addCommand(exports.tsnDeepDown);
canon.addCommand(exports.tsnDeepDownNested);
canon.addCommand(exports.tsnDeepDownNestedCmd);
canon.addCommand(exports.tselarr);
canon.addCommand(exports.tsm);
canon.addCommand(exports.tsg);
};
exports.shutdown = function() {
canon.removeCommand(exports.tsv);
canon.removeCommand(exports.tsr);
canon.removeCommand(exports.tse);
canon.removeCommand(exports.tsj);
canon.removeCommand(exports.tsb);
canon.removeCommand(exports.tss);
canon.removeCommand(exports.tsu);
canon.removeCommand(exports.tsn);
canon.removeCommand(exports.tsnDif);
canon.removeCommand(exports.tsnExt);
canon.removeCommand(exports.tsnExte);
canon.removeCommand(exports.tsnExten);
canon.removeCommand(exports.tsnExtend);
canon.removeCommand(exports.tsnDeep);
canon.removeCommand(exports.tsnDeepDown);
canon.removeCommand(exports.tsnDeepDownNested);
canon.removeCommand(exports.tsnDeepDownNestedCmd);
canon.removeCommand(exports.tselarr);
canon.removeCommand(exports.tsm);
canon.removeCommand(exports.tsg);
types.deregisterType(exports.optionType);
types.deregisterType(exports.optionValue);
};
exports.option1 = { type: types.getType('string') };
exports.option2 = { type: types.getType('number') };
var lastOption = undefined;
exports.optionType = new SelectionType({
name: 'optionType',
lookup: [
{ name: 'option1', value: exports.option1 },
{ name: 'option2', value: exports.option2 }
],
noMatch: function() {
lastOption = undefined;
},
stringify: function(option) {
lastOption = option;
return SelectionType.prototype.stringify.call(this, option);
},
parse: function(arg) {
var conversion = SelectionType.prototype.parse.call(this, arg);
lastOption = conversion.value;
return conversion;
}
});
exports.optionValue = new DeferredType({
name: 'optionValue',
defer: function() {
if (lastOption && lastOption.type) {
return lastOption.type;
}
else {
return types.getType('blank');
}
}
});
exports.onCommandExec = util.createEvent('commands.onCommandExec');
function createExec(name) {
return function(args, context) {
var data = {
command: exports[name],
args: args,
context: context
};
exports.onCommandExec(data);
return data;
};
}
exports.tsv = {
name: 'tsv',
params: [
{ name: 'optionType', type: 'optionType' },
{ name: 'optionValue', type: 'optionValue' }
],
exec: createExec('tsv')
};
exports.tsr = {
name: 'tsr',
params: [ { name: 'text', type: 'string' } ],
exec: createExec('tsr')
};
exports.tse = {
name: 'tse',
params: [ { name: 'node', type: 'node' } ],
exec: createExec('tse')
};
exports.tsj = {
name: 'tsj',
params: [ { name: 'javascript', type: 'javascript' } ],
exec: createExec('tsj')
};
exports.tsb = {
name: 'tsb',
params: [ { name: 'toggle', type: 'boolean' } ],
exec: createExec('tsb')
};
exports.tss = {
name: 'tss',
exec: createExec('tss')
};
exports.tsu = {
name: 'tsu',
params: [ { name: 'num', type: { name: 'number', max: 10, min: -5, step: 3 } } ],
exec: createExec('tsu')
};
exports.tsn = {
name: 'tsn'
};
exports.tsnDif = {
name: 'tsn dif',
params: [ { name: 'text', type: 'string' } ],
exec: createExec('tsnDif')
};
exports.tsnExt = {
name: 'tsn ext',
params: [ { name: 'text', type: 'string' } ],
exec: createExec('tsnExt')
};
exports.tsnExte = {
name: 'tsn exte',
params: [ { name: 'text', type: 'string' } ],
exec: createExec('')
};
exports.tsnExten = {
name: 'tsn exten',
params: [ { name: 'text', type: 'string' } ],
exec: createExec('tsnExte')
};
exports.tsnExtend = {
name: 'tsn extend',
params: [ { name: 'text', type: 'string' } ],
exec: createExec('tsnExtend')
};
exports.tsnDeep = {
name: 'tsn deep',
};
exports.tsnDeepDown = {
name: 'tsn deep down',
};
exports.tsnDeepDownNested = {
name: 'tsn deep down nested',
};
exports.tsnDeepDownNestedCmd = {
name: 'tsn deep down nested cmd',
exec: createExec('tsnDeepDownNestedCmd')
};
exports.tselarr = {
name: 'tselarr',
params: [
{ name: 'num', type: { name: 'selection', data: [ '1', '2', '3' ] } },
{ name: 'arr', type: { name: 'array', subtype: 'string' } },
],
exec: createExec('tselarr')
};
exports.tsm = {
name: 'tsm',
description: 'a 3-param test selection|string|number',
params: [
{ name: 'abc', type: { name: 'selection', data: [ 'a', 'b', 'c' ] } },
{ name: 'txt', type: 'string' },
{ name: 'num', type: { name: 'number', max: 42, min: 0 } },
],
exec: createExec('tsm')
};
exports.tsg = {
name: 'tsg',
description: 'a param group test',
params: [
{ name: 'solo', type: { name: 'selection', data: [ 'aaa', 'bbb', 'ccc' ] } },
{
group: 'First',
params: [
{ name: 'txt1', type: 'string', defaultValue: null },
{ name: 'bool', type: 'boolean' }
]
},
{
group: 'Second',
params: [
{ name: 'txt2', type: 'string', defaultValue: 'd' },
{ name: 'num', type: { name: 'number', min: 40 }, defaultValue: 42 }
]
}
],
exec: createExec('tsg')
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testCompletion', ['require', 'exports', 'module' , 'test/assert', 'gclitest/mockCommands'], function(require, exports, module) {
var test = require('test/assert');
var mockCommands = require('gclitest/mockCommands');
exports.setup = function() {
mockCommands.setup();
};
exports.shutdown = function() {
mockCommands.shutdown();
};
function type(typed, tests, options) {
var inputter = options.display.inputter;
var completer = options.display.completer;
inputter.setInput(typed);
if (tests.cursor) {
inputter.setCursor({ start: tests.cursor, end: tests.cursor });
}
if (tests.emptyParameters == null) {
tests.emptyParameters = [];
}
var realParams = completer.emptyParameters;
test.is(tests.emptyParameters.length, realParams.length,
'emptyParameters.length for \'' + typed + '\'');
if (realParams.length === tests.emptyParameters.length) {
for (var i = 0; i < realParams.length; i++) {
test.is(tests.emptyParameters[i], realParams[i].replace(/\u00a0/g, ' '),
'emptyParameters[' + i + '] for \'' + typed + '\'');
}
}
if (tests.directTabText) {
test.is(tests.directTabText, completer.directTabText,
'directTabText for \'' + typed + '\'');
}
else {
test.is('', completer.directTabText,
'directTabText for \'' + typed + '\'');
}
if (tests.arrowTabText) {
test.is(' \u00a0\u21E5 ' + tests.arrowTabText,
completer.arrowTabText,
'arrowTabText for \'' + typed + '\'');
}
else {
test.is('', completer.arrowTabText,
'arrowTabText for \'' + typed + '\'');
}
}
exports.testActivate = function(options) {
if (!options.display) {
test.log('No display. Skipping activate tests');
return;
}
type('', { }, options);
type(' ', { }, options);
type('tsr', {
emptyParameters: [ ' <text>' ]
}, options);
type('tsr ', {
emptyParameters: [ '<text>' ]
}, options);
type('tsr b', { }, options);
type('tsb', {
emptyParameters: [ ' [toggle]' ]
}, options);
type('tsm', {
emptyParameters: [ ' <abc>', ' <txt>', ' <num>' ]
}, options);
type('tsm ', {
emptyParameters: [ ' <txt>', ' <num>' ],
directTabText: 'a'
}, options);
type('tsm a', {
emptyParameters: [ ' <txt>', ' <num>' ]
}, options);
type('tsm a ', {
emptyParameters: [ '<txt>', ' <num>' ]
}, options);
type('tsm a ', {
emptyParameters: [ '<txt>', ' <num>' ]
}, options);
type('tsm a d', {
emptyParameters: [ ' <num>' ]
}, options);
type('tsm a "d d"', {
emptyParameters: [ ' <num>' ]
}, options);
type('tsm a "d ', {
emptyParameters: [ ' <num>' ]
}, options);
type('tsm a "d d" ', {
emptyParameters: [ '<num>' ]
}, options);
type('tsm a "d d ', {
emptyParameters: [ ' <num>' ]
}, options);
type('tsm d r', {
emptyParameters: [ ' <num>' ]
}, options);
type('tsm a d ', {
emptyParameters: [ '<num>' ]
}, options);
type('tsm a d 4', { }, options);
type('tsg', {
emptyParameters: [ ' <solo>' ]
}, options);
type('tsg ', {
directTabText: 'aaa'
}, options);
type('tsg a', {
directTabText: 'aa'
}, options);
type('tsg b', {
directTabText: 'bb'
}, options);
type('tsg d', { }, options);
type('tsg aa', {
directTabText: 'a'
}, options);
type('tsg aaa', { }, options);
type('tsg aaa ', { }, options);
type('tsg aaa d', { }, options);
type('tsg aaa dddddd', { }, options);
type('tsg aaa dddddd ', { }, options);
type('tsg aaa "d', { }, options);
type('tsg aaa "d d', { }, options);
type('tsg aaa "d d"', { }, options);
type('tsn ex ', { }, options);
type('selarr', {
arrowTabText: 'tselarr'
}, options);
type('tselar 1', { }, options);
type('tselar 1', {
cursor: 7
}, options);
type('tselar 1', {
cursor: 6,
arrowTabText: 'tselarr'
}, options);
type('tselar 1', {
cursor: 5,
arrowTabText: 'tselarr'
}, options);
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testExec', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/canon', 'gclitest/mockCommands', 'gcli/types/node', 'test/assert'], function(require, exports, module) {
var Requisition = require('gcli/cli').Requisition;
var canon = require('gcli/canon');
var mockCommands = require('gclitest/mockCommands');
var nodetype = require('gcli/types/node');
var test = require('test/assert');
var actualExec;
var actualOutput;
var hideExec = false;
exports.setup = function() {
mockCommands.setup();
mockCommands.onCommandExec.add(commandExeced);
canon.commandOutputManager.onOutput.add(commandOutputed);
};
exports.shutdown = function() {
mockCommands.shutdown();
mockCommands.onCommandExec.remove(commandExeced);
canon.commandOutputManager.onOutput.remove(commandOutputed);
};
function commandExeced(ev) {
actualExec = ev;
}
function commandOutputed(ev) {
actualOutput = ev.output;
}
function exec(command, expectedArgs) {
var environment = {};
var requisition = new Requisition(environment);
var outputObject = requisition.exec({ typed: command, hidden: hideExec });
test.is(command.indexOf(actualExec.command.name), 0, 'Command name: ' + command);
test.is(command, outputObject.typed, 'outputObject.command for: ' + command);
test.ok(outputObject.completed, 'outputObject.completed false for: ' + command);
if (expectedArgs == null) {
test.ok(false, 'expectedArgs == null for ' + command);
return;
}
if (actualExec.args == null) {
test.ok(false, 'actualExec.args == null for ' + command);
return;
}
test.is(Object.keys(expectedArgs).length, Object.keys(actualExec.args).length,
'Arg count: ' + command);
Object.keys(expectedArgs).forEach(function(arg) {
var expectedArg = expectedArgs[arg];
var actualArg = actualExec.args[arg];
if (Array.isArray(expectedArg)) {
if (!Array.isArray(actualArg)) {
test.ok(false, 'actual is not an array. ' + command + '/' + arg);
return;
}
test.is(expectedArg.length, actualArg.length,
'Array length: ' + command + '/' + arg);
for (var i = 0; i < expectedArg.length; i++) {
test.is(expectedArg[i], actualArg[i],
'Member: "' + command + '/' + arg + '/' + i);
}
}
else {
test.is(expectedArg, actualArg, 'Command: "' + command + '" arg: ' + arg);
}
});
test.is(environment, actualExec.context.environment, 'Environment');
if (!hideExec) {
test.is(false, actualOutput.error, 'output error is false');
test.is(command, actualOutput.typed, 'command is typed');
test.ok(typeof actualOutput.canonical === 'string', 'canonical exists');
test.is(actualExec.args, actualOutput.args, 'actualExec.args is actualOutput.args');
}
}
exports.testExec = function(options) {
hideExec = options.hideExec;
exec('tss', {});
// Bug 707008 - GCLI deferred types don't work properly
exec('tsv option1 10', { optionType: mockCommands.option1, optionValue: '10' });
exec('tsv option2 10', { optionType: mockCommands.option2, optionValue: 10 });
exec('tsr fred', { text: 'fred' });
exec('tsr fred bloggs', { text: 'fred bloggs' });
exec('tsr "fred bloggs"', { text: 'fred bloggs' });
exec('tsb', { toggle: false });
exec('tsb --toggle', { toggle: true });
exec('tsu 10', { num: 10 });
exec('tsu --num 10', { num: 10 });
// Bug 704829 - Enable GCLI Javascript parameters
// The answer to this should be 2
exec('tsj { 1 + 1 }', { javascript: '1 + 1' });
var origDoc = nodetype.getDocument();
nodetype.setDocument(mockDoc);
exec('tse :root', { node: mockBody });
nodetype.setDocument(origDoc);
exec('tsn dif fred', { text: 'fred' });
exec('tsn exten fred', { text: 'fred' });
exec('tsn extend fred', { text: 'fred' });
exec('tselarr 1', { num: '1', arr: [ ] });
exec('tselarr 1 a', { num: '1', arr: [ 'a' ] });
exec('tselarr 1 a b', { num: '1', arr: [ 'a', 'b' ] });
exec('tsm a 10 10', { abc: 'a', txt: '10', num: 10 });
// Bug 707009 - GCLI doesn't always fill in default parameters properly
exec('tsg aaa', { solo: 'aaa', txt1: null, bool: false, txt2: 'd', num: 42 });
};
var mockBody = {
style: {}
};
var mockDoc = {
querySelectorAll: function(css) {
if (css === ':root') {
return {
length: 1,
item: function(i) {
return mockBody;
}
};
}
throw new Error('mockDoc.querySelectorAll(\'' + css + '\') error');
}
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testHelp', ['require', 'exports', 'module' , 'gclitest/helpers'], function(require, exports, module) {
var helpers = require('gclitest/helpers');
exports.testHelpStatus = function(options) {
helpers.status(options, {
typed: 'help',
markup: 'VVVV',
status: 'VALID',
emptyParameters: [ " [search]" ]
});
helpers.status(options, {
typed: 'help foo',
markup: 'VVVVVVVV',
status: 'VALID',
emptyParameters: [ ]
});
helpers.status(options, {
typed: 'help foo bar',
markup: 'VVVVVVVVVVVV',
status: 'VALID',
emptyParameters: [ ]
});
};
exports.testHelpExec = function(options) {
if (options.isFirefox) {
helpers.exec(options, {
typed: 'help',
args: { search: null },
outputMatch: [
/Available Commands/,
/Get help/
]
});
}
else {
helpers.exec(options, {
typed: 'help',
args: { search: null },
outputMatch: [
/Welcome to GCLI/,
/Source \(BSD\)/,
/Get help/
]
});
}
helpers.exec(options, {
typed: 'help nomatch',
args: { search: 'nomatch' },
outputMatch: /Commands starting with 'nomatch':$/
});
helpers.exec(options, {
typed: 'help help',
args: { search: 'help' },
outputMatch: [
/Synopsis:/,
/Provide help either/,
/\(string, optional\)/
]
});
helpers.exec(options, {
typed: 'help a b',
args: { search: 'a b' },
outputMatch: /Commands starting with 'a b':$/
});
helpers.exec(options, {
typed: 'help hel',
args: { search: 'hel' },
outputMatch: [
/Commands starting with 'hel':/,
/Get help on the available commands/
]
});
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/helpers', ['require', 'exports', 'module' , 'test/assert'], function(require, exports, module) {
var test = require('test/assert');
/**
* Check that we can parse command input.
* Doesn't execute the command, just checks that we grok the input properly:
*
* helpers.status({
* // Test inputs
* typed: "ech", // Required
* cursor: 3, // Optional cursor position
*
* // Thing to check
* status: "INCOMPLETE", // One of "VALID", "ERROR", "INCOMPLETE"
* emptyParameters: [ "<message>" ], // Still to type
* directTabText: "o", // Simple completion text
* arrowTabText: "", // When the completion is not an extension
* markup: "VVVIIIEEE", // What state should the error markup be in
* });
*/
exports.status = function(options, tests) {
var requisition = options.display.requisition;
var inputter = options.display.inputter;
var completer = options.display.completer;
if (tests.typed) {
inputter.setInput(tests.typed);
}
else {
test.ok(false, "Missing typed for " + JSON.stringify(tests));
return;
}
if (tests.cursor) {
inputter.setCursor(tests.cursor);
}
if (tests.status) {
test.is(requisition.getStatus().toString(), tests.status,
"status for " + tests.typed);
}
if (tests.emptyParameters != null) {
var realParams = completer.emptyParameters;
test.is(realParams.length, tests.emptyParameters.length,
'emptyParameters.length for \'' + tests.typed + '\'');
if (realParams.length === tests.emptyParameters.length) {
for (var i = 0; i < realParams.length; i++) {
test.is(realParams[i].replace(/\u00a0/g, ' '), tests.emptyParameters[i],
'emptyParameters[' + i + '] for \'' + tests.typed + '\'');
}
}
}
if (tests.markup) {
var cursor = tests.cursor ? tests.cursor.start : tests.typed.length;
var statusMarkup = requisition.getInputStatusMarkup(cursor);
var actualMarkup = statusMarkup.map(function(s) {
return Array(s.string.length + 1).join(s.status.toString()[0]);
}).join('');
test.is(tests.markup, actualMarkup, 'markup for ' + tests.typed);
}
if (tests.directTabText) {
test.is(completer.directTabText, tests.directTabText,
'directTabText for \'' + tests.typed + '\'');
}
if (tests.arrowTabText) {
test.is(completer.arrowTabText, ' \u00a0\u21E5 ' + tests.arrowTabText,
'arrowTabText for \'' + tests.typed + '\'');
}
};
/**
* Execute a command:
*
* helpers.exec({
* // Test inputs
* typed: "echo hi", // Optional, uses existing if undefined
*
* // Thing to check
* args: { message: "hi" }, // Check that the args were understood properly
* outputMatch: /^hi$/, // Regex to test against textContent of output
* blankOutput: true, // Special checks when there is no output
* });
*/
exports.exec = function(options, tests) {
var requisition = options.display.requisition;
var inputter = options.display.inputter;
tests = tests || {};
if (tests.typed) {
inputter.setInput(tests.typed);
}
var typed = inputter.getInputState().typed;
var output = requisition.exec({ hidden: true });
test.is(typed, output.typed, 'output.command for: ' + typed);
if (tests.completed !== false) {
test.ok(output.completed, 'output.completed false for: ' + typed);
}
else {
// It is actually an error if we say something is async and it turns
// out not to be? For now we're saying 'no'
// test.ok(!output.completed, 'output.completed true for: ' + typed);
}
if (tests.args != null) {
test.is(Object.keys(tests.args).length, Object.keys(output.args).length,
'arg count for ' + typed);
Object.keys(output.args).forEach(function(arg) {
var expectedArg = tests.args[arg];
var actualArg = output.args[arg];
if (Array.isArray(expectedArg)) {
if (!Array.isArray(actualArg)) {
test.ok(false, 'actual is not an array. ' + typed + '/' + arg);
return;
}
test.is(expectedArg.length, actualArg.length,
'array length: ' + typed + '/' + arg);
for (var i = 0; i < expectedArg.length; i++) {
test.is(expectedArg[i], actualArg[i],
'member: "' + typed + '/' + arg + '/' + i);
}
}
else {
test.is(expectedArg, actualArg, 'typed: "' + typed + '" arg: ' + arg);
}
});
}
if (!options.window.document.createElement) {
test.log('skipping output tests (missing doc.createElement) for ' + typed);
return;
}
var div = options.window.document.createElement('div');
output.toDom(div);
var displayed = div.textContent.trim();
if (tests.outputMatch) {
function doTest(match, against) {
if (!match.test(against)) {
test.ok(false, "html output for " + typed + " against " + match.source);
console.log("Actual textContent");
console.log(against);
}
}
if (Array.isArray(tests.outputMatch)) {
tests.outputMatch.forEach(function(match) {
doTest(match, displayed);
});
}
else {
doTest(tests.outputMatch, displayed);
}
}
if (tests.blankOutput != null) {
if (!/^$/.test(displayed)) {
test.ok(false, "html for " + typed + " (textContent sent to info)");
console.log("Actual textContent");
console.log(displayed);
}
}
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testHistory', ['require', 'exports', 'module' , 'test/assert', 'gcli/history'], function(require, exports, module) {
var test = require('test/assert');
var History = require('gcli/history').History;
exports.setup = function() {
};
exports.shutdown = function() {
};
exports.testSimpleHistory = function () {
var history = new History({});
history.add('foo');
history.add('bar');
test.is('bar', history.backward());
test.is('foo', history.backward());
// Adding to the history again moves us back to the start of the history.
history.add('quux');
test.is('quux', history.backward());
test.is('bar', history.backward());
test.is('foo', history.backward());
};
exports.testBackwardsPastIndex = function () {
var history = new History({});
history.add('foo');
history.add('bar');
test.is('bar', history.backward());
test.is('foo', history.backward());
// Moving backwards past recorded history just keeps giving you the last
// item.
test.is('foo', history.backward());
};
exports.testForwardsPastIndex = function () {
var history = new History({});
history.add('foo');
history.add('bar');
test.is('bar', history.backward());
test.is('foo', history.backward());
// Going forward through the history again.
test.is('bar', history.forward());
// 'Present' time.
test.is('', history.forward());
// Going to the 'future' just keeps giving us the empty string.
test.is('', history.forward());
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testInputter', ['require', 'exports', 'module' , 'gclitest/mockCommands', 'gcli/util', 'test/assert'], function(require, exports, module) {
var mockCommands = require('gclitest/mockCommands');
var KeyEvent = require('gcli/util').KeyEvent;
var test = require('test/assert');
var latestEvent = undefined;
var latestOutput = undefined;
var latestData = undefined;
var outputted = function(ev) {
function updateData() {
latestData = latestOutput.data;
}
if (latestOutput != null) {
ev.output.onChange.remove(updateData);
}
latestEvent = ev;
latestOutput = ev.output;
ev.output.onChange.add(updateData);
};
exports.setup = function(options) {
options.display.requisition.commandOutputManager.onOutput.add(outputted);
mockCommands.setup();
};
exports.shutdown = function(options) {
mockCommands.shutdown();
options.display.requisition.commandOutputManager.onOutput.remove(outputted);
};
exports.testOutput = function(options) {
latestEvent = undefined;
latestOutput = undefined;
latestData = undefined;
var inputter = options.display.inputter;
var focusManager = options.display.focusManager;
inputter.setInput('tss');
inputter.onKeyDown({
keyCode: KeyEvent.DOM_VK_RETURN
});
test.is(inputter.element.value, 'tss', 'inputter should do nothing on RETURN keyDown');
test.is(latestEvent, undefined, 'no events this test');
test.is(latestData, undefined, 'no data this test');
inputter.onKeyUp({
keyCode: KeyEvent.DOM_VK_RETURN
});
test.ok(latestEvent != null, 'events this test');
test.is(latestData.command.name, 'tss', 'last command is tss');
test.is(inputter.element.value, '', 'inputter should exec on RETURN keyUp');
test.ok(focusManager._recentOutput, 'recent output happened');
inputter.onKeyUp({
keyCode: KeyEvent.DOM_VK_F1
});
test.ok(!focusManager._recentOutput, 'no recent output happened post F1');
test.ok(focusManager._helpRequested, 'F1 = help');
inputter.onKeyUp({
keyCode: KeyEvent.DOM_VK_ESCAPE
});
test.ok(!focusManager._helpRequested, 'ESCAPE = anti help');
latestOutput.onClose();
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testJs', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/types', 'gcli/types/javascript', 'gcli/canon', 'test/assert'], function(require, exports, module) {
var Requisition = require('gcli/cli').Requisition;
var Status = require('gcli/types').Status;
var javascript = require('gcli/types/javascript');
var canon = require('gcli/canon');
var test = require('test/assert');
var debug = false;
var requ;
var assign;
var status;
var statuses;
var tempWindow;
exports.setup = function(options) {
tempWindow = javascript.getGlobalObject();
javascript.setGlobalObject(options.window);
Object.defineProperty(options.window, 'donteval', {
get: function() {
test.ok(false, 'donteval should not be used');
return { cant: '', touch: '', 'this': '' };
},
enumerable: true,
configurable : true
});
};
exports.shutdown = function(options) {
delete options.window.donteval;
javascript.setGlobalObject(tempWindow);
tempWindow = undefined;
};
function input(typed) {
if (!requ) {
requ = new Requisition();
}
var cursor = { start: typed.length, end: typed.length };
requ.update(typed);
if (debug) {
console.log('####### TEST: typed="' + typed +
'" cur=' + cursor.start +
' cli=', requ);
}
status = requ.getStatus();
statuses = requ.getInputStatusMarkup(cursor.start).map(function(s) {
return Array(s.string.length + 1).join(s.status.toString()[0]);
}).join('');
if (requ.commandAssignment.value) {
assign = requ.getAssignment(0);
}
else {
assign = undefined;
}
}
function predictionsHas(name) {
return assign.getPredictions().some(function(prediction) {
return name === prediction.name;
}, this);
}
function check(expStatuses, expStatus, expAssign, expPredict) {
test.is('{', requ.commandAssignment.value.name, 'is exec');
test.is(expStatuses, statuses, 'unexpected status markup');
test.is(expStatus.toString(), status.toString(), 'unexpected status');
test.is(expAssign, assign.value, 'unexpected assignment');
if (expPredict != null) {
var contains;
if (Array.isArray(expPredict)) {
expPredict.forEach(function(p) {
contains = predictionsHas(p);
test.ok(contains, 'missing prediction ' + p);
});
}
else if (typeof expPredict === 'number') {
contains = true;
test.is(assign.getPredictions().length, expPredict, 'prediction count');
if (assign.getPredictions().length !== expPredict) {
assign.getPredictions().forEach(function(prediction) {
test.log('actual prediction: ', prediction);
});
}
}
else {
contains = predictionsHas(expPredict);
test.ok(contains, 'missing prediction ' + expPredict);
}
if (!contains) {
test.log('Predictions: ' + assign.getPredictions().map(function(p) {
return p.name;
}).join(', '));
}
}
}
exports.testBasic = function(options) {
if (!canon.getCommand('{')) {
test.log('Skipping exec tests because { is not registered');
return;
}
input('{');
check('V', Status.ERROR, undefined);
input('{ ');
check('VV', Status.ERROR, undefined);
input('{ w');
check('VVI', Status.ERROR, 'w', 'window');
input('{ windo');
check('VVIIIII', Status.ERROR, 'windo', 'window');
input('{ window');
check('VVVVVVVV', Status.VALID, 'window');
input('{ window.d');
check('VVIIIIIIII', Status.ERROR, 'window.d', 'window.document');
input('{ window.document.title');
check('VVVVVVVVVVVVVVVVVVVVVVV', Status.VALID, 'window.document.title', 0);
input('{ d');
check('VVI', Status.ERROR, 'd', 'document');
input('{ document.title');
check('VVVVVVVVVVVVVVVV', Status.VALID, 'document.title', 0);
test.ok('donteval' in options.window, 'donteval exists');
input('{ don');
check('VVIII', Status.ERROR, 'don', 'donteval');
input('{ donteval');
check('VVVVVVVVVV', Status.VALID, 'donteval', 0);
/*
// This is a controversial test - technically we can tell that it's an error
// because 'donteval.' is a syntax error, however donteval is unsafe so we
// are playing safe by bailing out early. It's enough of a corner case that
// I don't think it warrants fixing
input('{ donteval.');
check('VVIIIIIIIII', Status.ERROR, 'donteval.', 0);
*/
input('{ donteval.cant');
check('VVVVVVVVVVVVVVV', Status.VALID, 'donteval.cant', 0);
input('{ donteval.xxx');
check('VVVVVVVVVVVVVV', Status.VALID, 'donteval.xxx', 0);
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testKeyboard', ['require', 'exports', 'module' , 'gcli/cli', 'gcli/canon', 'gclitest/mockCommands', 'gcli/types/javascript', 'test/assert'], function(require, exports, module) {
var Requisition = require('gcli/cli').Requisition;
var canon = require('gcli/canon');
var mockCommands = require('gclitest/mockCommands');
var javascript = require('gcli/types/javascript');
var test = require('test/assert');
var tempWindow;
var inputter;
exports.setup = function(options) {
tempWindow = javascript.getGlobalObject();
javascript.setGlobalObject(options.window);
if (options.display) {
inputter = options.display.inputter;
}
mockCommands.setup();
};
exports.shutdown = function(options) {
mockCommands.shutdown();
inputter = undefined;
javascript.setGlobalObject(tempWindow);
tempWindow = undefined;
};
var COMPLETES_TO = 'complete';
var KEY_UPS_TO = 'keyup';
var KEY_DOWNS_TO = 'keydown';
function check(initial, action, after, choice, cursor, expectedCursor) {
var requisition;
if (inputter) {
requisition = inputter.requisition;
inputter.setInput(initial);
}
else {
requisition = new Requisition();
requisition.update(initial);
}
if (cursor == null) {
cursor = initial.length;
}
var assignment = requisition.getAssignmentAt(cursor);
switch (action) {
case COMPLETES_TO:
requisition.complete({ start: cursor, end: cursor }, choice);
break;
case KEY_UPS_TO:
assignment.increment();
break;
case KEY_DOWNS_TO:
assignment.decrement();
break;
}
test.is(after, requisition.toString(),
initial + ' + ' + action + ' -> ' + after);
if (expectedCursor != null) {
if (inputter) {
test.is(expectedCursor, inputter.getInputState().cursor.start,
'Ending cursor position for \'' + initial + '\'');
}
}
}
exports.testComplete = function(options) {
if (!inputter) {
test.log('Missing display, reduced checks');
}
check('tsela', COMPLETES_TO, 'tselarr ', 0);
check('tsn di', COMPLETES_TO, 'tsn dif ', 0);
check('tsg a', COMPLETES_TO, 'tsg aaa ', 0);
check('tsn e', COMPLETES_TO, 'tsn extend ', -5);
check('tsn e', COMPLETES_TO, 'tsn ext ', -4);
check('tsn e', COMPLETES_TO, 'tsn exte ', -3);
check('tsn e', COMPLETES_TO, 'tsn exten ', -2);
check('tsn e', COMPLETES_TO, 'tsn extend ', -1);
check('tsn e', COMPLETES_TO, 'tsn ext ', 0);
check('tsn e', COMPLETES_TO, 'tsn exte ', 1);
check('tsn e', COMPLETES_TO, 'tsn exten ', 2);
check('tsn e', COMPLETES_TO, 'tsn extend ', 3);
check('tsn e', COMPLETES_TO, 'tsn ext ', 4);
check('tsn e', COMPLETES_TO, 'tsn exte ', 5);
check('tsn e', COMPLETES_TO, 'tsn exten ', 6);
check('tsn e', COMPLETES_TO, 'tsn extend ', 7);
check('tsn e', COMPLETES_TO, 'tsn ext ', 8);
if (!canon.getCommand('{')) {
test.log('Skipping exec tests because { is not registered');
}
else {
check('{ wind', COMPLETES_TO, '{ window', 0);
check('{ window.docum', COMPLETES_TO, '{ window.document', 0);
// Bug 717228: This fails under node
if (!options.isNode) {
check('{ window.document.titl', COMPLETES_TO, '{ window.document.title ', 0);
}
else {
test.log('Running under Node. Skipping tests due to bug 717228.');
}
}
};
exports.testInternalComplete = function(options) {
// Bug 664377
// check('tsela 1', COMPLETES_TO, 'tselarr 1', 0, 3, 8);
};
exports.testIncrDecr = function() {
check('tsu -70', KEY_UPS_TO, 'tsu -5');
check('tsu -7', KEY_UPS_TO, 'tsu -5');
check('tsu -6', KEY_UPS_TO, 'tsu -5');
check('tsu -5', KEY_UPS_TO, 'tsu -3');
check('tsu -4', KEY_UPS_TO, 'tsu -3');
check('tsu -3', KEY_UPS_TO, 'tsu 0');
check('tsu -2', KEY_UPS_TO, 'tsu 0');
check('tsu -1', KEY_UPS_TO, 'tsu 0');
check('tsu 0', KEY_UPS_TO, 'tsu 3');
check('tsu 1', KEY_UPS_TO, 'tsu 3');
check('tsu 2', KEY_UPS_TO, 'tsu 3');
check('tsu 3', KEY_UPS_TO, 'tsu 6');
check('tsu 4', KEY_UPS_TO, 'tsu 6');
check('tsu 5', KEY_UPS_TO, 'tsu 6');
check('tsu 6', KEY_UPS_TO, 'tsu 9');
check('tsu 7', KEY_UPS_TO, 'tsu 9');
check('tsu 8', KEY_UPS_TO, 'tsu 9');
check('tsu 9', KEY_UPS_TO, 'tsu 10');
check('tsu 10', KEY_UPS_TO, 'tsu 10');
check('tsu 100', KEY_UPS_TO, 'tsu -5');
check('tsu -70', KEY_DOWNS_TO, 'tsu 10');
check('tsu -7', KEY_DOWNS_TO, 'tsu 10');
check('tsu -6', KEY_DOWNS_TO, 'tsu 10');
check('tsu -5', KEY_DOWNS_TO, 'tsu -5');
check('tsu -4', KEY_DOWNS_TO, 'tsu -5');
check('tsu -3', KEY_DOWNS_TO, 'tsu -5');
check('tsu -2', KEY_DOWNS_TO, 'tsu -3');
check('tsu -1', KEY_DOWNS_TO, 'tsu -3');
check('tsu 0', KEY_DOWNS_TO, 'tsu -3');
check('tsu 1', KEY_DOWNS_TO, 'tsu 0');
check('tsu 2', KEY_DOWNS_TO, 'tsu 0');
check('tsu 3', KEY_DOWNS_TO, 'tsu 0');
check('tsu 4', KEY_DOWNS_TO, 'tsu 3');
check('tsu 5', KEY_DOWNS_TO, 'tsu 3');
check('tsu 6', KEY_DOWNS_TO, 'tsu 3');
check('tsu 7', KEY_DOWNS_TO, 'tsu 6');
check('tsu 8', KEY_DOWNS_TO, 'tsu 6');
check('tsu 9', KEY_DOWNS_TO, 'tsu 6');
check('tsu 10', KEY_DOWNS_TO, 'tsu 9');
check('tsu 100', KEY_DOWNS_TO, 'tsu 10');
// Bug 707007 - GCLI increment and decrement operations cycle through
// selection options in the wrong order
check('tselarr 1', KEY_DOWNS_TO, 'tselarr 2');
check('tselarr 2', KEY_DOWNS_TO, 'tselarr 3');
check('tselarr 3', KEY_DOWNS_TO, 'tselarr 1');
check('tselarr 3', KEY_UPS_TO, 'tselarr 2');
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testPref', ['require', 'exports', 'module' , 'gcli/commands/pref', 'gclitest/helpers', 'gclitest/mockSettings', 'test/assert'], function(require, exports, module) {
var pref = require('gcli/commands/pref');
var helpers = require('gclitest/helpers');
var mockSettings = require('gclitest/mockSettings');
var test = require('test/assert');
exports.setup = function(options) {
if (!options.isFirefox) {
mockSettings.setup();
}
else {
test.log('Skipping testPref in Firefox.');
}
};
exports.shutdown = function(options) {
if (!options.isFirefox) {
mockSettings.shutdown();
}
};
exports.testPrefSetStatus = function(options) {
if (options.isFirefox) {
test.log('Skipping testPref in Firefox.');
return;
}
helpers.status(options, {
typed: 'pref s',
markup: 'IIIIVI',
status: 'ERROR',
directTabText: 'et'
});
helpers.status(options, {
typed: 'pref set',
markup: 'VVVVVVVV',
status: 'ERROR',
emptyParameters: [ ' <setting>', ' <value>' ]
});
helpers.status(options, {
typed: 'pref xxx',
markup: 'EEEEVEEE',
status: 'ERROR'
});
helpers.status(options, {
typed: 'pref set ',
markup: 'VVVVVVVVV',
status: 'ERROR',
emptyParameters: [ ' <value>' ]
});
helpers.status(options, {
typed: 'pref set ',
markup: 'VVVVVVVVV',
status: 'ERROR',
emptyParameters: [ ' <value>' ]
});
helpers.status(options, {
typed: 'pref set tempTBo',
markup: 'VVVVVVVVVIIIIIII',
directTabText: 'ol',
status: 'ERROR',
emptyParameters: [ ' <value>' ]
});
helpers.status(options, {
typed: 'pref set tempTBool 4',
markup: 'VVVVVVVVVVVVVVVVVVVE',
directTabText: '',
status: 'ERROR',
emptyParameters: [ ]
});
helpers.status(options, {
typed: 'pref set tempNumber 4',
markup: 'VVVVVVVVVVVVVVVVVVVVV',
directTabText: '',
status: 'VALID',
emptyParameters: [ ]
});
};
exports.testPrefExec = function(options) {
if (options.isFirefox) {
test.log('Skipping testPref in Firefox.');
return;
}
var initialAllowSet = pref.allowSet.value;
pref.allowSet.value = false;
test.is(mockSettings.tempNumber.value, 42, 'set to 42');
helpers.exec(options, {
typed: 'pref set tempNumber 4',
args: {
setting: mockSettings.tempNumber,
value: 4
},
outputMatch: [ /void your warranty/, /I promise/ ]
});
test.is(mockSettings.tempNumber.value, 42, 'still set to 42');
pref.allowSet.value = true;
helpers.exec(options, {
typed: 'pref set tempNumber 4',
args: {
setting: mockSettings.tempNumber,
value: 4
},
blankOutput: true
});
test.is(mockSettings.tempNumber.value, 4, 'set to 4');
helpers.exec(options, {
typed: 'pref reset tempNumber',
args: {
setting: mockSettings.tempNumber
},
blankOutput: true
});
test.is(mockSettings.tempNumber.value, 42, 'reset to 42');
pref.allowSet.value = initialAllowSet;
helpers.exec(options, {
typed: 'pref list tempNum',
args: {
search: 'tempNum'
},
outputMatch: /Filter/
});
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gcli/commands/pref', ['require', 'exports', 'module' , 'gcli/index', 'gcli/l10n', 'gcli/util', 'gcli/settings', 'gcli/promise', 'text!gcli/commands/pref_list_outer.html', 'text!gcli/commands/pref_list.css', 'text!gcli/commands/pref_set_check.html', 'text!gcli/commands/pref_list_inner.html'], function(require, exports, module) {
var gcli = require('gcli/index');
var l10n = require('gcli/l10n');
var util = require('gcli/util');
var settings = require('gcli/settings');
var Promise = require('gcli/promise').Promise;
/**
* Record if the user has clicked on 'Got It!'
*/
var allowSetSettingSpec = {
name: 'allowSet',
type: 'boolean',
description: l10n.lookup('allowSetDesc'),
defaultValue: false
};
exports.allowSet = undefined;
/**
* 'pref' command
*/
var prefCmdSpec = {
name: 'pref',
description: l10n.lookup('prefDesc'),
manual: l10n.lookup('prefManual')
};
/**
* 'pref list' command
*/
var prefListCmdSpec = {
name: 'pref list',
description: l10n.lookup('prefListDesc'),
manual: l10n.lookup('prefListManual'),
params: [
{
name: 'search',
type: 'string',
defaultValue: null,
description: l10n.lookup('prefListSearchDesc'),
manual: l10n.lookup('prefListSearchManual')
}
],
exec: function Command_prefList(args, context) {
return context.createView({
html: require('text!gcli/commands/pref_list_outer.html'),
data: new PrefList(args, context),
options: {
blankNullUndefined: true,
allowEval: true,
stack: 'pref_list_outer.html'
},
css: require('text!gcli/commands/pref_list.css'),
cssId: 'gcli-pref-list'
});
}
};
/**
* 'pref set' command
*/
var prefSetCmdSpec = {
name: 'pref set',
description: l10n.lookup('prefSetDesc'),
manual: l10n.lookup('prefSetManual'),
params: [
{
name: 'setting',
type: 'setting',
description: l10n.lookup('prefSetSettingDesc'),
manual: l10n.lookup('prefSetSettingManual')
},
{
name: 'value',
type: 'settingValue',
description: l10n.lookup('prefSetValueDesc'),
manual: l10n.lookup('prefSetValueManual')
}
],
exec: function Command_prefSet(args, context) {
if (!exports.allowSet.value &&
args.setting.name !== exports.allowSet.name) {
return context.createView({
html: require('text!gcli/commands/pref_set_check.html'),
options: { allowEval: true, stack: 'pref_set_check.html' },
data: {
l10n: l10n.propertyLookup,
activate: function() {
context.exec('pref set allowSet true');
}
},
});
}
args.setting.value = args.value;
return null;
}
};
/**
* 'pref reset' command
*/
var prefResetCmdSpec = {
name: 'pref reset',
description: l10n.lookup('prefResetDesc'),
manual: l10n.lookup('prefResetManual'),
params: [
{
name: 'setting',
type: 'setting',
description: l10n.lookup('prefResetSettingDesc'),
manual: l10n.lookup('prefResetSettingManual')
}
],
exec: function Command_prefReset(args, context) {
args.setting.setDefault();
return null;
}
};
/**
* Registration and de-registration.
*/
exports.startup = function() {
exports.allowSet = settings.addSetting(allowSetSettingSpec);
gcli.addCommand(prefCmdSpec);
gcli.addCommand(prefListCmdSpec);
gcli.addCommand(prefSetCmdSpec);
gcli.addCommand(prefResetCmdSpec);
};
exports.shutdown = function() {
gcli.removeCommand(prefCmdSpec);
gcli.removeCommand(prefListCmdSpec);
gcli.removeCommand(prefSetCmdSpec);
gcli.removeCommand(prefResetCmdSpec);
settings.removeSetting(allowSetSettingSpec);
exports.allowSet = undefined;
};
/**
* A manager for our version of about:config
*/
function PrefList(args, context) {
this.search = args.search;
this.context = context;
this.url = util.createUrlLookup(module);
this.edit = this.url('pref_list_edit.png');
}
/**
*
*/
PrefList.prototype.onLoad = function(element) {
var table = element.querySelector('.gcli-pref-list-table');
this.updateTable(table);
return '';
};
/**
* Forward localization lookups
*/
PrefList.prototype.l10n = l10n.propertyLookup;
/**
* Called from the template onkeyup for the filter element
*/
PrefList.prototype.updateTable = function(table) {
util.clearElement(table);
var view = this.context.createView({
html: require('text!gcli/commands/pref_list_inner.html'),
options: { blankNullUndefined: true, stack: 'pref_list_inner.html' },
data: this
});
var child = view.toDom(table.ownerDocument);
util.setContents(table, child);
};
/**
* Which preferences match the filter?
*/
Object.defineProperty(PrefList.prototype, 'preferences', {
get: function() {
return settings.getAll(this.search);
},
enumerable: true
});
/**
* Which preferences match the filter?
*/
Object.defineProperty(PrefList.prototype, 'promisePreferences', {
get: function() {
var promise = new Promise();
setTimeout(function() {
promise.resolve(settings.getAll(this.search));
}.bind(this), 10);
return promise;
},
enumerable: true
});
PrefList.prototype.onFilterChange = function(ev) {
if (ev.target.value !== this.search) {
this.search = ev.target.value;
var root = ev.target.parentNode.parentNode;
var table = root.querySelector('.gcli-pref-list-table');
this.updateTable(table);
}
};
PrefList.prototype.onSetClick = function(ev) {
var typed = ev.currentTarget.getAttribute('data-command');
this.context.update(typed);
};
});
define("text!gcli/commands/pref_list_outer.html", [], "<div ignore=\"${onLoad(__element)}\">\n" +
" <div class=\"gcli-pref-list-filter\">\n" +
" ${l10n.prefOutputFilter}:\n" +
" <input onKeyUp=\"${onFilterChange}\" value=\"${search}\"/>\n" +
" </div>\n" +
" <table class=\"gcli-pref-list-table\">\n" +
" <colgroup>\n" +
" <col class=\"gcli-pref-list-name\"/>\n" +
" <col class=\"gcli-pref-list-value\"/>\n" +
" </colgroup>\n" +
" <tr>\n" +
" <th>${l10n.prefOutputName}</th>\n" +
" <th>${l10n.prefOutputValue}</th>\n" +
" </tr>\n" +
" </table>\n" +
" <div class=\"gcli-pref-list-scroller\">\n" +
" <table class=\"gcli-pref-list-table\" save=\"${table}\">\n" +
" </table>\n" +
" </div>\n" +
"</div>\n" +
"");
define("text!gcli/commands/pref_list.css", [], "\n" +
".gcli-pref-list-scroller {\n" +
" max-height: 200px;\n" +
" overflow-y: auto;\n" +
" overflow-x: hidden;\n" +
" display: inline-block;\n" +
"}\n" +
"\n" +
".gcli-pref-list-table {\n" +
" width: 500px;\n" +
" table-layout: fixed;\n" +
"}\n" +
"\n" +
".gcli-pref-list-table tr > th {\n" +
" text-align: left;\n" +
"}\n" +
"\n" +
".gcli-pref-list-table tr > td {\n" +
" text-overflow: elipsis;\n" +
" word-wrap: break-word;\n" +
"}\n" +
"\n" +
".gcli-pref-list-name {\n" +
" width: 70%;\n" +
"}\n" +
"\n" +
".gcli-pref-list-command {\n" +
" display: none;\n" +
"}\n" +
"\n" +
".gcli-pref-list-row:hover .gcli-pref-list-command {\n" +
" display: inline-block;\n" +
"}\n" +
"");
define("text!gcli/commands/pref_set_check.html", [], "<div>\n" +
" <p><strong>${l10n.prefSetCheckHeading}</strong></p>\n" +
" <p>${l10n.prefSetCheckBody}</p>\n" +
" <button onclick=\"${activate}\">${l10n.prefSetCheckGo}</button>\n" +
"</div>\n" +
"");
define("text!gcli/commands/pref_list_inner.html", [], "<table>\n" +
" <colgroup>\n" +
" <col class=\"gcli-pref-list-name\"/>\n" +
" <col class=\"gcli-pref-list-value\"/>\n" +
" </colgroup>\n" +
" <tr class=\"gcli-pref-list-row\" foreach=\"preference in ${promisePreferences}\">\n" +
" <td>${preference.name}</td>\n" +
" <td onclick=\"${onSetClick}\" data-command=\"pref set ${preference.name} \">\n" +
" ${preference.value}\n" +
" <img class=\"gcli-pref-list-command\" _src=\"${edit}\"/>\n" +
" </td>\n" +
" </tr>\n" +
"</table>\n" +
"");
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/mockSettings', ['require', 'exports', 'module' , 'gcli/settings'], function(require, exports, module) {
var settings = require('gcli/settings');
var tempTBoolSpec = {
name: 'tempTBool',
type: 'boolean',
description: 'temporary default true boolean',
defaultValue: true
};
exports.tempTBool = undefined;
var tempFBoolSpec = {
name: 'tempFBool',
type: 'boolean',
description: 'temporary default false boolean',
defaultValue: false
};
exports.tempFBool = undefined;
var tempUStringSpec = {
name: 'tempUString',
type: 'string',
description: 'temporary default undefined string'
};
exports.tempUString = undefined;
var tempNStringSpec = {
name: 'tempNString',
type: 'string',
description: 'temporary default undefined string',
defaultValue: null
};
exports.tempNString = undefined;
var tempQStringSpec = {
name: 'tempQString',
type: 'string',
description: 'temporary default "q" string',
defaultValue: 'q'
};
exports.tempQString = undefined;
var tempNumberSpec = {
name: 'tempNumber',
type: 'number',
description: 'temporary number',
defaultValue: 42
};
exports.tempNumber = undefined;
var tempSelectionSpec = {
name: 'tempSelection',
type: { name: 'selection', data: [ 'a', 'b', 'c' ] },
description: 'temporary selection',
defaultValue: 'a'
};
exports.tempSelection = undefined;
/**
* Registration and de-registration.
*/
exports.setup = function() {
exports.tempTBool = settings.addSetting(tempTBoolSpec);
exports.tempFBool = settings.addSetting(tempFBoolSpec);
exports.tempUString = settings.addSetting(tempUStringSpec);
exports.tempNString = settings.addSetting(tempNStringSpec);
exports.tempQString = settings.addSetting(tempQStringSpec);
exports.tempNumber = settings.addSetting(tempNumberSpec);
exports.tempSelection = settings.addSetting(tempSelectionSpec);
};
exports.shutdown = function() {
settings.removeSetting(tempTBoolSpec);
settings.removeSetting(tempFBoolSpec);
settings.removeSetting(tempUStringSpec);
settings.removeSetting(tempNStringSpec);
settings.removeSetting(tempQStringSpec);
settings.removeSetting(tempNumberSpec);
settings.removeSetting(tempSelectionSpec);
exports.tempTBool = undefined;
exports.tempFBool = undefined;
exports.tempUString = undefined;
exports.tempNString = undefined;
exports.tempQString = undefined;
exports.tempNumber = undefined;
exports.tempSelection = undefined;
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testRequire', ['require', 'exports', 'module' , 'test/assert', 'gclitest/requirable'], function(require, exports, module) {
var test = require('test/assert');
exports.testWorking = function() {
// There are lots of requirement tests that we could be doing here
// The fact that we can get anything at all working is a testament to
// require doing what it should - we don't need to test the
var requireable = require('gclitest/requirable');
test.is('thing1', requireable.thing1);
test.is(2, requireable.thing2);
test.ok(requireable.thing3 === undefined);
};
exports.testDomains = function() {
var requireable = require('gclitest/requirable');
test.ok(requireable.status === undefined);
requireable.setStatus(null);
test.is(null, requireable.getStatus());
test.ok(requireable.status === undefined);
requireable.setStatus('42');
test.is('42', requireable.getStatus());
test.ok(requireable.status === undefined);
if (define.Domain) {
var domain = new define.Domain();
var requireable2 = domain.require('gclitest/requirable');
test.is(undefined, requireable2.status);
test.is('initial', requireable2.getStatus());
requireable2.setStatus(999);
test.is(999, requireable2.getStatus());
test.is(undefined, requireable2.status);
test.is('42', requireable.getStatus());
test.is(undefined, requireable.status);
}
};
exports.testLeakage = function() {
var requireable = require('gclitest/requirable');
test.ok(requireable.setup === undefined);
test.ok(requireable.shutdown === undefined);
test.ok(requireable.testWorking === undefined);
};
exports.testMultiImport = function() {
var r1 = require('gclitest/requirable');
var r2 = require('gclitest/requirable');
test.is(r1, r2);
};
exports.testUncompilable = function() {
// This test is commented out because it breaks the RequireJS module
// loader and because it causes console output and because testing failure
// cases such as this is something of a luxury
// It's not totally clear how a module loader should perform with unusable
// modules, however at least it should go into a flat spin ...
// GCLI mini_require reports an error as it should
/*
if (define.Domain) {
try {
var unrequireable = require('gclitest/unrequirable');
t.fail();
}
catch (ex) {
console.error(ex);
}
}
*/
};
exports.testRecursive = function() {
// See Bug 658583
/*
var recurse = require('gclitest/recurse');
*/
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/requirable', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.thing1 = 'thing1';
exports.thing2 = 2;
var status = 'initial';
exports.setStatus = function(aStatus) { status = aStatus; };
exports.getStatus = function() { return status; };
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testResource', ['require', 'exports', 'module' , 'gcli/types/resource', 'gcli/types', 'test/assert'], function(require, exports, module) {
var resource = require('gcli/types/resource');
var types = require('gcli/types');
var Status = require('gcli/types').Status;
var test = require('test/assert');
var tempDocument;
exports.setup = function(options) {
tempDocument = resource.getDocument();
resource.setDocument(options.window.document);
};
exports.shutdown = function(options) {
resource.setDocument(tempDocument);
tempDocument = undefined;
};
exports.testPredictions = function(options) {
if (options.window.isFake || options.isFirefox) {
test.log('Skipping resource tests: window.isFake || isFirefox');
return;
}
var resource1 = types.getType('resource');
var predictions1 = resource1.parseString('').getPredictions();
test.ok(predictions1.length > 1, 'have resources');
predictions1.forEach(function(prediction) {
checkPrediction(resource1, prediction);
});
var resource2 = types.getType({ name: 'resource', include: 'text/javascript' });
var predictions2 = resource2.parseString('').getPredictions();
test.ok(predictions2.length > 1, 'have resources');
predictions2.forEach(function(prediction) {
checkPrediction(resource2, prediction);
});
var resource3 = types.getType({ name: 'resource', include: 'text/css' });
var predictions3 = resource3.parseString('').getPredictions();
// jsdom fails to support digging into stylesheets
if (!options.isNode) {
test.ok(predictions3.length >= 1, 'have resources');
}
else {
test.log('Running under Node. ' +
'Skipping checks due to jsdom document.stylsheets support.');
}
predictions3.forEach(function(prediction) {
checkPrediction(resource3, prediction);
});
var resource4 = types.getType({ name: 'resource' });
var predictions4 = resource4.parseString('').getPredictions();
test.is(predictions1.length, predictions4.length, 'type spec');
// Bug 734045
// test.is(predictions2.length + predictions3.length, predictions4.length, 'split');
};
function checkPrediction(res, prediction) {
var name = prediction.name;
var value = prediction.value;
var conversion = res.parseString(name);
test.is(conversion.getStatus(), Status.VALID, 'status VALID for ' + name);
test.is(conversion.value, value, 'value for ' + name);
var strung = res.stringify(value);
test.is(strung, name, 'stringify for ' + name);
test.is(typeof value.loadContents, 'function', 'resource for ' + name);
test.is(typeof value.element, 'object', 'resource for ' + name);
}
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testScratchpad', ['require', 'exports', 'module' , 'test/assert'], function(require, exports, module) {
var test = require('test/assert');
var origScratchpad;
exports.setup = function(options) {
if (options.display) {
origScratchpad = options.display.inputter.scratchpad;
options.display.inputter.scratchpad = stubScratchpad;
}
};
exports.shutdown = function(options) {
if (options.display) {
options.display.inputter.scratchpad = origScratchpad;
}
};
var stubScratchpad = {
shouldActivate: function(ev) {
return true;
},
activatedCount: 0,
linkText: 'scratchpad.linkText'
};
stubScratchpad.activate = function(value) {
stubScratchpad.activatedCount++;
return true;
};
exports.testActivate = function(options) {
if (!options.display) {
test.log('No display. Skipping scratchpad tests');
return;
}
var ev = {};
stubScratchpad.activatedCount = 0;
options.display.inputter.onKeyUp(ev);
test.is(1, stubScratchpad.activatedCount, 'scratchpad is activated');
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testSettings', ['require', 'exports', 'module' , 'gclitest/mockSettings', 'test/assert'], function(require, exports, module) {
var mockSettings = require('gclitest/mockSettings');
var test = require('test/assert');
exports.setup = function(options) {
if (!options.isFirefox) {
mockSettings.setup();
}
else {
test.log('Skipping testSettings in Firefox.');
}
};
exports.shutdown = function(options) {
if (!options.isFirefox) {
mockSettings.shutdown();
}
};
exports.testChange = function(options) {
if (options.isFirefox) {
test.log('Skipping testPref in Firefox.');
return;
}
mockSettings.tempTBool.setDefault();
mockSettings.tempFBool.setDefault();
mockSettings.tempUString.setDefault();
mockSettings.tempNString.setDefault();
mockSettings.tempQString.setDefault();
mockSettings.tempNumber.setDefault();
mockSettings.tempSelection.setDefault();
test.is(mockSettings.tempTBool.value, true, 'tempTBool default');
test.is(mockSettings.tempFBool.value, false, 'tempFBool default');
test.is(mockSettings.tempUString.value, undefined, 'tempUString default');
test.is(mockSettings.tempNString.value, null, 'tempNString default');
test.is(mockSettings.tempQString.value, 'q', 'tempQString default');
test.is(mockSettings.tempNumber.value, 42, 'tempNumber default');
test.is(mockSettings.tempSelection.value, 'a', 'tempSelection default');
function tempTBoolCheck(ev) {
test.is(ev.setting, mockSettings.tempTBool, 'tempTBool event setting');
test.is(ev.value, false, 'tempTBool event value');
test.is(ev.setting.value, false, 'tempTBool event setting value');
}
mockSettings.tempTBool.onChange.add(tempTBoolCheck);
mockSettings.tempTBool.value = false;
test.is(mockSettings.tempTBool.value, false, 'tempTBool change');
function tempFBoolCheck(ev) {
test.is(ev.setting, mockSettings.tempFBool, 'tempFBool event setting');
test.is(ev.value, true, 'tempFBool event value');
test.is(ev.setting.value, true, 'tempFBool event setting value');
}
mockSettings.tempFBool.onChange.add(tempFBoolCheck);
mockSettings.tempFBool.value = true;
test.is(mockSettings.tempFBool.value, true, 'tempFBool change');
function tempUStringCheck(ev) {
test.is(ev.setting, mockSettings.tempUString, 'tempUString event setting');
test.is(ev.value, 'x', 'tempUString event value');
test.is(ev.setting.value, 'x', 'tempUString event setting value');
}
mockSettings.tempUString.onChange.add(tempUStringCheck);
mockSettings.tempUString.value = 'x';
test.is(mockSettings.tempUString.value, 'x', 'tempUString change');
function tempNStringCheck(ev) {
test.is(ev.setting, mockSettings.tempNString, 'tempNString event setting');
test.is(ev.value, 'y', 'tempNString event value');
test.is(ev.setting.value, 'y', 'tempNString event setting value');
}
mockSettings.tempNString.onChange.add(tempNStringCheck);
mockSettings.tempNString.value = 'y';
test.is(mockSettings.tempNString.value, 'y', 'tempNString change');
function tempQStringCheck(ev) {
test.is(ev.setting, mockSettings.tempQString, 'tempQString event setting');
test.is(ev.value, 'qq', 'tempQString event value');
test.is(ev.setting.value, 'qq', 'tempQString event setting value');
}
mockSettings.tempQString.onChange.add(tempQStringCheck);
mockSettings.tempQString.value = 'qq';
test.is(mockSettings.tempQString.value, 'qq', 'tempQString change');
function tempNumberCheck(ev) {
test.is(ev.setting, mockSettings.tempNumber, 'tempNumber event setting');
test.is(ev.value, -1, 'tempNumber event value');
test.is(ev.setting.value, -1, 'tempNumber event setting value');
}
mockSettings.tempNumber.onChange.add(tempNumberCheck);
mockSettings.tempNumber.value = -1;
test.is(mockSettings.tempNumber.value, -1, 'tempNumber change');
function tempSelectionCheck(ev) {
test.is(ev.setting, mockSettings.tempSelection, 'tempSelection event setting');
test.is(ev.value, 'b', 'tempSelection event value');
test.is(ev.setting.value, 'b', 'tempSelection event setting value');
}
mockSettings.tempSelection.onChange.add(tempSelectionCheck);
mockSettings.tempSelection.value = 'b';
test.is(mockSettings.tempSelection.value, 'b', 'tempSelection change');
mockSettings.tempTBool.onChange.remove(tempTBoolCheck);
mockSettings.tempFBool.onChange.remove(tempFBoolCheck);
mockSettings.tempUString.onChange.remove(tempUStringCheck);
mockSettings.tempNString.onChange.remove(tempNStringCheck);
mockSettings.tempQString.onChange.remove(tempQStringCheck);
mockSettings.tempNumber.onChange.remove(tempNumberCheck);
mockSettings.tempSelection.onChange.remove(tempSelectionCheck);
function tempNStringReCheck(ev) {
test.is(ev.setting, mockSettings.tempNString, 'tempNString event reset');
test.is(ev.value, null, 'tempNString event revalue');
test.is(ev.setting.value, null, 'tempNString event setting revalue');
}
mockSettings.tempNString.onChange.add(tempNStringReCheck);
mockSettings.tempTBool.setDefault();
mockSettings.tempFBool.setDefault();
mockSettings.tempUString.setDefault();
mockSettings.tempNString.setDefault();
mockSettings.tempQString.setDefault();
mockSettings.tempNumber.setDefault();
mockSettings.tempSelection.setDefault();
mockSettings.tempNString.onChange.remove(tempNStringReCheck);
test.is(mockSettings.tempTBool.value, true, 'tempTBool reset');
test.is(mockSettings.tempFBool.value, false, 'tempFBool reset');
test.is(mockSettings.tempUString.value, undefined, 'tempUString reset');
test.is(mockSettings.tempNString.value, null, 'tempNString reset');
test.is(mockSettings.tempQString.value, 'q', 'tempQString reset');
test.is(mockSettings.tempNumber.value, 42, 'tempNumber reset');
test.is(mockSettings.tempSelection.value, 'a', 'tempSelection reset');
};
});
/*
* Copyright (c) 2009 Panagiotis Astithas
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
define('gclitest/testSpell', ['require', 'exports', 'module' , 'test/assert', 'gcli/types/spell'], function(require, exports, module) {
var test = require('test/assert');
var Speller = require('gcli/types/spell').Speller;
exports.setup = function() {
};
exports.shutdown = function() {
};
exports.testSpellerSimple = function(options) {
if (options.isFirefox) {
test.log('Skipping testPref in Firefox.');
return;
}
var speller = new Speller();
speller.train(Object.keys(options.window));
test.is(speller.correct('document'), 'document');
test.is(speller.correct('documen'), 'document');
test.is(speller.correct('ocument'), 'document');
test.is(speller.correct('odcument'), 'document');
test.is(speller.correct('========='), null);
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testSplit', ['require', 'exports', 'module' , 'test/assert', 'gclitest/mockCommands', 'gcli/cli', 'gcli/canon'], function(require, exports, module) {
var test = require('test/assert');
var mockCommands = require('gclitest/mockCommands');
var Requisition = require('gcli/cli').Requisition;
var canon = require('gcli/canon');
exports.setup = function() {
mockCommands.setup();
};
exports.shutdown = function() {
mockCommands.shutdown();
};
exports.testSplitSimple = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('s');
requ._split(args);
test.is(0, args.length);
test.is('s', requ.commandAssignment.arg.text);
};
exports.testFlatCommand = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('tsv');
requ._split(args);
test.is(0, args.length);
test.is('tsv', requ.commandAssignment.value.name);
args = requ._tokenize('tsv a b');
requ._split(args);
test.is('tsv', requ.commandAssignment.value.name);
test.is(2, args.length);
test.is('a', args[0].text);
test.is('b', args[1].text);
};
exports.testJavascript = function() {
if (!canon.getCommand('{')) {
test.log('Skipping testJavascript because { is not registered');
return;
}
var args;
var requ = new Requisition();
args = requ._tokenize('{');
requ._split(args);
test.is(1, args.length);
test.is('', args[0].text);
test.is('', requ.commandAssignment.arg.text);
test.is('{', requ.commandAssignment.value.name);
};
// BUG 663081 - add tests for sub commands
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testTokenize', ['require', 'exports', 'module' , 'test/assert', 'gcli/cli', 'gcli/argument'], function(require, exports, module) {
var test = require('test/assert');
var Requisition = require('gcli/cli').Requisition;
var Argument = require('gcli/argument').Argument;
var ScriptArgument = require('gcli/argument').ScriptArgument;
exports.testBlanks = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('');
test.is(1, args.length);
test.is('', args[0].text);
test.is('', args[0].prefix);
test.is('', args[0].suffix);
args = requ._tokenize(' ');
test.is(1, args.length);
test.is('', args[0].text);
test.is(' ', args[0].prefix);
test.is('', args[0].suffix);
};
exports.testTokSimple = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('s');
test.is(1, args.length);
test.is('s', args[0].text);
test.is('', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof Argument);
args = requ._tokenize('s s');
test.is(2, args.length);
test.is('s', args[0].text);
test.is('', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof Argument);
test.is('s', args[1].text);
test.is(' ', args[1].prefix);
test.is('', args[1].suffix);
test.ok(args[1] instanceof Argument);
};
exports.testJavascript = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('{x}');
test.is(1, args.length);
test.is('x', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{ x }');
test.is(1, args.length);
test.is('x', args[0].text);
test.is('{ ', args[0].prefix);
test.is(' }', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{x} {y}');
test.is(2, args.length);
test.is('x', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
test.is('y', args[1].text);
test.is(' {', args[1].prefix);
test.is('}', args[1].suffix);
test.ok(args[1] instanceof ScriptArgument);
args = requ._tokenize('{x}{y}');
test.is(2, args.length);
test.is('x', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
test.is('y', args[1].text);
test.is('{', args[1].prefix);
test.is('}', args[1].suffix);
test.ok(args[1] instanceof ScriptArgument);
args = requ._tokenize('{');
test.is(1, args.length);
test.is('', args[0].text);
test.is('{', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{ ');
test.is(1, args.length);
test.is('', args[0].text);
test.is('{ ', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{x');
test.is(1, args.length);
test.is('x', args[0].text);
test.is('{', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
};
exports.testRegularNesting = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('{"x"}');
test.is(1, args.length);
test.is('"x"', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{\'x\'}');
test.is(1, args.length);
test.is('\'x\'', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('"{x}"');
test.is(1, args.length);
test.is('{x}', args[0].text);
test.is('"', args[0].prefix);
test.is('"', args[0].suffix);
test.ok(args[0] instanceof Argument);
args = requ._tokenize('\'{x}\'');
test.is(1, args.length);
test.is('{x}', args[0].text);
test.is('\'', args[0].prefix);
test.is('\'', args[0].suffix);
test.ok(args[0] instanceof Argument);
};
exports.testDeepNesting = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('{{}}');
test.is(1, args.length);
test.is('{}', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{{x} {y}}');
test.is(1, args.length);
test.is('{x} {y}', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
args = requ._tokenize('{{w} {{{x}}}} {y} {{{z}}}');
test.is(3, args.length);
test.is('{w} {{{x}}}', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
test.is('y', args[1].text);
test.is(' {', args[1].prefix);
test.is('}', args[1].suffix);
test.ok(args[1] instanceof ScriptArgument);
test.is('{{z}}', args[2].text);
test.is(' {', args[2].prefix);
test.is('}', args[2].suffix);
test.ok(args[2] instanceof ScriptArgument);
args = requ._tokenize('{{w} {{{x}}} {y} {{{z}}}');
test.is(1, args.length);
test.is('{w} {{{x}}} {y} {{{z}}}', args[0].text);
test.is('{', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
};
exports.testStrangeNesting = function() {
var args;
var requ = new Requisition();
// Note: When we get real JS parsing this should break
args = requ._tokenize('{"x}"}');
test.is(2, args.length);
test.is('"x', args[0].text);
test.is('{', args[0].prefix);
test.is('}', args[0].suffix);
test.ok(args[0] instanceof ScriptArgument);
test.is('}', args[1].text);
test.is('"', args[1].prefix);
test.is('', args[1].suffix);
test.ok(args[1] instanceof Argument);
};
exports.testComplex = function() {
var args;
var requ = new Requisition();
args = requ._tokenize(' 1234 \'12 34\'');
test.is(2, args.length);
test.is('1234', args[0].text);
test.is(' ', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof Argument);
test.is('12 34', args[1].text);
test.is(' \'', args[1].prefix);
test.is('\'', args[1].suffix);
test.ok(args[1] instanceof Argument);
args = requ._tokenize('12\'34 "12 34" \\'); // 12'34 "12 34" \
test.is(3, args.length);
test.is('12\'34', args[0].text);
test.is('', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof Argument);
test.is('12 34', args[1].text);
test.is(' "', args[1].prefix);
test.is('"', args[1].suffix);
test.ok(args[1] instanceof Argument);
test.is('\\', args[2].text);
test.is(' ', args[2].prefix);
test.is('', args[2].suffix);
test.ok(args[2] instanceof Argument);
};
exports.testPathological = function() {
var args;
var requ = new Requisition();
args = requ._tokenize('a\\ b \\t\\n\\r \\\'x\\\" \'d'); // a_b \t\n\r \'x\" 'd
test.is(4, args.length);
test.is('a b', args[0].text);
test.is('', args[0].prefix);
test.is('', args[0].suffix);
test.ok(args[0] instanceof Argument);
test.is('\t\n\r', args[1].text);
test.is(' ', args[1].prefix);
test.is('', args[1].suffix);
test.ok(args[1] instanceof Argument);
test.is('\'x"', args[2].text);
test.is(' ', args[2].prefix);
test.is('', args[2].suffix);
test.ok(args[2] instanceof Argument);
test.is('d', args[3].text);
test.is(' \'', args[3].prefix);
test.is('', args[3].suffix);
test.ok(args[3] instanceof Argument);
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testTooltip', ['require', 'exports', 'module' , 'test/assert', 'gclitest/mockCommands'], function(require, exports, module) {
var test = require('test/assert');
var mockCommands = require('gclitest/mockCommands');
exports.setup = function() {
mockCommands.setup();
};
exports.shutdown = function() {
mockCommands.shutdown();
};
function type(typed, tests, options) {
var inputter = options.display.inputter;
var tooltip = options.display.tooltip;
inputter.setInput(typed);
if (tests.cursor) {
inputter.setCursor({ start: tests.cursor, end: tests.cursor });
}
if (!options.isNode) {
if (tests.important) {
test.ok(tooltip.field.isImportant, 'Important for ' + typed);
}
else {
test.ok(!tooltip.field.isImportant, 'Not important for ' + typed);
}
if (tests.options) {
var names = tooltip.field.menu.items.map(function(item) {
return item.name.textContent ? item.name.textContent : item.name;
});
test.is(tests.options.join('|'), names.join('|'), 'Options for ' + typed);
}
if (tests.error) {
test.is(tests.error, tooltip.errorEle.textContent, 'Error for ' + typed);
}
else {
test.is('', tooltip.errorEle.textContent, 'No error for ' + typed);
}
}
}
exports.testActivate = function(options) {
if (!options.display) {
test.log('No display. Skipping activate tests');
return;
}
if (options.isNode) {
test.log('Running under Node. Reduced checks due to JSDom.textContent');
}
type(' ', { }, options);
type('tsb ', {
important: true,
options: [ 'false', 'true' ]
}, options);
type('tsb t', {
important: true,
options: [ 'true' ]
}, options);
type('tsb tt', {
important: true,
options: [ ],
error: 'Can\'t use \'tt\'.'
}, options);
type('asdf', {
important: false,
options: [ ],
error: 'Can\'t use \'asdf\'.'
}, options);
type('', { }, options);
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testTypes', ['require', 'exports', 'module' , 'test/assert', 'gcli/types'], function(require, exports, module) {
var test = require('test/assert');
var types = require('gcli/types');
exports.setup = function() {
};
exports.shutdown = function() {
};
exports.testDefault = function(options) {
if (options.isNode) {
test.log('Running under Node. ' +
'Skipping tests due to issues with resource type.');
return;
}
types.getTypeNames().forEach(function(name) {
if (name === 'selection') {
name = { name: 'selection', data: [ 'a', 'b' ] };
}
if (name === 'deferred') {
name = {
name: 'deferred',
defer: function() { return types.getType('string'); }
};
}
if (name === 'array') {
name = { name: 'array', subtype: 'string' };
}
var type = types.getType(name);
if (type.name !== 'boolean' && type.name !== 'array') {
test.ok(type.getBlank().value === undefined,
'default defined for ' + type.name);
}
});
};
});
/*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
define('gclitest/testUtil', ['require', 'exports', 'module' , 'gcli/util', 'test/assert'], function(require, exports, module) {
var util = require('gcli/util');
var test = require('test/assert');
exports.testFindCssSelector = function(options) {
if (options.window.isFake) {
test.log('Skipping dom.findCssSelector tests due to window.isFake');
return;
}
var nodes = options.window.document.querySelectorAll('*');
for (var i = 0; i < nodes.length; i++) {
var selector = util.findCssSelector(nodes[i]);
var matches = options.window.document.querySelectorAll(selector);
test.is(matches.length, 1, 'multiple matches for ' + selector);
test.is(matches[0], nodes[i], 'non-matching selector: ' + selector);
}
};
});
let testModuleNames = [
'gclitest/index',
'gclitest/suite',
'test/examiner',
'test/assert',
'gclitest/testCli',
'gclitest/mockCommands',
'gclitest/testCompletion',
'gclitest/testExec',
'gclitest/testHelp',
'gclitest/helpers',
'gclitest/testHistory',
'gclitest/testInputter',
'gclitest/testJs',
'gclitest/testKeyboard',
'gclitest/testPref',
'gcli/commands/pref',
'text!gcli/commands/pref_list_outer.html',
'text!gcli/commands/pref_list.css',
'text!gcli/commands/pref_set_check.html',
'text!gcli/commands/pref_list_inner.html',
'gclitest/mockSettings',
'gclitest/testRequire',
'gclitest/requirable',
'gclitest/testResource',
'gclitest/testScratchpad',
'gclitest/testSettings',
'gclitest/testSpell',
'gclitest/testSplit',
'gclitest/testTokenize',
'gclitest/testTooltip',
'gclitest/testTypes',
'gclitest/testUtil',
];
// Cached so it still exists during cleanup until we need it to
let localDefine;
const TEST_URI = "data:text/html;charset=utf-8,gcli-web";
function test() {
localDefine = define;
DeveloperToolbarTest.test(TEST_URI, function(browser, tab) {
var gclitest = define.globalDomain.require("gclitest/index");
gclitest.run({
display: DeveloperToolbar.display,
isFirefox: true,
window: browser.contentDocument.defaultView
});
finish();
});
}
registerCleanupFunction(function() {
testModuleNames.forEach(function(moduleName) {
delete localDefine.modules[moduleName];
delete localDefine.globalDomain.modules[moduleName];
});
localDefine = undefined;
});