diff options
Diffstat (limited to 'dom/system/gonk/tests')
54 files changed, 0 insertions, 26190 deletions
diff --git a/dom/system/gonk/tests/header_helpers.js b/dom/system/gonk/tests/header_helpers.js deleted file mode 100644 index 8d1144f75..000000000 --- a/dom/system/gonk/tests/header_helpers.js +++ /dev/null @@ -1,217 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - - -var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"] - .getService(Ci.mozIJSSubScriptLoader); - -/** - * Start a new RIL worker. - * - * @param custom_ns - * Namespace with symbols to be injected into the new worker - * namespace. - * - * @return an object that represents the worker's namespace. - * - * @note that this does not start an actual worker thread. The worker - * is executed on the main thread, within a separate namespace object. - */ -function newWorker(custom_ns) { - let worker_ns = { - importScripts: function() { - Array.slice(arguments).forEach(function(script) { - if (!script.startsWith("resource:")) { - script = "resource://gre/modules/" + script; - } - subscriptLoader.loadSubScript(script, this); - }, this); - }, - - postRILMessage: function(message) { - }, - - postMessage: function(message) { - }, - - // Define these variables inside the worker scope so ES5 strict mode - // doesn't flip out. - onmessage: undefined, - onerror: undefined, - - DEBUG: true - }; - // The 'self' variable in a worker points to the worker's own namespace. - worker_ns.self = worker_ns; - - // Copy the custom definitions over. - for (let key in custom_ns) { - worker_ns[key] = custom_ns[key]; - } - - // fake require() for toolkit/components/workerloader/require.js - let require = (function() { - return function require(script) { - worker_ns.module = {}; - worker_ns.importScripts(script); - return worker_ns; - } - })(); - - Object.freeze(require); - Object.defineProperty(worker_ns, "require", { - value: require, - enumerable: true, - configurable: false - }); - - // Load the RIL worker itself. - worker_ns.importScripts("ril_worker.js"); - - // Register at least one client. - worker_ns.ContextPool.registerClient({ clientId: 0 }); - - return worker_ns; -} - -/** - * Create a buffered RIL worker. - * - * @return A worker object that stores sending octets in a internal buffer. - */ -function newUint8Worker() { - let worker = newWorker(); - let index = 0; // index for read - let buf = []; - - let context = worker.ContextPool._contexts[0]; - context.Buf.writeUint8 = function(value) { - buf.push(value); - }; - - context.Buf.readUint8 = function() { - return buf[index++]; - }; - - context.Buf.seekIncoming = function(offset) { - index += offset; - }; - - context.Buf.getReadAvailable = function() { - return buf.length - index; - }; - - worker.debug = do_print; - - return worker; -} - -/** - * Create a worker that keeps posted chrome message. - */ -function newInterceptWorker() { - let postedMessage; - let worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - postedMessage = message; - } - }); - return { - get postedMessage() { - return postedMessage; - }, - get worker() { - return worker; - } - }; -} - -/** - * Create a parcel suitable for postRILMessage(). - * - * @param fakeParcelSize - * Value to be written to parcel size field for testing - * incorrect/incomplete parcel reading. Replaced with correct - * one determined length of data if negative. - * @param response - * Response code of the incoming parcel. - * @param request - * Request code of the incoming parcel. - * @param data - * Extra data to be appended. - * - * @return an Uint8Array carrying all parcel data. - */ -function newIncomingParcel(fakeParcelSize, response, request, data) { - const UINT32_SIZE = 4; - const PARCEL_SIZE_SIZE = 4; - - let realParcelSize = data.length + 2 * UINT32_SIZE; - let buffer = new ArrayBuffer(realParcelSize + PARCEL_SIZE_SIZE); - let bytes = new Uint8Array(buffer); - - let writeIndex = 0; - function writeUint8(value) { - bytes[writeIndex] = value; - ++writeIndex; - } - - function writeInt32(value) { - writeUint8(value & 0xff); - writeUint8((value >> 8) & 0xff); - writeUint8((value >> 16) & 0xff); - writeUint8((value >> 24) & 0xff); - } - - function writeParcelSize(value) { - writeUint8((value >> 24) & 0xff); - writeUint8((value >> 16) & 0xff); - writeUint8((value >> 8) & 0xff); - writeUint8(value & 0xff); - } - - if (fakeParcelSize < 0) { - fakeParcelSize = realParcelSize; - } - writeParcelSize(fakeParcelSize); - - writeInt32(response); - writeInt32(request); - - // write parcel data - for (let ii = 0; ii < data.length; ++ii) { - writeUint8(data[ii]); - } - - return bytes; -} - -/** - * Create a parcel buffer which represents the hex string. - * - * @param hexString - * The HEX string to be converted. - * - * @return an Uint8Array carrying all parcel data. - */ -function hexStringToParcelByteArrayData(hexString) { - let length = Math.ceil((hexString.length / 2)); - let bytes = new Uint8Array(4 + length); - - bytes[0] = length & 0xFF; - bytes[1] = (length >> 8) & 0xFF; - bytes[2] = (length >> 16) & 0xFF; - bytes[3] = (length >> 24) & 0xFF; - - for (let i = 0; i < length; i ++) { - bytes[i + 4] = Number.parseInt(hexString.substr(i * 2, 2), 16); - } - - return bytes; -} diff --git a/dom/system/gonk/tests/marionette/head.js b/dom/system/gonk/tests/marionette/head.js deleted file mode 100644 index 5a6ee1272..000000000 --- a/dom/system/gonk/tests/marionette/head.js +++ /dev/null @@ -1,345 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_CONTEXT = "chrome"; - -const SETTINGS_KEY_DATA_ENABLED = "ril.data.enabled"; -const SETTINGS_KEY_DATA_APN_SETTINGS = "ril.data.apnSettings"; -const SETTINGS_KEY_WIFI_ENABLED = "wifi.enabled"; - -const TOPIC_CONNECTION_STATE_CHANGED = "network-connection-state-changed"; -const TOPIC_NETWORK_ACTIVE_CHANGED = "network-active-changed"; - -const NETWORK_STATE_UNKNOWN = Ci.nsINetworkInfo.NETWORK_STATE_UNKNOWN; -const NETWORK_STATE_CONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTING; -const NETWORK_STATE_CONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED; -const NETWORK_STATE_DISCONNECTING = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTING; -const NETWORK_STATE_DISCONNECTED = Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED; - -const NETWORK_TYPE_MOBILE = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE; -const NETWORK_TYPE_MOBILE_MMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_MMS; -const NETWORK_TYPE_MOBILE_SUPL = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_SUPL; -const NETWORK_TYPE_MOBILE_IMS = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_IMS; -const NETWORK_TYPE_MOBILE_DUN = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_DUN; -const NETWORK_TYPE_MOBILE_FOTA = Ci.nsINetworkInfo.NETWORK_TYPE_MOBILE_FOTA; - -const networkTypes = [ - NETWORK_TYPE_MOBILE, - NETWORK_TYPE_MOBILE_MMS, - NETWORK_TYPE_MOBILE_SUPL, - NETWORK_TYPE_MOBILE_IMS, - NETWORK_TYPE_MOBILE_DUN, - NETWORK_TYPE_MOBILE_FOTA -]; - -var Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise; - -var ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer); -ok(ril, "ril.constructor is " + ril.constructor); - -var radioInterface = ril.getRadioInterface(0); -ok(radioInterface, "radioInterface.constructor is " + radioInterface.constrctor); - -var _pendingEmulatorShellCmdCount = 0; -var _pendingEmulatorCmdCount = 0; - -/** - * Send emulator shell command with safe guard. - * - * We should only call |finish()| after all emulator shell command transactions - * end, so here comes with the pending counter. Resolve when the emulator - * shell gives response. Never reject. - * - * Fulfill params: - * result -- an array of emulator shell response lines. - * - * @param aCommands - * A string array commands to be passed to emulator through adb shell. - * - * @return A deferred promise. - */ -function runEmulatorShellCmdSafe(aCommands) { - return new Promise(function(aResolve, aReject) { - ++_pendingEmulatorShellCmdCount; - runEmulatorShell(aCommands, function(aResult) { - --_pendingEmulatorShellCmdCount; - - log("Emulator shell response: " + JSON.stringify(aResult)); - aResolve(aResult); - }); - }); -} - -/** - * Send emulator command with safe guard. - * - * We should only call |finish()| after all emulator command transactions - * end, so here comes with the pending counter. Resolve when the emulator - * gives positive response, and reject otherwise. - * - * Fulfill params: - * result -- an array of emulator response lines. - * Reject params: - * result -- an array of emulator response lines. - * - * @param aCommand - * A string command to be passed to emulator through its telnet console. - * - * @return A deferred promise. - */ -function runEmulatorCmdSafe(aCommand) { - log(aCommand); - return new Promise(function(aResolve, aReject) { - ++_pendingEmulatorCmdCount; - runEmulatorCmd(aCommand, function(aResult) { - --_pendingEmulatorCmdCount; - - log("Emulator console response: " + JSON.stringify(aResult)); - if (Array.isArray(aResult) && - aResult[aResult.length - 1] === "OK") { - aResolve(aResult); - } else { - aReject(aResult); - } - }); - }); -} - -/** - * Get mozSettings value specified by @aKey. - * - * Resolve if that mozSettings value is retrieved successfully, reject - * otherwise. - * - * Fulfill params: The corresponding mozSettings value of the key. - * Reject params: (none) - * - * @param aKey - * A string. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ -function getSettings(aKey, aAllowError) { - let request = window.navigator.mozSettings.createLock().get(aKey); - return request.then(function resolve(aValue) { - log("getSettings(" + aKey + ") - success"); - return aValue[aKey]; - }, function reject(aError) { - ok(aAllowError, "getSettings(" + aKey + ") - error"); - }); -} - -/** - * Set mozSettings values. - * - * Resolve if that mozSettings value is set successfully, reject otherwise. - * - * Fulfill params: (none) - * Reject params: (none) - * - * @param aKey - * A string key. - * @param aValue - * An object value. - * @param aAllowError [optional] - * A boolean value. If set to true, an error response won't be treated - * as test failure. Default: false. - * - * @return A deferred promise. - */ -function setSettings(aKey, aValue, aAllowError) { - let settings = {}; - settings[aKey] = aValue; - let lock = window.navigator.mozSettings.createLock(); - let request = lock.set(settings); - let deferred = Promise.defer(); - lock.onsettingstransactionsuccess = function () { - log("setSettings(" + JSON.stringify(settings) + ") - success"); - deferred.resolve(); - }; - lock.onsettingstransactionfailure = function () { - ok(aAllowError, "setSettings(" + JSON.stringify(settings) + ") - error"); - // We resolve even though we've thrown an error, since the ok() - // will do that. - deferred.resolve(); - }; - return deferred.promise; -} - -/** - * Wait for observer event. - * - * Resolve if that topic event occurs. Never reject. - * - * Fulfill params: the subject passed. - * - * @param aTopic - * A string topic name. - * - * @return A deferred promise. - */ -function waitForObserverEvent(aTopic) { - let obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); - let deferred = Promise.defer(); - - obs.addObserver(function observer(subject, topic, data) { - if (topic === aTopic) { - obs.removeObserver(observer, aTopic); - deferred.resolve(subject); - } - }, aTopic, false); - - return deferred.promise; -} - -/** - * Wait for one named event. - * - * Resolve if that named event occurs. Never reject. - * - * Fulfill params: the DOMEvent passed. - * - * @param aEventTarget - * An EventTarget object. - * @param aEventName - * A string event name. - * @param aMatchFun [optional] - * A matching function returns true or false to filter the event. - * - * @return A deferred promise. - */ -function waitForTargetEvent(aEventTarget, aEventName, aMatchFun) { - return new Promise(function(aResolve, aReject) { - aEventTarget.addEventListener(aEventName, function onevent(aEvent) { - if (!aMatchFun || aMatchFun(aEvent)) { - aEventTarget.removeEventListener(aEventName, onevent); - ok(true, "Event '" + aEventName + "' got."); - aResolve(aEvent); - } - }); - }); -} - -/** - * Set the default data connection enabling state, wait for - * "network-connection-state-changed" event and verify state. - * - * Fulfill params: instance of nsIRilNetworkInfo of the network connected. - * - * @param aEnabled - * A boolean state. - * - * @return A deferred promise. - */ -function setDataEnabledAndWait(aEnabled) { - let promises = []; - promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED) - .then(function(aSubject) { - ok(aSubject instanceof Ci.nsIRilNetworkInfo, - "subject should be an instance of nsIRilNetworkInfo"); - is(aSubject.type, NETWORK_TYPE_MOBILE, - "subject.type should be " + NETWORK_TYPE_MOBILE); - is(aSubject.state, - aEnabled ? Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED - : Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, - "subject.state should be " + aEnabled ? "CONNECTED" : "DISCONNECTED"); - - return aSubject; - })); - promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aEnabled)); - - return Promise.all(promises).then(aValues => aValues[0]); -} - -/** - * Setup a certain type of data connection, wait for - * "network-connection-state-changed" event and verify state. - * - * Fulfill params: instance of nsIRilNetworkInfo of the network connected. - * - * @param aNetworkType - * The mobile network type to setup. - * - * @return A deferred promise. - */ -function setupDataCallAndWait(aNetworkType) { - log("setupDataCallAndWait: " + aNetworkType); - - let promises = []; - promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED) - .then(function(aSubject) { - ok(aSubject instanceof Ci.nsIRilNetworkInfo, - "subject should be an instance of nsIRilNetworkInfo"); - is(aSubject.type, aNetworkType, - "subject.type should be " + aNetworkType); - is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED, - "subject.state should be CONNECTED"); - - return aSubject; - })); - promises.push(radioInterface.setupDataCallByType(aNetworkType)); - - return Promise.all(promises).then(aValues => aValues[0]); -} - -/** - * Deactivate a certain type of data connection, wait for - * "network-connection-state-changed" event and verify state. - * - * Fulfill params: (none) - * - * @param aNetworkType - * The mobile network type to deactivate. - * - * @return A deferred promise. - */ -function deactivateDataCallAndWait(aNetworkType) { - log("deactivateDataCallAndWait: " + aNetworkType); - - let promises = []; - promises.push(waitForObserverEvent(TOPIC_CONNECTION_STATE_CHANGED) - .then(function(aSubject) { - ok(aSubject instanceof Ci.nsIRilNetworkInfo, - "subject should be an instance of nsIRilNetworkInfo"); - is(aSubject.type, aNetworkType, - "subject.type should be " + aNetworkType); - is(aSubject.state, Ci.nsINetworkInfo.NETWORK_STATE_DISCONNECTED, - "subject.state should be DISCONNECTED"); - })); - promises.push(radioInterface.deactivateDataCallByType(aNetworkType)); - - return Promise.all(promises); -} - -/** - * Wait for pending emulator transactions and call |finish()|. - */ -function cleanUp() { - // Use ok here so that we have at least one test run. - ok(true, ":: CLEANING UP ::"); - - waitFor(finish, function() { - return _pendingEmulatorShellCmdCount === 0 && - _pendingEmulatorCmdCount === 0; - }); -} - -/** - * Basic test routine helper. - * - * This helper does nothing but clean-ups. - * - * @param aTestCaseMain - * A function that takes no parameter. - */ -function startTestBase(aTestCaseMain) { - Promise.resolve() - .then(aTestCaseMain) - .then(cleanUp, function(aException) { - ok(false, "promise rejects during test: " + aException); - cleanUp(); - }); -} diff --git a/dom/system/gonk/tests/marionette/manifest.ini b/dom/system/gonk/tests/marionette/manifest.ini deleted file mode 100644 index 528fe3baf..000000000 --- a/dom/system/gonk/tests/marionette/manifest.ini +++ /dev/null @@ -1,19 +0,0 @@ -[DEFAULT] -run-if = buildapp == 'b2g' - -[test_geolocation.js] -skip-if = true # Bug 808783 -[test_fakevolume.js] -[test_ril_code_quality.py] -[test_screen_state.js] -[test_dsds_numRadioInterfaces.js] -[test_data_connection.js] -[test_network_active_changed.js] -[test_multiple_data_connection.js] -[test_data_connection_proxy.js] -[test_network_interface_list_service.js] -[test_all_network_info.js] -[test_network_interface_mtu.js] -skip-if = android_version < '19' -[test_timezone_changes.js] -skip-if = android_version < '19' diff --git a/dom/system/gonk/tests/marionette/ril_jshint/README.md b/dom/system/gonk/tests/marionette/ril_jshint/README.md deleted file mode 100644 index a63967d63..000000000 --- a/dom/system/gonk/tests/marionette/ril_jshint/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Test RIL Code Quality -===================== - -For more information, please refer to - -* Bug 880643 - B2G RIL: Add a code quality test on try server for RIL javascript code in gecko -* Slide: https://speakerdeck.com/aknow/improve-code-quality-of-ril-code-by-jshint -* Document: https://hackpad.com/Code-Quality-Test-For-RIL-Javascript-Code-In-Gecko-cz5j7YIGiw8 - diff --git a/dom/system/gonk/tests/marionette/ril_jshint/jshint.js b/dom/system/gonk/tests/marionette/ril_jshint/jshint.js deleted file mode 100644 index ec5263a5b..000000000 --- a/dom/system/gonk/tests/marionette/ril_jshint/jshint.js +++ /dev/null @@ -1,11096 +0,0 @@ -//2.1.3 -var JSHINT; -(function () { -var require; -require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({1:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; - - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - if (ev.source === window && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -} - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; - -},{}],2:[function(require,module,exports){ -(function(process){if (!process.EventEmitter) process.EventEmitter = function () {}; - -var EventEmitter = exports.EventEmitter = process.EventEmitter; -var isArray = typeof Array.isArray === 'function' - ? Array.isArray - : function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]' - } -; -function indexOf (xs, x) { - if (xs.indexOf) return xs.indexOf(x); - for (var i = 0; i < xs.length; i++) { - if (x === xs[i]) return i; - } - return -1; -} - -// By default EventEmitters will print a warning if more than -// 10 listeners are added to it. This is a useful default which -// helps finding memory leaks. -// -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -var defaultMaxListeners = 10; -EventEmitter.prototype.setMaxListeners = function(n) { - if (!this._events) this._events = {}; - this._events.maxListeners = n; -}; - - -EventEmitter.prototype.emit = function(type) { - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events || !this._events.error || - (isArray(this._events.error) && !this._events.error.length)) - { - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error("Uncaught, unspecified 'error' event."); - } - return false; - } - } - - if (!this._events) return false; - var handler = this._events[type]; - if (!handler) return false; - - if (typeof handler == 'function') { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - var args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - return true; - - } else if (isArray(handler)) { - var args = Array.prototype.slice.call(arguments, 1); - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { - listeners[i].apply(this, args); - } - return true; - - } else { - return false; - } -}; - -// EventEmitter is defined in src/node_events.cc -// EventEmitter.prototype.emit() is also defined there. -EventEmitter.prototype.addListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('addListener only takes instances of Function'); - } - - if (!this._events) this._events = {}; - - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); - - if (!this._events[type]) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } else if (isArray(this._events[type])) { - - // Check for listener leak - if (!this._events[type].warned) { - var m; - if (this._events.maxListeners !== undefined) { - m = this._events.maxListeners; - } else { - m = defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - - // If we've already got an array, just append. - this._events[type].push(listener); - } else { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - var self = this; - self.on(type, function g() { - self.removeListener(type, g); - listener.apply(this, arguments); - }); - - return this; -}; - -EventEmitter.prototype.removeListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('removeListener only takes instances of Function'); - } - - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events || !this._events[type]) return this; - - var list = this._events[type]; - - if (isArray(list)) { - var i = indexOf(list, listener); - if (i < 0) return this; - list.splice(i, 1); - if (list.length == 0) - delete this._events[type]; - } else if (this._events[type] === listener) { - delete this._events[type]; - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - if (arguments.length === 0) { - this._events = {}; - return this; - } - - // does not use listeners(), so no side effect of creating _events[type] - if (type && this._events && this._events[type]) this._events[type] = null; - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - if (!this._events) this._events = {}; - if (!this._events[type]) this._events[type] = []; - if (!isArray(this._events[type])) { - this._events[type] = [this._events[type]]; - } - return this._events[type]; -}; - -})(require("__browserify_process")) -},{"__browserify_process":1}],3:[function(require,module,exports){ -(function(){// jshint -W001 - -"use strict"; - -// Identifiers provided by the ECMAScript standard. - -exports.reservedVars = { - arguments : false, - NaN : false -}; - -exports.ecmaIdentifiers = { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - "eval" : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - JSON : false, - Math : false, - Map : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - Set : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false, - WeakMap : false -}; - -// Global variables commonly provided by a web browser environment. - -exports.browser = { - ArrayBuffer : false, - ArrayBufferView : false, - Audio : false, - Blob : false, - addEventListener : false, - applicationCache : false, - atob : false, - blur : false, - btoa : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - DataView : false, - DOMParser : false, - defaultStatus : false, - document : false, - Element : false, - ElementTimeControl : false, - event : false, - FileReader : false, - Float32Array : false, - Float64Array : false, - FormData : false, - focus : false, - frames : false, - getComputedStyle : false, - HTMLElement : false, - HTMLAnchorElement : false, - HTMLBaseElement : false, - HTMLBlockquoteElement: false, - HTMLBodyElement : false, - HTMLBRElement : false, - HTMLButtonElement : false, - HTMLCanvasElement : false, - HTMLDirectoryElement : false, - HTMLDivElement : false, - HTMLDListElement : false, - HTMLFieldSetElement : false, - HTMLFontElement : false, - HTMLFormElement : false, - HTMLFrameElement : false, - HTMLFrameSetElement : false, - HTMLHeadElement : false, - HTMLHeadingElement : false, - HTMLHRElement : false, - HTMLHtmlElement : false, - HTMLIFrameElement : false, - HTMLImageElement : false, - HTMLInputElement : false, - HTMLIsIndexElement : false, - HTMLLabelElement : false, - HTMLLayerElement : false, - HTMLLegendElement : false, - HTMLLIElement : false, - HTMLLinkElement : false, - HTMLMapElement : false, - HTMLMenuElement : false, - HTMLMetaElement : false, - HTMLModElement : false, - HTMLObjectElement : false, - HTMLOListElement : false, - HTMLOptGroupElement : false, - HTMLOptionElement : false, - HTMLParagraphElement : false, - HTMLParamElement : false, - HTMLPreElement : false, - HTMLQuoteElement : false, - HTMLScriptElement : false, - HTMLSelectElement : false, - HTMLStyleElement : false, - HTMLTableCaptionElement: false, - HTMLTableCellElement : false, - HTMLTableColElement : false, - HTMLTableElement : false, - HTMLTableRowElement : false, - HTMLTableSectionElement: false, - HTMLTextAreaElement : false, - HTMLTitleElement : false, - HTMLUListElement : false, - HTMLVideoElement : false, - history : false, - Int16Array : false, - Int32Array : false, - Int8Array : false, - Image : false, - length : false, - localStorage : false, - location : false, - MessageChannel : false, - MessageEvent : false, - MessagePort : false, - moveBy : false, - moveTo : false, - MutationObserver : false, - name : false, - Node : false, - NodeFilter : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - openDatabase : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener : false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - sessionStorage : false, - setInterval : false, - setTimeout : false, - SharedWorker : false, - status : false, - SVGAElement : false, - SVGAltGlyphDefElement: false, - SVGAltGlyphElement : false, - SVGAltGlyphItemElement: false, - SVGAngle : false, - SVGAnimateColorElement: false, - SVGAnimateElement : false, - SVGAnimateMotionElement: false, - SVGAnimateTransformElement: false, - SVGAnimatedAngle : false, - SVGAnimatedBoolean : false, - SVGAnimatedEnumeration: false, - SVGAnimatedInteger : false, - SVGAnimatedLength : false, - SVGAnimatedLengthList: false, - SVGAnimatedNumber : false, - SVGAnimatedNumberList: false, - SVGAnimatedPathData : false, - SVGAnimatedPoints : false, - SVGAnimatedPreserveAspectRatio: false, - SVGAnimatedRect : false, - SVGAnimatedString : false, - SVGAnimatedTransformList: false, - SVGAnimationElement : false, - SVGCSSRule : false, - SVGCircleElement : false, - SVGClipPathElement : false, - SVGColor : false, - SVGColorProfileElement: false, - SVGColorProfileRule : false, - SVGComponentTransferFunctionElement: false, - SVGCursorElement : false, - SVGDefsElement : false, - SVGDescElement : false, - SVGDocument : false, - SVGElement : false, - SVGElementInstance : false, - SVGElementInstanceList: false, - SVGEllipseElement : false, - SVGExternalResourcesRequired: false, - SVGFEBlendElement : false, - SVGFEColorMatrixElement: false, - SVGFEComponentTransferElement: false, - SVGFECompositeElement: false, - SVGFEConvolveMatrixElement: false, - SVGFEDiffuseLightingElement: false, - SVGFEDisplacementMapElement: false, - SVGFEDistantLightElement: false, - SVGFEDropShadowElement: false, - SVGFEFloodElement : false, - SVGFEFuncAElement : false, - SVGFEFuncBElement : false, - SVGFEFuncGElement : false, - SVGFEFuncRElement : false, - SVGFEGaussianBlurElement: false, - SVGFEImageElement : false, - SVGFEMergeElement : false, - SVGFEMergeNodeElement: false, - SVGFEMorphologyElement: false, - SVGFEOffsetElement : false, - SVGFEPointLightElement: false, - SVGFESpecularLightingElement: false, - SVGFESpotLightElement: false, - SVGFETileElement : false, - SVGFETurbulenceElement: false, - SVGFilterElement : false, - SVGFilterPrimitiveStandardAttributes: false, - SVGFitToViewBox : false, - SVGFontElement : false, - SVGFontFaceElement : false, - SVGFontFaceFormatElement: false, - SVGFontFaceNameElement: false, - SVGFontFaceSrcElement: false, - SVGFontFaceUriElement: false, - SVGForeignObjectElement: false, - SVGGElement : false, - SVGGlyphElement : false, - SVGGlyphRefElement : false, - SVGGradientElement : false, - SVGHKernElement : false, - SVGICCColor : false, - SVGImageElement : false, - SVGLangSpace : false, - SVGLength : false, - SVGLengthList : false, - SVGLineElement : false, - SVGLinearGradientElement: false, - SVGLocatable : false, - SVGMPathElement : false, - SVGMarkerElement : false, - SVGMaskElement : false, - SVGMatrix : false, - SVGMetadataElement : false, - SVGMissingGlyphElement: false, - SVGNumber : false, - SVGNumberList : false, - SVGPaint : false, - SVGPathElement : false, - SVGPathSeg : false, - SVGPathSegArcAbs : false, - SVGPathSegArcRel : false, - SVGPathSegClosePath : false, - SVGPathSegCurvetoCubicAbs: false, - SVGPathSegCurvetoCubicRel: false, - SVGPathSegCurvetoCubicSmoothAbs: false, - SVGPathSegCurvetoCubicSmoothRel: false, - SVGPathSegCurvetoQuadraticAbs: false, - SVGPathSegCurvetoQuadraticRel: false, - SVGPathSegCurvetoQuadraticSmoothAbs: false, - SVGPathSegCurvetoQuadraticSmoothRel: false, - SVGPathSegLinetoAbs : false, - SVGPathSegLinetoHorizontalAbs: false, - SVGPathSegLinetoHorizontalRel: false, - SVGPathSegLinetoRel : false, - SVGPathSegLinetoVerticalAbs: false, - SVGPathSegLinetoVerticalRel: false, - SVGPathSegList : false, - SVGPathSegMovetoAbs : false, - SVGPathSegMovetoRel : false, - SVGPatternElement : false, - SVGPoint : false, - SVGPointList : false, - SVGPolygonElement : false, - SVGPolylineElement : false, - SVGPreserveAspectRatio: false, - SVGRadialGradientElement: false, - SVGRect : false, - SVGRectElement : false, - SVGRenderingIntent : false, - SVGSVGElement : false, - SVGScriptElement : false, - SVGSetElement : false, - SVGStopElement : false, - SVGStringList : false, - SVGStylable : false, - SVGStyleElement : false, - SVGSwitchElement : false, - SVGSymbolElement : false, - SVGTRefElement : false, - SVGTSpanElement : false, - SVGTests : false, - SVGTextContentElement: false, - SVGTextElement : false, - SVGTextPathElement : false, - SVGTextPositioningElement: false, - SVGTitleElement : false, - SVGTransform : false, - SVGTransformList : false, - SVGTransformable : false, - SVGURIReference : false, - SVGUnitTypes : false, - SVGUseElement : false, - SVGVKernElement : false, - SVGViewElement : false, - SVGViewSpec : false, - SVGZoomAndPan : false, - TimeEvent : false, - top : false, - Uint16Array : false, - Uint32Array : false, - Uint8Array : false, - Uint8ClampedArray : false, - WebSocket : false, - window : false, - Worker : false, - XMLHttpRequest : false, - XMLSerializer : false, - XPathEvaluator : false, - XPathException : false, - XPathExpression : false, - XPathNSResolver : false, - XPathResult : false -}; - -exports.devel = { - alert : false, - confirm: false, - console: false, - Debug : false, - opera : false, - prompt : false -}; - -exports.worker = { - importScripts: true, - postMessage : true, - self : true -}; - -// Widely adopted global names that are not part of ECMAScript standard -exports.nonstandard = { - escape : false, - unescape: false -}; - -// Globals provided by popular JavaScript environments. - -exports.couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false, - provides : false -}; - -exports.node = { - __filename : false, - __dirname : false, - Buffer : false, - DataView : false, - console : false, - exports : true, // In Node it is ok to exports = module.exports = foo(); - GLOBAL : false, - global : false, - module : false, - process : false, - require : false, - setTimeout : false, - clearTimeout : false, - setInterval : false, - clearInterval : false, - setImmediate : false, // v0.9.1+ - clearImmediate: false // v0.9.1+ -}; - -exports.phantom = { - phantom : true, - require : true, - WebPage : true -}; - -exports.rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - importPackage: false, - "java" : false, - load : false, - loadClass : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false -}; - -exports.wsh = { - ActiveXObject : true, - Enumerator : true, - GetObject : true, - ScriptEngine : true, - ScriptEngineBuildVersion : true, - ScriptEngineMajorVersion : true, - ScriptEngineMinorVersion : true, - VBArray : true, - WSH : true, - WScript : true, - XDomainRequest : true -}; - -// Globals provided by popular JavaScript libraries. - -exports.dojo = { - dojo : false, - dijit : false, - dojox : false, - define : false, - "require": false -}; - -exports.jquery = { - "$" : false, - jQuery : false -}; - -exports.mootools = { - "$" : false, - "$$" : false, - Asset : false, - Browser : false, - Chain : false, - Class : false, - Color : false, - Cookie : false, - Core : false, - Document : false, - DomReady : false, - DOMEvent : false, - DOMReady : false, - Drag : false, - Element : false, - Elements : false, - Event : false, - Events : false, - Fx : false, - Group : false, - Hash : false, - HtmlTable : false, - Iframe : false, - IframeShim : false, - InputValidator: false, - instanceOf : false, - Keyboard : false, - Locale : false, - Mask : false, - MooTools : false, - Native : false, - Options : false, - OverText : false, - Request : false, - Scroller : false, - Slick : false, - Slider : false, - Sortables : false, - Spinner : false, - Swiff : false, - Tips : false, - Type : false, - typeOf : false, - URI : false, - Window : false -}; - -exports.prototypejs = { - "$" : false, - "$$" : false, - "$A" : false, - "$F" : false, - "$H" : false, - "$R" : false, - "$break" : false, - "$continue" : false, - "$w" : false, - Abstract : false, - Ajax : false, - Class : false, - Enumerable : false, - Element : false, - Event : false, - Field : false, - Form : false, - Hash : false, - Insertion : false, - ObjectRange : false, - PeriodicalExecuter: false, - Position : false, - Prototype : false, - Selector : false, - Template : false, - Toggle : false, - Try : false, - Autocompleter : false, - Builder : false, - Control : false, - Draggable : false, - Draggables : false, - Droppables : false, - Effect : false, - Sortable : false, - SortableObserver : false, - Sound : false, - Scriptaculous : false -}; - -exports.yui = { - YUI : false, - Y : false, - YUI_config: false -}; - - -})() -},{}],4:[function(require,module,exports){ -"use strict"; - -var state = { - syntax: {}, - - reset: function () { - this.tokens = { - prev: null, - next: null, - curr: null - }; - - this.option = {}; - this.ignored = {}; - this.directive = {}; - this.jsonMode = false; - this.jsonWarnings = []; - this.lines = []; - this.tab = ""; - this.cache = {}; // Node.JS doesn't have Map. Sniff. - } -}; - -exports.state = state; - -},{}],5:[function(require,module,exports){ -(function(){"use strict"; - -exports.register = function (linter) { - // Check for properties named __proto__. This special property was - // deprecated and then re-introduced for ES6. - - linter.on("Identifier", function style_scanProto(data) { - if (linter.getOption("proto")) { - return; - } - - if (data.name === "__proto__") { - linter.warn("W103", { - line: data.line, - char: data.char, - data: [ data.name ] - }); - } - }); - - // Check for properties named __iterator__. This is a special property - // available only in browsers with JavaScript 1.7 implementation. - - linter.on("Identifier", function style_scanIterator(data) { - if (linter.getOption("iterator")) { - return; - } - - if (data.name === "__iterator__") { - linter.warn("W104", { - line: data.line, - char: data.char, - data: [ data.name ] - }); - } - }); - - // Check for dangling underscores. - - linter.on("Identifier", function style_scanDangling(data) { - if (!linter.getOption("nomen")) { - return; - } - - // Underscore.js - if (data.name === "_") { - return; - } - - // In Node, __dirname and __filename should be ignored. - if (linter.getOption("node")) { - if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) { - return; - } - } - - if (/^(_+.*|.*_+)$/.test(data.name)) { - linter.warn("W105", { - line: data.line, - char: data.from, - data: [ "dangling '_'", data.name ] - }); - } - }); - - // Check that all identifiers are using camelCase notation. - // Exceptions: names like MY_VAR and _myVar. - - linter.on("Identifier", function style_scanCamelCase(data) { - if (!linter.getOption("camelcase")) { - return; - } - - if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) { - linter.warn("W106", { - line: data.line, - char: data.from, - data: [ data.name ] - }); - } - }); - - // Enforce consistency in style of quoting. - - linter.on("String", function style_scanQuotes(data) { - var quotmark = linter.getOption("quotmark"); - var code; - - if (!quotmark) { - return; - } - - // If quotmark is set to 'single' warn about all double-quotes. - - if (quotmark === "single" && data.quote !== "'") { - code = "W109"; - } - - // If quotmark is set to 'double' warn about all single-quotes. - - if (quotmark === "double" && data.quote !== "\"") { - code = "W108"; - } - - // If quotmark is set to true, remember the first quotation style - // and then warn about all others. - - if (quotmark === true) { - if (!linter.getCache("quotmark")) { - linter.setCache("quotmark", data.quote); - } - - if (linter.getCache("quotmark") !== data.quote) { - code = "W110"; - } - } - - if (code) { - linter.warn(code, { - line: data.line, - char: data.char, - }); - } - }); - - linter.on("Number", function style_scanNumbers(data) { - if (data.value.charAt(0) === ".") { - // Warn about a leading decimal point. - linter.warn("W008", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } - - if (data.value.substr(data.value.length - 1) === ".") { - // Warn about a trailing decimal point. - linter.warn("W047", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } - - if (/^00+/.test(data.value)) { - // Multiple leading zeroes. - linter.warn("W046", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } - }); - - // Warn about script URLs. - - linter.on("String", function style_scanJavaScriptURLs(data) { - var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - - if (linter.getOption("scripturl")) { - return; - } - - if (re.test(data.value)) { - linter.warn("W107", { - line: data.line, - char: data.char - }); - } - }); -}; -})() -},{}],6:[function(require,module,exports){ -/* - * Regular expressions. Some of these are stupidly long. - */ - -/*jshint maxlen:1000 */ - -"use string"; - -// Unsafe comment or string (ax) -exports.unsafeString = - /@cc|<\/?|script|\]\s*\]|<\s*!|</i; - -// Unsafe characters that are silently deleted by one or more browsers (cx) -exports.unsafeChars = - /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - -// Characters in strings that need escaping (nx and nxg) -exports.needEsc = - /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; - -exports.needEscGlobal = - /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - -// Star slash (lx) -exports.starSlash = /\*\//; - -// Identifier (ix) -exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/; - -// JavaScript URL (jx) -exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - -// Catches /* falls through */ comments (ft) -//exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/; -exports.fallsThrough = /^\s*\/\/\s*Falls?\sthrough.*\s*$/; - -},{}],7:[function(require,module,exports){ -(function(global){/*global window, global*/ -var util = require("util") -var assert = require("assert") - -var slice = Array.prototype.slice -var console -var times = {} - -if (typeof global !== "undefined" && global.console) { - console = global.console -} else if (typeof window !== "undefined" && window.console) { - console = window.console -} else { - console = window.console = {} -} - -var functions = [ - [log, "log"] - , [info, "info"] - , [warn, "warn"] - , [error, "error"] - , [time, "time"] - , [timeEnd, "timeEnd"] - , [trace, "trace"] - , [dir, "dir"] - , [assert, "assert"] -] - -for (var i = 0; i < functions.length; i++) { - var tuple = functions[i] - var f = tuple[0] - var name = tuple[1] - - if (!console[name]) { - console[name] = f - } -} - -module.exports = console - -function log() {} - -function info() { - console.log.apply(console, arguments) -} - -function warn() { - console.log.apply(console, arguments) -} - -function error() { - console.warn.apply(console, arguments) -} - -function time(label) { - times[label] = Date.now() -} - -function timeEnd(label) { - var time = times[label] - if (!time) { - throw new Error("No such label: " + label) - } - - var duration = Date.now() - time - console.log(label + ": " + duration + "ms") -} - -function trace() { - var err = new Error() - err.name = "Trace" - err.message = util.format.apply(null, arguments) - console.error(err.stack) -} - -function dir(object) { - console.log(util.inspect(object) + "\n") -} - -function assert(expression) { - if (!expression) { - var arr = slice.call(arguments, 1) - assert.ok(false, util.format.apply(null, arr)) - } -} - -})(window) -},{"util":8,"assert":9}],10:[function(require,module,exports){ -(function(){/* - * Lexical analysis and token construction. - */ - -"use strict"; - -var _ = require("underscore"); -var events = require("events"); -var reg = require("./reg.js"); -var state = require("./state.js").state; - -// Some of these token types are from JavaScript Parser API -// while others are specific to JSHint parser. -// JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API - -var Token = { - Identifier: 1, - Punctuator: 2, - NumericLiteral: 3, - StringLiteral: 4, - Comment: 5, - Keyword: 6, - NullLiteral: 7, - BooleanLiteral: 8, - RegExp: 9 -}; - -// This is auto generated from the unicode tables. -// The tables are at: -// http://www.fileformat.info/info/unicode/category/Lu/list.htm -// http://www.fileformat.info/info/unicode/category/Ll/list.htm -// http://www.fileformat.info/info/unicode/category/Lt/list.htm -// http://www.fileformat.info/info/unicode/category/Lm/list.htm -// http://www.fileformat.info/info/unicode/category/Lo/list.htm -// http://www.fileformat.info/info/unicode/category/Nl/list.htm - -var unicodeLetterTable = [ - 170, 170, 181, 181, 186, 186, 192, 214, - 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, - 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, - 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, - 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, - 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, - 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, - 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, - 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361, - 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, - 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, - 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, - 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, - 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, - 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, - 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, - 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, - 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, - 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, - 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, - 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, - 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, - 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, - 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, - 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, - 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, - 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, - 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, - 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, - 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, - 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, - 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, - 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346, - 4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696, - 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, - 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, - 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, - 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, - 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, - 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, - 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, - 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, - 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141, - 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, - 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, - 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, - 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, - 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, - 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, - 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, - 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, - 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, - 11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621, - 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, - 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, - 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, - 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, - 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, - 12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312, - 19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124, - 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, - 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, - 42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921, - 43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042, - 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, - 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, - 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, - 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, - 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, - 43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798, - 43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032, - 55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045, - 64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279, - 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, - 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, - 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, - 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, - 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, - 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, - 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, - 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334, - 66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511, - 66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592, - 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, - 67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115, - 68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405, - 68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687, - 69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894, - 92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964, - 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, - 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, - 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, - 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, - 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, - 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, - 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, - 131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972, - 177984, 177984, 178205, 178205, 194560, 195101 -]; - -var identifierStartTable = []; - -for (var i = 0; i < 128; i++) { - identifierStartTable[i] = - i === 36 || // $ - i >= 65 && i <= 90 || // A-Z - i === 95 || // _ - i >= 97 && i <= 122; // a-z -} - -var identifierPartTable = []; - -for (var i = 0; i < 128; i++) { - identifierPartTable[i] = - identifierStartTable[i] || // $, _, A-Z, a-z - i >= 48 && i <= 57; // 0-9 -} - -// Object that handles postponed lexing verifications that checks the parsed -// environment state. - -function asyncTrigger() { - var _checks = []; - - return { - push: function (fn) { - _checks.push(fn); - }, - - check: function () { - for (var check in _checks) { - _checks[check](); - } - - _checks.splice(0, _checks.length); - } - }; -} - -/* - * Lexer for JSHint. - * - * This object does a char-by-char scan of the provided source code - * and produces a sequence of tokens. - * - * var lex = new Lexer("var i = 0;"); - * lex.start(); - * lex.token(); // returns the next token - * - * You have to use the token() method to move the lexer forward - * but you don't have to use its return value to get tokens. In addition - * to token() method returning the next token, the Lexer object also - * emits events. - * - * lex.on("Identifier", function (data) { - * if (data.name.indexOf("_") >= 0) { - * // Produce a warning. - * } - * }); - * - * Note that the token() method returns tokens in a JSLint-compatible - * format while the event emitter uses a slightly modified version of - * Mozilla's JavaScript Parser API. Eventually, we will move away from - * JSLint format. - */ -function Lexer(source) { - var lines = source; - - if (typeof lines === "string") { - lines = lines - .replace(/\r\n/g, "\n") - .replace(/\r/g, "\n") - .split("\n"); - } - - // If the first line is a shebang (#!), make it a blank and move on. - // Shebangs are used by Node scripts. - - if (lines[0] && lines[0].substr(0, 2) === "#!") { - lines[0] = ""; - } - - this.emitter = new events.EventEmitter(); - this.source = source; - this.lines = lines; - this.prereg = true; - - this.line = 0; - this.char = 1; - this.from = 1; - this.input = ""; - - for (var i = 0; i < state.option.indent; i += 1) { - state.tab += " "; - } -} - -Lexer.prototype = { - _lines: [], - - get lines() { - this._lines = state.lines; - return this._lines; - }, - - set lines(val) { - this._lines = val; - state.lines = this._lines; - }, - - /* - * Return the next i character without actually moving the - * char pointer. - */ - peek: function (i) { - return this.input.charAt(i || 0); - }, - - /* - * Move the char pointer forward i times. - */ - skip: function (i) { - i = i || 1; - this.char += i; - this.input = this.input.slice(i); - }, - - /* - * Subscribe to a token event. The API for this method is similar - * Underscore.js i.e. you can subscribe to multiple events with - * one call: - * - * lex.on("Identifier Number", function (data) { - * // ... - * }); - */ - on: function (names, listener) { - names.split(" ").forEach(function (name) { - this.emitter.on(name, listener); - }.bind(this)); - }, - - /* - * Trigger a token event. All arguments will be passed to each - * listener. - */ - trigger: function () { - this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments)); - }, - - /* - * Postpone a token event. the checking condition is set as - * last parameter, and the trigger function is called in a - * stored callback. To be later called using the check() function - * by the parser. This avoids parser's peek() to give the lexer - * a false context. - */ - triggerAsync: function (type, args, checks, fn) { - checks.push(function () { - if (fn()) { - this.trigger(type, args); - } - }.bind(this)); - }, - - /* - * Extract a punctuator out of the next sequence of characters - * or return 'null' if its not possible. - * - * This method's implementation was heavily influenced by the - * scanPunctuator function in the Esprima parser's source code. - */ - scanPunctuator: function () { - var ch1 = this.peek(); - var ch2, ch3, ch4; - - switch (ch1) { - // Most common single-character punctuators - case ".": - if ((/^[0-9]$/).test(this.peek(1))) { - return null; - } - if (this.peek(1) === "." && this.peek(2) === ".") { - return { - type: Token.Punctuator, - value: "..." - }; - } - /* falls through */ - case "(": - case ")": - case ";": - case ",": - case "{": - case "}": - case "[": - case "]": - case ":": - case "~": - case "?": - return { - type: Token.Punctuator, - value: ch1 - }; - - // A pound sign (for Node shebangs) - case "#": - return { - type: Token.Punctuator, - value: ch1 - }; - - // We're at the end of input - case "": - return null; - } - - // Peek more characters - - ch2 = this.peek(1); - ch3 = this.peek(2); - ch4 = this.peek(3); - - // 4-character punctuator: >>>= - - if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") { - return { - type: Token.Punctuator, - value: ">>>=" - }; - } - - // 3-character punctuators: === !== >>> <<= >>= - - if (ch1 === "=" && ch2 === "=" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "===" - }; - } - - if (ch1 === "!" && ch2 === "=" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "!==" - }; - } - - if (ch1 === ">" && ch2 === ">" && ch3 === ">") { - return { - type: Token.Punctuator, - value: ">>>" - }; - } - - if (ch1 === "<" && ch2 === "<" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "<<=" - }; - } - - if (ch1 === ">" && ch2 === ">" && ch3 === "=") { - return { - type: Token.Punctuator, - value: ">>=" - }; - } - - // Fat arrow punctuator - if (ch1 === "=" && ch2 === ">") { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } - - // 2-character punctuators: <= >= == != ++ -- << >> && || - // += -= *= %= &= |= ^= (but not /=, see below) - if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } - - if ("<>=!+-*%&|^".indexOf(ch1) >= 0) { - if (ch2 === "=") { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } - - return { - type: Token.Punctuator, - value: ch1 - }; - } - - // Special case: /=. We need to make sure that this is an - // operator and not a regular expression. - - if (ch1 === "/") { - if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) { - // /= is not a part of a regular expression, return it as a - // punctuator. - return { - type: Token.Punctuator, - value: "/=" - }; - } - - return { - type: Token.Punctuator, - value: "/" - }; - } - - return null; - }, - - /* - * Extract a comment out of the next sequence of characters and/or - * lines or return 'null' if its not possible. Since comments can - * span across multiple lines this method has to move the char - * pointer. - * - * In addition to normal JavaScript comments (// and /*) this method - * also recognizes JSHint- and JSLint-specific comments such as - * /*jshint, /*jslint, /*globals and so on. - */ - scanComments: function () { - var ch1 = this.peek(); - var ch2 = this.peek(1); - var rest = this.input.substr(2); - var startLine = this.line; - var startChar = this.char; - - // Create a comment token object and make sure it - // has all the data JSHint needs to work with special - // comments. - - function commentToken(label, body, opt) { - var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"]; - var isSpecial = false; - var value = label + body; - var commentType = "plain"; - opt = opt || {}; - - if (opt.isMultiline) { - value += "*/"; - } - - special.forEach(function (str) { - if (isSpecial) { - return; - } - - // Don't recognize any special comments other than jshint for single-line - // comments. This introduced many problems with legit comments. - if (label === "//" && str !== "jshint") { - return; - } - - if (body.substr(0, str.length) === str) { - isSpecial = true; - label = label + str; - body = body.substr(str.length); - } - - if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) { - isSpecial = true; - label = label + " " + str; - body = body.substr(str.length + 1); - } - - if (!isSpecial) { - return; - } - - switch (str) { - case "member": - commentType = "members"; - break; - case "global": - commentType = "globals"; - break; - default: - commentType = str; - } - }); - - return { - type: Token.Comment, - commentType: commentType, - value: value, - body: body, - isSpecial: isSpecial, - isMultiline: opt.isMultiline || false, - isMalformed: opt.isMalformed || false - }; - } - - // End of unbegun comment. Raise an error and skip that input. - if (ch1 === "*" && ch2 === "/") { - this.trigger("error", { - code: "E018", - line: startLine, - character: startChar - }); - - this.skip(2); - return null; - } - - // Comments must start either with // or /* - if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) { - return null; - } - - // One-line comment - if (ch2 === "/") { - this.skip(this.input.length); // Skip to the EOL. - return commentToken("//", rest); - } - - var body = ""; - - /* Multi-line comment */ - if (ch2 === "*") { - this.skip(2); - - while (this.peek() !== "*" || this.peek(1) !== "/") { - if (this.peek() === "") { // End of Line - body += "\n"; - - // If we hit EOF and our comment is still unclosed, - // trigger an error and end the comment implicitly. - if (!this.nextLine()) { - this.trigger("error", { - code: "E017", - line: startLine, - character: startChar - }); - - return commentToken("/*", body, { - isMultiline: true, - isMalformed: true - }); - } - } else { - body += this.peek(); - this.skip(); - } - } - - this.skip(2); - return commentToken("/*", body, { isMultiline: true }); - } - }, - - /* - * Extract a keyword out of the next sequence of characters or - * return 'null' if its not possible. - */ - scanKeyword: function () { - var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input); - var keywords = [ - "if", "in", "do", "var", "for", "new", - "try", "let", "this", "else", "case", - "void", "with", "enum", "while", "break", - "catch", "throw", "const", "yield", "class", - "super", "return", "typeof", "delete", - "switch", "export", "import", "default", - "finally", "extends", "function", "continue", - "debugger", "instanceof" - ]; - - if (result && keywords.indexOf(result[0]) >= 0) { - return { - type: Token.Keyword, - value: result[0] - }; - } - - return null; - }, - - /* - * Extract a JavaScript identifier out of the next sequence of - * characters or return 'null' if its not possible. In addition, - * to Identifier this method can also produce BooleanLiteral - * (true/false) and NullLiteral (null). - */ - scanIdentifier: function () { - var id = ""; - var index = 0; - var type, char; - - // Detects any character in the Unicode categories "Uppercase - // letter (Lu)", "Lowercase letter (Ll)", "Titlecase letter - // (Lt)", "Modifier letter (Lm)", "Other letter (Lo)", or - // "Letter number (Nl)". - // - // Both approach and unicodeLetterTable were borrowed from - // Google's Traceur. - - function isUnicodeLetter(code) { - for (var i = 0; i < unicodeLetterTable.length;) { - if (code < unicodeLetterTable[i++]) { - return false; - } - - if (code <= unicodeLetterTable[i++]) { - return true; - } - } - - return false; - } - - function isHexDigit(str) { - return (/^[0-9a-fA-F]$/).test(str); - } - - var readUnicodeEscapeSequence = function () { - /*jshint validthis:true */ - index += 1; - - if (this.peek(index) !== "u") { - return null; - } - - var ch1 = this.peek(index + 1); - var ch2 = this.peek(index + 2); - var ch3 = this.peek(index + 3); - var ch4 = this.peek(index + 4); - var code; - - if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) { - code = parseInt(ch1 + ch2 + ch3 + ch4, 16); - - if (isUnicodeLetter(code)) { - index += 5; - return "\\u" + ch1 + ch2 + ch3 + ch4; - } - - return null; - } - - return null; - }.bind(this); - - var getIdentifierStart = function () { - /*jshint validthis:true */ - var chr = this.peek(index); - var code = chr.charCodeAt(0); - - if (code === 92) { - return readUnicodeEscapeSequence(); - } - - if (code < 128) { - if (identifierStartTable[code]) { - index += 1; - return chr; - } - - return null; - } - - if (isUnicodeLetter(code)) { - index += 1; - return chr; - } - - return null; - }.bind(this); - - var getIdentifierPart = function () { - /*jshint validthis:true */ - var chr = this.peek(index); - var code = chr.charCodeAt(0); - - if (code === 92) { - return readUnicodeEscapeSequence(); - } - - if (code < 128) { - if (identifierPartTable[code]) { - index += 1; - return chr; - } - - return null; - } - - if (isUnicodeLetter(code)) { - index += 1; - return chr; - } - - return null; - }.bind(this); - - char = getIdentifierStart(); - if (char === null) { - return null; - } - - id = char; - for (;;) { - char = getIdentifierPart(); - - if (char === null) { - break; - } - - id += char; - } - - switch (id) { - case "true": - case "false": - type = Token.BooleanLiteral; - break; - case "null": - type = Token.NullLiteral; - break; - default: - type = Token.Identifier; - } - - return { - type: type, - value: id - }; - }, - - /* - * Extract a numeric literal out of the next sequence of - * characters or return 'null' if its not possible. This method - * supports all numeric literals described in section 7.8.3 - * of the EcmaScript 5 specification. - * - * This method's implementation was heavily influenced by the - * scanNumericLiteral function in the Esprima parser's source code. - */ - scanNumericLiteral: function () { - var index = 0; - var value = ""; - var length = this.input.length; - var char = this.peek(index); - var bad; - - function isDecimalDigit(str) { - return (/^[0-9]$/).test(str); - } - - function isOctalDigit(str) { - return (/^[0-7]$/).test(str); - } - - function isHexDigit(str) { - return (/^[0-9a-fA-F]$/).test(str); - } - - function isIdentifierStart(ch) { - return (ch === "$") || (ch === "_") || (ch === "\\") || - (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z"); - } - - // Numbers must start either with a decimal digit or a point. - - if (char !== "." && !isDecimalDigit(char)) { - return null; - } - - if (char !== ".") { - value = this.peek(index); - index += 1; - char = this.peek(index); - - if (value === "0") { - // Base-16 numbers. - if (char === "x" || char === "X") { - index += 1; - value += char; - - while (index < length) { - char = this.peek(index); - if (!isHexDigit(char)) { - break; - } - value += char; - index += 1; - } - - if (value.length <= 2) { // 0x - return { - type: Token.NumericLiteral, - value: value, - isMalformed: true - }; - } - - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } - - return { - type: Token.NumericLiteral, - value: value, - base: 16, - isMalformed: false - }; - } - - // Base-8 numbers. - if (isOctalDigit(char)) { - index += 1; - value += char; - bad = false; - - while (index < length) { - char = this.peek(index); - - // Numbers like '019' (note the 9) are not valid octals - // but we still parse them and mark as malformed. - - if (isDecimalDigit(char)) { - bad = true; - } else if (!isOctalDigit(char)) { - break; - } - value += char; - index += 1; - } - - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } - - return { - type: Token.NumericLiteral, - value: value, - base: 8, - isMalformed: false - }; - } - - // Decimal numbers that start with '0' such as '09' are illegal - // but we still parse them and return as malformed. - - if (isDecimalDigit(char)) { - index += 1; - value += char; - } - } - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; - } - value += char; - index += 1; - } - } - - // Decimal digits. - - if (char === ".") { - value += char; - index += 1; - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; - } - value += char; - index += 1; - } - } - - // Exponent part. - - if (char === "e" || char === "E") { - value += char; - index += 1; - char = this.peek(index); - - if (char === "+" || char === "-") { - value += this.peek(index); - index += 1; - } - - char = this.peek(index); - if (isDecimalDigit(char)) { - value += char; - index += 1; - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; - } - value += char; - index += 1; - } - } else { - return null; - } - } - - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } - - return { - type: Token.NumericLiteral, - value: value, - base: 10, - isMalformed: !isFinite(value) - }; - }, - - /* - * Extract a string out of the next sequence of characters and/or - * lines or return 'null' if its not possible. Since strings can - * span across multiple lines this method has to move the char - * pointer. - * - * This method recognizes pseudo-multiline JavaScript strings: - * - * var str = "hello\ - * world"; - */ - scanStringLiteral: function (checks) { - /*jshint loopfunc:true */ - var quote = this.peek(); - - // String must start with a quote. - if (quote !== "\"" && quote !== "'") { - return null; - } - - // In JSON strings must always use double quotes. - this.triggerAsync("warning", { - code: "W108", - line: this.line, - character: this.char // +1? - }, checks, function () { return state.jsonMode && quote !== "\""; }); - - var value = ""; - var startLine = this.line; - var startChar = this.char; - var allowNewLine = false; - - this.skip(); - - while (this.peek() !== quote) { - while (this.peek() === "") { // End Of Line - - // If an EOL is not preceded by a backslash, show a warning - // and proceed like it was a legit multi-line string where - // author simply forgot to escape the newline symbol. - // - // Another approach is to implicitly close a string on EOL - // but it generates too many false positives. - - if (!allowNewLine) { - this.trigger("warning", { - code: "W112", - line: this.line, - character: this.char - }); - } else { - allowNewLine = false; - - // Otherwise show a warning if multistr option was not set. - // For JSON, show warning no matter what. - - this.triggerAsync("warning", { - code: "W043", - line: this.line, - character: this.char - }, checks, function () { return !state.option.multistr; }); - - this.triggerAsync("warning", { - code: "W042", - line: this.line, - character: this.char - }, checks, function () { return state.jsonMode && state.option.multistr; }); - } - - // If we get an EOF inside of an unclosed string, show an - // error and implicitly close it at the EOF point. - - if (!this.nextLine()) { - this.trigger("error", { - code: "E029", - line: startLine, - character: startChar - }); - - return { - type: Token.StringLiteral, - value: value, - isUnclosed: true, - quote: quote - }; - } - } - - allowNewLine = false; - var char = this.peek(); - var jump = 1; // A length of a jump, after we're done - // parsing this character. - - if (char < " ") { - // Warn about a control character in a string. - this.trigger("warning", { - code: "W113", - line: this.line, - character: this.char, - data: [ "<non-printable>" ] - }); - } - - // Special treatment for some escaped characters. - - if (char === "\\") { - this.skip(); - char = this.peek(); - - switch (char) { - case "'": - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\'" ] - }, checks, function () {return state.jsonMode; }); - break; - case "b": - char = "\b"; - break; - case "f": - char = "\f"; - break; - case "n": - char = "\n"; - break; - case "r": - char = "\r"; - break; - case "t": - char = "\t"; - break; - case "0": - char = "\0"; - - // Octal literals fail in strict mode. - // Check if the number is between 00 and 07. - var n = parseInt(this.peek(1), 10); - this.triggerAsync("warning", { - code: "W115", - line: this.line, - character: this.char - }, checks, - function () { return n >= 0 && n <= 7 && state.directive["use strict"]; }); - break; - case "u": - char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16)); - jump = 5; - break; - case "v": - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\v" ] - }, checks, function () { return state.jsonMode; }); - - char = "\v"; - break; - case "x": - var x = parseInt(this.input.substr(1, 2), 16); - - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\x-" ] - }, checks, function () { return state.jsonMode; }); - - char = String.fromCharCode(x); - jump = 3; - break; - case "\\": - case "\"": - case "/": - break; - case "": - allowNewLine = true; - char = ""; - break; - case "!": - if (value.slice(value.length - 2) === "<") { - break; - } - - /*falls through */ - default: - // Weird escaping. - this.trigger("warning", { - code: "W044", - line: this.line, - character: this.char - }); - } - } - - value += char; - this.skip(jump); - } - - this.skip(); - return { - type: Token.StringLiteral, - value: value, - isUnclosed: false, - quote: quote - }; - }, - - /* - * Extract a regular expression out of the next sequence of - * characters and/or lines or return 'null' if its not possible. - * - * This method is platform dependent: it accepts almost any - * regular expression values but then tries to compile and run - * them using system's RegExp object. This means that there are - * rare edge cases where one JavaScript engine complains about - * your regular expression while others don't. - */ - scanRegExp: function () { - var index = 0; - var length = this.input.length; - var char = this.peek(); - var value = char; - var body = ""; - var flags = []; - var malformed = false; - var isCharSet = false; - var terminated; - - var scanUnexpectedChars = function () { - // Unexpected control character - if (char < " ") { - malformed = true; - this.trigger("warning", { - code: "W048", - line: this.line, - character: this.char - }); - } - - // Unexpected escaped character - if (char === "<") { - malformed = true; - this.trigger("warning", { - code: "W049", - line: this.line, - character: this.char, - data: [ char ] - }); - } - }.bind(this); - - // Regular expressions must start with '/' - if (!this.prereg || char !== "/") { - return null; - } - - index += 1; - terminated = false; - - // Try to get everything in between slashes. A couple of - // cases aside (see scanUnexpectedChars) we don't really - // care whether the resulting expression is valid or not. - // We will check that later using the RegExp object. - - while (index < length) { - char = this.peek(index); - value += char; - body += char; - - if (isCharSet) { - if (char === "]") { - if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") { - isCharSet = false; - } - } - - if (char === "\\") { - index += 1; - char = this.peek(index); - body += char; - value += char; - - scanUnexpectedChars(); - } - - index += 1; - continue; - } - - if (char === "\\") { - index += 1; - char = this.peek(index); - body += char; - value += char; - - scanUnexpectedChars(); - - if (char === "/") { - index += 1; - continue; - } - - if (char === "[") { - index += 1; - continue; - } - } - - if (char === "[") { - isCharSet = true; - index += 1; - continue; - } - - if (char === "/") { - body = body.substr(0, body.length - 1); - terminated = true; - index += 1; - break; - } - - index += 1; - } - - // A regular expression that was never closed is an - // error from which we cannot recover. - - if (!terminated) { - this.trigger("error", { - code: "E015", - line: this.line, - character: this.from - }); - - return void this.trigger("fatal", { - line: this.line, - from: this.from - }); - } - - // Parse flags (if any). - - while (index < length) { - char = this.peek(index); - if (!/[gim]/.test(char)) { - break; - } - flags.push(char); - value += char; - index += 1; - } - - // Check regular expression for correctness. - - try { - new RegExp(body, flags.join("")); - } catch (err) { - malformed = true; - this.trigger("error", { - code: "E016", - line: this.line, - character: this.char, - data: [ err.message ] // Platform dependent! - }); - } - - return { - type: Token.RegExp, - value: value, - flags: flags, - isMalformed: malformed - }; - }, - - /* - * Scan for any occurence of mixed tabs and spaces. If smarttabs option - * is on, ignore tabs followed by spaces. - * - * Tabs followed by one space followed by a block comment are allowed. - */ - scanMixedSpacesAndTabs: function () { - var at, match; - - if (state.option.smarttabs) { - // Negative look-behind for "//" - match = this.input.match(/(\/\/|^\s?\*)? \t/); - at = match && !match[1] ? 0 : -1; - } else { - at = this.input.search(/ \t|\t [^\*]/); - } - - return at; - }, - - /* - * Scan for characters that get silently deleted by one or more browsers. - */ - scanUnsafeChars: function () { - return this.input.search(reg.unsafeChars); - }, - - /* - * Produce the next raw token or return 'null' if no tokens can be matched. - * This method skips over all space characters. - */ - next: function (checks) { - this.from = this.char; - - // Move to the next non-space character. - var start; - if (/\s/.test(this.peek())) { - start = this.char; - - while (/\s/.test(this.peek())) { - this.from += 1; - this.skip(); - } - - if (this.peek() === "") { // EOL - if (!/^\s*$/.test(this.lines[this.line - 1]) && state.option.trailing) { - this.trigger("warning", { code: "W102", line: this.line, character: start }); - } - } - } - - // Methods that work with multi-line structures and move the - // character pointer. - - var match = this.scanComments() || - this.scanStringLiteral(checks); - - if (match) { - return match; - } - - // Methods that don't move the character pointer. - - match = - this.scanRegExp() || - this.scanPunctuator() || - this.scanKeyword() || - this.scanIdentifier() || - this.scanNumericLiteral(); - - if (match) { - this.skip(match.value.length); - return match; - } - - // No token could be matched, give up. - - return null; - }, - - /* - * Switch to the next line and reset all char pointers. Once - * switched, this method also checks for mixed spaces and tabs - * and other minor warnings. - */ - nextLine: function () { - var char; - - if (this.line >= this.lines.length) { - return false; - } - - this.input = this.lines[this.line]; - this.line += 1; - this.char = 1; - this.from = 1; - - char = this.scanMixedSpacesAndTabs(); - if (char >= 0) { - this.trigger("warning", { code: "W099", line: this.line, character: char + 1 }); - } - - this.input = this.input.replace(/\t/g, state.tab); - char = this.scanUnsafeChars(); - - if (char >= 0) { - this.trigger("warning", { code: "W100", line: this.line, character: char }); - } - - // If there is a limit on line length, warn when lines get too - // long. - - if (state.option.maxlen && state.option.maxlen < this.input.length) { - this.trigger("warning", { code: "W101", line: this.line, character: this.input.length }); - } - - return true; - }, - - /* - * This is simply a synonym for nextLine() method with a friendlier - * public name. - */ - start: function () { - this.nextLine(); - }, - - /* - * Produce the next token. This function is called by advance() to get - * the next token. It retuns a token in a JSLint-compatible format. - */ - token: function () { - /*jshint loopfunc:true */ - var checks = asyncTrigger(); - var token; - - - function isReserved(token, isProperty) { - if (!token.reserved) { - return false; - } - - if (token.meta && token.meta.isFutureReservedWord) { - // ES3 FutureReservedWord in an ES5 environment. - if (state.option.inES5(true) && !token.meta.es5) { - return false; - } - - // Some ES5 FutureReservedWord identifiers are active only - // within a strict mode environment. - if (token.meta.strictOnly) { - if (!state.option.strict && !state.directive["use strict"]) { - return false; - } - } - - if (isProperty) { - return false; - } - } - - return true; - } - - // Produce a token object. - var create = function (type, value, isProperty) { - /*jshint validthis:true */ - var obj; - - if (type !== "(endline)" && type !== "(end)") { - this.prereg = false; - } - - if (type === "(punctuator)") { - switch (value) { - case ".": - case ")": - case "~": - case "#": - case "]": - this.prereg = false; - break; - default: - this.prereg = true; - } - - obj = Object.create(state.syntax[value] || state.syntax["(error)"]); - } - - if (type === "(identifier)") { - if (value === "return" || value === "case" || value === "typeof") { - this.prereg = true; - } - - if (_.has(state.syntax, value)) { - obj = Object.create(state.syntax[value] || state.syntax["(error)"]); - - // If this can't be a reserved keyword, reset the object. - if (!isReserved(obj, isProperty && type === "(identifier)")) { - obj = null; - } - } - } - - if (!obj) { - obj = Object.create(state.syntax[type]); - } - - obj.identifier = (type === "(identifier)"); - obj.type = obj.type || type; - obj.value = value; - obj.line = this.line; - obj.character = this.char; - obj.from = this.from; - - if (isProperty && obj.identifier) { - obj.isProperty = isProperty; - } - - obj.check = checks.check; - - return obj; - }.bind(this); - - for (;;) { - if (!this.input.length) { - return create(this.nextLine() ? "(endline)" : "(end)", ""); - } - - token = this.next(checks); - - if (!token) { - if (this.input.length) { - // Unexpected character. - this.trigger("error", { - code: "E024", - line: this.line, - character: this.char, - data: [ this.peek() ] - }); - - this.input = ""; - } - - continue; - } - - switch (token.type) { - case Token.StringLiteral: - this.triggerAsync("String", { - line: this.line, - char: this.char, - from: this.from, - value: token.value, - quote: token.quote - }, checks, function () { return true; }); - - return create("(string)", token.value); - case Token.Identifier: - this.trigger("Identifier", { - line: this.line, - char: this.char, - from: this.form, - name: token.value, - isProperty: state.tokens.curr.id === "." - }); - - /* falls through */ - case Token.Keyword: - case Token.NullLiteral: - case Token.BooleanLiteral: - return create("(identifier)", token.value, state.tokens.curr.id === "."); - - case Token.NumericLiteral: - if (token.isMalformed) { - this.trigger("warning", { - code: "W045", - line: this.line, - character: this.char, - data: [ token.value ] - }); - } - - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "0x-" ] - }, checks, function () { return token.base === 16 && state.jsonMode; }); - - this.triggerAsync("warning", { - code: "W115", - line: this.line, - character: this.char - }, checks, function () { - return state.directive["use strict"] && token.base === 8; - }); - - this.trigger("Number", { - line: this.line, - char: this.char, - from: this.from, - value: token.value, - base: token.base, - isMalformed: token.malformed - }); - - return create("(number)", token.value); - - case Token.RegExp: - return create("(regexp)", token.value); - - case Token.Comment: - state.tokens.curr.comment = true; - - if (token.isSpecial) { - return { - value: token.value, - body: token.body, - type: token.commentType, - isSpecial: token.isSpecial, - line: this.line, - character: this.char, - from: this.from - }; - } - - break; - - case "": - break; - - default: - return create("(punctuator)", token.value); - } - } - } -}; - -exports.Lexer = Lexer; - -})() -},{"events":2,"./reg.js":6,"./state.js":4,"underscore":11}],"jshint":[function(require,module,exports){ -module.exports=require('E/GbHF'); -},{}],"E/GbHF":[function(require,module,exports){ -(function(){/*! - * JSHint, by JSHint Community. - * - * This file (and this file only) is licensed under the same slightly modified - * MIT license that JSLint is. It stops evil-doers everywhere: - * - * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * The Software shall be used for Good, not Evil. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -/*jshint quotmark:double */ -/*global console:true */ -/*exported console */ - -var _ = require("underscore"); -var events = require("events"); -var vars = require("../shared/vars.js"); -var messages = require("../shared/messages.js"); -var Lexer = require("./lex.js").Lexer; -var reg = require("./reg.js"); -var state = require("./state.js").state; -var style = require("./style.js"); - -// We need this module here because environments such as IE and Rhino -// don't necessarilly expose the 'console' API and browserify uses -// it to log things. It's a sad state of affair, really. -var console = require("console-browserify"); - -// We build the application inside a function so that we produce only a singleton -// variable. That function will be invoked immediately, and its return value is -// the JSHINT function itself. - -var JSHINT = (function () { - "use strict"; - - var anonname, // The guessed name for anonymous functions. - api, // Extension API - - // These are operators that should not be used with the ! operator. - bang = { - "<" : true, - "<=" : true, - "==" : true, - "===": true, - "!==": true, - "!=" : true, - ">" : true, - ">=" : true, - "+" : true, - "-" : true, - "*" : true, - "/" : true, - "%" : true - }, - - // These are the JSHint boolean options. - boolOptions = { - asi : true, // if automatic semicolon insertion should be tolerated - bitwise : true, // if bitwise operators should not be allowed - boss : true, // if advanced usage of assignments should be allowed - browser : true, // if the standard browser globals should be predefined - camelcase : true, // if identifiers should be required in camel case - couch : true, // if CouchDB globals should be predefined - curly : true, // if curly braces around all blocks should be required - debug : true, // if debugger statements should be allowed - devel : true, // if logging globals should be predefined (console, alert, etc.) - dojo : true, // if Dojo Toolkit globals should be predefined - eqeqeq : true, // if === should be required - eqnull : true, // if == null comparisons should be tolerated - es3 : true, // if ES3 syntax should be allowed - es5 : true, // if ES5 syntax should be allowed (is now set per default) - esnext : true, // if es.next specific syntax should be allowed - moz : true, // if mozilla specific syntax should be allowed - evil : true, // if eval should be allowed - expr : true, // if ExpressionStatement should be allowed as Programs - forin : true, // if for in statements must filter - funcscope : true, // if only function scope should be used for scope tests - gcl : true, // if JSHint should be compatible with Google Closure Linter - globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict') - immed : true, // if immediate invocations must be wrapped in parens - iterator : true, // if the `__iterator__` property should be allowed - jquery : true, // if jQuery globals should be predefined - lastsemic : true, // if semicolons may be ommitted for the trailing - // statements inside of a one-line blocks. - laxbreak : true, // if line breaks should not be checked - laxcomma : true, // if line breaks should not be checked around commas - loopfunc : true, // if functions should be allowed to be defined within - // loops - mootools : true, // if MooTools globals should be predefined - multistr : true, // allow multiline strings - newcap : true, // if constructor names must be capitalized - noarg : true, // if arguments.caller and arguments.callee should be - // disallowed - node : true, // if the Node.js environment globals should be - // predefined - noempty : true, // if empty blocks should be disallowed - nonew : true, // if using `new` for side-effects should be disallowed - nonstandard : true, // if non-standard (but widely adopted) globals should - // be predefined - nomen : true, // if names should be checked - onevar : true, // if only one var statement per function should be - // allowed - passfail : true, // if the scan should stop on first error - phantom : true, // if PhantomJS symbols should be allowed - plusplus : true, // if increment/decrement should not be allowed - proto : true, // if the `__proto__` property should be allowed - prototypejs : true, // if Prototype and Scriptaculous globals should be - // predefined - rhino : true, // if the Rhino environment globals should be predefined - undef : true, // if variables should be declared before used - scripturl : true, // if script-targeted URLs should be tolerated - shadow : true, // if variable shadowing should be tolerated - smarttabs : true, // if smarttabs should be tolerated - // (http://www.emacswiki.org/emacs/SmartTabs) - strict : true, // require the "use strict"; pragma - sub : true, // if all forms of subscript notation are tolerated - supernew : true, // if `new function () { ... };` and `new Object;` - // should be tolerated - trailing : true, // if trailing whitespace rules apply - validthis : true, // if 'this' inside a non-constructor function is valid. - // This is a function scoped option only. - withstmt : true, // if with statements should be allowed - white : true, // if strict whitespace rules apply - worker : true, // if Web Worker script symbols should be allowed - wsh : true, // if the Windows Scripting Host environment globals - // should be predefined - yui : true, // YUI variables should be predefined - - // Obsolete options - onecase : true, // if one case switch statements should be allowed - regexp : true, // if the . should not be allowed in regexp literals - regexdash : true // if unescaped first/last dash (-) inside brackets - // should be tolerated - }, - - // These are the JSHint options that can take any value - // (we use this object to detect invalid options) - valOptions = { - maxlen : false, - indent : false, - maxerr : false, - predef : false, - quotmark : false, //'single'|'double'|true - scope : false, - maxstatements: false, // {int} max statements per function - maxdepth : false, // {int} max nested block depth per function - maxparams : false, // {int} max params per function - maxcomplexity: false, // {int} max cyclomatic complexity per function - unused : true, // warn if variables are unused. Available options: - // false - don't check for unused variables - // true - "vars" + check last function param - // "vars" - skip checking unused function params - // "strict" - "vars" + check all function params - latedef : false // warn if the variable is used before its definition - // false - don't emit any warnings - // true - warn if any variable is used before its definition - // "nofunc" - warn for any variable but function declarations - }, - - // These are JSHint boolean options which are shared with JSLint - // where the definition in JSHint is opposite JSLint - invertedOptions = { - bitwise : true, - forin : true, - newcap : true, - nomen : true, - plusplus: true, - regexp : true, - undef : true, - white : true, - - // Inverted and renamed, use JSHint name here - eqeqeq : true, - onevar : true, - strict : true - }, - - // These are JSHint boolean options which are shared with JSLint - // where the name has been changed but the effect is unchanged - renamedOptions = { - eqeq : "eqeqeq", - vars : "onevar", - windows: "wsh", - sloppy : "strict" - }, - - declared, // Globals that were declared using /*global ... */ syntax. - exported, // Variables that are used outside of the current file. - - functionicity = [ - "closure", "exception", "global", "label", - "outer", "unused", "var" - ], - - funct, // The current function - functions, // All of the functions - - global, // The global scope - implied, // Implied globals - inblock, - indent, - lookahead, - lex, - member, - membersOnly, - noreach, - predefined, // Global variables defined by option - - scope, // The current scope - stack, - unuseds, - urls, - warnings, - - extraModules = [], - emitter = new events.EventEmitter(); - - function checkOption(name, t) { - name = name.trim(); - - if (/^[+-]W\d{3}$/g.test(name)) { - return true; - } - - if (valOptions[name] === undefined && boolOptions[name] === undefined) { - if (t.type !== "jslint") { - error("E001", t, name); - return false; - } - } - - return true; - } - - function isString(obj) { - return Object.prototype.toString.call(obj) === "[object String]"; - } - - function isIdentifier(tkn, value) { - if (!tkn) - return false; - - if (!tkn.identifier || tkn.value !== value) - return false; - - return true; - } - - function isReserved(token) { - if (!token.reserved) { - return false; - } - - if (token.meta && token.meta.isFutureReservedWord) { - // ES3 FutureReservedWord in an ES5 environment. - if (state.option.inES5(true) && !token.meta.es5) { - return false; - } - - // Some ES5 FutureReservedWord identifiers are active only - // within a strict mode environment. - if (token.meta.strictOnly) { - if (!state.option.strict && !state.directive["use strict"]) { - return false; - } - } - - if (token.isProperty) { - return false; - } - } - - return true; - } - - function supplant(str, data) { - return str.replace(/\{([^{}]*)\}/g, function (a, b) { - var r = data[b]; - return typeof r === "string" || typeof r === "number" ? r : a; - }); - } - - function combine(t, o) { - var n; - for (n in o) { - if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) { - t[n] = o[n]; - } - } - } - - function updatePredefined() { - Object.keys(JSHINT.blacklist).forEach(function (key) { - delete predefined[key]; - }); - } - - function assume() { - if (state.option.es5) { - warning("I003"); - } - if (state.option.couch) { - combine(predefined, vars.couch); - } - - if (state.option.rhino) { - combine(predefined, vars.rhino); - } - - if (state.option.phantom) { - combine(predefined, vars.phantom); - } - - if (state.option.prototypejs) { - combine(predefined, vars.prototypejs); - } - - if (state.option.node) { - combine(predefined, vars.node); - } - - if (state.option.devel) { - combine(predefined, vars.devel); - } - - if (state.option.dojo) { - combine(predefined, vars.dojo); - } - - if (state.option.browser) { - combine(predefined, vars.browser); - } - - if (state.option.nonstandard) { - combine(predefined, vars.nonstandard); - } - - if (state.option.jquery) { - combine(predefined, vars.jquery); - } - - if (state.option.mootools) { - combine(predefined, vars.mootools); - } - - if (state.option.worker) { - combine(predefined, vars.worker); - } - - if (state.option.wsh) { - combine(predefined, vars.wsh); - } - - if (state.option.globalstrict && state.option.strict !== false) { - state.option.strict = true; - } - - if (state.option.yui) { - combine(predefined, vars.yui); - } - - // Let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz - - state.option.inMoz = function (strict) { - if (strict) { - return state.option.moz && !state.option.esnext; - } - return state.option.moz; - }; - - state.option.inESNext = function (strict) { - if (strict) { - return !state.option.moz && state.option.esnext; - } - return state.option.moz || state.option.esnext; - }; - - state.option.inES5 = function (/* strict */) { - return !state.option.es3; - }; - - state.option.inES3 = function (strict) { - if (strict) { - return !state.option.moz && !state.option.esnext && state.option.es3; - } - return state.option.es3; - }; - } - - // Produce an error warning. - function quit(code, line, chr) { - var percentage = Math.floor((line / state.lines.length) * 100); - var message = messages.errors[code].desc; - - throw { - name: "JSHintError", - line: line, - character: chr, - message: message + " (" + percentage + "% scanned).", - raw: message - }; - } - - function isundef(scope, code, token, a) { - return JSHINT.undefs.push([scope, code, token, a]); - } - - function warning(code, t, a, b, c, d) { - var ch, l, w, msg; - - if (/^W\d{3}$/.test(code)) { - if (state.ignored[code]) - return; - - msg = messages.warnings[code]; - } else if (/E\d{3}/.test(code)) { - msg = messages.errors[code]; - } else if (/I\d{3}/.test(code)) { - msg = messages.info[code]; - } - - t = t || state.tokens.next; - if (t.id === "(end)") { // `~ - t = state.tokens.curr; - } - - l = t.line || 0; - ch = t.from || 0; - - w = { - id: "(error)", - raw: msg.desc, - code: msg.code, - evidence: state.lines[l - 1] || "", - line: l, - character: ch, - scope: JSHINT.scope, - a: a, - b: b, - c: c, - d: d - }; - - w.reason = supplant(msg.desc, w); - JSHINT.errors.push(w); - - if (state.option.passfail) { - quit("E042", l, ch); - } - - warnings += 1; - if (warnings >= state.option.maxerr) { - quit("E043", l, ch); - } - - return w; - } - - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); - } - - function error(m, t, a, b, c, d) { - warning(m, t, a, b, c, d); - } - - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); - } - - // Tracking of "internal" scripts, like eval containing a static string - function addInternalSrc(elem, src) { - var i; - i = { - id: "(internal)", - elem: elem, - value: src - }; - JSHINT.internals.push(i); - return i; - } - - function addlabel(t, type, tkn, islet) { - // Define t in the current function in the current scope. - if (type === "exception") { - if (_.has(funct["(context)"], t)) { - if (funct[t] !== true && !state.option.node) { - warning("W002", state.tokens.next, t); - } - } - } - - if (_.has(funct, t) && !funct["(global)"]) { - if (funct[t] === true) { - if (state.option.latedef) { - if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) || - !_.contains([funct[t], type], "unction")) { - warning("W003", state.tokens.next, t); - } - } - } else { - if (!state.option.shadow && type !== "exception" || - (funct["(blockscope)"].getlabel(t))) { - warning("W004", state.tokens.next, t); - } - } - } - - // a double definition of a let variable in same block throws a TypeError - //if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) { - // error("E044", state.tokens.next, t); - //} - - // if the identifier is from a let, adds it only to the current blockscope - if (islet) { - funct["(blockscope)"].current.add(t, type, state.tokens.curr); - } else { - - funct[t] = type; - - if (tkn) { - funct["(tokens)"][t] = tkn; - } - - if (funct["(global)"]) { - global[t] = funct; - if (_.has(implied, t)) { - if (state.option.latedef) { - if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) || - !_.contains([funct[t], type], "unction")) { - warning("W003", state.tokens.next, t); - } - } - - delete implied[t]; - } - } else { - scope[t] = funct; - } - } - } - - function doOption() { - var nt = state.tokens.next; - var body = nt.body.split(",").map(function (s) { return s.trim(); }); - var predef = {}; - - if (nt.type === "globals") { - body.forEach(function (g) { - g = g.split(":"); - var key = g[0]; - var val = g[1]; - - if (key.charAt(0) === "-") { - key = key.slice(1); - val = false; - - JSHINT.blacklist[key] = key; - updatePredefined(); - } else { - predef[key] = (val === "true"); - } - }); - - combine(predefined, predef); - - for (var key in predef) { - if (_.has(predef, key)) { - declared[key] = nt; - } - } - } - - if (nt.type === "exported") { - body.forEach(function (e) { - exported[e] = true; - }); - } - - if (nt.type === "members") { - membersOnly = membersOnly || {}; - - body.forEach(function (m) { - var ch1 = m.charAt(0); - var ch2 = m.charAt(m.length - 1); - - if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) { - m = m - .substr(1, m.length - 2) - .replace("\\b", "\b") - .replace("\\t", "\t") - .replace("\\n", "\n") - .replace("\\v", "\v") - .replace("\\f", "\f") - .replace("\\r", "\r") - .replace("\\\\", "\\") - .replace("\\\"", "\""); - } - - membersOnly[m] = false; - }); - } - - var numvals = [ - "maxstatements", - "maxparams", - "maxdepth", - "maxcomplexity", - "maxerr", - "maxlen", - "indent" - ]; - - if (nt.type === "jshint" || nt.type === "jslint") { - body.forEach(function (g) { - g = g.split(":"); - var key = (g[0] || "").trim(); - var val = (g[1] || "").trim(); - - if (!checkOption(key, nt)) { - return; - } - - if (numvals.indexOf(key) >= 0) { - - // GH988 - numeric options can be disabled by setting them to `false` - if (val !== "false") { - val = +val; - - if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) { - error("E032", nt, g[1].trim()); - return; - } - - if (key === "indent") { - state.option["(explicitIndent)"] = true; - } - state.option[key] = val; - } else { - if (key === "indent") { - state.option["(explicitIndent)"] = false; - } else { - state.option[key] = false; - } - } - - return; - } - - if (key === "validthis") { - // `validthis` is valid only within a function scope. - if (funct["(global)"]) { - error("E009"); - } else { - if (val === "true" || val === "false") { - state.option.validthis = (val === "true"); - } else { - error("E002", nt); - } - } - return; - } - - if (key === "quotmark") { - switch (val) { - case "true": - case "false": - state.option.quotmark = (val === "true"); - break; - case "double": - case "single": - state.option.quotmark = val; - break; - default: - error("E002", nt); - } - return; - } - - if (key === "unused") { - switch (val) { - case "true": - state.option.unused = true; - break; - case "false": - state.option.unused = false; - break; - case "vars": - case "strict": - state.option.unused = val; - break; - default: - error("E002", nt); - } - return; - } - - if (key === "latedef") { - switch (val) { - case "true": - state.option.latedef = true; - break; - case "false": - state.option.latedef = false; - break; - case "nofunc": - state.option.latedef = "nofunc"; - break; - default: - error("E002", nt); - } - return; - } - - var match = /^([+-])(W\d{3})$/g.exec(key); - if (match) { - // ignore for -W..., unignore for +W... - state.ignored[match[2]] = (match[1] === "-"); - return; - } - - var tn; - if (val === "true" || val === "false") { - if (nt.type === "jslint") { - tn = renamedOptions[key] || key; - state.option[tn] = (val === "true"); - - if (invertedOptions[tn] !== undefined) { - state.option[tn] = !state.option[tn]; - } - } else { - state.option[key] = (val === "true"); - } - - if (key === "newcap") { - state.option["(explicitNewcap)"] = true; - } - return; - } - - error("E002", nt); - }); - - assume(); - } - } - - // We need a peek function. If it has an argument, it peeks that much farther - // ahead. It is used to distinguish - // for ( var i in ... - // from - // for ( var i = ... - - function peek(p) { - var i = p || 0, j = 0, t; - - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; - } - return t; - } - - // Produce the next token. It looks for programming errors. - - function advance(id, t) { - switch (state.tokens.curr.id) { - case "(number)": - if (state.tokens.next.id === ".") { - warning("W005", state.tokens.curr); - } - break; - case "-": - if (state.tokens.next.id === "-" || state.tokens.next.id === "--") { - warning("W006"); - } - break; - case "+": - if (state.tokens.next.id === "+" || state.tokens.next.id === "++") { - warning("W007"); - } - break; - } - - if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) { - anonname = state.tokens.curr.value; - } - - if (id && state.tokens.next.id !== id) { - if (t) { - if (state.tokens.next.id === "(end)") { - error("E019", t, t.id); - } else { - error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value); - } - } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) { - warning("W116", state.tokens.next, id, state.tokens.next.value); - } - } - - state.tokens.prev = state.tokens.curr; - state.tokens.curr = state.tokens.next; - for (;;) { - state.tokens.next = lookahead.shift() || lex.token(); - - if (!state.tokens.next) { // No more tokens left, give up - quit("E041", state.tokens.curr.line); - } - - if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") { - return; - } - - if (state.tokens.next.check) { - state.tokens.next.check(); - } - - if (state.tokens.next.isSpecial) { - doOption(); - } else { - if (state.tokens.next.id !== "(endline)") { - break; - } - } - } - } - - // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it - // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is - // like .nud except that it is only used on the first token of a statement. - // Having .fud makes it much easier to define statement-oriented languages like - // JavaScript. I retained Pratt's nomenclature. - - // .nud Null denotation - // .fud First null denotation - // .led Left denotation - // lbp Left binding power - // rbp Right binding power - - // They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - var left, isArray = false, isObject = false, isLetExpr = false; - - // if current expression is a let expression - if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.next, "let expressions"); - } - isLetExpr = true; - // create a new block scope we use only for the current expression - funct["(blockscope)"].stack(); - advance("let"); - advance("("); - state.syntax["let"].fud.call(state.syntax["let"].fud, false); - advance(")"); - } - - if (state.tokens.next.id === "(end)") - error("E006", state.tokens.curr); - - advance(); - - if (initial) { - anonname = "anonymous"; - funct["(verb)"] = state.tokens.curr.value; - } - - if (initial === true && state.tokens.curr.fud) { - left = state.tokens.curr.fud(); - } else { - if (state.tokens.curr.nud) { - left = state.tokens.curr.nud(); - } else { - error("E030", state.tokens.curr, state.tokens.curr.id); - } - - var end_of_expr = state.tokens.next.identifier && - !state.tokens.curr.led && - state.tokens.curr.line !== state.tokens.next.line; - while (rbp < state.tokens.next.lbp && !end_of_expr) { - isArray = state.tokens.curr.value === "Array"; - isObject = state.tokens.curr.value === "Object"; - - // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() - // Line breaks in IfStatement heads exist to satisfy the checkJSHint - // "Line too long." error. - if (left && (left.value || (left.first && left.first.value))) { - // If the left.value is not "new", or the left.first.value is a "." - // then safely assume that this is not "new Array()" and possibly - // not "new Object()"... - if (left.value !== "new" || - (left.first && left.first.value && left.first.value === ".")) { - isArray = false; - // ...In the case of Object, if the left.value and state.tokens.curr.value - // are not equal, then safely assume that this not "new Object()" - if (left.value !== state.tokens.curr.value) { - isObject = false; - } - } - } - - advance(); - - if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { - warning("W009", state.tokens.curr); - } - - if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { - warning("W010", state.tokens.curr); - } - - if (left && state.tokens.curr.led) { - left = state.tokens.curr.led(left); - } else { - error("E033", state.tokens.curr, state.tokens.curr.id); - } - } - } - if (isLetExpr) { - funct["(blockscope)"].unstack(); - } - return left; - } - - -// Functions for conformance of style. - - function adjacent(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (state.option.white) { - if (left.character !== right.from && left.line === right.line) { - left.from += (left.character - left.from); - warning("W011", left, left.value); - } - } - } - - function nobreak(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (state.option.white && (left.character !== right.from || left.line !== right.line)) { - warning("W012", right, right.value); - } - } - - function nospace(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (state.option.white && !left.comment) { - if (left.line === right.line) { - adjacent(left, right); - } - } - } - - function nonadjacent(left, right) { - if (state.option.white) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - - if (left.value === ";" && right.value === ";") { - return; - } - - if (left.line === right.line && left.character === right.from) { - left.from += (left.character - left.from); - warning("W013", left, left.value); - } - } - } - - function nobreaknonadjacent(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (!state.option.laxbreak && left.line !== right.line) { - warning("W014", right, right.id); - } else if (state.option.white) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (left.character === right.from) { - left.from += (left.character - left.from); - warning("W013", left, left.value); - } - } - } - - function indentation(bias) { - if (!state.option.white && !state.option["(explicitIndent)"]) { - return; - } - - if (state.tokens.next.id === "(end)") { - return; - } - - var i = indent + (bias || 0); - if (state.tokens.next.from !== i) { - warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from); - } - } - - function nolinebreak(t) { - t = t || state.tokens.curr; - if (t.line !== state.tokens.next.line) { - warning("E022", t, t.value); - } - } - - - function comma(opts) { - opts = opts || {}; - - if (!opts.peek) { - if (state.tokens.curr.line !== state.tokens.next.line) { - if (!state.option.laxcomma) { - if (comma.first) { - warning("I001"); - comma.first = false; - } - warning("W014", state.tokens.curr, state.tokens.next.value); - } - } else if (!state.tokens.curr.comment && - state.tokens.curr.character !== state.tokens.next.from && state.option.white) { - state.tokens.curr.from += (state.tokens.curr.character - state.tokens.curr.from); - warning("W011", state.tokens.curr, state.tokens.curr.value); - } - - advance(","); - } - - // TODO: This is a temporary solution to fight against false-positives in - // arrays and objects with trailing commas (see GH-363). The best solution - // would be to extract all whitespace rules out of parser. - - if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") { - nonadjacent(state.tokens.curr, state.tokens.next); - } - - if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) { - // Keywords that cannot follow a comma operator. - switch (state.tokens.next.value) { - case "break": - case "case": - case "catch": - case "continue": - case "default": - case "do": - case "else": - case "finally": - case "for": - case "if": - case "in": - case "instanceof": - case "return": - case "yield": - case "switch": - case "throw": - case "try": - case "var": - case "let": - case "while": - case "with": - error("E024", state.tokens.next, state.tokens.next.value); - return false; - } - } - - if (state.tokens.next.type === "(punctuator)") { - switch (state.tokens.next.value) { - case "}": - case "]": - case ",": - if (opts.allowTrailing) { - return true; - } - - /* falls through */ - case ")": - error("E024", state.tokens.next, state.tokens.next.value); - return false; - } - } - return true; - } - - // Functional constructors for making the symbols that will be inherited by - // tokens. - - function symbol(s, p) { - var x = state.syntax[s]; - if (!x || typeof x !== "object") { - state.syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } - - function delim(s) { - return symbol(s, 0); - } - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - function blockstmt(s, f) { - var x = stmt(s, f); - x.block = true; - return x; - } - - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { - x.identifier = x.reserved = true; - } - return x; - } - - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); - x.nud = (typeof f === "function") ? f : function () { - this.right = expression(150); - this.arity = "unary"; - if (this.id === "++" || this.id === "--") { - if (state.option.plusplus) { - warning("W016", this, this.id); - } else if ((!this.right.identifier || isReserved(this.right)) && - this.right.id !== "." && this.right.id !== "[") { - warning("W017", this); - } - } - return this; - }; - return x; - } - - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; - } - - function reserve(name, func) { - var x = type(name, func); - x.identifier = true; - x.reserved = true; - return x; - } - - function FutureReservedWord(name, meta) { - var x = type(name, (meta && meta.nud) || function () { - return this; - }); - - meta = meta || {}; - meta.isFutureReservedWord = true; - - x.value = name; - x.identifier = true; - x.reserved = true; - x.meta = meta; - - return x; - } - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === "function") { - v(this); - } - return this; - }); - } - - function infix(s, f, p, w) { - var x = symbol(s, p); - reserveName(x); - x.led = function (left) { - if (!w) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - } - if (s === "in" && left.id === "!") { - warning("W018", left, "!"); - } - if (typeof f === "function") { - return f(left, this); - } else { - this.left = left; - this.right = expression(p); - return this; - } - }; - return x; - } - - - function application(s) { - var x = symbol(s, 42); - - x.led = function (left) { - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "arrow function syntax (=>)"); - } - - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - - this.left = left; - this.right = doFunction(undefined, undefined, false, left); - return this; - }; - return x; - } - - function relation(s, f) { - var x = symbol(s, 100); - - x.led = function (left) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - var right = expression(100); - - if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { - warning("W019", this); - } else if (f) { - f.apply(this, [left, right]); - } - - if (!left || !right) { - quit("E041", state.tokens.curr.line); - } - - if (left.id === "!") { - warning("W018", left, "!"); - } - - if (right.id === "!") { - warning("W018", right, "!"); - } - - this.left = left; - this.right = right; - return this; - }; - return x; - } - - function isPoorRelation(node) { - return node && - ((node.type === "(number)" && +node.value === 0) || - (node.type === "(string)" && node.value === "") || - (node.type === "null" && !state.option.eqnull) || - node.type === "true" || - node.type === "false" || - node.type === "undefined"); - } - - function assignop(s) { - symbol(s, 20).exps = true; - - return infix(s, function (left, that) { - that.left = left; - - if (left) { - if (predefined[left.value] === false && - scope[left.value]["(global)"] === true) { - warning("W020", left); - } else if (left["function"]) { - warning("W021", left, left.value); - } - - if (funct[left.value] === "const") { - error("E013", left, left.value); - } - - if (left.id === ".") { - if (!left.left) { - warning("E031", that); - } else if (left.left.value === "arguments" && !state.directive["use strict"]) { - warning("E031", that); - } - - that.right = expression(19); - return that; - } else if (left.id === "[") { - if (state.tokens.curr.left.first) { - state.tokens.curr.left.first.forEach(function (t) { - if (funct[t.value] === "const") { - error("E013", t, t.value); - } - }); - } else if (!left.left) { - warning("E031", that); - } else if (left.left.value === "arguments" && !state.directive["use strict"]) { - warning("E031", that); - } - that.right = expression(19); - return that; - } else if (left.identifier && !isReserved(left)) { - if (funct[left.value] === "exception") { - warning("W022", left); - } - that.right = expression(19); - return that; - } - - if (left === state.syntax["function"]) { - warning("W023", state.tokens.curr); - } - } - - error("E031", that); - }, 20); - } - - - function bitwise(s, f, p) { - var x = symbol(s, p); - reserveName(x); - x.led = (typeof f === "function") ? f : function (left) { - if (state.option.bitwise) { - warning("W016", this, this.id); - } - this.left = left; - this.right = expression(p); - return this; - }; - return x; - } - - - function bitwiseassignop(s) { - symbol(s, 20).exps = true; - return infix(s, function (left, that) { - if (state.option.bitwise) { - warning("W016", that, that.id); - } - nonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - if (left) { - if (left.id === "." || left.id === "[" || - (left.identifier && !isReserved(left))) { - expression(19); - return that; - } - if (left === state.syntax["function"]) { - warning("W023", state.tokens.curr); - } - return that; - } - error("E031", that); - }, 20); - } - - - function suffix(s) { - var x = symbol(s, 150); - - x.led = function (left) { - if (state.option.plusplus) { - warning("W016", this, this.id); - } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") { - warning("W017", this); - } - - this.left = left; - return this; - }; - return x; - } - - // fnparam means that this identifier is being defined as a function - // argument (see identifier()) - // prop means that this identifier is that of an object property - - function optionalidentifier(fnparam, prop) { - if (!state.tokens.next.identifier) { - return; - } - - advance(); - - var curr = state.tokens.curr; - var meta = curr.meta || {}; - var val = state.tokens.curr.value; - - if (!isReserved(curr)) { - return val; - } - - if (prop) { - if (state.option.inES5() || meta.isFutureReservedWord) { - return val; - } - } - - if (fnparam && val === "undefined") { - return val; - } - - // Display an info message about reserved words as properties - // and ES5 but do it only once. - if (prop && !api.getCache("displayed:I002")) { - api.setCache("displayed:I002", true); - warning("I002"); - } - - warning("W024", state.tokens.curr, state.tokens.curr.id); - return val; - } - - // fnparam means that this identifier is being defined as a function - // argument - // prop means that this identifier is that of an object property - function identifier(fnparam, prop) { - var i = optionalidentifier(fnparam, prop); - if (i) { - return i; - } - if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") { - warning("W025"); - } else { - error("E030", state.tokens.next, state.tokens.next.value); - } - } - - - function reachable(s) { - var i = 0, t; - if (state.tokens.next.id !== ";" || noreach) { - return; - } - for (;;) { - t = peek(i); - if (t.reach) { - return; - } - if (t.id !== "(endline)") { - if (t.id === "function") { - if (!state.option.latedef) { - break; - } - - warning("W026", t); - break; - } - - warning("W027", t, t.value, s); - break; - } - i += 1; - } - } - - - function statement(noindent) { - var values; - var i = indent, r, s = scope, t = state.tokens.next; - - if (t.id === ";") { - advance(";"); - return; - } - - // Is this a labelled statement? - var res = isReserved(t); - - // We're being more tolerant here: if someone uses - // a FutureReservedWord as a label, we warn but proceed - // anyway. - - if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") { - warning("W024", t, t.id); - res = false; - } - - // detect a destructuring assignment - if (_.has(["[", "{"], t.value)) { - if (lookupBlockType().isDestAssign) { - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "destructuring expression"); - } - values = destructuringExpression(); - values.forEach(function (tok) { - isundef(funct, "W117", tok.token, tok.id); - }); - advance("="); - destructuringExpressionMatch(values, expression(5, true)); - advance(";"); - return; - } - } - if (t.identifier && !res && peek().id === ":") { - advance(); - advance(":"); - scope = Object.create(s); - addlabel(t.value, "label"); - - if (!state.tokens.next.labelled && state.tokens.next.value !== "{") { - warning("W028", state.tokens.next, t.value, state.tokens.next.value); - } - - state.tokens.next.label = t.value; - t = state.tokens.next; - } - - // Is it a lonely block? - - if (t.id === "{") { - // Is it a switch case block? - // - // switch (foo) { - // case bar: { <= here. - // ... - // } - // } - var iscase = (funct["(verb)"] === "case" && state.tokens.curr.value === ":"); - block(true, true, false, false, iscase); - return; - } - - // Parse the statement. - - if (!noindent) { - indentation(); - } - r = expression(0, true); - - // Look for the final semicolon. - - if (!t.block) { - if (!state.option.expr && (!r || !r.exps)) { - warning("W030", state.tokens.curr); - } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") { - warning("W031", t); - } - - if (state.tokens.next.id !== ";") { - if (!state.option.asi) { - // If this is the last statement in a block that ends on - // the same line *and* option lastsemic is on, ignore the warning. - // Otherwise, complain about missing semicolon. - if (!state.option.lastsemic || state.tokens.next.id !== "}" || - state.tokens.next.line !== state.tokens.curr.line) { - warningAt("W033", state.tokens.curr.line, state.tokens.curr.character); - } - } - } else { - adjacent(state.tokens.curr, state.tokens.next); - advance(";"); - nonadjacent(state.tokens.curr, state.tokens.next); - } - } - - // Restore the indentation. - - indent = i; - scope = s; - return r; - } - - - function statements(startLine) { - var a = [], p; - - while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { - if (state.tokens.next.id === ";") { - p = peek(); - - if (!p || (p.id !== "(" && p.id !== "[")) { - warning("W032"); - } - - advance(";"); - } else { - a.push(statement(startLine === state.tokens.next.line)); - } - } - return a; - } - - - /* - * read all directives - * recognizes a simple form of asi, but always - * warns, if it is used - */ - function directives() { - var i, p, pn; - - for (;;) { - if (state.tokens.next.id === "(string)") { - p = peek(0); - if (p.id === "(endline)") { - i = 1; - do { - pn = peek(i); - i = i + 1; - } while (pn.id === "(endline)"); - - if (pn.id !== ";") { - if (pn.id !== "(string)" && pn.id !== "(number)" && - pn.id !== "(regexp)" && pn.identifier !== true && - pn.id !== "}") { - break; - } - warning("W033", state.tokens.next); - } else { - p = pn; - } - } else if (p.id === "}") { - // Directive with no other statements, warn about missing semicolon - warning("W033", p); - } else if (p.id !== ";") { - break; - } - - indentation(); - advance(); - if (state.directive[state.tokens.curr.value]) { - warning("W034", state.tokens.curr, state.tokens.curr.value); - } - - if (state.tokens.curr.value === "use strict") { - if (!state.option["(explicitNewcap)"]) - state.option.newcap = true; - state.option.undef = true; - } - - // there's no directive negation, so always set to true - state.directive[state.tokens.curr.value] = true; - - if (p.id === ";") { - advance(";"); - } - continue; - } - break; - } - } - - - /* - * Parses a single block. A block is a sequence of statements wrapped in - * braces. - * - * ordinary - true for everything but function bodies and try blocks. - * stmt - true if block can be a single statement (e.g. in if/for/while). - * isfunc - true if block is a function body - * isfatarrow - - * iscase - true if block is a switch case block - */ - function block(ordinary, stmt, isfunc, isfatarrow, iscase) { - var a, - b = inblock, - old_indent = indent, - m, - s = scope, - t, - line, - d; - - inblock = ordinary; - - if (!ordinary || !state.option.funcscope) - scope = Object.create(scope); - - nonadjacent(state.tokens.curr, state.tokens.next); - t = state.tokens.next; - - var metrics = funct["(metrics)"]; - metrics.nestedBlockDepth += 1; - metrics.verifyMaxNestedBlockDepthPerFunction(); - - if (state.tokens.next.id === "{") { - advance("{"); - - // create a new block scope - funct["(blockscope)"].stack(); - - line = state.tokens.curr.line; - if (state.tokens.next.id !== "}") { - indent += state.option.indent; - while (!ordinary && state.tokens.next.from > indent) { - indent += state.option.indent; - } - - if (isfunc) { - m = {}; - for (d in state.directive) { - if (_.has(state.directive, d)) { - m[d] = state.directive[d]; - } - } - directives(); - - if (state.option.strict && funct["(context)"]["(global)"]) { - if (!m["use strict"] && !state.directive["use strict"]) { - warning("E007"); - } - } - } - - a = statements(line); - - metrics.statementCount += a.length; - - if (isfunc) { - state.directive = m; - } - - indent -= state.option.indent; - if (line !== state.tokens.next.line) { - indentation(); - } - } else if (line !== state.tokens.next.line) { - indentation(); - } - advance("}", t); - - funct["(blockscope)"].unstack(); - - indent = old_indent; - } else if (!ordinary) { - if (isfunc) { - m = {}; - if (stmt && !isfatarrow && !state.option.inMoz(true)) { - error("W118", state.tokens.curr, "function closure expressions"); - } - - if (!stmt) { - for (d in state.directive) { - if (_.has(state.directive, d)) { - m[d] = state.directive[d]; - } - } - } - expression(5); - - if (state.option.strict && funct["(context)"]["(global)"]) { - if (!m["use strict"] && !state.directive["use strict"]) { - warning("E007"); - } - } - } else { - error("E021", state.tokens.next, "{", state.tokens.next.value); - } - } else { - - // check to avoid let declaration not within a block - funct["(nolet)"] = true; - - if (!stmt || state.option.curly) { - warning("W116", state.tokens.next, "{", state.tokens.next.value); - } - - noreach = true; - indent += state.option.indent; - // test indentation only if statement is in new line - a = [statement(state.tokens.next.line === state.tokens.curr.line)]; - indent -= state.option.indent; - noreach = false; - - delete funct["(nolet)"]; - } - // If it is a "break" in switch case, don't clear and let it propagate out. - if (!(iscase && funct["(verb)"] === "break")) funct["(verb)"] = null; - - if (!ordinary || !state.option.funcscope) scope = s; - inblock = b; - if (ordinary && state.option.noempty && (!a || a.length === 0)) { - warning("W035"); - } - metrics.nestedBlockDepth -= 1; - return a; - } - - - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== "boolean") { - warning("W036", state.tokens.curr, m); - } - if (typeof member[m] === "number") { - member[m] += 1; - } else { - member[m] = 1; - } - } - - - function note_implied(tkn) { - var name = tkn.value, line = tkn.line, a = implied[name]; - if (typeof a === "function") { - a = false; - } - - if (!a) { - a = [line]; - implied[name] = a; - } else if (a[a.length - 1] !== line) { - a.push(line); - } - } - - - // Build the syntax table by declaring the syntactic elements of the language. - - type("(number)", function () { - return this; - }); - - type("(string)", function () { - return this; - }); - - state.syntax["(identifier)"] = { - type: "(identifier)", - lbp: 0, - identifier: true, - nud: function () { - var v = this.value, - s = scope[v], - f; - - if (typeof s === "function") { - // Protection against accidental inheritance. - s = undefined; - } else if (typeof s === "boolean") { - f = funct; - funct = functions[0]; - addlabel(v, "var"); - s = funct; - funct = f; - } - var block; - if (_.has(funct, "(blockscope)")) { - block = funct["(blockscope)"].getlabel(v); - } - - // The name is in scope and defined in the current function. - if (funct === s || block) { - // Change 'unused' to 'var', and reject labels. - // the name is in a block scope - switch (block ? block[v]["(type)"] : funct[v]) { - case "unused": - if (block) block[v]["(type)"] = "var"; - else funct[v] = "var"; - break; - case "unction": - if (block) block[v]["(type)"] = "function"; - else funct[v] = "function"; - this["function"] = true; - break; - case "function": - this["function"] = true; - break; - case "label": - warning("W037", state.tokens.curr, v); - break; - } - } else if (funct["(global)"]) { - // The name is not defined in the function. If we are in the global - // scope, then we have an undefined variable. - // - // Operators typeof and delete do not raise runtime errors even if - // the base object of a reference is null so no need to display warning - // if we're inside of typeof or delete. - - if (typeof predefined[v] !== "boolean") { - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === "typeof" || anonname === "delete") || - (state.tokens.next && (state.tokens.next.value === "." || - state.tokens.next.value === "["))) { - - // if we're in a list comprehension, variables are declared - // locally and used before being defined. So we check - // the presence of the given variable in the comp array - // before declaring it undefined. - - if (!funct["(comparray)"].check(v)) { - isundef(funct, "W117", state.tokens.curr, v); - } - } - } - - note_implied(state.tokens.curr); - } else { - // If the name is already defined in the current - // function, but not as outer, then there is a scope error. - - switch (funct[v]) { - case "closure": - case "function": - case "var": - case "unused": - warning("W038", state.tokens.curr, v); - break; - case "label": - warning("W037", state.tokens.curr, v); - break; - case "outer": - case "global": - break; - default: - // If the name is defined in an outer function, make an outer entry, - // and if it was unused, make it var. - if (s === true) { - funct[v] = true; - } else if (s === null) { - warning("W039", state.tokens.curr, v); - note_implied(state.tokens.curr); - } else if (typeof s !== "object") { - // Operators typeof and delete do not raise runtime errors even - // if the base object of a reference is null so no need to - // - // display warning if we're inside of typeof or delete. - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === "typeof" || anonname === "delete") || - (state.tokens.next && - (state.tokens.next.value === "." || state.tokens.next.value === "["))) { - - isundef(funct, "W117", state.tokens.curr, v); - } - funct[v] = true; - note_implied(state.tokens.curr); - } else { - switch (s[v]) { - case "function": - case "unction": - this["function"] = true; - s[v] = "closure"; - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "var": - case "unused": - s[v] = "closure"; - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "closure": - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "label": - warning("W037", state.tokens.curr, v); - } - } - } - } - return this; - }, - led: function () { - error("E033", state.tokens.next, state.tokens.next.value); - } - }; - - type("(regexp)", function () { - return this; - }); - - // ECMAScript parser - - delim("(endline)"); - delim("(begin)"); - delim("(end)").reach = true; - delim("(error)").reach = true; - delim("}").reach = true; - delim(")"); - delim("]"); - delim("\"").reach = true; - delim("'").reach = true; - delim(";"); - delim(":").reach = true; - delim("#"); - - reserve("else"); - reserve("case").reach = true; - reserve("catch"); - reserve("default").reach = true; - reserve("finally"); - reservevar("arguments", function (x) { - if (state.directive["use strict"] && funct["(global)"]) { - warning("E008", x); - } - }); - reservevar("eval"); - reservevar("false"); - reservevar("Infinity"); - reservevar("null"); - reservevar("this", function (x) { - if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] && - funct["(name)"].charAt(0) > "Z") || funct["(global)"])) { - warning("W040", x); - } - }); - reservevar("true"); - reservevar("undefined"); - - assignop("=", "assign", 20); - assignop("+=", "assignadd", 20); - assignop("-=", "assignsub", 20); - assignop("*=", "assignmult", 20); - assignop("/=", "assigndiv", 20).nud = function () { - error("E014"); - }; - assignop("%=", "assignmod", 20); - - bitwiseassignop("&=", "assignbitand", 20); - bitwiseassignop("|=", "assignbitor", 20); - bitwiseassignop("^=", "assignbitxor", 20); - bitwiseassignop("<<=", "assignshiftleft", 20); - bitwiseassignop(">>=", "assignshiftright", 20); - bitwiseassignop(">>>=", "assignshiftrightunsigned", 20); - infix(",", function (left, that) { - var expr; - that.exprs = [left]; - if (!comma({peek: true})) { - return that; - } - while (true) { - if (!(expr = expression(5))) { - break; - } - that.exprs.push(expr); - if (state.tokens.next.value !== "," || !comma()) { - break; - } - } - return that; - }, 5, true); - infix("?", function (left, that) { - that.left = left; - that.right = expression(10); - advance(":"); - that["else"] = expression(10); - return that; - }, 30); - - infix("||", "or", 40); - infix("&&", "and", 50); - bitwise("|", "bitor", 70); - bitwise("^", "bitxor", 80); - bitwise("&", "bitand", 90); - relation("==", function (left, right) { - var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null"); - - if (!eqnull && state.option.eqeqeq) - warning("W116", this, "===", "=="); - else if (isPoorRelation(left)) - warning("W041", this, "===", left.value); - else if (isPoorRelation(right)) - warning("W041", this, "===", right.value); - - return this; - }); - relation("==="); - relation("!=", function (left, right) { - var eqnull = state.option.eqnull && - (left.value === "null" || right.value === "null"); - - if (!eqnull && state.option.eqeqeq) { - warning("W116", this, "!==", "!="); - } else if (isPoorRelation(left)) { - warning("W041", this, "!==", left.value); - } else if (isPoorRelation(right)) { - warning("W041", this, "!==", right.value); - } - return this; - }); - relation("!=="); - relation("<"); - relation(">"); - relation("<="); - relation(">="); - bitwise("<<", "shiftleft", 120); - bitwise(">>", "shiftright", 120); - bitwise(">>>", "shiftrightunsigned", 120); - infix("in", "in", 120); - infix("instanceof", "instanceof", 120); - infix("+", function (left, that) { - var right = expression(130); - if (left && right && left.id === "(string)" && right.id === "(string)") { - left.value += right.value; - left.character = right.character; - if (!state.option.scripturl && reg.javascriptURL.test(left.value)) { - warning("W050", left); - } - return left; - } - that.left = left; - that.right = right; - return that; - }, 130); - prefix("+", "num"); - prefix("+++", function () { - warning("W007"); - this.right = expression(150); - this.arity = "unary"; - return this; - }); - infix("+++", function (left) { - warning("W007"); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("-", "sub", 130); - prefix("-", "neg"); - prefix("---", function () { - warning("W006"); - this.right = expression(150); - this.arity = "unary"; - return this; - }); - infix("---", function (left) { - warning("W006"); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("*", "mult", 140); - infix("/", "div", 140); - infix("%", "mod", 140); - - suffix("++", "postinc"); - prefix("++", "preinc"); - state.syntax["++"].exps = true; - - suffix("--", "postdec"); - prefix("--", "predec"); - state.syntax["--"].exps = true; - prefix("delete", function () { - var p = expression(5); - if (!p || (p.id !== "." && p.id !== "[")) { - warning("W051"); - } - this.first = p; - return this; - }).exps = true; - - prefix("~", function () { - if (state.option.bitwise) { - warning("W052", this, "~"); - } - expression(150); - return this; - }); - - prefix("...", function () { - if (!state.option.inESNext()) { - warning("W104", this, "spread/rest operator"); - } - if (!state.tokens.next.identifier) { - error("E030", state.tokens.next, state.tokens.next.value); - } - expression(150); - return this; - }); - - prefix("!", function () { - this.right = expression(150); - this.arity = "unary"; - - if (!this.right) { // '!' followed by nothing? Give up. - quit("E041", this.line || 0); - } - - if (bang[this.right.id] === true) { - warning("W018", this, "!"); - } - return this; - }); - - prefix("typeof", "typeof"); - prefix("new", function () { - var c = expression(155), i; - if (c && c.id !== "function") { - if (c.identifier) { - c["new"] = true; - switch (c.value) { - case "Number": - case "String": - case "Boolean": - case "Math": - case "JSON": - warning("W053", state.tokens.prev, c.value); - break; - case "Function": - if (!state.option.evil) { - warning("W054"); - } - break; - case "Date": - case "RegExp": - break; - default: - if (c.id !== "function") { - i = c.value.substr(0, 1); - if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) { - warning("W055", state.tokens.curr); - } - } - } - } else { - if (c.id !== "." && c.id !== "[" && c.id !== "(") { - warning("W056", state.tokens.curr); - } - } - } else { - if (!state.option.supernew) - warning("W057", this); - } - adjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id !== "(" && !state.option.supernew) { - warning("W058", state.tokens.curr, state.tokens.curr.value); - } - this.first = c; - return this; - }); - state.syntax["new"].exps = true; - - prefix("void").exps = true; - - infix(".", function (left, that) { - adjacent(state.tokens.prev, state.tokens.curr); - nobreak(); - var m = identifier(false, true); - - if (typeof m === "string") { - countMember(m); - } - - that.left = left; - that.right = m; - - if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") { - warning("W001"); - } - - if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { - if (state.option.noarg) - warning("W059", left, m); - else if (state.directive["use strict"]) - error("E008"); - } else if (!state.option.evil && left && left.value === "document" && - (m === "write" || m === "writeln")) { - warning("W060", left); - } - - if (!state.option.evil && (m === "eval" || m === "execScript")) { - warning("W061"); - } - - return that; - }, 160, true); - - infix("(", function (left, that) { - if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") { - nobreak(state.tokens.prev, state.tokens.curr); - } - - nospace(); - if (state.option.immed && left && !left.immed && left.id === "function") { - warning("W062"); - } - - var n = 0; - var p = []; - - if (left) { - if (left.type === "(identifier)") { - if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if ("Number String Boolean Date Object".indexOf(left.value) === -1) { - if (left.value === "Math") { - warning("W063", left); - } else if (state.option.newcap) { - warning("W064", left); - } - } - } - } - } - - if (state.tokens.next.id !== ")") { - for (;;) { - p[p.length] = expression(10); - n += 1; - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - - advance(")"); - nospace(state.tokens.prev, state.tokens.curr); - - if (typeof left === "object") { - if (left.value === "parseInt" && n === 1) { - warning("W065", state.tokens.curr); - } - if (!state.option.evil) { - if (left.value === "eval" || left.value === "Function" || - left.value === "execScript") { - warning("W061", left); - - if (p[0] && [0].id === "(string)") { - addInternalSrc(left, p[0].value); - } - } else if (p[0] && p[0].id === "(string)" && - (left.value === "setTimeout" || - left.value === "setInterval")) { - warning("W066", left); - addInternalSrc(left, p[0].value); - - // window.setTimeout/setInterval - } else if (p[0] && p[0].id === "(string)" && - left.value === "." && - left.left.value === "window" && - (left.right === "setTimeout" || - left.right === "setInterval")) { - warning("W066", left); - addInternalSrc(left, p[0].value); - } - } - if (!left.identifier && left.id !== "." && left.id !== "[" && - left.id !== "(" && left.id !== "&&" && left.id !== "||" && - left.id !== "?") { - warning("W067", left); - } - } - - that.left = left; - return that; - }, 155, true).exps = true; - - prefix("(", function () { - nospace(); - var bracket, brackets = []; - var pn, pn1, i = 0; - - do { - pn = peek(i); - i += 1; - pn1 = peek(i); - i += 1; - } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)"); - - if (state.tokens.next.id === "function") { - state.tokens.next.immed = true; - } - - var exprs = []; - - if (state.tokens.next.id !== ")") { - for (;;) { - if (pn1.value === "=>" && state.tokens.next.value === "{") { - bracket = state.tokens.next; - bracket.left = destructuringExpression(); - brackets.push(bracket); - for (var t in bracket.left) { - exprs.push(bracket.left[t].token); - } - } else { - exprs.push(expression(5)); - } - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - - advance(")", this); - nospace(state.tokens.prev, state.tokens.curr); - if (state.option.immed && exprs[0] && exprs[0].id === "function") { - if (state.tokens.next.id !== "(" && - (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) { - warning("W068", this); - } - } - - if (state.tokens.next.value === "=>") { - return exprs; - } - if (!exprs.length) { - return; - } - exprs[exprs.length - 1].paren = true; - if (exprs.length > 1) { - return Object.create(state.syntax[","], { exprs: { value: exprs } }); - } - return exprs[0]; - }); - - application("=>"); - - infix("[", function (left, that) { - nobreak(state.tokens.prev, state.tokens.curr); - nospace(); - var e = expression(5), s; - if (e && e.type === "(string)") { - if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) { - warning("W061", that); - } - - countMember(e.value); - if (!state.option.sub && reg.identifier.test(e.value)) { - s = state.syntax[e.value]; - if (!s || !isReserved(s)) { - warning("W069", state.tokens.prev, e.value); - } - } - } - advance("]", that); - - if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") { - warning("W001"); - } - - nospace(state.tokens.prev, state.tokens.curr); - that.left = left; - that.right = e; - return that; - }, 160, true); - - function comprehensiveArrayExpression() { - var res = {}; - res.exps = true; - funct["(comparray)"].stack(); - - res.right = expression(5); - advance("for"); - if (state.tokens.next.value === "each") { - advance("each"); - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "for each"); - } - } - advance("("); - funct["(comparray)"].setState("define"); - res.left = expression(5); - advance(")"); - if (state.tokens.next.value === "if") { - advance("if"); - advance("("); - funct["(comparray)"].setState("filter"); - res.filter = expression(5); - advance(")"); - } - advance("]"); - funct["(comparray)"].unstack(); - return res; - } - - prefix("[", function () { - var blocktype = lookupBlockType(true); - if (blocktype.isCompArray) { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "array comprehension"); - } - return comprehensiveArrayExpression(); - } else if (blocktype.isDestAssign && !state.option.inESNext()) { - warning("W104", state.tokens.curr, "destructuring assignment"); - } - var b = state.tokens.curr.line !== state.tokens.next.line; - this.first = []; - if (b) { - indent += state.option.indent; - if (state.tokens.next.from === indent + state.option.indent) { - indent += state.option.indent; - } - } - while (state.tokens.next.id !== "(end)") { - while (state.tokens.next.id === ",") { - if (!state.option.inES5()) - warning("W070"); - advance(","); - } - if (state.tokens.next.id === "]") { - break; - } - if (b && state.tokens.curr.line !== state.tokens.next.line) { - indentation(); - } - this.first.push(expression(10)); - if (state.tokens.next.id === ",") { - comma({ allowTrailing: true }); - if (state.tokens.next.id === "]" && !state.option.inES5(true)) { - warning("W070", state.tokens.curr); - break; - } - } else { - break; - } - } - if (b) { - indent -= state.option.indent; - indentation(); - } - advance("]", this); - return this; - }, 160); - - - function property_name() { - var id = optionalidentifier(false, true); - - if (!id) { - if (state.tokens.next.id === "(string)") { - id = state.tokens.next.value; - advance(); - } else if (state.tokens.next.id === "(number)") { - id = state.tokens.next.value.toString(); - advance(); - } - } - - if (id === "hasOwnProperty") { - warning("W001"); - } - - return id; - } - - - function functionparams(parsed) { - var curr, next; - var params = []; - var ident; - var tokens = []; - var t; - - if (parsed) { - if (parsed instanceof Array) { - for (var i in parsed) { - curr = parsed[i]; - if (_.contains(["{", "["], curr.id)) { - for (t in curr.left) { - t = tokens[t]; - if (t.id) { - params.push(t.id); - addlabel(t.id, "unused", t.token); - } - } - } else if (curr.value === "...") { - if (!state.option.inESNext()) { - warning("W104", curr, "spread/rest operator"); - } - continue; - } else { - addlabel(curr.value, "unused", curr); - } - } - return params; - } else { - if (parsed.identifier === true) { - addlabel(parsed.value, "unused", parsed); - return [parsed]; - } - } - } - - next = state.tokens.next; - - advance("("); - nospace(); - - if (state.tokens.next.id === ")") { - advance(")"); - return; - } - - for (;;) { - if (_.contains(["{", "["], state.tokens.next.id)) { - tokens = destructuringExpression(); - for (t in tokens) { - t = tokens[t]; - if (t.id) { - params.push(t.id); - addlabel(t.id, "unused", t.token); - } - } - } else if (state.tokens.next.value === "...") { - if (!state.option.inESNext()) { - warning("W104", state.tokens.next, "spread/rest operator"); - } - advance("..."); - nospace(); - ident = identifier(true); - params.push(ident); - addlabel(ident, "unused", state.tokens.curr); - } else { - ident = identifier(true); - params.push(ident); - addlabel(ident, "unused", state.tokens.curr); - } - if (state.tokens.next.id === ",") { - comma(); - } else { - advance(")", next); - nospace(state.tokens.prev, state.tokens.curr); - return params; - } - } - } - - - function doFunction(name, statement, generator, fatarrowparams) { - var f; - var oldOption = state.option; - var oldIgnored = state.ignored; - var oldScope = scope; - - state.option = Object.create(state.option); - state.ignored = Object.create(state.ignored); - scope = Object.create(scope); - - funct = { - "(name)" : name || "\"" + anonname + "\"", - "(line)" : state.tokens.next.line, - "(character)" : state.tokens.next.character, - "(context)" : funct, - "(breakage)" : 0, - "(loopage)" : 0, - "(metrics)" : createMetrics(state.tokens.next), - "(scope)" : scope, - "(statement)" : statement, - "(tokens)" : {}, - "(blockscope)": funct["(blockscope)"], - "(comparray)" : funct["(comparray)"] - }; - - if (generator) { - funct["(generator)"] = true; - } - - f = funct; - state.tokens.curr.funct = funct; - - functions.push(funct); - - if (name) { - addlabel(name, "function"); - } - - funct["(params)"] = functionparams(fatarrowparams); - - funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]); - - block(false, true, true, fatarrowparams ? true:false); - - if (generator && funct["(generator)"] !== "yielded") { - error("E047", state.tokens.curr); - } - - funct["(metrics)"].verifyMaxStatementsPerFunction(); - funct["(metrics)"].verifyMaxComplexityPerFunction(); - funct["(unusedOption)"] = state.option.unused; - - scope = oldScope; - state.option = oldOption; - state.ignored = oldIgnored; - funct["(last)"] = state.tokens.curr.line; - funct["(lastcharacter)"] = state.tokens.curr.character; - funct = funct["(context)"]; - - return f; - } - - function createMetrics(functionStartToken) { - return { - statementCount: 0, - nestedBlockDepth: -1, - ComplexityCount: 1, - verifyMaxStatementsPerFunction: function () { - if (state.option.maxstatements && - this.statementCount > state.option.maxstatements) { - warning("W071", functionStartToken, this.statementCount); - } - }, - - verifyMaxParametersPerFunction: function (params) { - params = params || []; - - if (state.option.maxparams && params.length > state.option.maxparams) { - warning("W072", functionStartToken, params.length); - } - }, - - verifyMaxNestedBlockDepthPerFunction: function () { - if (state.option.maxdepth && - this.nestedBlockDepth > 0 && - this.nestedBlockDepth === state.option.maxdepth + 1) { - warning("W073", null, this.nestedBlockDepth); - } - }, - - verifyMaxComplexityPerFunction: function () { - var max = state.option.maxcomplexity; - var cc = this.ComplexityCount; - if (max && cc > max) { - warning("W074", functionStartToken, cc); - } - } - }; - } - - function increaseComplexityCount() { - funct["(metrics)"].ComplexityCount += 1; - } - - // Parse assignments that were found instead of conditionals. - // For example: if (a = 1) { ... } - - function checkCondAssignment(expr) { - var id = expr.id; - if (id === ",") { - expr = expr.exprs[expr.exprs.length - 1]; - id = expr.id; - } - switch (id) { - case "=": - case "+=": - case "-=": - case "*=": - case "%=": - case "&=": - case "|=": - case "^=": - case "/=": - if (!expr.paren && !state.option.boss) { - warning("W084"); - } - } - } - - - (function (x) { - x.nud = function (isclassdef) { - var b, f, i, p, t, g; - var props = {}; // All properties, including accessors - var tag = ""; - - function saveProperty(name, tkn) { - if (props[name] && _.has(props, name)) - warning("W075", state.tokens.next, i); - else - props[name] = {}; - - props[name].basic = true; - props[name].basictkn = tkn; - } - - function saveSetter(name, tkn) { - if (props[name] && _.has(props, name)) { - if (props[name].basic || props[name].setter) - warning("W075", state.tokens.next, i); - } else { - props[name] = {}; - } - - props[name].setter = true; - props[name].setterToken = tkn; - } - - function saveGetter(name) { - if (props[name] && _.has(props, name)) { - if (props[name].basic || props[name].getter) - warning("W075", state.tokens.next, i); - } else { - props[name] = {}; - } - - props[name].getter = true; - props[name].getterToken = state.tokens.curr; - } - - b = state.tokens.curr.line !== state.tokens.next.line; - if (b) { - indent += state.option.indent; - if (state.tokens.next.from === indent + state.option.indent) { - indent += state.option.indent; - } - } - - for (;;) { - if (state.tokens.next.id === "}") { - break; - } - - if (b) { - indentation(); - } - - if (isclassdef && state.tokens.next.value === "static") { - advance("static"); - tag = "static "; - } - - if (state.tokens.next.value === "get" && peek().id !== ":") { - advance("get"); - - if (!state.option.inES5(!isclassdef)) { - error("E034"); - } - - i = property_name(); - if (!i) { - error("E035"); - } - - // It is a Syntax Error if PropName of MethodDefinition is - // "constructor" and SpecialMethod of MethodDefinition is true. - if (isclassdef && i === "constructor") { - error("E049", state.tokens.next, "class getter method", i); - } - - saveGetter(tag + i); - t = state.tokens.next; - adjacent(state.tokens.curr, state.tokens.next); - f = doFunction(); - p = f["(params)"]; - - if (p) { - warning("W076", t, p[0], i); - } - - adjacent(state.tokens.curr, state.tokens.next); - } else if (state.tokens.next.value === "set" && peek().id !== ":") { - advance("set"); - - if (!state.option.inES5(!isclassdef)) { - error("E034"); - } - - i = property_name(); - if (!i) { - error("E035"); - } - - // It is a Syntax Error if PropName of MethodDefinition is - // "constructor" and SpecialMethod of MethodDefinition is true. - if (isclassdef && i === "constructor") { - error("E049", state.tokens.next, "class setter method", i); - } - - saveSetter(tag + i, state.tokens.next); - t = state.tokens.next; - adjacent(state.tokens.curr, state.tokens.next); - f = doFunction(); - p = f["(params)"]; - - if (!p || p.length !== 1) { - warning("W077", t, i); - } - } else { - g = false; - if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") { - if (!state.option.inESNext()) { - warning("W104", state.tokens.next, "generator functions"); - } - advance("*"); - g = true; - } - i = property_name(); - saveProperty(tag + i, state.tokens.next); - - if (typeof i !== "string") { - break; - } - - if (state.tokens.next.value === "(") { - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "concise methods"); - } - doFunction(i, undefined, g); - } else if (!isclassdef) { - advance(":"); - nonadjacent(state.tokens.curr, state.tokens.next); - expression(10); - } - } - // It is a Syntax Error if PropName of MethodDefinition is "prototype". - if (isclassdef && i === "prototype") { - error("E049", state.tokens.next, "class method", i); - } - - countMember(i); - if (isclassdef) { - tag = ""; - continue; - } - if (state.tokens.next.id === ",") { - comma({ allowTrailing: true, property: true }); - if (state.tokens.next.id === ",") { - warning("W070", state.tokens.curr); - } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) { - warning("W070", state.tokens.curr); - } - } else { - break; - } - } - if (b) { - indent -= state.option.indent; - indentation(); - } - advance("}", this); - - // Check for lonely setters if in the ES5 mode. - if (state.option.inES5()) { - for (var name in props) { - if (_.has(props, name) && props[name].setter && !props[name].getter) { - warning("W078", props[name].setterToken); - } - } - } - return this; - }; - x.fud = function () { - error("E036", state.tokens.curr); - }; - }(delim("{"))); - - function destructuringExpression() { - var id, ids; - var identifiers = []; - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "destructuring expression"); - } - var nextInnerDE = function () { - var ident; - if (_.contains(["[", "{"], state.tokens.next.value)) { - ids = destructuringExpression(); - for (var id in ids) { - id = ids[id]; - identifiers.push({ id: id.id, token: id.token }); - } - } else if (state.tokens.next.value === ",") { - identifiers.push({ id: null, token: state.tokens.curr }); - } else { - ident = identifier(); - if (ident) - identifiers.push({ id: ident, token: state.tokens.curr }); - } - }; - if (state.tokens.next.value === "[") { - advance("["); - nextInnerDE(); - while (state.tokens.next.value !== "]") { - advance(","); - nextInnerDE(); - } - advance("]"); - } else if (state.tokens.next.value === "{") { - advance("{"); - id = identifier(); - if (state.tokens.next.value === ":") { - advance(":"); - nextInnerDE(); - } else { - identifiers.push({ id: id, token: state.tokens.curr }); - } - while (state.tokens.next.value !== "}") { - advance(","); - id = identifier(); - if (state.tokens.next.value === ":") { - advance(":"); - nextInnerDE(); - } else { - identifiers.push({ id: id, token: state.tokens.curr }); - } - } - advance("}"); - } - return identifiers; - } - function destructuringExpressionMatch(tokens, value) { - if (value.first) { - _.zip(tokens, value.first).forEach(function (val) { - var token = val[0]; - var value = val[1]; - if (token && value) { - token.first = value; - } else if (token && token.first && !value) { - warning("W080", token.first, token.first.value); - } /* else { - XXX value is discarded: wouldn't it need a warning ? - } */ - }); - } - } - - var conststatement = stmt("const", function (prefix) { - var tokens, value; - // state variable to know if it is a lone identifier, or a destructuring statement. - var lone; - - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "const"); - } - - this.first = []; - for (;;) { - var names = []; - nonadjacent(state.tokens.curr, state.tokens.next); - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringExpression(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr } ]; - lone = true; - } - for (var t in tokens) { - t = tokens[t]; - if (funct[t.id] === "const") { - warning("E011", null, t.id); - } - if (funct["(global)"] && predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - if (t.id) { - addlabel(t.id, "const"); - names.push(t.token); - } - } - if (prefix) { - break; - } - - this.first = this.first.concat(names); - - if (state.tokens.next.id !== "=") { - warning("E012", state.tokens.curr, state.tokens.curr.value); - } - - if (state.tokens.next.id === "=") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("="); - nonadjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - error("E037", state.tokens.next, state.tokens.next.value); - } - value = expression(5); - if (lone) { - tokens[0].first = value; - } else { - destructuringExpressionMatch(names, value); - } - } - - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - return this; - }); - conststatement.exps = true; - var varstatement = stmt("var", function (prefix) { - // JavaScript does not have block scope. It only has function scope. So, - // declaring a variable in a block can have unexpected consequences. - var tokens, lone, value; - - if (funct["(onevar)"] && state.option.onevar) { - warning("W081"); - } else if (!funct["(global)"]) { - funct["(onevar)"] = true; - } - - this.first = []; - for (;;) { - var names = []; - nonadjacent(state.tokens.curr, state.tokens.next); - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringExpression(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr } ]; - lone = true; - } - for (var t in tokens) { - t = tokens[t]; - if (state.option.inESNext() && funct[t.id] === "const") { - warning("E011", null, t.id); - } - if (funct["(global)"] && predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - if (t.id) { - addlabel(t.id, "unused", t.token); - names.push(t.token); - } - } - if (prefix) { - break; - } - - this.first = this.first.concat(names); - - if (state.tokens.next.id === "=") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("="); - nonadjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - error("E038", state.tokens.next, state.tokens.next.value); - } - value = expression(5); - if (lone) { - tokens[0].first = value; - } else { - destructuringExpressionMatch(names, value); - } - } - - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - return this; - }); - varstatement.exps = true; - var letstatement = stmt("let", function (prefix) { - var tokens, lone, value, letblock; - - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "let"); - } - - if (state.tokens.next.value === "(") { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.next, "let block"); - } - advance("("); - funct["(blockscope)"].stack(); - letblock = true; - } else if (funct["(nolet)"]) { - error("E048", state.tokens.curr); - } - - if (funct["(onevar)"] && state.option.onevar) { - warning("W081"); - } else if (!funct["(global)"]) { - funct["(onevar)"] = true; - } - - this.first = []; - for (;;) { - var names = []; - nonadjacent(state.tokens.curr, state.tokens.next); - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringExpression(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr.value } ]; - lone = true; - } - for (var t in tokens) { - t = tokens[t]; - if (state.option.inESNext() && funct[t.id] === "const") { - warning("E011", null, t.id); - } - if (funct["(global)"] && predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - if (t.id && !funct["(nolet)"]) { - addlabel(t.id, "unused", t.token, true); - names.push(t.token); - } - } - if (prefix) { - break; - } - - this.first = this.first.concat(names); - - if (state.tokens.next.id === "=") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("="); - nonadjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - error("E037", state.tokens.next, state.tokens.next.value); - } - value = expression(5); - if (lone) { - tokens[0].first = value; - } else { - destructuringExpressionMatch(names, value); - } - } - - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - if (letblock) { - advance(")"); - block(true, true); - this.block = true; - funct["(blockscope)"].unstack(); - } - - return this; - }); - letstatement.exps = true; - - blockstmt("class", function () { - return classdef.call(this, true); - }); - - function classdef(stmt) { - /*jshint validthis:true */ - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "class"); - } - if (stmt) { - // BindingIdentifier - this.name = identifier(); - addlabel(this.name, "unused", state.tokens.curr); - } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { - // BindingIdentifier(opt) - this.name = identifier(); - } - classtail(this); - return this; - } - - function classtail(c) { - var strictness = state.directive["use strict"]; - - // ClassHeritage(opt) - if (state.tokens.next.value === "extends") { - advance("extends"); - c.heritage = expression(10); - } - - // A ClassBody is always strict code. - state.directive["use strict"] = true; - advance("{"); - // ClassBody(opt) - c.body = state.syntax["{"].nud(true); - state.directive["use strict"] = strictness; - } - - blockstmt("function", function () { - var generator = false; - if (state.tokens.next.value === "*") { - advance("*"); - if (state.option.inESNext(true)) { - generator = true; - } else { - warning("W119", state.tokens.curr, "function*"); - } - } - if (inblock) { - warning("W082", state.tokens.curr); - - } - var i = identifier(); - if (funct[i] === "const") { - warning("E011", null, i); - } - adjacent(state.tokens.curr, state.tokens.next); - addlabel(i, "unction", state.tokens.curr); - - doFunction(i, { statement: true }, generator); - if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) { - error("E039"); - } - return this; - }); - - prefix("function", function () { - var generator = false; - if (state.tokens.next.value === "*") { - if (!state.option.inESNext()) { - warning("W119", state.tokens.curr, "function*"); - } - advance("*"); - generator = true; - } - var i = optionalidentifier(); - if (i || state.option.gcl) { - adjacent(state.tokens.curr, state.tokens.next); - } else { - nonadjacent(state.tokens.curr, state.tokens.next); - } - doFunction(i, undefined, generator); - if (!state.option.loopfunc && funct["(loopage)"]) { - warning("W083"); - } - return this; - }); - - blockstmt("if", function () { - var t = state.tokens.next; - increaseComplexityCount(); - state.condition = true; - advance("("); - nonadjacent(this, t); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - state.condition = false; - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - if (state.tokens.next.id === "else") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("else"); - if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") { - statement(true); - } else { - block(true, true); - } - } - return this; - }); - - blockstmt("try", function () { - var b; - - function doCatch() { - var oldScope = scope; - var e; - - advance("catch"); - nonadjacent(state.tokens.curr, state.tokens.next); - advance("("); - - scope = Object.create(oldScope); - - e = state.tokens.next.value; - if (state.tokens.next.type !== "(identifier)") { - e = null; - warning("E030", state.tokens.next, e); - } - - advance(); - - funct = { - "(name)" : "(catch)", - "(line)" : state.tokens.next.line, - "(character)": state.tokens.next.character, - "(context)" : funct, - "(breakage)" : funct["(breakage)"], - "(loopage)" : funct["(loopage)"], - "(scope)" : scope, - "(statement)": false, - "(metrics)" : createMetrics(state.tokens.next), - "(catch)" : true, - "(tokens)" : {}, - "(blockscope)": funct["(blockscope)"], - "(comparray)": funct["(comparray)"] - }; - - if (e) { - addlabel(e, "exception"); - } - - if (state.tokens.next.value === "if") { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "catch filter"); - } - advance("if"); - expression(0); - } - - advance(")"); - - state.tokens.curr.funct = funct; - functions.push(funct); - - block(false); - - scope = oldScope; - - funct["(last)"] = state.tokens.curr.line; - funct["(lastcharacter)"] = state.tokens.curr.character; - funct = funct["(context)"]; - } - - block(false); - - while (state.tokens.next.id === "catch") { - increaseComplexityCount(); - if (b && (!state.option.inMoz(true))) { - warning("W118", state.tokens.next, "multiple catch blocks"); - } - doCatch(); - b = true; - } - - if (state.tokens.next.id === "finally") { - advance("finally"); - block(false); - return; - } - - if (!b) { - error("E021", state.tokens.next, "catch", state.tokens.next.value); - } - - return this; - }); - - blockstmt("while", function () { - var t = state.tokens.next; - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - }).labelled = true; - - blockstmt("with", function () { - var t = state.tokens.next; - if (state.directive["use strict"]) { - error("E010", state.tokens.curr); - } else if (!state.option.withstmt) { - warning("W085", state.tokens.curr); - } - - advance("("); - nonadjacent(this, t); - nospace(); - expression(0); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - - return this; - }); - - blockstmt("switch", function () { - var t = state.tokens.next, - g = false; - funct["(breakage)"] += 1; - advance("("); - nonadjacent(this, t); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - t = state.tokens.next; - advance("{"); - nonadjacent(state.tokens.curr, state.tokens.next); - indent += state.option.indent; - this.cases = []; - - for (;;) { - switch (state.tokens.next.id) { - case "case": - switch (funct["(verb)"]) { - case "yield": - case "break": - case "case": - case "continue": - case "return": - case "switch": - case "throw": - break; - default: - // You can tell JSHint that you don't use break intentionally by - // adding a comment /* falls through */ on a line just before - // the next `case`. - if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { - warning("W086", state.tokens.curr, "case"); - } - } - indentation(-state.option.indent); - advance("case"); - this.cases.push(expression(20)); - increaseComplexityCount(); - g = true; - advance(":"); - funct["(verb)"] = "case"; - break; - case "default": - switch (funct["(verb)"]) { - case "yield": - case "break": - case "continue": - case "return": - case "throw": - break; - default: - // Do not display a warning if 'default' is the first statement or if - // there is a special /* falls through */ comment. - if (this.cases.length) { - if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { - warning("W086", state.tokens.curr, "default"); - } - } - } - indentation(-state.option.indent); - advance("default"); - g = true; - advance(":"); - break; - case "}": - indent -= state.option.indent; - indentation(); - advance("}", t); - funct["(breakage)"] -= 1; - funct["(verb)"] = undefined; - return; - case "(end)": - error("E023", state.tokens.next, "}"); - return; - default: - if (g) { - switch (state.tokens.curr.id) { - case ",": - error("E040"); - return; - case ":": - g = false; - statements(); - break; - default: - error("E025", state.tokens.curr); - return; - } - } else { - if (state.tokens.curr.id === ":") { - advance(":"); - error("E024", state.tokens.curr, ":"); - statements(); - } else { - error("E021", state.tokens.next, "case", state.tokens.next.value); - return; - } - } - } - } - }).labelled = true; - - stmt("debugger", function () { - if (!state.option.debug) { - warning("W087"); - } - return this; - }).exps = true; - - (function () { - var x = stmt("do", function () { - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - - this.first = block(true, true); - advance("while"); - var t = state.tokens.next; - nonadjacent(state.tokens.curr, t); - advance("("); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - }); - x.labelled = true; - x.exps = true; - }()); - - blockstmt("for", function () { - var s, t = state.tokens.next; - var letscope = false; - var foreachtok = null; - - if (t.value === "each") { - foreachtok = t; - advance("each"); - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "for each"); - } - } - - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - - // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)? - var nextop; // contains the token of the "in" or "of" operator - var i = 0; - var inof = ["in", "of"]; - do { - nextop = peek(i); - ++i; - } while (!_.contains(inof, nextop.value) && nextop.value !== ";" && - nextop.type !== "(end)"); - - // if we're in a for (… in|of …) statement - if (_.contains(inof, nextop.value)) { - if (!state.option.inESNext() && nextop.value === "of") { - error("W104", nextop, "for of"); - } - if (state.tokens.next.id === "var") { - advance("var"); - state.syntax["var"].fud.call(state.syntax["var"].fud, true); - } else if (state.tokens.next.id === "let") { - advance("let"); - // create a new block scope - letscope = true; - funct["(blockscope)"].stack(); - state.syntax["let"].fud.call(state.syntax["let"].fud, true); - } else { - switch (funct[state.tokens.next.value]) { - case "unused": - funct[state.tokens.next.value] = "var"; - break; - case "var": - break; - default: - if (!funct["(blockscope)"].getlabel(state.tokens.next.value)) - warning("W088", state.tokens.next, state.tokens.next.value); - } - advance(); - } - advance(nextop.value); - expression(20); - advance(")", t); - s = block(true, true); - if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" || - s[0].value !== "if")) { - warning("W089", this); - } - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - } else { - if (foreachtok) { - error("E045", foreachtok); - } - if (state.tokens.next.id !== ";") { - if (state.tokens.next.id === "var") { - advance("var"); - state.syntax["var"].fud.call(state.syntax["var"].fud); - } else if (state.tokens.next.id === "let") { - advance("let"); - // create a new block scope - letscope = true; - funct["(blockscope)"].stack(); - state.syntax["let"].fud.call(state.syntax["let"].fud); - } else { - for (;;) { - expression(0, "for"); - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - } - nolinebreak(state.tokens.curr); - advance(";"); - if (state.tokens.next.id !== ";") { - checkCondAssignment(expression(0)); - } - nolinebreak(state.tokens.curr); - advance(";"); - if (state.tokens.next.id === ";") { - error("E021", state.tokens.next, ")", ";"); - } - if (state.tokens.next.id !== ")") { - for (;;) { - expression(0, "for"); - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - - } - // unstack loop blockscope - if (letscope) { - funct["(blockscope)"].unstack(); - } - return this; - }).labelled = true; - - - stmt("break", function () { - var v = state.tokens.next.value; - - if (funct["(breakage)"] === 0) - warning("W052", state.tokens.next, this.value); - - if (!state.option.asi) - nolinebreak(this); - - if (state.tokens.next.id !== ";") { - if (state.tokens.curr.line === state.tokens.next.line) { - if (funct[v] !== "label") { - warning("W090", state.tokens.next, v); - } else if (scope[v] !== funct) { - warning("W091", state.tokens.next, v); - } - this.first = state.tokens.next; - advance(); - } - } - reachable("break"); - return this; - }).exps = true; - - - stmt("continue", function () { - var v = state.tokens.next.value; - - if (funct["(breakage)"] === 0) - warning("W052", state.tokens.next, this.value); - - if (!state.option.asi) - nolinebreak(this); - - if (state.tokens.next.id !== ";") { - if (state.tokens.curr.line === state.tokens.next.line) { - if (funct[v] !== "label") { - warning("W090", state.tokens.next, v); - } else if (scope[v] !== funct) { - warning("W091", state.tokens.next, v); - } - this.first = state.tokens.next; - advance(); - } - } else if (!funct["(loopage)"]) { - warning("W052", state.tokens.next, this.value); - } - reachable("continue"); - return this; - }).exps = true; - - - stmt("return", function () { - if (this.line === state.tokens.next.line) { - if (state.tokens.next.id === "(regexp)") - warning("W092"); - - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - nonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(0); - - if (this.first && - this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) { - warningAt("W093", this.first.line, this.first.character); - } - } - } else { - if (state.tokens.next.type === "(punctuator)" && - ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) { - nolinebreak(this); // always warn (Line breaking error) - } - } - reachable("return"); - return this; - }).exps = true; - - stmt("yield", function () { - if (state.option.inESNext(true) && funct["(generator)"] !== true) { - error("E046", state.tokens.curr, "yield"); - } else if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "yield"); - } - funct["(generator)"] = "yielded"; - if (this.line === state.tokens.next.line) { - if (state.tokens.next.id === "(regexp)") - warning("W092"); - - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - nonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(0); - - if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) { - warningAt("W093", this.first.line, this.first.character); - } - } - } else if (!state.option.asi) { - nolinebreak(this); // always warn (Line breaking error) - } - return this; - }).exps = true; - - - stmt("throw", function () { - nolinebreak(this); - nonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(20); - reachable("throw"); - return this; - }).exps = true; - - // Future Reserved Words - - FutureReservedWord("abstract"); - FutureReservedWord("boolean"); - FutureReservedWord("byte"); - FutureReservedWord("char"); - FutureReservedWord("class", { es5: true, nud: classdef }); - FutureReservedWord("double"); - FutureReservedWord("enum", { es5: true }); - FutureReservedWord("export", { es5: true }); - FutureReservedWord("extends", { es5: true }); - FutureReservedWord("final"); - FutureReservedWord("float"); - FutureReservedWord("goto"); - FutureReservedWord("implements", { es5: true, strictOnly: true }); - FutureReservedWord("import", { es5: true }); - FutureReservedWord("int"); - FutureReservedWord("interface", { es5: true, strictOnly: true }); - FutureReservedWord("long"); - FutureReservedWord("native"); - FutureReservedWord("package", { es5: true, strictOnly: true }); - FutureReservedWord("private", { es5: true, strictOnly: true }); - FutureReservedWord("protected", { es5: true, strictOnly: true }); - FutureReservedWord("public", { es5: true, strictOnly: true }); - FutureReservedWord("short"); - FutureReservedWord("static", { es5: true, strictOnly: true }); - FutureReservedWord("super", { es5: true }); - FutureReservedWord("synchronized"); - FutureReservedWord("throws"); - FutureReservedWord("transient"); - FutureReservedWord("volatile"); - - // this function is used to determine wether a squarebracket or a curlybracket - // expression is a comprehension array, destructuring assignment or a json value. - - var lookupBlockType = function () { - var pn, pn1; - var i = 0; - var bracketStack = 0; - var ret = {}; - if (_.contains(["[", "{"], state.tokens.curr.value)) - bracketStack += 1; - if (_.contains(["[", "{"], state.tokens.next.value)) - bracketStack += 1; - if (_.contains(["]", "}"], state.tokens.next.value)) - bracketStack -= 1; - do { - pn = peek(i); - pn1 = peek(i + 1); - i = i + 1; - if (_.contains(["[", "{"], pn.value)) { - bracketStack += 1; - } else if (_.contains(["]", "}"], pn.value)) { - bracketStack -= 1; - } - if (pn.identifier && pn.value === "for" && bracketStack === 1) { - ret.isCompArray = true; - ret.notJson = true; - break; - } - if (_.contains(["}", "]"], pn.value) && pn1.value === "=") { - ret.isDestAssign = true; - ret.notJson = true; - break; - } - if (pn.value === ";") { - ret.isBlock = true; - ret.notJson = true; - } - } while (bracketStack > 0 && pn.id !== "(end)" && i < 15); - return ret; - }; - - // Check whether this function has been reached for a destructuring assign with undeclared values - function destructuringAssignOrJsonValue() { - // lookup for the assignment (esnext only) - // if it has semicolons, it is a block, so go parse it as a block - // or it's not a block, but there are assignments, check for undeclared variables - - var block = lookupBlockType(); - if (block.notJson) { - if (!state.option.inESNext() && block.isDestAssign) { - warning("W104", state.tokens.curr, "destructuring assignment"); - } - statements(); - // otherwise parse json value - } else { - state.option.laxbreak = true; - state.jsonMode = true; - jsonValue(); - } - } - - // array comprehension parsing function - // parses and defines the three states of the list comprehension in order - // to avoid defining global variables, but keeping them to the list comprehension scope - // only. The order of the states are as follows: - // * "use" which will be the returned iterative part of the list comprehension - // * "define" which will define the variables local to the list comprehension - // * "filter" which will help filter out values - - var arrayComprehension = function () { - var CompArray = function () { - this.mode = "use"; - this.variables = []; - }; - var _carrays = []; - var _current; - function declare(v) { - var l = _current.variables.filter(function (elt) { - // if it has, change its undef state - if (elt.value === v) { - elt.undef = false; - return v; - } - }).length; - return l !== 0; - } - function use(v) { - var l = _current.variables.filter(function (elt) { - // and if it has been defined - if (elt.value === v && !elt.undef) { - if (elt.unused === true) { - elt.unused = false; - } - return v; - } - }).length; - // otherwise we warn about it - return (l === 0); - } - return {stack: function () { - _current = new CompArray(); - _carrays.push(_current); - }, - unstack: function () { - _current.variables.filter(function (v) { - if (v.unused) - warning("W098", v.token, v.value); - if (v.undef) - isundef(v.funct, "W117", v.token, v.value); - }); - _carrays.splice(_carrays[_carrays.length - 1], 1); - _current = _carrays[_carrays.length - 1]; - }, - setState: function (s) { - if (_.contains(["use", "define", "filter"], s)) - _current.mode = s; - }, - check: function (v) { - // When we are in "use" state of the list comp, we enqueue that var - if (_current && _current.mode === "use") { - _current.variables.push({funct: funct, - token: state.tokens.curr, - value: v, - undef: true, - unused: false}); - return true; - // When we are in "define" state of the list comp, - } else if (_current && _current.mode === "define") { - // check if the variable has been used previously - if (!declare(v)) { - _current.variables.push({funct: funct, - token: state.tokens.curr, - value: v, - undef: false, - unused: true}); - } - return true; - // When we are in "filter" state, - } else if (_current && _current.mode === "filter") { - // we check whether current variable has been declared - if (use(v)) { - // if not we warn about it - isundef(funct, "W117", state.tokens.curr, v); - } - return true; - } - return false; - } - }; - }; - - - // Parse JSON - - function jsonValue() { - - function jsonObject() { - var o = {}, t = state.tokens.next; - advance("{"); - if (state.tokens.next.id !== "}") { - for (;;) { - if (state.tokens.next.id === "(end)") { - error("E026", state.tokens.next, t.line); - } else if (state.tokens.next.id === "}") { - warning("W094", state.tokens.curr); - break; - } else if (state.tokens.next.id === ",") { - error("E028", state.tokens.next); - } else if (state.tokens.next.id !== "(string)") { - warning("W095", state.tokens.next, state.tokens.next.value); - } - if (o[state.tokens.next.value] === true) { - warning("W075", state.tokens.next, state.tokens.next.value); - } else if ((state.tokens.next.value === "__proto__" && - !state.option.proto) || (state.tokens.next.value === "__iterator__" && - !state.option.iterator)) { - warning("W096", state.tokens.next, state.tokens.next.value); - } else { - o[state.tokens.next.value] = true; - } - advance(); - advance(":"); - jsonValue(); - if (state.tokens.next.id !== ",") { - break; - } - advance(","); - } - } - advance("}"); - } - - function jsonArray() { - var t = state.tokens.next; - advance("["); - if (state.tokens.next.id !== "]") { - for (;;) { - if (state.tokens.next.id === "(end)") { - error("E027", state.tokens.next, t.line); - } else if (state.tokens.next.id === "]") { - warning("W094", state.tokens.curr); - break; - } else if (state.tokens.next.id === ",") { - error("E028", state.tokens.next); - } - jsonValue(); - if (state.tokens.next.id !== ",") { - break; - } - advance(","); - } - } - advance("]"); - } - - switch (state.tokens.next.id) { - case "{": - jsonObject(); - break; - case "[": - jsonArray(); - break; - case "true": - case "false": - case "null": - case "(number)": - case "(string)": - advance(); - break; - case "-": - advance("-"); - if (state.tokens.curr.character !== state.tokens.next.from) { - warning("W011", state.tokens.curr); - } - adjacent(state.tokens.curr, state.tokens.next); - advance("(number)"); - break; - default: - error("E003", state.tokens.next); - } - } - - var blockScope = function () { - var _current = {}; - var _variables = [_current]; - - function _checkBlockLabels() { - for (var t in _current) { - if (_current[t]["(type)"] === "unused") { - if (state.option.unused) { - var tkn = _current[t]["(token)"]; - var line = tkn.line; - var chr = tkn.character; - warningAt("W098", line, chr, t); - } - } - } - } - - return { - stack: function () { - _current = {}; - _variables.push(_current); - }, - - unstack: function () { - _checkBlockLabels(); - _variables.splice(_variables.length - 1, 1); - _current = _.last(_variables); - }, - - getlabel: function (l) { - for (var i = _variables.length - 1 ; i >= 0; --i) { - if (_.has(_variables[i], l)) { - return _variables[i]; - } - } - }, - - current: { - has: function (t) { - return _.has(_current, t); - }, - add: function (t, type, tok) { - _current[t] = { "(type)" : type, - "(token)": tok }; - } - } - }; - }; - - // The actual JSHINT function itself. - var itself = function (s, o, g) { - var a, i, k, x; - var optionKeys; - var newOptionObj = {}; - var newIgnoredObj = {}; - - state.reset(); - - if (o && o.scope) { - JSHINT.scope = o.scope; - } else { - JSHINT.errors = []; - JSHINT.undefs = []; - JSHINT.internals = []; - JSHINT.blacklist = {}; - JSHINT.scope = "(main)"; - } - - predefined = Object.create(null); - combine(predefined, vars.ecmaIdentifiers); - combine(predefined, vars.reservedVars); - - combine(predefined, g || {}); - - declared = Object.create(null); - exported = Object.create(null); - - if (o) { - a = o.predef; - if (a) { - if (!Array.isArray(a) && typeof a === "object") { - a = Object.keys(a); - } - - a.forEach(function (item) { - var slice, prop; - - if (item[0] === "-") { - slice = item.slice(1); - JSHINT.blacklist[slice] = slice; - } else { - prop = Object.getOwnPropertyDescriptor(o.predef, item); - predefined[item] = prop ? prop.value : false; - } - }); - } - - optionKeys = Object.keys(o); - for (x = 0; x < optionKeys.length; x++) { - if (/^-W\d{3}$/g.test(optionKeys[x])) { - newIgnoredObj[optionKeys[x].slice(1)] = true; - } else { - newOptionObj[optionKeys[x]] = o[optionKeys[x]]; - - if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) - newOptionObj["(explicitNewcap)"] = true; - - if (optionKeys[x] === "indent") - newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true; - } - } - } - - state.option = newOptionObj; - state.ignored = newIgnoredObj; - - state.option.indent = state.option.indent || 4; - state.option.maxerr = state.option.maxerr || 50; - - indent = 1; - global = Object.create(predefined); - scope = global; - funct = { - "(global)": true, - "(name)": "(global)", - "(scope)": scope, - "(breakage)": 0, - "(loopage)": 0, - "(tokens)": {}, - "(metrics)": createMetrics(state.tokens.next), - "(blockscope)": blockScope(), - "(comparray)": arrayComprehension() - }; - functions = [funct]; - urls = []; - stack = null; - member = {}; - membersOnly = null; - implied = {}; - inblock = false; - lookahead = []; - warnings = 0; - unuseds = []; - - if (!isString(s) && !Array.isArray(s)) { - errorAt("E004", 0); - return false; - } - - api = { - get isJSON() { - return state.jsonMode; - }, - - getOption: function (name) { - return state.option[name] || null; - }, - - getCache: function (name) { - return state.cache[name]; - }, - - setCache: function (name, value) { - state.cache[name] = value; - }, - - warn: function (code, data) { - warningAt.apply(null, [ code, data.line, data.char ].concat(data.data)); - }, - - on: function (names, listener) { - names.split(" ").forEach(function (name) { - emitter.on(name, listener); - }.bind(this)); - } - }; - - emitter.removeAllListeners(); - (extraModules || []).forEach(function (func) { - func(api); - }); - - state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"]; - - lex = new Lexer(s); - - lex.on("warning", function (ev) { - warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data)); - }); - - lex.on("error", function (ev) { - errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data)); - }); - - lex.on("fatal", function (ev) { - quit("E041", ev.line, ev.from); - }); - - lex.on("Identifier", function (ev) { - emitter.emit("Identifier", ev); - }); - - lex.on("String", function (ev) { - emitter.emit("String", ev); - }); - - lex.on("Number", function (ev) { - emitter.emit("Number", ev); - }); - - lex.start(); - - // Check options - for (var name in o) { - if (_.has(o, name)) { - checkOption(name, state.tokens.curr); - } - } - - assume(); - - // combine the passed globals after we've assumed all our options - combine(predefined, g || {}); - - //reset values - comma.first = true; - - try { - advance(); - switch (state.tokens.next.id) { - case "{": - case "[": - destructuringAssignOrJsonValue(); - break; - default: - directives(); - - if (state.directive["use strict"]) { - if (!state.option.globalstrict && !state.option.node) { - warning("W097", state.tokens.prev); - } - } - - statements(); - } - advance((state.tokens.next && state.tokens.next.value !== ".") ? "(end)" : undefined); - funct["(blockscope)"].unstack(); - - var markDefined = function (name, context) { - do { - if (typeof context[name] === "string") { - // JSHINT marks unused variables as 'unused' and - // unused function declaration as 'unction'. This - // code changes such instances back 'var' and - // 'closure' so that the code in JSHINT.data() - // doesn't think they're unused. - - if (context[name] === "unused") - context[name] = "var"; - else if (context[name] === "unction") - context[name] = "closure"; - - return true; - } - - context = context["(context)"]; - } while (context); - - return false; - }; - - var clearImplied = function (name, line) { - if (!implied[name]) - return; - - var newImplied = []; - for (var i = 0; i < implied[name].length; i += 1) { - if (implied[name][i] !== line) - newImplied.push(implied[name][i]); - } - - if (newImplied.length === 0) - delete implied[name]; - else - implied[name] = newImplied; - }; - - var warnUnused = function (name, tkn, type, unused_opt) { - var line = tkn.line; - var chr = tkn.character; - - if (unused_opt === undefined) { - unused_opt = state.option.unused; - } - - if (unused_opt === true) { - unused_opt = "last-param"; - } - - var warnable_types = { - "vars": ["var"], - "last-param": ["var", "param"], - "strict": ["var", "param", "last-param"] - }; - - if (unused_opt) { - if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) { - warningAt("W098", line, chr, name); - } - } - - unuseds.push({ - name: name, - line: line, - character: chr - }); - }; - - var checkUnused = function (func, key) { - var type = func[key]; - var tkn = func["(tokens)"][key]; - - if (key.charAt(0) === "(") - return; - - if (type !== "unused" && type !== "unction") - return; - - // Params are checked separately from other variables. - if (func["(params)"] && func["(params)"].indexOf(key) !== -1) - return; - - // Variable is in global scope and defined as exported. - if (func["(global)"] && _.has(exported, key)) { - return; - } - - warnUnused(key, tkn, "var"); - }; - - // Check queued 'x is not defined' instances to see if they're still undefined. - for (i = 0; i < JSHINT.undefs.length; i += 1) { - k = JSHINT.undefs[i].slice(0); - - if (markDefined(k[2].value, k[0])) { - clearImplied(k[2].value, k[2].line); - } else if (state.option.undef) { - warning.apply(warning, k.slice(1)); - } - } - - functions.forEach(function (func) { - if (func["(unusedOption)"] === false) { - return; - } - - for (var key in func) { - if (_.has(func, key)) { - checkUnused(func, key); - } - } - - if (!func["(params)"]) - return; - - var params = func["(params)"].slice(); - var param = params.pop(); - var type, unused_opt; - - while (param) { - type = func[param]; - unused_opt = func["(unusedOption)"] || state.option.unused; - unused_opt = unused_opt === true ? "last-param" : unused_opt; - - // 'undefined' is a special case for (function (window, undefined) { ... })(); - // patterns. - - if (param === "undefined") - return; - - if (type === "unused" || type === "unction") { - warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]); - } else if (unused_opt === "last-param") { - return; - } - - param = params.pop(); - } - }); - - for (var key in declared) { - if (_.has(declared, key) && !_.has(global, key)) { - warnUnused(key, declared[key], "var"); - } - } - - } catch (err) { - if (err && err.name === "JSHintError") { - var nt = state.tokens.next || {}; - JSHINT.errors.push({ - scope : "(main)", - raw : err.raw, - reason : err.message, - line : err.line || nt.line, - character : err.character || nt.from - }, null); - } else { - throw err; - } - } - - // Loop over the listed "internals", and check them as well. - - if (JSHINT.scope === "(main)") { - o = o || {}; - - for (i = 0; i < JSHINT.internals.length; i += 1) { - k = JSHINT.internals[i]; - o.scope = k.elem; - itself(k.value, o, g); - } - } - - return JSHINT.errors.length === 0; - }; - - // Modules. - itself.addModule = function (func) { - extraModules.push(func); - }; - - itself.addModule(style.register); - - // Data summary. - itself.data = function () { - var data = { - functions: [], - options: state.option - }; - var implieds = []; - var members = []; - var fu, f, i, j, n, globals; - - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (state.jsonMode) { - data.json = true; - } - - for (n in implied) { - if (_.has(implied, n)) { - implieds.push({ - name: n, - line: implied[n] - }); - } - } - - if (implieds.length > 0) { - data.implieds = implieds; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(scope); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - f = functions[i]; - fu = {}; - - for (j = 0; j < functionicity.length; j += 1) { - fu[functionicity[j]] = []; - } - - for (j = 0; j < functionicity.length; j += 1) { - if (fu[functionicity[j]].length === 0) { - delete fu[functionicity[j]]; - } - } - - fu.name = f["(name)"]; - fu.param = f["(params)"]; - fu.line = f["(line)"]; - fu.character = f["(character)"]; - fu.last = f["(last)"]; - fu.lastcharacter = f["(lastcharacter)"]; - data.functions.push(fu); - } - - if (unuseds.length > 0) { - data.unused = unuseds; - } - - members = []; - for (n in member) { - if (typeof member[n] === "number") { - data.member = member; - break; - } - } - - return data; - }; - - itself.jshint = itself; - - return itself; -}()); - -// Make JSHINT a Node module, if possible. -if (typeof exports === "object" && exports) { - exports.JSHINT = JSHINT; -} - -})() -},{"events":2,"../shared/vars.js":3,"./lex.js":10,"./reg.js":6,"./state.js":4,"../shared/messages.js":12,"./style.js":5,"console-browserify":7,"underscore":11}],12:[function(require,module,exports){ -(function(){"use strict"; - -var _ = require("underscore"); - -var errors = { - // JSHint options - E001: "Bad option: '{a}'.", - E002: "Bad option value.", - - // JSHint input - E003: "Expected a JSON value.", - E004: "Input is neither a string nor an array of strings.", - E005: "Input is empty.", - E006: "Unexpected early end of program.", - - // Strict mode - E007: "Missing \"use strict\" statement.", - E008: "Strict violation.", - E009: "Option 'validthis' can't be used in a global scope.", - E010: "'with' is not allowed in strict mode.", - - // Constants - E011: "const '{a}' has already been declared.", - E012: "const '{a}' is initialized to 'undefined'.", - E013: "Attempting to override '{a}' which is a constant.", - - // Regular expressions - E014: "A regular expression literal can be confused with '/='.", - E015: "Unclosed regular expression.", - E016: "Invalid regular expression.", - - // Tokens - E017: "Unclosed comment.", - E018: "Unbegun comment.", - E019: "Unmatched '{a}'.", - E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - E021: "Expected '{a}' and instead saw '{b}'.", - E022: "Line breaking error '{a}'.", - E023: "Missing '{a}'.", - E024: "Unexpected '{a}'.", - E025: "Missing ':' on a case clause.", - E026: "Missing '}' to match '{' from line {a}.", - E027: "Missing ']' to match '[' form line {a}.", - E028: "Illegal comma.", - E029: "Unclosed string.", - - // Everything else - E030: "Expected an identifier and instead saw '{a}'.", - E031: "Bad assignment.", // FIXME: Rephrase - E032: "Expected a small integer or 'false' and instead saw '{a}'.", - E033: "Expected an operator and instead saw '{a}'.", - E034: "get/set are ES5 features.", - E035: "Missing property name.", - E036: "Expected to see a statement and instead saw a block.", - E037: "Constant {a} was not declared correctly.", - E038: "Variable {a} was not declared correctly.", - E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.", - E040: "Each value should have its own case label.", - E041: "Unrecoverable syntax error.", - E042: "Stopping.", - E043: "Too many errors.", - E044: "'{a}' is already defined and can't be redefined.", - E045: "Invalid for each loop.", - E046: "A yield statement shall be within a generator function (with syntax: `function*`)", - E047: "A generator function shall contain a yield statement.", - E048: "Let declaration not directly within block.", - E049: "A {a} cannot be named '{b}'." -}; - -var warnings = { - W001: "'hasOwnProperty' is a really bad name.", - W002: "Value of '{a}' may be overwritten in IE.", - W003: "'{a}' was used before it was defined.", - W004: "'{a}' is already defined.", - W005: "A dot following a number can be confused with a decimal point.", - W006: "Confusing minuses.", - W007: "Confusing pluses.", - W008: "A leading decimal point can be confused with a dot: '{a}'.", - W009: "The array literal notation [] is preferrable.", - W010: "The object literal notation {} is preferrable.", - W011: "Unexpected space after '{a}'.", - W012: "Unexpected space before '{a}'.", - W013: "Missing space after '{a}'.", - W014: "Bad line breaking before '{a}'.", - W015: "Expected '{a}' to have an indentation at {b} instead at {c}.", - W016: "Unexpected use of '{a}'.", - W017: "Bad operand.", - W018: "Confusing use of '{a}'.", - W019: "Use the isNaN function to compare with NaN.", - W020: "Read only.", - W021: "'{a}' is a function.", - W022: "Do not assign to the exception parameter.", - W023: "Expected an identifier in an assignment and instead saw a function invocation.", - W024: "Expected an identifier and instead saw '{a}' (a reserved word).", - W025: "Missing name in function declaration.", - W026: "Inner functions should be listed at the top of the outer function.", - W027: "Unreachable '{a}' after '{b}'.", - W028: "Label '{a}' on {b} statement.", - W030: "Expected an assignment or function call and instead saw an expression.", - W031: "Do not use 'new' for side effects.", - W032: "Unnecessary semicolon.", - W033: "Missing semicolon.", - W034: "Unnecessary directive \"{a}\".", - W035: "Empty block.", - W036: "Unexpected /*member '{a}'.", - W037: "'{a}' is a statement label.", - W038: "'{a}' used out of scope.", - W039: "'{a}' is not allowed.", - W040: "Possible strict violation.", - W041: "Use '{a}' to compare with '{b}'.", - W042: "Avoid EOL escaping.", - W043: "Bad escaping of EOL. Use option multistr if needed.", - W044: "Bad or unnecessary escaping.", - W045: "Bad number '{a}'.", - W046: "Don't use extra leading zeros '{a}'.", - W047: "A trailing decimal point can be confused with a dot: '{a}'.", - W048: "Unexpected control character in regular expression.", - W049: "Unexpected escaped character '{a}' in regular expression.", - W050: "JavaScript URL.", - W051: "Variables should not be deleted.", - W052: "Unexpected '{a}'.", - W053: "Do not use {a} as a constructor.", - W054: "The Function constructor is a form of eval.", - W055: "A constructor name should start with an uppercase letter.", - W056: "Bad constructor.", - W057: "Weird construction. Is 'new' unnecessary?", - W058: "Missing '()' invoking a constructor.", - W059: "Avoid arguments.{a}.", - W060: "document.write can be a form of eval.", - W061: "eval can be harmful.", - W062: "Wrap an immediate function invocation in parens " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself.", - W063: "Math is not a function.", - W064: "Missing 'new' prefix when invoking a constructor.", - W065: "Missing radix parameter.", - W066: "Implied eval. Consider passing a function instead of a string.", - W067: "Bad invocation.", - W068: "Wrapping non-IIFE function literals in parens is unnecessary.", - W069: "['{a}'] is better written in dot notation.", - W070: "Extra comma. (it breaks older versions of IE)", - W071: "This function has too many statements. ({a})", - W072: "This function has too many parameters. ({a})", - W073: "Blocks are nested too deeply. ({a})", - W074: "This function's cyclomatic complexity is too high. ({a})", - W075: "Duplicate key '{a}'.", - W076: "Unexpected parameter '{a}' in get {b} function.", - W077: "Expected a single parameter in set {a} function.", - W078: "Setter is defined without getter.", - W079: "Redefinition of '{a}'.", - W080: "It's not necessary to initialize '{a}' to 'undefined'.", - W081: "Too many var statements.", - W082: "Function declarations should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", - W083: "Don't make functions within a loop.", - W084: "Expected a conditional expression and instead saw an assignment.", - W085: "Don't use 'with'.", - W086: "Expected a 'break' statement before '{a}'.", - W087: "Forgotten 'debugger' statement?", - W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", - W089: "The body of a for in should be wrapped in an if statement to filter " + - "unwanted properties from the prototype.", - W090: "'{a}' is not a statement label.", - W091: "'{a}' is out of scope.", - W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.", - W093: "Did you mean to return a conditional instead of an assignment?", - W094: "Unexpected comma.", - W095: "Expected a string and instead saw {a}.", - W096: "The '{a}' key may produce unexpected results.", - W097: "Use the function form of \"use strict\".", - W098: "'{a}' is defined but never used.", - W099: "Mixed spaces and tabs.", - W100: "This character may get silently deleted by one or more browsers.", - W101: "Line is too long.", - W102: "Trailing whitespace.", - W103: "The '{a}' property is deprecated.", - W104: "'{a}' is only available in JavaScript 1.7.", - W105: "Unexpected {a} in '{b}'.", - W106: "Identifier '{a}' is not in camel case.", - W107: "Script URL.", - W108: "Strings must use doublequote.", - W109: "Strings must use singlequote.", - W110: "Mixed double and single quotes.", - W112: "Unclosed string.", - W113: "Control character in string: {a}.", - W114: "Avoid {a}.", - W115: "Octal literals are not allowed in strict mode.", - W116: "Expected '{a}' and instead saw '{b}'.", - W117: "'{a}' is not defined.", - W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).", - W119: "'{a}' is only available in ES6 (use esnext option)." -}; - -var info = { - I001: "Comma warnings can be turned off with 'laxcomma'.", - I002: "Reserved words as properties can be used under the 'es5' option.", - I003: "ES5 option is now set per default" -}; - -exports.errors = {}; -exports.warnings = {}; -exports.info = {}; - -_.each(errors, function (desc, code) { - exports.errors[code] = { code: code, desc: desc }; -}); - -_.each(warnings, function (desc, code) { - exports.warnings[code] = { code: code, desc: desc }; -}); - -_.each(info, function (desc, code) { - exports.info[code] = { code: code, desc: desc }; -}); - -})() -},{"underscore":11}],8:[function(require,module,exports){ -var events = require('events'); - -exports.isArray = isArray; -exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'}; -exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'}; - - -exports.print = function () {}; -exports.puts = function () {}; -exports.debug = function() {}; - -exports.inspect = function(obj, showHidden, depth, colors) { - var seen = []; - - var stylize = function(str, styleType) { - // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - var styles = - { 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] }; - - var style = - { 'special': 'cyan', - 'number': 'blue', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' }[styleType]; - - if (style) { - return '\033[' + styles[style][0] + 'm' + str + - '\033[' + styles[style][1] + 'm'; - } else { - return str; - } - }; - if (! colors) { - stylize = function(str, styleType) { return str; }; - } - - function format(value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (value && typeof value.inspect === 'function' && - // Filter out the util module, it's inspect function is special - value !== exports && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - return value.inspect(recurseTimes); - } - - // Primitive types cannot have properties - switch (typeof value) { - case 'undefined': - return stylize('undefined', 'undefined'); - - case 'string': - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return stylize(simple, 'string'); - - case 'number': - return stylize('' + value, 'number'); - - case 'boolean': - return stylize('' + value, 'boolean'); - } - // For some reason typeof null is "object", so special case here. - if (value === null) { - return stylize('null', 'null'); - } - - // Look up the keys of the object. - var visible_keys = Object_keys(value); - var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys; - - // Functions without properties can be shortcutted. - if (typeof value === 'function' && keys.length === 0) { - if (isRegExp(value)) { - return stylize('' + value, 'regexp'); - } else { - var name = value.name ? ': ' + value.name : ''; - return stylize('[Function' + name + ']', 'special'); - } - } - - // Dates without properties can be shortcutted - if (isDate(value) && keys.length === 0) { - return stylize(value.toUTCString(), 'date'); - } - - var base, type, braces; - // Determine the object type - if (isArray(value)) { - type = 'Array'; - braces = ['[', ']']; - } else { - type = 'Object'; - braces = ['{', '}']; - } - - // Make functions say that they are functions - if (typeof value === 'function') { - var n = value.name ? ': ' + value.name : ''; - base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; - } else { - base = ''; - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + value.toUTCString(); - } - - if (keys.length === 0) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return stylize('' + value, 'regexp'); - } else { - return stylize('[Object]', 'special'); - } - } - - seen.push(value); - - var output = keys.map(function(key) { - var name, str; - if (value.__lookupGetter__) { - if (value.__lookupGetter__(key)) { - if (value.__lookupSetter__(key)) { - str = stylize('[Getter/Setter]', 'special'); - } else { - str = stylize('[Getter]', 'special'); - } - } else { - if (value.__lookupSetter__(key)) { - str = stylize('[Setter]', 'special'); - } - } - } - if (visible_keys.indexOf(key) < 0) { - name = '[' + key + ']'; - } - if (!str) { - if (seen.indexOf(value[key]) < 0) { - if (recurseTimes === null) { - str = format(value[key]); - } else { - str = format(value[key], recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (isArray(value)) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = stylize('[Circular]', 'special'); - } - } - if (typeof name === 'undefined') { - if (type === 'Array' && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = stylize(name, 'string'); - } - } - - return name + ': ' + str; - }); - - seen.pop(); - - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.length + 1; - }, 0); - - if (length > 50) { - output = braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - - } else { - output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; - } - - return output; - } - return format(obj, (typeof depth === 'undefined' ? 2 : depth)); -}; - - -function isArray(ar) { - return ar instanceof Array || - Array.isArray(ar) || - (ar && ar !== Object.prototype && isArray(ar.__proto__)); -} - - -function isRegExp(re) { - return re instanceof RegExp || - (typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]'); -} - - -function isDate(d) { - if (d instanceof Date) return true; - if (typeof d !== 'object') return false; - var properties = Date.prototype && Object_getOwnPropertyNames(Date.prototype); - var proto = d.__proto__ && Object_getOwnPropertyNames(d.__proto__); - return JSON.stringify(proto) === JSON.stringify(properties); -} - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - -exports.log = function (msg) {}; - -exports.pump = null; - -var Object_keys = Object.keys || function (obj) { - var res = []; - for (var key in obj) res.push(key); - return res; -}; - -var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) { - var res = []; - for (var key in obj) { - if (Object.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; -}; - -var Object_create = Object.create || function (prototype, properties) { - // from es5-shim - var object; - if (prototype === null) { - object = { '__proto__' : null }; - } - else { - if (typeof prototype !== 'object') { - throw new TypeError( - 'typeof prototype[' + (typeof prototype) + '] != \'object\'' - ); - } - var Type = function () {}; - Type.prototype = prototype; - object = new Type(); - object.__proto__ = prototype; - } - if (typeof properties !== 'undefined' && Object.defineProperties) { - Object.defineProperties(object, properties); - } - return object; -}; - -exports.inherits = function(ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object_create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); -}; - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (typeof f !== 'string') { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(exports.inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': return JSON.stringify(args[i++]); - default: - return x; - } - }); - for(var x = args[i]; i < len; x = args[++i]){ - if (x === null || typeof x !== 'object') { - str += ' ' + x; - } else { - str += ' ' + exports.inspect(x); - } - } - return str; -}; - -},{"events":2}],9:[function(require,module,exports){ -(function(){// UTILITY -var util = require('util'); -var Buffer = require("buffer").Buffer; -var pSlice = Array.prototype.slice; - -function objectKeys(object) { - if (Object.keys) return Object.keys(object); - var result = []; - for (var name in object) { - if (Object.prototype.hasOwnProperty.call(object, name)) { - result.push(name); - } - } - return result; -} - -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.message = options.message; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - var stackStartFunction = options.stackStartFunction || fail; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } -}; -util.inherits(assert.AssertionError, Error); - -function replacer(key, value) { - if (value === undefined) { - return '' + value; - } - if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) { - return value.toString(); - } - if (typeof value === 'function' || value instanceof RegExp) { - return value.toString(); - } - return value; -} - -function truncate(s, n) { - if (typeof s == 'string') { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} - -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name + ':', this.message].join(' '); - } else { - return [ - this.name + ':', - truncate(JSON.stringify(this.actual, replacer), 128), - this.operator, - truncate(JSON.stringify(this.expected, replacer), 128) - ].join(' '); - } -}; - -// assert.AssertionError instanceof Error - -assert.AssertionError.__proto__ = Error.prototype; - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!!!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -function _deepEqual(actual, expected) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { - if (actual.length != expected.length) return false; - - for (var i = 0; i < actual.length; i++) { - if (actual[i] !== expected[i]) return false; - } - - return true; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { - return actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected); - } -} - -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b); - } - try { - var ka = objectKeys(a), - kb = objectKeys(b), - key, i; - } catch (e) {//happens when one is a string literal and the other isn't - return false; - } - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key])) return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (expected instanceof RegExp) { - return expected.test(actual); - } else if (actual instanceof expected) { - return true; - } else if (expected.call({}, actual) === true) { - return true; - } - - return false; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - try { - block(); - } catch (e) { - actual = e; - } - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail('Missing expected exception' + message); - } - - if (!shouldThrow && expectedException(actual, expected)) { - fail('Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [true].concat(pSlice.call(arguments))); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws.apply(this, [false].concat(pSlice.call(arguments))); -}; - -assert.ifError = function(err) { if (err) {throw err;}}; - -})() -},{"util":8,"buffer":13}],11:[function(require,module,exports){ -(function(){// Underscore.js 1.4.4 -// http://underscorejs.org -// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore may be freely distributed under the MIT license. - -(function() { - - // Baseline setup - // -------------- - - // Establish the root object, `window` in the browser, or `global` on the server. - var root = this; - - // Save the previous value of the `_` variable. - var previousUnderscore = root._; - - // Establish the object that gets returned to break out of a loop iteration. - var breaker = {}; - - // Save bytes in the minified (but not gzipped) version: - var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; - - // Create quick reference variables for speed access to core prototypes. - var push = ArrayProto.push, - slice = ArrayProto.slice, - concat = ArrayProto.concat, - toString = ObjProto.toString, - hasOwnProperty = ObjProto.hasOwnProperty; - - // All **ECMAScript 5** native function implementations that we hope to use - // are declared here. - var - nativeForEach = ArrayProto.forEach, - nativeMap = ArrayProto.map, - nativeReduce = ArrayProto.reduce, - nativeReduceRight = ArrayProto.reduceRight, - nativeFilter = ArrayProto.filter, - nativeEvery = ArrayProto.every, - nativeSome = ArrayProto.some, - nativeIndexOf = ArrayProto.indexOf, - nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, - nativeBind = FuncProto.bind; - - // Create a safe reference to the Underscore object for use below. - var _ = function(obj) { - if (obj instanceof _) return obj; - if (!(this instanceof _)) return new _(obj); - this._wrapped = obj; - }; - - // Export the Underscore object for **Node.js**, with - // backwards-compatibility for the old `require()` API. If we're in - // the browser, add `_` as a global object via a string identifier, - // for Closure Compiler "advanced" mode. - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = _; - } - exports._ = _; - } else { - root._ = _; - } - - // Current version. - _.VERSION = '1.4.4'; - - // Collection Functions - // -------------------- - - // The cornerstone, an `each` implementation, aka `forEach`. - // Handles objects with the built-in `forEach`, arrays, and raw objects. - // Delegates to **ECMAScript 5**'s native `forEach` if available. - var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return; - if (nativeForEach && obj.forEach === nativeForEach) { - obj.forEach(iterator, context); - } else if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if (iterator.call(context, obj[i], i, obj) === breaker) return; - } - } else { - for (var key in obj) { - if (_.has(obj, key)) { - if (iterator.call(context, obj[key], key, obj) === breaker) return; - } - } - } - }; - - // Return the results of applying the iterator to each element. - // Delegates to **ECMAScript 5**'s native `map` if available. - _.map = _.collect = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); - each(obj, function(value, index, list) { - results[results.length] = iterator.call(context, value, index, list); - }); - return results; - }; - - var reduceError = 'Reduce of empty array with no initial value'; - - // **Reduce** builds up a single result from a list of values, aka `inject`, - // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. - _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduce && obj.reduce === nativeReduce) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); - } - each(obj, function(value, index, list) { - if (!initial) { - memo = value; - initial = true; - } else { - memo = iterator.call(context, memo, value, index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // The right-associative version of reduce, also known as `foldr`. - // Delegates to **ECMAScript 5**'s native `reduceRight` if available. - _.reduceRight = _.foldr = function(obj, iterator, memo, context) { - var initial = arguments.length > 2; - if (obj == null) obj = []; - if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { - if (context) iterator = _.bind(iterator, context); - return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); - } - var length = obj.length; - if (length !== +length) { - var keys = _.keys(obj); - length = keys.length; - } - each(obj, function(value, index, list) { - index = keys ? keys[--length] : --length; - if (!initial) { - memo = obj[index]; - initial = true; - } else { - memo = iterator.call(context, memo, obj[index], index, list); - } - }); - if (!initial) throw new TypeError(reduceError); - return memo; - }; - - // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { - var result; - any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { - result = value; - return true; - } - }); - return result; - }; - - // Return all the elements that pass a truth test. - // Delegates to **ECMAScript 5**'s native `filter` if available. - // Aliased as `select`. - _.filter = _.select = function(obj, iterator, context) { - var results = []; - if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); - each(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) results[results.length] = value; - }); - return results; - }; - - // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { - return _.filter(obj, function(value, index, list) { - return !iterator.call(context, value, index, list); - }, context); - }; - - // Determine whether all of the elements match a truth test. - // Delegates to **ECMAScript 5**'s native `every` if available. - // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = true; - if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); - each(obj, function(value, index, list) { - if (!(result = result && iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if at least one element in the object matches a truth test. - // Delegates to **ECMAScript 5**'s native `some` if available. - // Aliased as `any`. - var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); - var result = false; - if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); - each(obj, function(value, index, list) { - if (result || (result = iterator.call(context, value, index, list))) return breaker; - }); - return !!result; - }; - - // Determine if the array or object contains a given value (using `===`). - // Aliased as `include`. - _.contains = _.include = function(obj, target) { - if (obj == null) return false; - if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; - return any(obj, function(value) { - return value === target; - }); - }; - - // Invoke a method (with arguments) on every item in a collection. - _.invoke = function(obj, method) { - var args = slice.call(arguments, 2); - var isFunc = _.isFunction(method); - return _.map(obj, function(value) { - return (isFunc ? method : value[method]).apply(value, args); - }); - }; - - // Convenience version of a common use case of `map`: fetching a property. - _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); - }; - - // Convenience version of a common use case of `filter`: selecting only objects - // containing specific `key:value` pairs. - _.where = function(obj, attrs, first) { - if (_.isEmpty(attrs)) return first ? null : []; - return _[first ? 'find' : 'filter'](obj, function(value) { - for (var key in attrs) { - if (attrs[key] !== value[key]) return false; - } - return true; - }); - }; - - // Convenience version of a common use case of `find`: getting the first object - // containing specific `key:value` pairs. - _.findWhere = function(obj, attrs) { - return _.where(obj, attrs, true); - }; - - // Return the maximum element or (element-based computation). - // Can't optimize arrays of integers longer than 65,535 elements. - // See: https://bugs.webkit.org/show_bug.cgi?id=80797 - _.max = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.max.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity, value: -Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed >= result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Return the minimum element (or element-based computation). - _.min = function(obj, iterator, context) { - if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { - return Math.min.apply(Math, obj); - } - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity, value: Infinity}; - each(obj, function(value, index, list) { - var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); - }); - return result.value; - }; - - // Shuffle an array. - _.shuffle = function(obj) { - var rand; - var index = 0; - var shuffled = []; - each(obj, function(value) { - rand = _.random(index++); - shuffled[index - 1] = shuffled[rand]; - shuffled[rand] = value; - }); - return shuffled; - }; - - // An internal function to generate lookup iterators. - var lookupIterator = function(value) { - return _.isFunction(value) ? value : function(obj){ return obj[value]; }; - }; - - // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, value, context) { - var iterator = lookupIterator(value); - return _.pluck(_.map(obj, function(value, index, list) { - return { - value : value, - index : index, - criteria : iterator.call(context, value, index, list) - }; - }).sort(function(left, right) { - var a = left.criteria; - var b = right.criteria; - if (a !== b) { - if (a > b || a === void 0) return 1; - if (a < b || b === void 0) return -1; - } - return left.index < right.index ? -1 : 1; - }), 'value'); - }; - - // An internal function used for aggregate "group by" operations. - var group = function(obj, value, context, behavior) { - var result = {}; - var iterator = lookupIterator(value || _.identity); - each(obj, function(value, index) { - var key = iterator.call(context, value, index, obj); - behavior(result, key, value); - }); - return result; - }; - - // Groups the object's values by a criterion. Pass either a string attribute - // to group by, or a function that returns the criterion. - _.groupBy = function(obj, value, context) { - return group(obj, value, context, function(result, key, value) { - (_.has(result, key) ? result[key] : (result[key] = [])).push(value); - }); - }; - - // Counts instances of an object that group by a certain criterion. Pass - // either a string attribute to count by, or a function that returns the - // criterion. - _.countBy = function(obj, value, context) { - return group(obj, value, context, function(result, key) { - if (!_.has(result, key)) result[key] = 0; - result[key]++; - }); - }; - - // Use a comparator function to figure out the smallest index at which - // an object should be inserted so as to maintain order. Uses binary search. - _.sortedIndex = function(array, obj, iterator, context) { - iterator = iterator == null ? _.identity : lookupIterator(iterator); - var value = iterator.call(context, obj); - var low = 0, high = array.length; - while (low < high) { - var mid = (low + high) >>> 1; - iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; - } - return low; - }; - - // Safely convert anything iterable into a real, live array. - _.toArray = function(obj) { - if (!obj) return []; - if (_.isArray(obj)) return slice.call(obj); - if (obj.length === +obj.length) return _.map(obj, _.identity); - return _.values(obj); - }; - - // Return the number of elements in an object. - _.size = function(obj) { - if (obj == null) return 0; - return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; - }; - - // Array Functions - // --------------- - - // Get the first element of an array. Passing **n** will return the first N - // values in the array. Aliased as `head` and `take`. The **guard** check - // allows it to work with `_.map`. - _.first = _.head = _.take = function(array, n, guard) { - if (array == null) return void 0; - return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; - }; - - // Returns everything but the last entry of the array. Especially useful on - // the arguments object. Passing **n** will return all the values in - // the array, excluding the last N. The **guard** check allows it to work with - // `_.map`. - _.initial = function(array, n, guard) { - return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); - }; - - // Get the last element of an array. Passing **n** will return the last N - // values in the array. The **guard** check allows it to work with `_.map`. - _.last = function(array, n, guard) { - if (array == null) return void 0; - if ((n != null) && !guard) { - return slice.call(array, Math.max(array.length - n, 0)); - } else { - return array[array.length - 1]; - } - }; - - // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. - // Especially useful on the arguments object. Passing an **n** will return - // the rest N values in the array. The **guard** - // check allows it to work with `_.map`. - _.rest = _.tail = _.drop = function(array, n, guard) { - return slice.call(array, (n == null) || guard ? 1 : n); - }; - - // Trim out all falsy values from an array. - _.compact = function(array) { - return _.filter(array, _.identity); - }; - - // Internal implementation of a recursive `flatten` function. - var flatten = function(input, shallow, output) { - each(input, function(value) { - if (_.isArray(value)) { - shallow ? push.apply(output, value) : flatten(value, shallow, output); - } else { - output.push(value); - } - }); - return output; - }; - - // Return a completely flattened version of an array. - _.flatten = function(array, shallow) { - return flatten(array, shallow, []); - }; - - // Return a version of the array that does not contain the specified value(s). - _.without = function(array) { - return _.difference(array, slice.call(arguments, 1)); - }; - - // Produce a duplicate-free version of the array. If the array has already - // been sorted, you have the option of using a faster algorithm. - // Aliased as `unique`. - _.uniq = _.unique = function(array, isSorted, iterator, context) { - if (_.isFunction(isSorted)) { - context = iterator; - iterator = isSorted; - isSorted = false; - } - var initial = iterator ? _.map(array, iterator, context) : array; - var results = []; - var seen = []; - each(initial, function(value, index) { - if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { - seen.push(value); - results.push(array[index]); - } - }); - return results; - }; - - // Produce an array that contains the union: each distinct element from all of - // the passed-in arrays. - _.union = function() { - return _.uniq(concat.apply(ArrayProto, arguments)); - }; - - // Produce an array that contains every item shared between all the - // passed-in arrays. - _.intersection = function(array) { - var rest = slice.call(arguments, 1); - return _.filter(_.uniq(array), function(item) { - return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; - }); - }); - }; - - // Take the difference between one array and a number of other arrays. - // Only the elements present in just the first array will remain. - _.difference = function(array) { - var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); - return _.filter(array, function(value){ return !_.contains(rest, value); }); - }; - - // Zip together multiple lists into a single array -- elements that share - // an index go together. - _.zip = function() { - var args = slice.call(arguments); - var length = _.max(_.pluck(args, 'length')); - var results = new Array(length); - for (var i = 0; i < length; i++) { - results[i] = _.pluck(args, "" + i); - } - return results; - }; - - // Converts lists into objects. Pass either a single array of `[key, value]` - // pairs, or two parallel arrays of the same length -- one of keys, and one of - // the corresponding values. - _.object = function(list, values) { - if (list == null) return {}; - var result = {}; - for (var i = 0, l = list.length; i < l; i++) { - if (values) { - result[list[i]] = values[i]; - } else { - result[list[i][0]] = list[i][1]; - } - } - return result; - }; - - // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), - // we need this function. Return the position of the first occurrence of an - // item in an array, or -1 if the item is not included in the array. - // Delegates to **ECMAScript 5**'s native `indexOf` if available. - // If the array is large and already in sort order, pass `true` - // for **isSorted** to use binary search. - _.indexOf = function(array, item, isSorted) { - if (array == null) return -1; - var i = 0, l = array.length; - if (isSorted) { - if (typeof isSorted == 'number') { - i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted); - } else { - i = _.sortedIndex(array, item); - return array[i] === item ? i : -1; - } - } - if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); - for (; i < l; i++) if (array[i] === item) return i; - return -1; - }; - - // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. - _.lastIndexOf = function(array, item, from) { - if (array == null) return -1; - var hasIndex = from != null; - if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { - return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); - } - var i = (hasIndex ? from : array.length); - while (i--) if (array[i] === item) return i; - return -1; - }; - - // Generate an integer Array containing an arithmetic progression. A port of - // the native Python `range()` function. See - // [the Python documentation](http://docs.python.org/library/functions.html#range). - _.range = function(start, stop, step) { - if (arguments.length <= 1) { - stop = start || 0; - start = 0; - } - step = arguments[2] || 1; - - var len = Math.max(Math.ceil((stop - start) / step), 0); - var idx = 0; - var range = new Array(len); - - while(idx < len) { - range[idx++] = start; - start += step; - } - - return range; - }; - - // Function (ahem) Functions - // ------------------ - - // Create a function bound to a given object (assigning `this`, and arguments, - // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if - // available. - _.bind = function(func, context) { - if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); - var args = slice.call(arguments, 2); - return function() { - return func.apply(context, args.concat(slice.call(arguments))); - }; - }; - - // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. - _.partial = function(func) { - var args = slice.call(arguments, 1); - return function() { - return func.apply(this, args.concat(slice.call(arguments))); - }; - }; - - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. - _.bindAll = function(obj) { - var funcs = slice.call(arguments, 1); - if (funcs.length === 0) funcs = _.functions(obj); - each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); - return obj; - }; - - // Memoize an expensive function by storing its results. - _.memoize = function(func, hasher) { - var memo = {}; - hasher || (hasher = _.identity); - return function() { - var key = hasher.apply(this, arguments); - return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); - }; - }; - - // Delays a function for the given number of milliseconds, and then calls - // it with the arguments supplied. - _.delay = function(func, wait) { - var args = slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; - - // Defers a function, scheduling it to run after the current call stack has - // cleared. - _.defer = function(func) { - return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); - }; - - // Returns a function, that, when invoked, will only be triggered at most once - // during a given window of time. - _.throttle = function(func, wait) { - var context, args, timeout, result; - var previous = 0; - var later = function() { - previous = new Date; - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date; - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }; - - // Returns a function, that, as long as it continues to be invoked, will not - // be triggered. The function will be called after it stops being called for - // N milliseconds. If `immediate` is passed, trigger the function on the - // leading edge, instead of the trailing. - _.debounce = function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) result = func.apply(context, args); - }; - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) result = func.apply(context, args); - return result; - }; - }; - - // Returns a function that will be executed at most one time, no matter how - // often you call it. Useful for lazy initialization. - _.once = function(func) { - var ran = false, memo; - return function() { - if (ran) return memo; - ran = true; - memo = func.apply(this, arguments); - func = null; - return memo; - }; - }; - - // Returns the first function passed as an argument to the second, - // allowing you to adjust arguments, run code before and after, and - // conditionally execute the original function. - _.wrap = function(func, wrapper) { - return function() { - var args = [func]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; - }; - - // Returns a function that is the composition of a list of functions, each - // consuming the return value of the function that follows. - _.compose = function() { - var funcs = arguments; - return function() { - var args = arguments; - for (var i = funcs.length - 1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - return args[0]; - }; - }; - - // Returns a function that will only be executed after being called N times. - _.after = function(times, func) { - if (times <= 0) return func(); - return function() { - if (--times < 1) { - return func.apply(this, arguments); - } - }; - }; - - // Object Functions - // ---------------- - - // Retrieve the names of an object's properties. - // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); - var keys = []; - for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; - return keys; - }; - - // Retrieve the values of an object's properties. - _.values = function(obj) { - var values = []; - for (var key in obj) if (_.has(obj, key)) values.push(obj[key]); - return values; - }; - - // Convert an object into a list of `[key, value]` pairs. - _.pairs = function(obj) { - var pairs = []; - for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]); - return pairs; - }; - - // Invert the keys and values of an object. The values must be serializable. - _.invert = function(obj) { - var result = {}; - for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key; - return result; - }; - - // Return a sorted list of the function names available on the object. - // Aliased as `methods` - _.functions = _.methods = function(obj) { - var names = []; - for (var key in obj) { - if (_.isFunction(obj[key])) names.push(key); - } - return names.sort(); - }; - - // Extend a given object with all the properties in passed-in object(s). - _.extend = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Return a copy of the object only containing the whitelisted properties. - _.pick = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - each(keys, function(key) { - if (key in obj) copy[key] = obj[key]; - }); - return copy; - }; - - // Return a copy of the object without the blacklisted properties. - _.omit = function(obj) { - var copy = {}; - var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); - for (var key in obj) { - if (!_.contains(keys, key)) copy[key] = obj[key]; - } - return copy; - }; - - // Fill in a given object with default properties. - _.defaults = function(obj) { - each(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - if (obj[prop] == null) obj[prop] = source[prop]; - } - } - }); - return obj; - }; - - // Create a (shallow-cloned) duplicate of an object. - _.clone = function(obj) { - if (!_.isObject(obj)) return obj; - return _.isArray(obj) ? obj.slice() : _.extend({}, obj); - }; - - // Invokes interceptor with the obj, and then returns obj. - // The primary purpose of this method is to "tap into" a method chain, in - // order to perform operations on intermediate results within the chain. - _.tap = function(obj, interceptor) { - interceptor(obj); - return obj; - }; - - // Internal recursive comparison function for `isEqual`. - var eq = function(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. - if (a === b) return a !== 0 || 1 / a == 1 / b; - // A strict comparison is necessary because `null == undefined`. - if (a == null || b == null) return a === b; - // Unwrap any wrapped objects. - if (a instanceof _) a = a._wrapped; - if (b instanceof _) b = b._wrapped; - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className != toString.call(b)) return false; - switch (className) { - // Strings, numbers, dates, and booleans are compared by value. - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return a == String(b); - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for - // other numeric values. - return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a == +b; - // RegExps are compared by their source patterns and flags. - case '[object RegExp]': - return a.source == b.source && - a.global == b.global && - a.multiline == b.multiline && - a.ignoreCase == b.ignoreCase; - } - if (typeof a != 'object' || typeof b != 'object') return false; - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] == a) return bStack[length] == b; - } - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - var size = 0, result = true; - // Recursively compare objects and arrays. - if (className == '[object Array]') { - // Compare array lengths to determine if a deep comparison is necessary. - size = a.length; - result = size == b.length; - if (result) { - // Deep compare the contents, ignoring non-numeric properties. - while (size--) { - if (!(result = eq(a[size], b[size], aStack, bStack))) break; - } - } - } else { - // Objects with different constructors are not equivalent, but `Object`s - // from different frames are. - var aCtor = a.constructor, bCtor = b.constructor; - if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && - _.isFunction(bCtor) && (bCtor instanceof bCtor))) { - return false; - } - // Deep compare objects. - for (var key in a) { - if (_.has(a, key)) { - // Count the expected number of properties. - size++; - // Deep compare each member. - if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; - } - } - // Ensure that both objects contain the same number of properties. - if (result) { - for (key in b) { - if (_.has(b, key) && !(size--)) break; - } - result = !size; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return result; - }; - - // Perform a deep comparison to check if two objects are equal. - _.isEqual = function(a, b) { - return eq(a, b, [], []); - }; - - // Is a given array, string, or object empty? - // An "empty" object has no enumerable own-properties. - _.isEmpty = function(obj) { - if (obj == null) return true; - if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; - for (var key in obj) if (_.has(obj, key)) return false; - return true; - }; - - // Is a given value a DOM element? - _.isElement = function(obj) { - return !!(obj && obj.nodeType === 1); - }; - - // Is a given value an array? - // Delegates to ECMA5's native Array.isArray - _.isArray = nativeIsArray || function(obj) { - return toString.call(obj) == '[object Array]'; - }; - - // Is a given variable an object? - _.isObject = function(obj) { - return obj === Object(obj); - }; - - // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. - each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { - _['is' + name] = function(obj) { - return toString.call(obj) == '[object ' + name + ']'; - }; - }); - - // Define a fallback version of the method in browsers (ahem, IE), where - // there isn't any inspectable "Arguments" type. - if (!_.isArguments(arguments)) { - _.isArguments = function(obj) { - return !!(obj && _.has(obj, 'callee')); - }; - } - - // Optimize `isFunction` if appropriate. - if (typeof (/./) !== 'function') { - _.isFunction = function(obj) { - return typeof obj === 'function'; - }; - } - - // Is a given object a finite number? - _.isFinite = function(obj) { - return isFinite(obj) && !isNaN(parseFloat(obj)); - }; - - // Is the given value `NaN`? (NaN is the only number which does not equal itself). - _.isNaN = function(obj) { - return _.isNumber(obj) && obj != +obj; - }; - - // Is a given value a boolean? - _.isBoolean = function(obj) { - return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; - }; - - // Is a given value equal to null? - _.isNull = function(obj) { - return obj === null; - }; - - // Is a given variable undefined? - _.isUndefined = function(obj) { - return obj === void 0; - }; - - // Shortcut function for checking if an object has a given property directly - // on itself (in other words, not on a prototype). - _.has = function(obj, key) { - return hasOwnProperty.call(obj, key); - }; - - // Utility Functions - // ----------------- - - // Run Underscore.js in *noConflict* mode, returning the `_` variable to its - // previous owner. Returns a reference to the Underscore object. - _.noConflict = function() { - root._ = previousUnderscore; - return this; - }; - - // Keep the identity function around for default iterators. - _.identity = function(value) { - return value; - }; - - // Run a function **n** times. - _.times = function(n, iterator, context) { - var accum = Array(n); - for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); - return accum; - }; - - // Return a random integer between min and max (inclusive). - _.random = function(min, max) { - if (max == null) { - max = min; - min = 0; - } - return min + Math.floor(Math.random() * (max - min + 1)); - }; - - // List of HTML entities for escaping. - var entityMap = { - escape: { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/' - } - }; - entityMap.unescape = _.invert(entityMap.escape); - - // Regexes containing the keys and values listed immediately above. - var entityRegexes = { - escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), - unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') - }; - - // Functions for escaping and unescaping strings to/from HTML interpolation. - _.each(['escape', 'unescape'], function(method) { - _[method] = function(string) { - if (string == null) return ''; - return ('' + string).replace(entityRegexes[method], function(match) { - return entityMap[method][match]; - }); - }; - }); - - // If the value of the named property is a function then invoke it; - // otherwise, return it. - _.result = function(object, property) { - if (object == null) return null; - var value = object[property]; - return _.isFunction(value) ? value.call(object) : value; - }; - - // Add your own custom functions to the Underscore object. - _.mixin = function(obj) { - each(_.functions(obj), function(name){ - var func = _[name] = obj[name]; - _.prototype[name] = function() { - var args = [this._wrapped]; - push.apply(args, arguments); - return result.call(this, func.apply(_, args)); - }; - }); - }; - - // Generate a unique integer id (unique within the entire client session). - // Useful for temporary DOM ids. - var idCounter = 0; - _.uniqueId = function(prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - // By default, Underscore uses ERB-style template delimiters, change the - // following template settings to use alternative delimiters. - _.templateSettings = { - evaluate : /<%([\s\S]+?)%>/g, - interpolate : /<%=([\s\S]+?)%>/g, - escape : /<%-([\s\S]+?)%>/g - }; - - // When customizing `templateSettings`, if you don't want to define an - // interpolation, evaluation or escaping regex, we need one that is - // guaranteed not to match. - var noMatch = /(.)^/; - - // Certain characters need to be escaped so that they can be put into a - // string literal. - var escapes = { - "'": "'", - '\\': '\\', - '\r': 'r', - '\n': 'n', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; - - // JavaScript micro-templating, similar to John Resig's implementation. - // Underscore templating handles arbitrary delimiters, preserves whitespace, - // and correctly escapes quotes within interpolated code. - _.template = function(text, data, settings) { - var render; - settings = _.defaults({}, settings, _.templateSettings); - - // Combine delimiters into one regular expression via alternation. - var matcher = new RegExp([ - (settings.escape || noMatch).source, - (settings.interpolate || noMatch).source, - (settings.evaluate || noMatch).source - ].join('|') + '|$', 'g'); - - // Compile the template source, escaping string literals appropriately. - var index = 0; - var source = "__p+='"; - text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { - source += text.slice(index, offset) - .replace(escaper, function(match) { return '\\' + escapes[match]; }); - - if (escape) { - source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; - } - if (interpolate) { - source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; - } - if (evaluate) { - source += "';\n" + evaluate + "\n__p+='"; - } - index = offset + match.length; - return match; - }); - source += "';\n"; - - // If a variable is not specified, place data values in local scope. - if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - - source = "var __t,__p='',__j=Array.prototype.join," + - "print=function(){__p+=__j.call(arguments,'');};\n" + - source + "return __p;\n"; - - try { - render = new Function(settings.variable || 'obj', '_', source); - } catch (e) { - e.source = source; - throw e; - } - - if (data) return render(data, _); - var template = function(data) { - return render.call(this, data, _); - }; - - // Provide the compiled function source as a convenience for precompilation. - template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; - - return template; - }; - - // Add a "chain" function, which will delegate to the wrapper. - _.chain = function(obj) { - return _(obj).chain(); - }; - - // OOP - // --------------- - // If Underscore is called as a function, it returns a wrapped object that - // can be used OO-style. This wrapper holds altered versions of all the - // underscore functions. Wrapped objects may be chained. - - // Helper function to continue chaining intermediate results. - var result = function(obj) { - return this._chain ? _(obj).chain() : obj; - }; - - // Add all of the Underscore functions to the wrapper object. - _.mixin(_); - - // Add all mutator Array functions to the wrapper. - each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - var obj = this._wrapped; - method.apply(obj, arguments); - if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; - return result.call(this, obj); - }; - }); - - // Add all accessor Array functions to the wrapper. - each(['concat', 'join', 'slice'], function(name) { - var method = ArrayProto[name]; - _.prototype[name] = function() { - return result.call(this, method.apply(this._wrapped, arguments)); - }; - }); - - _.extend(_.prototype, { - - // Start chaining a wrapped Underscore object. - chain: function() { - this._chain = true; - return this; - }, - - // Extracts the result from a wrapped and chained object. - value: function() { - return this._wrapped; - } - - }); - -}).call(this); - -})() -},{}],14:[function(require,module,exports){ -exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isBE ? 0 : (nBytes - 1), - d = isBE ? 1 : -1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isBE ? (nBytes - 1) : 0, - d = isBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -},{}],13:[function(require,module,exports){ -(function(){function SlowBuffer (size) { - this.length = size; -}; - -var assert = require('assert'); - -exports.INSPECT_MAX_BYTES = 50; - - -function toHex(n) { - if (n < 16) return '0' + n.toString(16); - return n.toString(16); -} - -function utf8ToBytes(str) { - var byteArray = []; - for (var i = 0; i < str.length; i++) - if (str.charCodeAt(i) <= 0x7F) - byteArray.push(str.charCodeAt(i)); - else { - var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); - for (var j = 0; j < h.length; j++) - byteArray.push(parseInt(h[j], 16)); - } - - return byteArray; -} - -function asciiToBytes(str) { - var byteArray = [] - for (var i = 0; i < str.length; i++ ) - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push( str.charCodeAt(i) & 0xFF ); - - return byteArray; -} - -function base64ToBytes(str) { - return require("base64-js").toByteArray(str); -} - -SlowBuffer.byteLength = function (str, encoding) { - switch (encoding || "utf8") { - case 'hex': - return str.length / 2; - - case 'utf8': - case 'utf-8': - return utf8ToBytes(str).length; - - case 'ascii': - case 'binary': - return str.length; - - case 'base64': - return base64ToBytes(str).length; - - default: - throw new Error('Unknown encoding'); - } -}; - -function blitBuffer(src, dst, offset, length) { - var pos, i = 0; - while (i < length) { - if ((i+offset >= dst.length) || (i >= src.length)) - break; - - dst[i + offset] = src[i]; - i++; - } - return i; -} - -SlowBuffer.prototype.utf8Write = function (string, offset, length) { - var bytes, pos; - return SlowBuffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); -}; - -SlowBuffer.prototype.asciiWrite = function (string, offset, length) { - var bytes, pos; - return SlowBuffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); -}; - -SlowBuffer.prototype.binaryWrite = SlowBuffer.prototype.asciiWrite; - -SlowBuffer.prototype.base64Write = function (string, offset, length) { - var bytes, pos; - return SlowBuffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); -}; - -SlowBuffer.prototype.base64Slice = function (start, end) { - var bytes = Array.prototype.slice.apply(this, arguments) - return require("base64-js").fromByteArray(bytes); -} - -function decodeUtf8Char(str) { - try { - return decodeURIComponent(str); - } catch (err) { - return String.fromCharCode(0xFFFD); // UTF 8 invalid char - } -} - -SlowBuffer.prototype.utf8Slice = function () { - var bytes = Array.prototype.slice.apply(this, arguments); - var res = ""; - var tmp = ""; - var i = 0; - while (i < bytes.length) { - if (bytes[i] <= 0x7F) { - res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); - tmp = ""; - } else - tmp += "%" + bytes[i].toString(16); - - i++; - } - - return res + decodeUtf8Char(tmp); -} - -SlowBuffer.prototype.asciiSlice = function () { - var bytes = Array.prototype.slice.apply(this, arguments); - var ret = ""; - for (var i = 0; i < bytes.length; i++) - ret += String.fromCharCode(bytes[i]); - return ret; -} - -SlowBuffer.prototype.binarySlice = SlowBuffer.prototype.asciiSlice; - -SlowBuffer.prototype.inspect = function() { - var out = [], - len = this.length; - for (var i = 0; i < len; i++) { - out[i] = toHex(this[i]); - if (i == exports.INSPECT_MAX_BYTES) { - out[i + 1] = '...'; - break; - } - } - return '<SlowBuffer ' + out.join(' ') + '>'; -}; - - -SlowBuffer.prototype.hexSlice = function(start, end) { - var len = this.length; - - if (!start || start < 0) start = 0; - if (!end || end < 0 || end > len) end = len; - - var out = ''; - for (var i = start; i < end; i++) { - out += toHex(this[i]); - } - return out; -}; - - -SlowBuffer.prototype.toString = function(encoding, start, end) { - encoding = String(encoding || 'utf8').toLowerCase(); - start = +start || 0; - if (typeof end == 'undefined') end = this.length; - - // Fastpath empty strings - if (+end == start) { - return ''; - } - - switch (encoding) { - case 'hex': - return this.hexSlice(start, end); - - case 'utf8': - case 'utf-8': - return this.utf8Slice(start, end); - - case 'ascii': - return this.asciiSlice(start, end); - - case 'binary': - return this.binarySlice(start, end); - - case 'base64': - return this.base64Slice(start, end); - - case 'ucs2': - case 'ucs-2': - return this.ucs2Slice(start, end); - - default: - throw new Error('Unknown encoding'); - } -}; - - -SlowBuffer.prototype.hexWrite = function(string, offset, length) { - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } - - // must be an even number of digits - var strLen = string.length; - if (strLen % 2) { - throw new Error('Invalid hex string'); - } - if (length > strLen / 2) { - length = strLen / 2; - } - for (var i = 0; i < length; i++) { - var byte = parseInt(string.substr(i * 2, 2), 16); - if (isNaN(byte)) throw new Error('Invalid hex string'); - this[offset + i] = byte; - } - SlowBuffer._charsWritten = i * 2; - return i; -}; - - -SlowBuffer.prototype.write = function(string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length; - length = undefined; - } - } else { // legacy - var swap = encoding; - encoding = offset; - offset = length; - length = swap; - } - - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } - encoding = String(encoding || 'utf8').toLowerCase(); - - switch (encoding) { - case 'hex': - return this.hexWrite(string, offset, length); - - case 'utf8': - case 'utf-8': - return this.utf8Write(string, offset, length); - - case 'ascii': - return this.asciiWrite(string, offset, length); - - case 'binary': - return this.binaryWrite(string, offset, length); - - case 'base64': - return this.base64Write(string, offset, length); - - case 'ucs2': - case 'ucs-2': - return this.ucs2Write(string, offset, length); - - default: - throw new Error('Unknown encoding'); - } -}; - - -// slice(start, end) -SlowBuffer.prototype.slice = function(start, end) { - if (end === undefined) end = this.length; - - if (end > this.length) { - throw new Error('oob'); - } - if (start > end) { - throw new Error('oob'); - } - - return new Buffer(this, end - start, +start); -}; - -SlowBuffer.prototype.copy = function(target, targetstart, sourcestart, sourceend) { - var temp = []; - for (var i=sourcestart; i<sourceend; i++) { - assert.ok(typeof this[i] !== 'undefined', "copying undefined buffer bytes!"); - temp.push(this[i]); - } - - for (var i=targetstart; i<targetstart+temp.length; i++) { - target[i] = temp[i-targetstart]; - } -}; - -SlowBuffer.prototype.fill = function(value, start, end) { - if (end > this.length) { - throw new Error('oob'); - } - if (start > end) { - throw new Error('oob'); - } - - for (var i = start; i < end; i++) { - this[i] = value; - } -} - -function coerce(length) { - // Coerce length to a number (possibly NaN), round up - // in case it's fractional (e.g. 123.456) then do a - // double negate to coerce a NaN to 0. Easy, right? - length = ~~Math.ceil(+length); - return length < 0 ? 0 : length; -} - - -// Buffer - -function Buffer(subject, encoding, offset) { - if (!(this instanceof Buffer)) { - return new Buffer(subject, encoding, offset); - } - - var type; - - // Are we slicing? - if (typeof offset === 'number') { - this.length = coerce(encoding); - this.parent = subject; - this.offset = offset; - } else { - // Find the length - switch (type = typeof subject) { - case 'number': - this.length = coerce(subject); - break; - - case 'string': - this.length = Buffer.byteLength(subject, encoding); - break; - - case 'object': // Assume object is an array - this.length = coerce(subject.length); - break; - - default: - throw new Error('First argument needs to be a number, ' + - 'array or string.'); - } - - if (this.length > Buffer.poolSize) { - // Big buffer, just alloc one. - this.parent = new SlowBuffer(this.length); - this.offset = 0; - - } else { - // Small buffer. - if (!pool || pool.length - pool.used < this.length) allocPool(); - this.parent = pool; - this.offset = pool.used; - pool.used += this.length; - } - - // Treat array-ish objects as a byte array. - if (isArrayIsh(subject)) { - for (var i = 0; i < this.length; i++) { - if (subject instanceof Buffer) { - this.parent[i + this.offset] = subject.readUInt8(i); - } - else { - this.parent[i + this.offset] = subject[i]; - } - } - } else if (type == 'string') { - // We are a string - this.length = this.write(subject, 0, encoding); - } - } - -} - -function isArrayIsh(subject) { - return Array.isArray(subject) || Buffer.isBuffer(subject) || - subject && typeof subject === 'object' && - typeof subject.length === 'number'; -} - -exports.SlowBuffer = SlowBuffer; -exports.Buffer = Buffer; - -Buffer.poolSize = 8 * 1024; -var pool; - -function allocPool() { - pool = new SlowBuffer(Buffer.poolSize); - pool.used = 0; -} - - -// Static methods -Buffer.isBuffer = function isBuffer(b) { - return b instanceof Buffer || b instanceof SlowBuffer; -}; - -Buffer.concat = function (list, totalLength) { - if (!Array.isArray(list)) { - throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ - list should be an Array."); - } - - if (list.length === 0) { - return new Buffer(0); - } else if (list.length === 1) { - return list[0]; - } - - if (typeof totalLength !== 'number') { - totalLength = 0; - for (var i = 0; i < list.length; i++) { - var buf = list[i]; - totalLength += buf.length; - } - } - - var buffer = new Buffer(totalLength); - var pos = 0; - for (var i = 0; i < list.length; i++) { - var buf = list[i]; - buf.copy(buffer, pos); - pos += buf.length; - } - return buffer; -}; - -// Inspect -Buffer.prototype.inspect = function inspect() { - var out = [], - len = this.length; - - for (var i = 0; i < len; i++) { - out[i] = toHex(this.parent[i + this.offset]); - if (i == exports.INSPECT_MAX_BYTES) { - out[i + 1] = '...'; - break; - } - } - - return '<Buffer ' + out.join(' ') + '>'; -}; - - -Buffer.prototype.get = function get(i) { - if (i < 0 || i >= this.length) throw new Error('oob'); - return this.parent[this.offset + i]; -}; - - -Buffer.prototype.set = function set(i, v) { - if (i < 0 || i >= this.length) throw new Error('oob'); - return this.parent[this.offset + i] = v; -}; - - -// write(string, offset = 0, length = buffer.length-offset, encoding = 'utf8') -Buffer.prototype.write = function(string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length; - length = undefined; - } - } else { // legacy - var swap = encoding; - encoding = offset; - offset = length; - length = swap; - } - - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } - encoding = String(encoding || 'utf8').toLowerCase(); - - var ret; - switch (encoding) { - case 'hex': - ret = this.parent.hexWrite(string, this.offset + offset, length); - break; - - case 'utf8': - case 'utf-8': - ret = this.parent.utf8Write(string, this.offset + offset, length); - break; - - case 'ascii': - ret = this.parent.asciiWrite(string, this.offset + offset, length); - break; - - case 'binary': - ret = this.parent.binaryWrite(string, this.offset + offset, length); - break; - - case 'base64': - // Warning: maxLength not taken into account in base64Write - ret = this.parent.base64Write(string, this.offset + offset, length); - break; - - case 'ucs2': - case 'ucs-2': - ret = this.parent.ucs2Write(string, this.offset + offset, length); - break; - - default: - throw new Error('Unknown encoding'); - } - - Buffer._charsWritten = SlowBuffer._charsWritten; - - return ret; -}; - - -// toString(encoding, start=0, end=buffer.length) -Buffer.prototype.toString = function(encoding, start, end) { - encoding = String(encoding || 'utf8').toLowerCase(); - - if (typeof start == 'undefined' || start < 0) { - start = 0; - } else if (start > this.length) { - start = this.length; - } - - if (typeof end == 'undefined' || end > this.length) { - end = this.length; - } else if (end < 0) { - end = 0; - } - - start = start + this.offset; - end = end + this.offset; - - switch (encoding) { - case 'hex': - return this.parent.hexSlice(start, end); - - case 'utf8': - case 'utf-8': - return this.parent.utf8Slice(start, end); - - case 'ascii': - return this.parent.asciiSlice(start, end); - - case 'binary': - return this.parent.binarySlice(start, end); - - case 'base64': - return this.parent.base64Slice(start, end); - - case 'ucs2': - case 'ucs-2': - return this.parent.ucs2Slice(start, end); - - default: - throw new Error('Unknown encoding'); - } -}; - - -// byteLength -Buffer.byteLength = SlowBuffer.byteLength; - - -// fill(value, start=0, end=buffer.length) -Buffer.prototype.fill = function fill(value, start, end) { - value || (value = 0); - start || (start = 0); - end || (end = this.length); - - if (typeof value === 'string') { - value = value.charCodeAt(0); - } - if (!(typeof value === 'number') || isNaN(value)) { - throw new Error('value is not a number'); - } - - if (end < start) throw new Error('end < start'); - - // Fill 0 bytes; we're done - if (end === start) return 0; - if (this.length == 0) return 0; - - if (start < 0 || start >= this.length) { - throw new Error('start out of bounds'); - } - - if (end < 0 || end > this.length) { - throw new Error('end out of bounds'); - } - - return this.parent.fill(value, - start + this.offset, - end + this.offset); -}; - - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function(target, target_start, start, end) { - var source = this; - start || (start = 0); - end || (end = this.length); - target_start || (target_start = 0); - - if (end < start) throw new Error('sourceEnd < sourceStart'); - - // Copy 0 bytes; we're done - if (end === start) return 0; - if (target.length == 0 || source.length == 0) return 0; - - if (target_start < 0 || target_start >= target.length) { - throw new Error('targetStart out of bounds'); - } - - if (start < 0 || start >= source.length) { - throw new Error('sourceStart out of bounds'); - } - - if (end < 0 || end > source.length) { - throw new Error('sourceEnd out of bounds'); - } - - // Are we oob? - if (end > this.length) { - end = this.length; - } - - if (target.length - target_start < end - start) { - end = target.length - target_start + start; - } - - return this.parent.copy(target.parent, - target_start + target.offset, - start + this.offset, - end + this.offset); -}; - - -// slice(start, end) -Buffer.prototype.slice = function(start, end) { - if (end === undefined) end = this.length; - if (end > this.length) throw new Error('oob'); - if (start > end) throw new Error('oob'); - - return new Buffer(this.parent, end - start, +start + this.offset); -}; - - -// Legacy methods for backwards compatibility. - -Buffer.prototype.utf8Slice = function(start, end) { - return this.toString('utf8', start, end); -}; - -Buffer.prototype.binarySlice = function(start, end) { - return this.toString('binary', start, end); -}; - -Buffer.prototype.asciiSlice = function(start, end) { - return this.toString('ascii', start, end); -}; - -Buffer.prototype.utf8Write = function(string, offset) { - return this.write(string, offset, 'utf8'); -}; - -Buffer.prototype.binaryWrite = function(string, offset) { - return this.write(string, offset, 'binary'); -}; - -Buffer.prototype.asciiWrite = function(string, offset) { - return this.write(string, offset, 'ascii'); -}; - -Buffer.prototype.readUInt8 = function(offset, noAssert) { - var buffer = this; - - if (!noAssert) { - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return; - - return buffer.parent[buffer.offset + offset]; -}; - -function readUInt16(buffer, offset, isBigEndian, noAssert) { - var val = 0; - - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return 0; - - if (isBigEndian) { - val = buffer.parent[buffer.offset + offset] << 8; - if (offset + 1 < buffer.length) { - val |= buffer.parent[buffer.offset + offset + 1]; - } - } else { - val = buffer.parent[buffer.offset + offset]; - if (offset + 1 < buffer.length) { - val |= buffer.parent[buffer.offset + offset + 1] << 8; - } - } - - return val; -} - -Buffer.prototype.readUInt16LE = function(offset, noAssert) { - return readUInt16(this, offset, false, noAssert); -}; - -Buffer.prototype.readUInt16BE = function(offset, noAssert) { - return readUInt16(this, offset, true, noAssert); -}; - -function readUInt32(buffer, offset, isBigEndian, noAssert) { - var val = 0; - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return 0; - - if (isBigEndian) { - if (offset + 1 < buffer.length) - val = buffer.parent[buffer.offset + offset + 1] << 16; - if (offset + 2 < buffer.length) - val |= buffer.parent[buffer.offset + offset + 2] << 8; - if (offset + 3 < buffer.length) - val |= buffer.parent[buffer.offset + offset + 3]; - val = val + (buffer.parent[buffer.offset + offset] << 24 >>> 0); - } else { - if (offset + 2 < buffer.length) - val = buffer.parent[buffer.offset + offset + 2] << 16; - if (offset + 1 < buffer.length) - val |= buffer.parent[buffer.offset + offset + 1] << 8; - val |= buffer.parent[buffer.offset + offset]; - if (offset + 3 < buffer.length) - val = val + (buffer.parent[buffer.offset + offset + 3] << 24 >>> 0); - } - - return val; -} - -Buffer.prototype.readUInt32LE = function(offset, noAssert) { - return readUInt32(this, offset, false, noAssert); -}; - -Buffer.prototype.readUInt32BE = function(offset, noAssert) { - return readUInt32(this, offset, true, noAssert); -}; - - -/* - * Signed integer types, yay team! A reminder on how two's complement actually - * works. The first bit is the signed bit, i.e. tells us whether or not the - * number should be positive or negative. If the two's complement value is - * positive, then we're done, as it's equivalent to the unsigned representation. - * - * Now if the number is positive, you're pretty much done, you can just leverage - * the unsigned translations and return those. Unfortunately, negative numbers - * aren't quite that straightforward. - * - * At first glance, one might be inclined to use the traditional formula to - * translate binary numbers between the positive and negative values in two's - * complement. (Though it doesn't quite work for the most negative value) - * Mainly: - * - invert all the bits - * - add one to the result - * - * Of course, this doesn't quite work in Javascript. Take for example the value - * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of - * course, Javascript will do the following: - * - * > ~0xff80 - * -65409 - * - * Whoh there, Javascript, that's not quite right. But wait, according to - * Javascript that's perfectly correct. When Javascript ends up seeing the - * constant 0xff80, it has no notion that it is actually a signed number. It - * assumes that we've input the unsigned value 0xff80. Thus, when it does the - * binary negation, it casts it into a signed value, (positive 0xff80). Then - * when you perform binary negation on that, it turns it into a negative number. - * - * Instead, we're going to have to use the following general formula, that works - * in a rather Javascript friendly way. I'm glad we don't support this kind of - * weird numbering scheme in the kernel. - * - * (BIT-MAX - (unsigned)val + 1) * -1 - * - * The astute observer, may think that this doesn't make sense for 8-bit numbers - * (really it isn't necessary for them). However, when you get 16-bit numbers, - * you do. Let's go back to our prior example and see how this will look: - * - * (0xffff - 0xff80 + 1) * -1 - * (0x007f + 1) * -1 - * (0x0080) * -1 - */ -Buffer.prototype.readInt8 = function(offset, noAssert) { - var buffer = this; - var neg; - - if (!noAssert) { - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return; - - neg = buffer.parent[buffer.offset + offset] & 0x80; - if (!neg) { - return (buffer.parent[buffer.offset + offset]); - } - - return ((0xff - buffer.parent[buffer.offset + offset] + 1) * -1); -}; - -function readInt16(buffer, offset, isBigEndian, noAssert) { - var neg, val; - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'Trying to read beyond buffer length'); - } - - val = readUInt16(buffer, offset, isBigEndian, noAssert); - neg = val & 0x8000; - if (!neg) { - return val; - } - - return (0xffff - val + 1) * -1; -} - -Buffer.prototype.readInt16LE = function(offset, noAssert) { - return readInt16(this, offset, false, noAssert); -}; - -Buffer.prototype.readInt16BE = function(offset, noAssert) { - return readInt16(this, offset, true, noAssert); -}; - -function readInt32(buffer, offset, isBigEndian, noAssert) { - var neg, val; - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to read beyond buffer length'); - } - - val = readUInt32(buffer, offset, isBigEndian, noAssert); - neg = val & 0x80000000; - if (!neg) { - return (val); - } - - return (0xffffffff - val + 1) * -1; -} - -Buffer.prototype.readInt32LE = function(offset, noAssert) { - return readInt32(this, offset, false, noAssert); -}; - -Buffer.prototype.readInt32BE = function(offset, noAssert) { - return readInt32(this, offset, true, noAssert); -}; - -function readFloat(buffer, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to read beyond buffer length'); - } - - return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, - 23, 4); -} - -Buffer.prototype.readFloatLE = function(offset, noAssert) { - return readFloat(this, offset, false, noAssert); -}; - -Buffer.prototype.readFloatBE = function(offset, noAssert) { - return readFloat(this, offset, true, noAssert); -}; - -function readDouble(buffer, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset + 7 < buffer.length, - 'Trying to read beyond buffer length'); - } - - return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, - 52, 8); -} - -Buffer.prototype.readDoubleLE = function(offset, noAssert) { - return readDouble(this, offset, false, noAssert); -}; - -Buffer.prototype.readDoubleBE = function(offset, noAssert) { - return readDouble(this, offset, true, noAssert); -}; - - -/* - * We have to make sure that the value is a valid integer. This means that it is - * non-negative. It has no fractional component and that it does not exceed the - * maximum allowed value. - * - * value The number to check for validity - * - * max The maximum value - */ -function verifuint(value, max) { - assert.ok(typeof (value) == 'number', - 'cannot write a non-number as a number'); - - assert.ok(value >= 0, - 'specified a negative value for writing an unsigned value'); - - assert.ok(value <= max, 'value is larger than maximum value for type'); - - assert.ok(Math.floor(value) === value, 'value has a fractional component'); -} - -Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { - var buffer = this; - - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'trying to write beyond buffer length'); - - verifuint(value, 0xff); - } - - if (offset < buffer.length) { - buffer.parent[buffer.offset + offset] = value; - } -}; - -function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'trying to write beyond buffer length'); - - verifuint(value, 0xffff); - } - - for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { - buffer.parent[buffer.offset + offset + i] = - (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> - (isBigEndian ? 1 - i : i) * 8; - } - -} - -Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { - writeUInt16(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { - writeUInt16(this, value, offset, true, noAssert); -}; - -function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'trying to write beyond buffer length'); - - verifuint(value, 0xffffffff); - } - - for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { - buffer.parent[buffer.offset + offset + i] = - (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; - } -} - -Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { - writeUInt32(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { - writeUInt32(this, value, offset, true, noAssert); -}; - - -/* - * We now move onto our friends in the signed number category. Unlike unsigned - * numbers, we're going to have to worry a bit more about how we put values into - * arrays. Since we are only worrying about signed 32-bit values, we're in - * slightly better shape. Unfortunately, we really can't do our favorite binary - * & in this system. It really seems to do the wrong thing. For example: - * - * > -32 & 0xff - * 224 - * - * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of - * this aren't treated as a signed number. Ultimately a bad thing. - * - * What we're going to want to do is basically create the unsigned equivalent of - * our representation and pass that off to the wuint* functions. To do that - * we're going to do the following: - * - * - if the value is positive - * we can pass it directly off to the equivalent wuint - * - if the value is negative - * we do the following computation: - * mb + val + 1, where - * mb is the maximum unsigned value in that byte size - * val is the Javascript negative integer - * - * - * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If - * you do out the computations: - * - * 0xffff - 128 + 1 - * 0xffff - 127 - * 0xff80 - * - * You can then encode this value as the signed version. This is really rather - * hacky, but it should work and get the job done which is our goal here. - */ - -/* - * A series of checks to make sure we actually have a signed 32-bit number - */ -function verifsint(value, max, min) { - assert.ok(typeof (value) == 'number', - 'cannot write a non-number as a number'); - - assert.ok(value <= max, 'value larger than maximum allowed value'); - - assert.ok(value >= min, 'value smaller than minimum allowed value'); - - assert.ok(Math.floor(value) === value, 'value has a fractional component'); -} - -function verifIEEE754(value, max, min) { - assert.ok(typeof (value) == 'number', - 'cannot write a non-number as a number'); - - assert.ok(value <= max, 'value larger than maximum allowed value'); - - assert.ok(value >= min, 'value smaller than minimum allowed value'); -} - -Buffer.prototype.writeInt8 = function(value, offset, noAssert) { - var buffer = this; - - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'Trying to write beyond buffer length'); - - verifsint(value, 0x7f, -0x80); - } - - if (value >= 0) { - buffer.writeUInt8(value, offset, noAssert); - } else { - buffer.writeUInt8(0xff + value + 1, offset, noAssert); - } -}; - -function writeInt16(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'Trying to write beyond buffer length'); - - verifsint(value, 0x7fff, -0x8000); - } - - if (value >= 0) { - writeUInt16(buffer, value, offset, isBigEndian, noAssert); - } else { - writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); - } -} - -Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { - writeInt16(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { - writeInt16(this, value, offset, true, noAssert); -}; - -function writeInt32(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to write beyond buffer length'); - - verifsint(value, 0x7fffffff, -0x80000000); - } - - if (value >= 0) { - writeUInt32(buffer, value, offset, isBigEndian, noAssert); - } else { - writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); - } -} - -Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { - writeInt32(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { - writeInt32(this, value, offset, true, noAssert); -}; - -function writeFloat(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to write beyond buffer length'); - - verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); - } - - require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, - 23, 4); -} - -Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { - writeFloat(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { - writeFloat(this, value, offset, true, noAssert); -}; - -function writeDouble(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 7 < buffer.length, - 'Trying to write beyond buffer length'); - - verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); - } - - require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, - 52, 8); -} - -Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { - writeDouble(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { - writeDouble(this, value, offset, true, noAssert); -}; - -SlowBuffer.prototype.readUInt8 = Buffer.prototype.readUInt8; -SlowBuffer.prototype.readUInt16LE = Buffer.prototype.readUInt16LE; -SlowBuffer.prototype.readUInt16BE = Buffer.prototype.readUInt16BE; -SlowBuffer.prototype.readUInt32LE = Buffer.prototype.readUInt32LE; -SlowBuffer.prototype.readUInt32BE = Buffer.prototype.readUInt32BE; -SlowBuffer.prototype.readInt8 = Buffer.prototype.readInt8; -SlowBuffer.prototype.readInt16LE = Buffer.prototype.readInt16LE; -SlowBuffer.prototype.readInt16BE = Buffer.prototype.readInt16BE; -SlowBuffer.prototype.readInt32LE = Buffer.prototype.readInt32LE; -SlowBuffer.prototype.readInt32BE = Buffer.prototype.readInt32BE; -SlowBuffer.prototype.readFloatLE = Buffer.prototype.readFloatLE; -SlowBuffer.prototype.readFloatBE = Buffer.prototype.readFloatBE; -SlowBuffer.prototype.readDoubleLE = Buffer.prototype.readDoubleLE; -SlowBuffer.prototype.readDoubleBE = Buffer.prototype.readDoubleBE; -SlowBuffer.prototype.writeUInt8 = Buffer.prototype.writeUInt8; -SlowBuffer.prototype.writeUInt16LE = Buffer.prototype.writeUInt16LE; -SlowBuffer.prototype.writeUInt16BE = Buffer.prototype.writeUInt16BE; -SlowBuffer.prototype.writeUInt32LE = Buffer.prototype.writeUInt32LE; -SlowBuffer.prototype.writeUInt32BE = Buffer.prototype.writeUInt32BE; -SlowBuffer.prototype.writeInt8 = Buffer.prototype.writeInt8; -SlowBuffer.prototype.writeInt16LE = Buffer.prototype.writeInt16LE; -SlowBuffer.prototype.writeInt16BE = Buffer.prototype.writeInt16BE; -SlowBuffer.prototype.writeInt32LE = Buffer.prototype.writeInt32LE; -SlowBuffer.prototype.writeInt32BE = Buffer.prototype.writeInt32BE; -SlowBuffer.prototype.writeFloatLE = Buffer.prototype.writeFloatLE; -SlowBuffer.prototype.writeFloatBE = Buffer.prototype.writeFloatBE; -SlowBuffer.prototype.writeDoubleLE = Buffer.prototype.writeDoubleLE; -SlowBuffer.prototype.writeDoubleBE = Buffer.prototype.writeDoubleBE; - -})() -},{"assert":9,"./buffer_ieee754":14,"base64-js":15}],15:[function(require,module,exports){ -(function (exports) { - 'use strict'; - - var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - - function b64ToByteArray(b64) { - var i, j, l, tmp, placeHolders, arr; - - if (b64.length % 4 > 0) { - throw 'Invalid string. Length must be a multiple of 4'; - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64.indexOf('='); - placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; - - // base64 is 4/3 + up to two characters of the original data - arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length; - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); - arr.push((tmp & 0xFF0000) >> 16); - arr.push((tmp & 0xFF00) >> 8); - arr.push(tmp & 0xFF); - } - - if (placeHolders === 2) { - tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); - arr.push(tmp & 0xFF); - } else if (placeHolders === 1) { - tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); - arr.push((tmp >> 8) & 0xFF); - arr.push(tmp & 0xFF); - } - - return arr; - } - - function uint8ToBase64(uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length; - - function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; - }; - - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); - output += tripletToBase64(temp); - } - - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1]; - output += lookup[temp >> 2]; - output += lookup[(temp << 4) & 0x3F]; - output += '=='; - break; - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); - output += lookup[temp >> 10]; - output += lookup[(temp >> 4) & 0x3F]; - output += lookup[(temp << 2) & 0x3F]; - output += '='; - break; - } - - return output; - } - - module.exports.toByteArray = b64ToByteArray; - module.exports.fromByteArray = uint8ToBase64; -}()); - -},{}]},{},["E/GbHF"]) -; -JSHINT = require('jshint').JSHINT; -}()); diff --git a/dom/system/gonk/tests/marionette/ril_jshint/jshintrc b/dom/system/gonk/tests/marionette/ril_jshint/jshintrc deleted file mode 100644 index 437fe1a6f..000000000 --- a/dom/system/gonk/tests/marionette/ril_jshint/jshintrc +++ /dev/null @@ -1,118 +0,0 @@ -{ - // JSHint Default Configuration File (as on JSHint website) - // See http://jshint.com/docs/ for more details - - // Modify for RIL usage. - - "maxerr" : 10000, // {int} Maximum error before stopping - - // Enforcing - "bitwise" : false, // true: Prohibit bitwise operators (&, |, ^, etc.) - "camelcase" : false, // true: Identifiers must be in camelCase - "curly" : false, // true: Require {} for every new block or scope - "eqeqeq" : false, // true: Require triple equals (===) for comparison - "forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty() - "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` - //"indent" : 2, // {int} Number of spaces to use for indentation - "latedef" : false, // true: Require variables/functions to be defined before being used - "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` - "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` - "noempty" : false, // true: Prohibit use of empty blocks - "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) - "plusplus" : false, // true: Prohibit use of `++` & `--` - "quotmark" : false, // Quotation mark consistency: - // false : do nothing (default) - // true : ensure whatever is used is consistent - // "single" : require single quotes - // "double" : require double quotes - "undef" : false, // true: Require all non-global variables to be declared (prevents global leaks) - "unused" : false, // true: Require all defined variables be used - "strict" : false, // true: Requires all functions run in ES5 Strict Mode - "trailing" : false, // true: Prohibit trailing whitespaces - "maxparams" : false, // {int} Max number of formal params allowed per function - "maxdepth" : false, // {int} Max depth of nested blocks (within functions) - "maxstatements" : false, // {int} Max number statements per function - "maxcomplexity" : false, // {int} Max cyclomatic complexity per function - "maxlen" : false, // {int} Max number of characters per line - - // Relaxing - "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) - "boss" : false, // true: Tolerate assignments where comparisons would be expected - "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. - "eqnull" : true, // true: Tolerate use of `== null` - "es5" : false, // true: Allow ES5 syntax (ex: getters and setters) - "esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`) - "moz" : true, // true: Allow Mozilla specific syntax (extends and overrides esnext features) - // (ex: `for each`, multiple try/catch, function expression…) - "evil" : false, // true: Tolerate use of `eval` and `new Function()` - "expr" : false, // true: Tolerate `ExpressionStatement` as Programs - "funcscope" : false, // true: Tolerate defining variables inside control statements" - "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict') - "iterator" : false, // true: Tolerate using the `__iterator__` property - "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block - "laxbreak" : true, // true: Tolerate possibly unsafe line breakings - "laxcomma" : false, // true: Tolerate comma-first style coding - "loopfunc" : false, // true: Tolerate functions being defined in loops - "multistr" : false, // true: Tolerate multi-line strings - "proto" : true, // true: Tolerate using the `__proto__` property - "scripturl" : false, // true: Tolerate script-targeted URLs - "smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment - "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` - "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation - "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` - "validthis" : true, // true: Tolerate using this in a non-constructor function - - // Environments - "browser" : false, // Web Browser (window, document, etc) - "couch" : false, // CouchDB - "devel" : true, // Development/debugging (alert, confirm, etc) - "dojo" : false, // Dojo Toolkit - "jquery" : false, // jQuery - "mootools" : false, // MooTools - "node" : false, // Node.js - "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) - "prototypejs" : false, // Prototype and Scriptaculous - "rhino" : false, // Rhino - "worker" : true, // Web Workers - "wsh" : false, // Windows Scripting Host - "yui" : false, // Yahoo User Interface - - // Legacy - "nomen" : false, // true: Prohibit dangling `_` in variables - "onevar" : false, // true: Allow only one `var` statement per function - "passfail" : false, // true: Stop on first error - "white" : false, // true: Check against strict whitespace and indentation rules - - // Custom Globals - "predef" : [ ], // additional predefined global variables - - "globals": { - "ChromeWorker": false, - "Components": false, - "DOMRequestIpcHelper": false, - "ObjectWrapper": false, - "PhoneNumberUtils": false, - "RILNetworkInterface": false, - "Services": false, - "Uint8Array": false, - "WAP": false, - "XPCOMUtils": false, - "cpmm": false, - "dump": false, - "gAudioManager": false, - "gMessageManager": false, - "gMobileMessageDatabaseService": false, - "gMobileMessageService": false, - "gNetworkManager": false, - "gPowerManagerService": false, - "gSettingsService": false, - "gSmsService": false, - "gSystemMessenger": false, - "gSystemWorkerManager": false, - "gTimeService": false, - "gUUIDGenerator": false, - "ppmm": true, - - "__end_guardian_for_easy_sorting__": false - } -} diff --git a/dom/system/gonk/tests/marionette/test_all_network_info.js b/dom/system/gonk/tests/marionette/test_all_network_info.js deleted file mode 100644 index 5225ab6d6..000000000 --- a/dom/system/gonk/tests/marionette/test_all_network_info.js +++ /dev/null @@ -1,106 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -var networkManager = - Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager); -ok(networkManager, - "networkManager.constructor is " + networkManager.constructor); - -var wifiManager = window.navigator.mozWifiManager; -ok(wifiManager, "wifiManager.constructor is " + wifiManager.constructor); - -function setEmulatorAPN() { - let apn = [ - [{"carrier":"T-Mobile US", - "apn":"epc.tmobile.com", - "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types":["default","supl","mms","ims","dun", "fota"]}] - ]; - - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn); -} - -function ensureWifiEnabled(aEnabled) { - if (wifiManager.enabled === aEnabled) { - log('Already ' + (aEnabled ? 'enabled' : 'disabled')); - return Promise.resolve(); - } - return requestWifiEnabled(aEnabled); -} - -function requestWifiEnabled(aEnabled) { - let promises = []; - - promises.push(waitForTargetEvent(wifiManager, aEnabled ? 'enabled' : 'disabled', - function() { - return wifiManager.enabled === aEnabled ? true : false; - })); - promises.push(setSettings(SETTINGS_KEY_WIFI_ENABLED, aEnabled)); - - return Promise.all(promises); -} - -// Test initial State -function verifyInitialState() { - log("= verifyInitialState ="); - - // Data and wifi should be off before starting any test. - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then(value => { - is(value, false, "Data must be off"); - }) - .then(() => ensureWifiEnabled(false)); -} - -function testAllNetworkInfo(aAnyConnected) { - log("= testAllNetworkInfo = " + aAnyConnected); - - let allNetworkInfo = networkManager.allNetworkInfo; - ok(allNetworkInfo, "NetworkManager.allNetworkInfo"); - - let count = Object.keys(allNetworkInfo).length; - ok(count > 0, "NetworkManager.allNetworkInfo count"); - - let connected = false; - for (let networkId in allNetworkInfo) { - if (allNetworkInfo.hasOwnProperty(networkId)) { - let networkInfo = allNetworkInfo[networkId]; - if (networkInfo.state == Ci.nsINetworkInfo.NETWORK_STATE_CONNECTED) { - connected = true; - break; - } - } - } - - is(aAnyConnected, connected, "NetworkManager.allNetworkInfo any connected"); -} - -// Start test -startTestBase(function() { - - let origApnSettings, origWifiEnabled; - return Promise.resolve() - .then(() => { - origWifiEnabled = wifiManager.enabled; - }) - .then(() => verifyInitialState()) - .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS)) - .then(value => { - origApnSettings = value; - }) - .then(() => setEmulatorAPN()) - .then(() => setDataEnabledAndWait(true)) - .then(() => testAllNetworkInfo(true)) - .then(() => setDataEnabledAndWait(false)) - .then(() => testAllNetworkInfo(false)) - // Restore original apn settings and wifi state. - .then(() => { - if (origApnSettings) { - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings); - } - }) - .then(() => ensureWifiEnabled(origWifiEnabled)); -}); diff --git a/dom/system/gonk/tests/marionette/test_data_connection.js b/dom/system/gonk/tests/marionette/test_data_connection.js deleted file mode 100644 index 5a53b1e5f..000000000 --- a/dom/system/gonk/tests/marionette/test_data_connection.js +++ /dev/null @@ -1,70 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -function setEmulatorAPN() { - let apn = [ - [{"carrier":"T-Mobile US", - "apn":"epc.tmobile.com", - "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types":["default","supl","mms","ims","dun", "fota"]}] - ]; - - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn); -} - -// Test initial State -function testInitialState() { - log("= testInitialState ="); - - // Data should be off before starting any test. - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then(value => { - is(value, false, "Data must be off"); - }); -} - -// Test default data Connection -function testDefaultDataConnection() { - log("= testDefaultDataConnection ="); - - // Enable default data - return setDataEnabledAndWait(true) - // Disable default data - .then(() => setDataEnabledAndWait(false)); -} - -// Test non default data connection -function testNonDefaultDataConnection() { - log("= testNonDefaultDataConnection ="); - - function doTestNonDefaultDataConnection(type) { - log("doTestNonDefaultDataConnection: " + type); - - return setupDataCallAndWait(type) - .then(() => deactivateDataCallAndWait(type)); - } - - let currentApn; - return getSettings(SETTINGS_KEY_DATA_APN_SETTINGS) - .then(value => { - currentApn = value; - }) - .then(setEmulatorAPN) - .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_MMS)) - .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_SUPL)) - .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_IMS)) - .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_DUN)) - .then(() => doTestNonDefaultDataConnection(NETWORK_TYPE_MOBILE_FOTA)) - // Restore APN settings - .then(() => setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, currentApn)); -} - -// Start test -startTestBase(function() { - return testInitialState() - .then(() => testDefaultDataConnection()) - .then(() => testNonDefaultDataConnection()); -}); diff --git a/dom/system/gonk/tests/marionette/test_data_connection_proxy.js b/dom/system/gonk/tests/marionette/test_data_connection_proxy.js deleted file mode 100644 index a99187538..000000000 --- a/dom/system/gonk/tests/marionette/test_data_connection_proxy.js +++ /dev/null @@ -1,99 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -const HTTP_PROXY = "10.0.2.200"; -const HTTP_PROXY_PORT = "8080"; -const MANUAL_PROXY_CONFIGURATION = 1; - -// Test initial State -function verifyInitialState() { - log("= verifyInitialState ="); - - // Data should be off before starting any test. - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then(value => { - is(value, false, "Data must be off"); - }); -} - -function setTestApn() { - let apn = [ - [ {"carrier": "T-Mobile US", - "apn": "epc.tmobile.com", - "proxy": HTTP_PROXY, - "port": HTTP_PROXY_PORT, - "mmsc": "http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types": ["default","supl","mms"]} ] - ]; - - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn); -} - -function waitForHttpProxyVerified(aShouldBeSet) { - let TIME_OUT_VALUE = 20000; - - return new Promise(function(aResolve, aReject) { - try { - waitFor(aResolve, () => { - let proxyType = SpecialPowers.getIntPref("network.proxy.type"); - let httpProxy = SpecialPowers.getCharPref("network.proxy.http"); - let sslProxy = SpecialPowers.getCharPref("network.proxy.ssl"); - let httpProxyPort = SpecialPowers.getIntPref("network.proxy.http_port"); - let sslProxyPort = SpecialPowers.getIntPref("network.proxy.ssl_port"); - - if ((aShouldBeSet && - proxyType == MANUAL_PROXY_CONFIGURATION && - httpProxy == HTTP_PROXY && - sslProxy == HTTP_PROXY && - httpProxyPort == HTTP_PROXY_PORT && - sslProxyPort == HTTP_PROXY_PORT) || - (!aShouldBeSet && proxyType != MANUAL_PROXY_CONFIGURATION && - !httpProxy && !sslProxy && !httpProxyPort && !sslProxyPort)) { - return true; - } - - return false; - }, TIME_OUT_VALUE); - } catch(aError) { - // Timed out. - aReject(aError); - } - }); -} - -function testDefaultDataHttpProxy() { - log("= testDefaultDataHttpProxy ="); - - return setDataEnabledAndWait(true) - .then(() => waitForHttpProxyVerified(true)) - .then(() => setDataEnabledAndWait(false)) - .then(() => waitForHttpProxyVerified(false)); -} - -function testNonDefaultDataHttpProxy(aType) { - log("= testNonDefaultDataHttpProxy - " + aType + " ="); - - return setupDataCallAndWait(aType) - // Http proxy should not be set for non-default data connections. - .then(() => waitForHttpProxyVerified(false)) - .then(() => deactivateDataCallAndWait(aType)); -} - -// Start test -startTestBase(function() { - let origApnSettings; - return verifyInitialState() - .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS)) - .then(value => { - origApnSettings = value; - }) - .then(() => setTestApn()) - .then(() => testDefaultDataHttpProxy()) - .then(() => testNonDefaultDataHttpProxy(NETWORK_TYPE_MOBILE_MMS)) - .then(() => testNonDefaultDataHttpProxy(NETWORK_TYPE_MOBILE_SUPL)) - // Restore APN settings - .then(() => setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings)); -}); diff --git a/dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.js b/dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.js deleted file mode 100644 index e178b8b65..000000000 --- a/dom/system/gonk/tests/marionette/test_dsds_numRadioInterfaces.js +++ /dev/null @@ -1,43 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_CONTEXT = "chrome"; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/systemlibs.js"); - -const NS_RIL_CONTRACTID = "@mozilla.org/ril;1"; - -const PROP_RO_MOZ_RIL_NUMCLIENTS = "ro.moz.ril.numclients"; - -const PREF_RIL_NUM_RADIO_INTERFACES = "ril.numRadioInterfaces"; - -ok(libcutils, "libcutils is available"); - -var propNum = (function() { - try { - let numString = libcutils.property_get(PROP_RO_MOZ_RIL_NUMCLIENTS, "1"); - let num = parseInt(numString, 10); - if (num >= 0) { - return num; - } - } catch (e) {} -})(); - -log("Retrieved '" + PROP_RO_MOZ_RIL_NUMCLIENTS + "' = " + propNum); -ok(propNum, PROP_RO_MOZ_RIL_NUMCLIENTS); - -var prefNum = Services.prefs.getIntPref(PREF_RIL_NUM_RADIO_INTERFACES); -log("Retrieved '" + PREF_RIL_NUM_RADIO_INTERFACES + "' = " + prefNum); - -var ril = Cc[NS_RIL_CONTRACTID].getService(Ci.nsIRadioInterfaceLayer); -ok(ril, "ril.constructor is " + ril.constructor); - -var ifaceNum = ril.numRadioInterfaces; -log("Retrieved 'nsIRadioInterfaceLayer.numRadioInterfaces' = " + ifaceNum); - -is(propNum, prefNum); -is(propNum, ifaceNum); - -finish(); diff --git a/dom/system/gonk/tests/marionette/test_fakevolume.js b/dom/system/gonk/tests/marionette/test_fakevolume.js deleted file mode 100644 index 173f9ac11..000000000 --- a/dom/system/gonk/tests/marionette/test_fakevolume.js +++ /dev/null @@ -1,25 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 10000; - -var Cc = SpecialPowers.Cc; -var Ci = SpecialPowers.Ci; - -var volumeService = Cc["@mozilla.org/telephony/volume-service;1"].getService(Ci.nsIVolumeService); -ok(volumeService, "Should have volume service"); - -var volName = "fake"; -var mountPoint = "/data/fake/storage"; -volumeService.createFakeVolume(volName, mountPoint); - -var vol = volumeService.getVolumeByName(volName); -ok(vol, "volume shouldn't be null"); - -is(volName, vol.name, "name"); -is(mountPoint, vol.mountPoint, "moutnPoint"); -is(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state"); - -ok(vol.mountGeneration > 0, "mount generation should not be zero"); - -finish(); diff --git a/dom/system/gonk/tests/marionette/test_geolocation.js b/dom/system/gonk/tests/marionette/test_geolocation.js deleted file mode 100644 index 201c8b3e3..000000000 --- a/dom/system/gonk/tests/marionette/test_geolocation.js +++ /dev/null @@ -1,117 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 10000; - -var geolocation = window.navigator.geolocation; -ok(geolocation); - -var sample = []; -var result = []; -var wpid; - -/** - * Grant special power to get the geolocation - */ -SpecialPowers.addPermission("geolocation", true, document); - -/** - * Disable wifi geolocation provider - */ -wifiUri = SpecialPowers.getCharPref("geo.wifi.uri"); -SpecialPowers.setCharPref("geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=stop-responding"); - -/** - * Helper that compares the geolocation against the web API. - */ -function verifyLocation() { - - log("Sample:" + sample.join(',')); - log("Result:" + result.join(',')); - - for (i in sample) { - is(sample.pop(), result.pop()); - } - - window.setTimeout(cleanup, 0); -} - -/** - * Test story begins here. - */ -function setup() { - log("Providing initial setup: set geographic position watcher."); - - - wpid = geolocation.watchPosition(function(position) { - log("Position changes: (" + position.coords.latitude + "/" + position.coords.longitude + ")"); - result.push(""+position.coords.latitude + "/" + position.coords.longitude); - }); - - lat = 0; - lon = 0; - - cmd = "geo fix " + lon + " " + lat; - sample.push(lat+"/"+lon); - - runEmulatorCmd(cmd, function(result) { - window.setTimeout(movePosition_1, 0); - }); -} - -function movePosition_1() { - log("Geolocation changes. Move to Position 1."); - - lat = 25; - lon = 121.56499833333334; - - cmd = "geo fix " + lon + " " + lat; - sample.push(lat+"/"+lon); - - runEmulatorCmd(cmd, function(result) { - window.setTimeout(movePosition_2, 0); - }); -} - -function movePosition_2() { - log("Geolocation changes to a negative longitude. Move to Position 2."); - - lat = 37.393; - lon = -122.08199833333335; - - cmd = "geo fix " + lon + " " + lat; - sample.push(lat+"/"+lon); - - runEmulatorCmd(cmd, function(result) { - window.setTimeout(movePosition_3, 0); - }); -} - -function movePosition_3() { - log("Geolocation changes with WatchPosition. Move to Position 3."); - - lat = -22; - lon = -43; - - cmd = "geo fix " + lon + " " + lat; - sample.push(lat+"/"+lon); - - geolocation.getCurrentPosition(function(position) { - log("getCurrentPosition: Expected location: ("+lat+"/"+lon+"); Current location: (" + position.coords.latitude + "/" + position.coords.longitude + ")"); - is(lat, position.coords.latitude); - is(lon, position.coords.longitude); - }); - - runEmulatorCmd(cmd, function(result) { - window.setTimeout(verifyLocation, 0); - }); -} - -function cleanup() { - geolocation.clearWatch(wpid); - SpecialPowers.removePermission("geolocation", document); - SpecialPowers.setCharPref("geo.wifi.uri", wifiUri); - finish(); -} - -setup(); diff --git a/dom/system/gonk/tests/marionette/test_multiple_data_connection.js b/dom/system/gonk/tests/marionette/test_multiple_data_connection.js deleted file mode 100644 index 24abd4451..000000000 --- a/dom/system/gonk/tests/marionette/test_multiple_data_connection.js +++ /dev/null @@ -1,89 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -// Must sync with hardware/ril/reference-ril/reference-ril.c -const MAX_DATA_CONTEXTS = 4; - -function setEmulatorAPN() { - // Use different apn for each network type. - let apn = [[ { "carrier":"T-Mobile US", - "apn":"epc1.tmobile.com", - "types":["default"] }, - { "carrier":"T-Mobile US", - "apn":"epc2.tmobile.com", - "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types":["mms"] }, - { "carrier":"T-Mobile US", - "apn":"epc3.tmobile.com", - "types":["supl"] }, - { "carrier":"T-Mobile US", - "apn":"epc4.tmobile.com", - "types":["ims"] }, - { "carrier":"T-Mobile US", - "apn":"epc5.tmobile.com", - "types":["dun"] }, - { "carrier":"T-Mobile US", - "apn":"epc6.tmobile.com", - "types":["fota"] }]]; - - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn); -} - -// Test initial State -function testInitialState() { - log("= testInitialState ="); - - // Data should be off before starting any test. - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then(value => { - is(value, false, "Data must be off"); - }); -} - -function testSetupConcurrentDataCalls() { - log("= testSetupConcurrentDataCalls ="); - - let promise = Promise.resolve(); - // Skip default mobile type. - for (let i = 1; i < MAX_DATA_CONTEXTS; i++) { - let type = networkTypes[i]; - promise = promise.then(() => setupDataCallAndWait(type)); - } - return promise; -} - -function testDeactivateConcurrentDataCalls() { - log("= testDeactivateConcurrentDataCalls ="); - - let promise = Promise.resolve(); - // Skip default mobile type. - for (let i = 1; i < MAX_DATA_CONTEXTS; i++) { - let type = networkTypes[i]; - promise = promise.then(() => deactivateDataCallAndWait(type)); - } - return promise; -} - -// Start test -startTestBase(function() { - - let origApnSettings; - return testInitialState() - .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS)) - .then(value => { - origApnSettings = value; - }) - .then(() => setEmulatorAPN()) - .then(() => setDataEnabledAndWait(true)) - .then(() => testSetupConcurrentDataCalls()) - .then(() => testDeactivateConcurrentDataCalls()) - .then(() => setDataEnabledAndWait(false)) - .then(() => { - if (origApnSettings) { - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings); - } - }); -}); diff --git a/dom/system/gonk/tests/marionette/test_network_active_changed.js b/dom/system/gonk/tests/marionette/test_network_active_changed.js deleted file mode 100644 index 5886f37ed..000000000 --- a/dom/system/gonk/tests/marionette/test_network_active_changed.js +++ /dev/null @@ -1,52 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -var networkManager = - Cc["@mozilla.org/network/manager;1"].getService(Ci.nsINetworkManager); -ok(networkManager, - "networkManager.constructor is " + networkManager.constructor); - -function testInitialState() { - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then((enabled) => { - is(enabled, false, "data should be off by default"); - is(networkManager.activeNetworkInfo, null, - "networkManager.activeNetworkInfo should be null by default"); - }); -} - -function testActiveNetworkChangedBySwitchingDataCall(aDataCallEnabled) { - log("Test active network by switching dataCallEnabled to " + aDataCallEnabled); - - let promises = []; - promises.push(waitForObserverEvent(TOPIC_NETWORK_ACTIVE_CHANGED)); - promises.push(setSettings(SETTINGS_KEY_DATA_ENABLED, aDataCallEnabled)); - - return Promise.all(promises).then(function(results) { - let subject = results[0]; - - if (aDataCallEnabled) { - ok(subject instanceof Ci.nsINetworkInfo, - "subject should be an instance of nsINetworkInfo"); - ok(subject instanceof Ci.nsIRilNetworkInfo, - "subject should be an instance of nsIRilNetworkInfo"); - is(subject.type, NETWORK_TYPE_MOBILE, - "subject.type should be NETWORK_TYPE_MOBILE"); - } - - is(subject, networkManager.activeNetworkInfo, - "subject should be equal with networkManager.activeNetworkInfo"); - }); -} - -// Start test -startTestBase(function() { - return testInitialState() - // Test active network changed by enabling data call. - .then(() => testActiveNetworkChangedBySwitchingDataCall(true)) - // Test active network changed by disabling data call. - .then(() => testActiveNetworkChangedBySwitchingDataCall(false)); -}); diff --git a/dom/system/gonk/tests/marionette/test_network_interface_list_service.js b/dom/system/gonk/tests/marionette/test_network_interface_list_service.js deleted file mode 100644 index 549940fa5..000000000 --- a/dom/system/gonk/tests/marionette/test_network_interface_list_service.js +++ /dev/null @@ -1,95 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -function getNetworkInfo(aType) { - let networkListService = - Cc["@mozilla.org/network/interface-list-service;1"]. - getService(Ci.nsINetworkInterfaceListService); - // Get all available interfaces - let networkList = networkListService.getDataInterfaceList(0); - - // Try to get nsINetworkInterface for aType. - let numberOfInterface = networkList.getNumberOfInterface(); - for (let i = 0; i < numberOfInterface; i++) { - let info = networkList.getInterfaceInfo(i); - if (info.type === aType) { - return info; - } - } - - return null; -} - -// Test getDataInterfaceList by enabling/disabling mobile data. -function testGetDataInterfaceList(aMobileDataEnabled) { - log("Test getDataInterfaceList with mobile data " + - aMobileDataEnabled ? "enabled" : "disabled"); - - return setDataEnabledAndWait(aMobileDataEnabled) - .then(() => getNetworkInfo(NETWORK_TYPE_MOBILE)) - .then((networkInfo) => { - if (!networkInfo) { - ok(false, "Should get an valid nsINetworkInfo for mobile"); - return; - } - - ok(networkInfo instanceof Ci.nsINetworkInfo, - "networkInfo should be an instance of nsINetworkInfo"); - - let ipAddresses = {}; - let prefixs = {}; - let numOfGateways = {}; - let numOfDnses = {}; - let numOfIpAddresses = networkInfo.getAddresses(ipAddresses, prefixs); - let gateways = networkInfo.getGateways(numOfGateways); - let dnses = networkInfo.getDnses(numOfDnses); - - if (aMobileDataEnabled) { - // Mobile data is enabled. - is(networkInfo.state, NETWORK_STATE_CONNECTED, "check state"); - ok(numOfIpAddresses > 0, "check number of ipAddresses"); - ok(ipAddresses.value.length > 0, "check ipAddresses.length"); - ok(prefixs.value.length > 0, "check prefixs.length"); - ok(numOfGateways.value > 0, "check number of gateways"); - ok(prefixs.value.length > 0, "check prefixs.length"); - ok(gateways.length > 0, "check gateways.length"); - ok(numOfDnses.value > 0, "check number of dnses"); - ok(dnses.length > 0, "check dnses.length"); - } else { - // Mobile data is disabled. - is(networkInfo.state, NETWORK_STATE_DISCONNECTED, "check state"); - is(numOfIpAddresses, 0, "check number of ipAddresses"); - is(ipAddresses.value.length, 0, "check ipAddresses.length"); - is(prefixs.value.length, 0, "check prefixs.length"); - is(numOfGateways.value, 0, "check number of gateways"); - is(prefixs.value.length, 0, "check prefixs.length"); - is(gateways.length, 0, "check gateways.length"); - is(numOfDnses.value, 0, "check number of dnses"); - is(dnses.length, 0, "check dnses.length"); - } - }); -} - -// Start test -startTestBase(function() { - return Promise.resolve() - // Test initial State - .then(() => { - log("Test initial state"); - - // Data should be off before starting any test. - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then(value => { - is(value, false, "Mobile data must be off"); - }); - }) - - // Test getDataInterfaceList with mobile data enabled. - .then(() => testGetDataInterfaceList(true)) - - // Test getDataInterfaceList with mobile data disabled. - .then(() => testGetDataInterfaceList(false)); -}); diff --git a/dom/system/gonk/tests/marionette/test_network_interface_mtu.js b/dom/system/gonk/tests/marionette/test_network_interface_mtu.js deleted file mode 100644 index 679efe2ed..000000000 --- a/dom/system/gonk/tests/marionette/test_network_interface_mtu.js +++ /dev/null @@ -1,100 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = "head.js"; - -const TEST_MTU1 = "1410"; -const TEST_MTU2 = "1440"; - -function setEmulatorAPN() { - let apn = [ - [ { "carrier":"T-Mobile US", - "apn":"epc1.tmobile.com", - "types":["default"], - "mtu": TEST_MTU1 }, - { "carrier":"T-Mobile US", - "apn":"epc2.tmobile.com", - "mmsc":"http://mms.msg.eng.t-mobile.com/mms/wapenc", - "types":["supl","mms","ims","dun", "fota"], - "mtu": TEST_MTU2 } ] - ]; - - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, apn); -} - -function verifyInitialState() { - // Data should be off before starting any test. - return getSettings(SETTINGS_KEY_DATA_ENABLED) - .then(value => { - is(value, false, "Data must be off"); - }); -} - -function verifyMtu(aInterfaceName, aMtu) { - return runEmulatorShellCmdSafe(['ip', 'link', 'show', 'dev', aInterfaceName]) - .then(aLines => { - // Sample output: - // - // 4: rmnet0: <BROADCAST,MULTICAST> mtu 1410 qdisc pfifo_fast state DOWN mode DEFAULT qlen 1000 - // link/ether 52:54:00:12:34:58 brd ff:ff:ff:ff:ff:ff - // - let mtu; - aLines.some(function (aLine) { - let tokens = aLine.trim().split(/\s+/); - let mtuIndex = tokens.indexOf('mtu'); - if (mtuIndex < 0 || mtuIndex + 1 >= tokens.length) { - return false; - } - - mtu = tokens[mtuIndex + 1]; - return true; - }); - - is(mtu, aMtu, aInterfaceName + "'s mtu."); - }); -} - -function testDefaultDataCallMtu() { - log("= testDefaultDataCallMtu ="); - - return setDataEnabledAndWait(true) - .then(aNetworkInfo => verifyMtu(aNetworkInfo.name, TEST_MTU1)) - .then(() => setDataEnabledAndWait(false)); -} - -function testNonDefaultDataCallMtu() { - log("= testNonDefaultDataCallMtu ="); - - function doTestNonDefaultDataCallMtu(aType) { - log("doTestNonDefaultDataCallMtu: " + aType); - - return setupDataCallAndWait(aType) - .then(aNetworkInfo => verifyMtu(aNetworkInfo.name, TEST_MTU2)) - .then(() => deactivateDataCallAndWait(aType)); - } - - return doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_MMS) - .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_SUPL)) - .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_IMS)) - .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_DUN)) - .then(() => doTestNonDefaultDataCallMtu(NETWORK_TYPE_MOBILE_FOTA)); -} - -// Start test -startTestBase(function() { - let origApnSettings; - return verifyInitialState() - .then(() => getSettings(SETTINGS_KEY_DATA_APN_SETTINGS)) - .then(value => { - origApnSettings = value; - }) - .then(() => setEmulatorAPN()) - .then(() => testDefaultDataCallMtu()) - .then(() => testNonDefaultDataCallMtu()) - .then(() => { - if (origApnSettings) { - return setSettings(SETTINGS_KEY_DATA_APN_SETTINGS, origApnSettings); - } - }); -}); diff --git a/dom/system/gonk/tests/marionette/test_ril_code_quality.py b/dom/system/gonk/tests/marionette/test_ril_code_quality.py deleted file mode 100644 index d741d8a2e..000000000 --- a/dom/system/gonk/tests/marionette/test_ril_code_quality.py +++ /dev/null @@ -1,371 +0,0 @@ -""" -The test performs the static code analysis check by JSHint. - -Target js files: -- RadioInterfaceLayer.js -- ril_worker.js -- ril_consts.js - -If the js file contains the line of 'importScript()' (Ex: ril_worker.js), the -test will perform a special merge step before excuting JSHint. - -Ex: Script A --------------------------------- -importScripts('Script B') -... --------------------------------- - -We merge these two scripts into one by the following way. - --------------------------------- -[Script B (ex: ril_consts.js)] -(function(){ [Script A (ex: ril_worker.js)] -})(); --------------------------------- - -Script A (ril_worker.js) runs global strict mode. -Script B (ril_consts.js) not. - -The above merge way ensures the correct scope of 'strict mode.' -""" - -import bisect -import inspect -import os -import os.path -import re -import unicodedata - -from marionette_harness import MarionetteTestCase - - -class StringUtility: - - """A collection of some string utilities.""" - - @staticmethod - def find_match_lines(lines, pattern): - """Return a list of lines that contains given pattern.""" - return [line for line in lines if pattern in line] - - @staticmethod - def remove_non_ascii(data): - """Remove non ascii characters in data and return it as new string.""" - if type(data).__name__ == 'unicode': - data = unicodedata.normalize( - 'NFKD', data).encode('ascii', 'ignore') - return data - - @staticmethod - def auto_close(lines): - """Ensure every line ends with '\n'.""" - if lines and not lines[-1].endswith('\n'): - lines[-1] += '\n' - return lines - - @staticmethod - def auto_wrap_strict_mode(lines): - """Wrap by function scope if lines contain 'use strict'.""" - if StringUtility.find_match_lines(lines, 'use strict'): - lines[0] = '(function(){' + lines[0] - lines.append('})();\n') - return lines - - @staticmethod - def get_imported_list(lines): - """Get a list of imported items.""" - return [item - for line in StringUtility.find_match_lines(lines, 'importScripts') - for item in StringUtility._get_imported_list_from_line(line)] - - @staticmethod - def _get_imported_list_from_line(line): - """Extract all items from 'importScripts(...)'. - - importScripts("ril_consts.js", "systemlibs.js") - => ['ril_consts', 'systemlibs.js'] - - """ - pattern = re.compile(r'\s*importScripts\((.*)\)') - m = pattern.match(line) - if not m: - raise Exception('Parse importScripts error.') - return [name.translate(None, '\' "') for name in m.group(1).split(',')] - - -class ResourceUriFileReader: - - """Handle the process of reading the source code from system.""" - - URI_PREFIX = 'resource://gre/' - URI_PATH = { - 'RadioInterfaceLayer.js': 'components/RadioInterfaceLayer.js', - 'ril_worker.js': 'modules/ril_worker.js', - 'ril_consts.js': 'modules/ril_consts.js', - 'systemlibs.js': 'modules/systemlibs.js', - 'worker_buf.js': 'modules/workers/worker_buf.js', - } - - CODE_OPEN_CHANNEL_BY_URI = ''' - var Cc = Components.classes; - var Ci = Components.interfaces; - var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); - var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); - global.uri = '%(uri)s'; - global.channel = ios.newChannel2(global.uri, - null, - null, - null, // aLoadingNode - secMan.getSystemPrincipal(), - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - Ci.nsIContentPolicy.TYPE_OTHER); - ''' - - CODE_GET_SPEC = ''' - return global.channel.URI.spec; - ''' - - CODE_READ_CONTENT = ''' - var Cc = Components.classes; - var Ci = Components.interfaces; - - var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader); - var inputStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream); - - var jaruri = global.channel.URI.QueryInterface(Ci.nsIJARURI); - var file = jaruri.JARFile.QueryInterface(Ci.nsIFileURL).file; - var entry = jaruri.JAREntry; - zipReader.open(file); - inputStream.init(zipReader.getInputStream(entry)); - var content = inputStream.read(inputStream.available()); - inputStream.close(); - zipReader.close(); - return content; - ''' - - @classmethod - def get_uri(cls, filename): - """Convert filename to URI in system.""" - if filename.startswith(cls.URI_PREFIX): - return filename - else: - return cls.URI_PREFIX + cls.URI_PATH[filename] - - def __init__(self, marionette): - self.runjs = lambda x: marionette.execute_script(x, - new_sandbox=False, - sandbox='system') - - def read_file(self, filename): - """Read file and return the contents as string.""" - content = self._read_uri(self.get_uri(filename)) - content = content.replace('"use strict";', '') - return StringUtility.remove_non_ascii(content) - - def _read_uri(self, uri): - """Read URI in system and return the contents as string.""" - # Open the uri as a channel. - self.runjs(self.CODE_OPEN_CHANNEL_BY_URI % {'uri': uri}) - - # Make sure spec is a jar uri, and not recursive. - # Ex: 'jar:file:///system/b2g/omni.ja!/modules/ril_worker.js' - # - # For simplicity, we don't handle other special cases in this test. - # If B2G build system changes in the future, such as put the jar in - # another jar, the test case will fail. - spec = self.runjs(self.CODE_GET_SPEC) - if (not spec.startswith('jar:file://')) or (spec.count('jar:') != 1): - raise Exception('URI resolve error') - - # Read the content from channel. - content = self.runjs(self.CODE_READ_CONTENT) - return content - - -class JSHintEngine: - - """Invoke jshint script on system.""" - - CODE_INIT_JSHINT = ''' - %(script)s; - global.JSHINT = JSHINT; - global.options = JSON.parse(%(config_string)s); - global.globals = global.options.globals; - delete global.options.globals; - ''' - - CODE_RUN_JSHINT = ''' - global.script = %(code)s; - return global.JSHINT(global.script, global.options, global.globals); - ''' - - CODE_GET_JSHINT_ERROR = ''' - return global.JSHINT.errors; - ''' - - def __init__(self, marionette, script, config): - # Remove single line comment in config. - config = '\n'.join([line.partition('//')[0] - for line in config.splitlines()]) - - # Set global (JSHINT, options, global) in js environment. - self.runjs = lambda x: marionette.execute_script(x, - new_sandbox=False, - sandbox='system') - self.runjs(self.CODE_INIT_JSHINT % - {'script': script, 'config_string': repr(config)}) - - def run(self, code, filename=''): - """Excute JShint check for the given code.""" - check_pass = self.runjs(self.CODE_RUN_JSHINT % {'code': repr(code)}) - errors = self.runjs(self.CODE_GET_JSHINT_ERROR) - return check_pass, self._get_error_messages(errors, filename) - - def _get_error_messages(self, errors, filename=''): - """ - Convert an error object to a list of readable string. - - [{"a": null, "c": null, "code": "W033", "d": null, "character": 6, - "evidence": "var a", "raw": "Missing semicolon.", - "reason": "Missing semicolon.", "b": null, "scope": "(main)", "line": 1, - "id": "(error)"}] - => line 1, col 6, Missing semicolon. - - """ - LINE, COL, REASON = u'line', u'character', u'reason' - return ["%s: line %s, col %s, %s" % - (filename, error[LINE], error[COL], error[REASON]) - for error in errors if error] - - -class Linter: - - """Handle the linting related process.""" - - def __init__(self, code_reader, jshint, reporter=None): - """Set the linter with code_reader, jshint engine, and reporter. - - Should have following functionality. - - code_reader.read_file(filename) - - jshint.run(code, filename) - - reporter([...]) - - """ - self.code_reader = code_reader - self.jshint = jshint - if reporter is None: - self.reporter = lambda x: '\n'.join(x) - else: - self.reporter = reporter - - def lint_file(self, filename): - """Lint the file and return (pass, error_message).""" - # Get code contents. - code = self.code_reader.read_file(filename) - lines = code.splitlines() - import_list = StringUtility.get_imported_list(lines) - if not import_list: - check_pass, error_message = self.jshint.run(code, filename) - else: - newlines, info = self._merge_multiple_codes(filename, import_list) - # Each line of |newlines| contains '\n'. - check_pass, error_message = self.jshint.run(''.join(newlines)) - error_message = self._convert_merged_result(error_message, info) - # Only keep errors for this file. - error_message = [line for line in error_message - if line.startswith(filename)] - check_pass = (len(error_message) == 0) - return check_pass, self.reporter(error_message) - - def _merge_multiple_codes(self, filename, import_list): - """Merge multiple codes from filename and import_list.""" - dirname, filename = os.path.split(filename) - dst_line = 1 - dst_results = [] - info = [] - - # Put the imported script first, and then the original script. - for f in import_list + [filename]: - filepath = os.path.join(dirname, f) - - # Maintain a mapping table. - # New line number after merge => original file and line number. - info.append((dst_line, filepath, 1)) - try: - code = self.code_reader.read_file(filepath) - lines = code.splitlines(True) # Keep '\n'. - src_results = StringUtility.auto_wrap_strict_mode( - StringUtility.auto_close(lines)) - dst_results.extend(src_results) - dst_line += len(src_results) - except: - info.pop() - return dst_results, info - - def _convert_merged_result(self, error_lines, line_info): - pattern = re.compile(r'(.*): line (\d+),(.*)') - start_line = [info[0] for info in line_info] - new_result_lines = [] - for line in error_lines: - m = pattern.match(line) - if not m: - continue - - line_number, remain = int(m.group(2)), m.group(3) - - # [1, 2, 7, 8] - # ^ for 7, pos = 3 - # ^ for 6, pos = 2 - pos = bisect.bisect_right(start_line, line_number) - dst_line, name, src_line = line_info[pos - 1] - real_line_number = line_number - dst_line + src_line - new_result_lines.append( - "%s: line %s,%s" % (name, real_line_number, remain)) - return new_result_lines - - -class TestRILCodeQuality(MarionetteTestCase): - - JSHINT_PATH = 'ril_jshint/jshint.js' - JSHINTRC_PATH = 'ril_jshint/jshintrc' - - def _read_local_file(self, filepath): - """Read file content from local (folder of this test case).""" - test_dir = os.path.dirname(inspect.getfile(TestRILCodeQuality)) - return open(os.path.join(test_dir, filepath)).read() - - def _get_extended_error_message(self, error_message): - return '\n'.join(['See errors below and more information in Bug 880643', - '\n'.join(error_message), - 'See errors above and more information in Bug 880643']) - - def _check(self, filename): - check_pass, error_message = self.linter.lint_file(filename) - self.assertTrue(check_pass, error_message) - - def setUp(self): - MarionetteTestCase.setUp(self) - self.linter = Linter( - ResourceUriFileReader(self.marionette), - JSHintEngine(self.marionette, - self._read_local_file(self.JSHINT_PATH), - self._read_local_file(self.JSHINTRC_PATH)), - self._get_extended_error_message) - - def tearDown(self): - MarionetteTestCase.tearDown(self) - - def test_RadioInterfaceLayer(self): - self._check('RadioInterfaceLayer.js') - - # Bug 936504. Disable the test for 'ril_worker.js'. It sometimes runs very - # slow and causes the timeout fail on try server. - #def test_ril_worker(self): - # self._check('ril_worker.js') - - def test_ril_consts(self): - self._check('ril_consts.js') - - def test_worker_buf(self): - self._check('worker_buf.js') diff --git a/dom/system/gonk/tests/marionette/test_screen_state.js b/dom/system/gonk/tests/marionette/test_screen_state.js deleted file mode 100644 index 2281412d5..000000000 --- a/dom/system/gonk/tests/marionette/test_screen_state.js +++ /dev/null @@ -1,47 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 10000; - -var Services = SpecialPowers.Services; - -function testScreenState(on, expected, msg) { - // send event to RadioInterface - Services.obs.notifyObservers(null, 'screen-state-changed', on); - // maybe rild/qemu needs some time to process the event - window.setTimeout(function() { - runEmulatorCmd('gsm report creg', function(result) { - is(result.pop(), 'OK', '\'gsm report creg\' successful'); - ok(result.indexOf(expected) !== -1, msg); - runNextTest(); - })}, 1000); -} - -function testScreenStateDisabled() { - testScreenState('off', '+CREG: 1', 'screen is disabled'); -} - -function testScreenStateEnabled() { - testScreenState('on', '+CREG: 2', 'screen is enabled'); -} - -var tests = [ - testScreenStateDisabled, - testScreenStateEnabled -]; - -function runNextTest() { - let test = tests.shift(); - if (!test) { - cleanUp(); - return; - } - - test(); -} - -function cleanUp() { - finish(); -} - -runNextTest(); diff --git a/dom/system/gonk/tests/marionette/test_timezone_changes.js b/dom/system/gonk/tests/marionette/test_timezone_changes.js deleted file mode 100644 index 11dbaec5a..000000000 --- a/dom/system/gonk/tests/marionette/test_timezone_changes.js +++ /dev/null @@ -1,135 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -MARIONETTE_TIMEOUT = 60000; -MARIONETTE_HEAD_JS = 'head.js'; - -function init() { - let promises = []; - - /* - * The initial timezone of the emulator could be anywhere, depends the host - * machine. Ensure resetting it to UTC before testing. - */ - promises.push(runEmulatorCmdSafe('gsm timezone 0')); - promises.push(new Promise((aResolve, aReject) => { - waitFor(aResolve, () => { - return new Date().getTimezoneOffset() === 0; - }); - })); - - return Promise.all(promises); -} - -function paddingZeros(aNumber, aLength) { - let str = '' + aNumber; - while (str.length < aLength) { - str = '0' + str; - } - - return str; -} - -function verifyDate(aTestDate, aUTCOffsetDate) { - // Verify basic properties. - is(aUTCOffsetDate.getUTCFullYear(), aTestDate.getFullYear(), 'year'); - is(aUTCOffsetDate.getUTCMonth(), aTestDate.getMonth(), 'month'); - is(aUTCOffsetDate.getUTCDate(), aTestDate.getDate(), 'date'); - is(aUTCOffsetDate.getUTCHours(), aTestDate.getHours(), 'hours'); - is(aUTCOffsetDate.getUTCMinutes(), aTestDate.getMinutes(), 'minutes'); - is(aUTCOffsetDate.getUTCMilliseconds(), aTestDate.getMilliseconds(), 'milliseconds'); - - // Ensure toLocaleString also uses correct timezone. - // It uses ICU's timezone instead of the offset calculated from gecko prtime. - let expectedDateString = - paddingZeros(aUTCOffsetDate.getUTCMonth() + 1, 2) + '/' + - paddingZeros(aUTCOffsetDate.getUTCDate(), 2); - let dateString = aTestDate.toLocaleString('en-US', { - month: '2-digit', - day: '2-digit', - }); - let expectedTimeString = - paddingZeros(aUTCOffsetDate.getUTCHours(), 2) + ':' + - paddingZeros(aUTCOffsetDate.getUTCMinutes(), 2); - let timeString = aTestDate.toLocaleString('en-US', { - hour12: false, - hour: '2-digit', - minute: '2-digit' - }); - - is(expectedDateString, dateString, 'dateString'); - is(expectedTimeString, timeString, 'timeString'); -} - -function waitForTimezoneUpdate(aTzOffset, - aTestDateInMillis = 86400000, // Use 'UTC 00:00:00, 2nd of Jan, 1970' by default. - aTransTzOffset, aTransTestDateInMillis) { - return new Promise(function(aResolve, aReject) { - window.addEventListener('moztimechange', function onevent(aEvent) { - // Since there could be multiple duplicate moztimechange event, wait until - // timezone is actually changed to expected value before removing the - // listener. - let testDate = new Date(aTestDateInMillis); - if (testDate.getTimezoneOffset() === aTzOffset) { - window.removeEventListener('moztimechange', onevent); - - // The UTC time of offsetDate is the same as the expected local time of - // testDate. We'll use it to verify the values. - let offsetDate = new Date(aTestDateInMillis - aTzOffset * 60 * 1000); - verifyDate(testDate, offsetDate); - - // Verify transition time if given. - if (aTransTzOffset !== undefined) { - testDate = new Date(aTransTestDateInMillis); - is(testDate.getTimezoneOffset(), aTransTzOffset); - - // Verify transition date. - offsetDate = new Date(aTransTestDateInMillis - aTransTzOffset * 60 * 1000); - verifyDate(testDate, offsetDate); - } - - aResolve(aEvent); - } - }); - }); -} - -function testChangeNitzTimezone(aTzDiff) { - let promises = []; - - // aTzOffset should be the expected value for getTimezoneOffset(). - // Note that getTimezoneOffset() is not so straightforward, - // it values (UTC - localtime), so UTC+08:00 returns -480. - promises.push(waitForTimezoneUpdate(-aTzDiff * 15)); - promises.push(runEmulatorCmdSafe('gsm timezone ' + aTzDiff)); - - return Promise.all(promises); -} - -function testChangeOlsonTimezone(aOlsonTz, aTzOffset, aTestDateInMillis, - aTransTzOffset, aTransTestDateInMillis) { - let promises = []; - - promises.push(waitForTimezoneUpdate(aTzOffset, aTestDateInMillis, - aTransTzOffset, aTransTestDateInMillis)); - promises.push(setSettings('time.timezone', aOlsonTz)); - - return Promise.all(promises); -} - -// Start test -startTestBase(function() { - return init() - .then(() => testChangeNitzTimezone(36)) // UTC+09:00 - .then(() => testChangeOlsonTimezone('America/New_York', - 300, 1446357600000, // 2015/11/01 02:00 UTC-04:00 => 01:00 UTC-05:00 (EST) - 240, 1425798000000)) // 2015/03/08 02:00 UTC-05:00 => 03:00 UTC-04:00 (EDT) - .then(() => testChangeNitzTimezone(-22)) // UTC-05:30 - .then(() => testChangeNitzTimezone(51)) // UTC+12:45 - .then(() => testChangeOlsonTimezone('Australia/Adelaide', - -570, 1428165000000, // 2015/04/05 03:00 UTC+10:30 => 02:00 UTC+09:30 (ACST) - -630, 1443889800000)) // 2015/10/04 02:00 UTC+09:30 => 03:00 UTC+10:30 (ACDT) - .then(() => testChangeNitzTimezone(-38)) // UTC-09:30 - .then(() => testChangeNitzTimezone(0)) // UTC - .then(() => runEmulatorCmdSafe('gsm timezone auto')); -}); diff --git a/dom/system/gonk/tests/test_ril_system_messenger.js b/dom/system/gonk/tests/test_ril_system_messenger.js deleted file mode 100644 index a588d0ddb..000000000 --- a/dom/system/gonk/tests/test_ril_system_messenger.js +++ /dev/null @@ -1,1187 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -var RIL = {}; -Cu.import("resource://gre/modules/ril_consts.js", RIL); - -XPCOMUtils.defineLazyServiceGetter(this, "gStkCmdFactory", - "@mozilla.org/icc/stkcmdfactory;1", - "nsIStkCmdFactory"); - -/** - * Name space for RILSystemMessenger.jsm. Only initialized after first call to - * newRILSystemMessenger. - */ -var RSM; - -var gReceivedMsgType = null; -var gReceivedMessage = null; - -/** - * Create a new RILSystemMessenger instance. - * - * @return a RILSystemMessenger instance. - */ -function newRILSystemMessenger() { - if (!RSM) { - RSM = Cu.import("resource://gre/modules/RILSystemMessenger.jsm", {}); - equal(typeof RSM.RILSystemMessenger, "function", "RSM.RILSystemMessenger"); - } - - let rsm = new RSM.RILSystemMessenger(); - rsm.broadcastMessage = (aType, aMessage) => { - gReceivedMsgType = aType; - gReceivedMessage = aMessage; - }; - - rsm.createCommandMessage = (aStkProactiveCmd) => { - return gStkCmdFactory.createCommandMessage(aStkProactiveCmd); - }; - - return rsm; -} - -function equal_received_system_message(aType, aMessage) { - equal(aType, gReceivedMsgType); - deepEqual(aMessage, gReceivedMessage); - gReceivedMsgType = null; - gReceivedMessage = null; -} - -/** - * Verify that each nsIXxxMessenger could be retrieved. - */ -function run_test() { - let telephonyMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"] - .getService(Ci.nsITelephonyMessenger); - - let smsMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"] - .getService(Ci.nsISmsMessenger); - - let cellbroadcastMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"] - .getService(Ci.nsICellbroadcastMessenger); - - let mobileConnectionMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"] - .getService(Ci.nsIMobileConnectionMessenger); - - let iccMessenger = Cc["@mozilla.org/ril/system-messenger-helper;1"] - .getService(Ci.nsIIccMessenger); - - ok(telephonyMessenger !== null, "Get TelephonyMessenger."); - ok(smsMessenger != null, "Get SmsMessenger."); - ok(cellbroadcastMessenger != null, "Get CellbroadcastMessenger."); - ok(mobileConnectionMessenger != null, "Get MobileConnectionMessenger."); - ok(iccMessenger != null, "Get IccMessenger."); - - run_next_test(); -} - -/** - * Verify RILSystemMessenger.notifyNewCall() - */ -add_test(function test_telephony_messenger_notify_new_call() { - let messenger = newRILSystemMessenger(); - - messenger.notifyNewCall(); - equal_received_system_message("telephony-new-call", {}); - - run_next_test(); -}); - -/** - * Verify RILSystemMessenger.notifyCallEnded() - */ -add_test(function test_telephony_messenger_notify_call_ended() { - let messenger = newRILSystemMessenger(); - - messenger.notifyCallEnded(1, - "+0987654321", - null, - true, - 500, - false, - true); - - equal_received_system_message("telephony-call-ended", { - serviceId: 1, - number: "+0987654321", - emergency: true, - duration: 500, - direction: "incoming", - hangUpLocal: true - }); - - // Verify 'optional' parameter of secondNumber. - messenger.notifyCallEnded(1, - "+0987654321", - "+1234567890", - true, - 500, - true, - false); - - equal_received_system_message("telephony-call-ended", { - serviceId: 1, - number: "+0987654321", - emergency: true, - duration: 500, - direction: "outgoing", - hangUpLocal: false, - secondNumber: "+1234567890" - }); - - run_next_test(); -}); - -/** - * Verify RILSystemMessenger.notifySms() - */ -add_test(function test_sms_messenger_notify_sms() { - let messenger = newRILSystemMessenger(); - let timestamp = Date.now(); - let sentTimestamp = timestamp + 100; - let deliveryTimestamp = sentTimestamp + 100; - - // Verify 'sms-received' system message. - messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_RECEIVED, - 1, - 2, - "99887766554433221100", - Ci.nsISmsService.DELIVERY_TYPE_RECEIVED, - Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS, - "+0987654321", - null, - "Incoming message", - Ci.nsISmsService.MESSAGE_CLASS_TYPE_CLASS_2, - timestamp, - sentTimestamp, - 0, - false); - - equal_received_system_message("sms-received", { - iccId: "99887766554433221100", - type: "sms", - id: 1, - threadId: 2, - delivery: "received", - deliveryStatus: "success", - sender: "+0987654321", - receiver: null, - body: "Incoming message", - messageClass: "class-2", - timestamp: timestamp, - sentTimestamp: sentTimestamp, - deliveryTimestamp: 0, - read: false - }); - - // Verify 'sms-sent' system message. - messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT, - 3, - 4, - "99887766554433221100", - Ci.nsISmsService.DELIVERY_TYPE_SENT, - Ci.nsISmsService.DELIVERY_STATUS_TYPE_PENDING, - null, - "+0987654321", - "Outgoing message", - Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL, - timestamp, - 0, - 0, - true); - - equal_received_system_message("sms-sent", { - iccId: "99887766554433221100", - type: "sms", - id: 3, - threadId: 4, - delivery: "sent", - deliveryStatus: "pending", - sender: null, - receiver: "+0987654321", - body: "Outgoing message", - messageClass: "normal", - timestamp: timestamp, - sentTimestamp: 0, - deliveryTimestamp: 0, - read: true - }); - - // Verify 'sms-delivery-success' system message. - messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_SUCCESS, - 5, - 6, - "99887766554433221100", - Ci.nsISmsService.DELIVERY_TYPE_SENT, - Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS, - null, - "+0987654321", - "Outgoing message", - Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL, - timestamp, - 0, - deliveryTimestamp, - true); - - equal_received_system_message("sms-delivery-success", { - iccId: "99887766554433221100", - type: "sms", - id: 5, - threadId: 6, - delivery: "sent", - deliveryStatus: "success", - sender: null, - receiver: "+0987654321", - body: "Outgoing message", - messageClass: "normal", - timestamp: timestamp, - sentTimestamp: 0, - deliveryTimestamp: deliveryTimestamp, - read: true - }); - - // Verify 'sms-failed' system message. - messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT_FAILED, - 7, - 8, - "99887766554433221100", - Ci.nsISmsService.DELIVERY_TYPE_ERROR, - Ci.nsISmsService.DELIVERY_STATUS_TYPE_ERROR, - null, - "+0987654321", - "Outgoing message", - Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL, - timestamp, - 0, - 0, - true); - - equal_received_system_message("sms-failed", { - iccId: "99887766554433221100", - type: "sms", - id: 7, - threadId: 8, - delivery: "error", - deliveryStatus: "error", - sender: null, - receiver: "+0987654321", - body: "Outgoing message", - messageClass: "normal", - timestamp: timestamp, - sentTimestamp: 0, - deliveryTimestamp: 0, - read: true - }); - - // Verify 'sms-delivery-error' system message. - messenger.notifySms(Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_ERROR, - 9, - 10, - "99887766554433221100", - Ci.nsISmsService.DELIVERY_TYPE_SENT, - Ci.nsISmsService.DELIVERY_STATUS_TYPE_ERROR, - null, - "+0987654321", - "Outgoing message", - Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL, - timestamp, - 0, - 0, - true); - - equal_received_system_message("sms-delivery-error", { - iccId: "99887766554433221100", - type: "sms", - id: 9, - threadId: 10, - delivery: "sent", - deliveryStatus: "error", - sender: null, - receiver: "+0987654321", - body: "Outgoing message", - messageClass: "normal", - timestamp: timestamp, - sentTimestamp: 0, - deliveryTimestamp: 0, - read: true - }); - - // Verify the protection of invalid nsISmsMessenger.NOTIFICATION_TYPEs. - try { - messenger.notifySms(5, - 1, - 2, - "99887766554433221100", - Ci.nsISmsService.DELIVERY_TYPE_RECEIVED, - Ci.nsISmsService.DELIVERY_STATUS_TYPE_SUCCESS, - "+0987654321", - null, - "Incoming message", - Ci.nsISmsService.MESSAGE_CLASS_TYPE_NORMAL, - timestamp, - sentTimestamp, - 0, - false); - ok(false, "Failed to verify the protection of invalid nsISmsMessenger.NOTIFICATION_TYPE!"); - } catch (e) {} - - run_next_test(); -}); - -/** - * Verify RILSystemMessenger.notifyCbMessageReceived() - */ -add_test(function test_cellbroadcast_messenger_notify_cb_message_received() { - let messenger = newRILSystemMessenger(); - let timestamp = Date.now(); - - // Verify ETWS - messenger.notifyCbMessageReceived(0, - Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_CELL_IMMEDIATE, - 256, - 4352, - null, - null, - Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL, - timestamp, - Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID, - true, - Ci.nsICellBroadcastService.GSM_ETWS_WARNING_EARTHQUAKE, - false, - true); - equal_received_system_message("cellbroadcast-received", { - serviceId: 0, - gsmGeographicalScope: "cell-immediate", - messageCode: 256, - messageId: 4352, - language: null, - body: null, - messageClass: "normal", - timestamp: timestamp, - cdmaServiceCategory: null, - etws: { - warningType: "earthquake", - emergencyUserAlert: false, - popup: true - } - }); - - // Verify Normal CB Message - messenger.notifyCbMessageReceived(1, - Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_PLMN, - 0, - 50, - "en", - "The quick brown fox jumps over the lazy dog", - Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL, - timestamp, - Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID, - false, - Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID, - false, - false); - equal_received_system_message("cellbroadcast-received", { - serviceId: 1, - gsmGeographicalScope: "plmn", - messageCode: 0, - messageId: 50, - language: "en", - body: "The quick brown fox jumps over the lazy dog", - messageClass: "normal", - timestamp: timestamp, - cdmaServiceCategory: null, - etws: null - }); - - // Verify CB Message with ETWS Info - messenger.notifyCbMessageReceived(0, - Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_LOCATION_AREA, - 0, - 4354, - "en", - "Earthquake & Tsunami Warning!", - Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_0, - timestamp, - Ci.nsICellBroadcastService.CDMA_SERVICE_CATEGORY_INVALID, - true, - Ci.nsICellBroadcastService.GSM_ETWS_WARNING_EARTHQUAKE_TSUNAMI, - true, - false); - equal_received_system_message("cellbroadcast-received", { - serviceId: 0, - gsmGeographicalScope: "location-area", - messageCode: 0, - messageId: 4354, - language: "en", - body: "Earthquake & Tsunami Warning!", - messageClass: "class-0", - timestamp: timestamp, - cdmaServiceCategory: null, - etws: { - warningType: "earthquake-tsunami", - emergencyUserAlert: true, - popup: false - } - }); - - // Verify CDMA CB Message - messenger.notifyCbMessageReceived(0, - Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_INVALID, - 0, - 0, - null, - "CDMA CB Message", - Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL, - timestamp, - 512, - false, - Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID, - false, - false); - equal_received_system_message("cellbroadcast-received", { - serviceId: 0, - gsmGeographicalScope: null, - messageCode: 0, - messageId: 0, - language: null, - body: "CDMA CB Message", - messageClass: "normal", - timestamp: timestamp, - cdmaServiceCategory: 512, - etws: null - }); - - run_next_test(); -}); - -/** - * Verify RILSystemMessenger.notifyUssdReceived() - */ -add_test(function test_mobileconnection_notify_ussd_received() { - let messenger = newRILSystemMessenger(); - - messenger.notifyUssdReceived(0, "USSD Message", false); - - equal_received_system_message("ussd-received", { - serviceId: 0, - message: "USSD Message", - sessionEnded: false - }); - - messenger.notifyUssdReceived(1, "USSD Message", true); - - equal_received_system_message("ussd-received", { - serviceId: 1, - message: "USSD Message", - sessionEnded: true - }); - - run_next_test(); -}); - -/** - * Verify RILSystemMessenger.notifyCdmaInfoRecXXX() - */ -add_test(function test_mobileconnection_notify_cdma_info() { - let messenger = newRILSystemMessenger(); - - messenger.notifyCdmaInfoRecDisplay(0, "CDMA Display Info"); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 0, - display: "CDMA Display Info" - }); - - messenger.notifyCdmaInfoRecCalledPartyNumber(1, 1, 2, "+0987654321", 3, 4); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 1, - calledNumber: { - type: 1, - plan: 2, - number: "+0987654321", - pi: 3, - si: 4 - } - }); - - messenger.notifyCdmaInfoRecCallingPartyNumber(0, 5, 6, "+1234567890", 7, 8); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 0, - callingNumber: { - type: 5, - plan: 6, - number: "+1234567890", - pi: 7, - si: 8 - } - }); - - messenger.notifyCdmaInfoRecConnectedPartyNumber(1, 4, 3, "+56473839201", 2, 1); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 1, - connectedNumber: { - type: 4, - plan: 3, - number: "+56473839201", - pi: 2, - si: 1 - } - }); - - messenger.notifyCdmaInfoRecSignal(0, 1, 2, 3); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 0, - signal: { - type: 1, - alertPitch: 2, - signal: 3 - } - }); - - messenger.notifyCdmaInfoRecRedirectingNumber(1, 8, 7, "+1029384756", 6, 5, 4); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 1, - redirect: { - type: 8, - plan: 7, - number: "+1029384756", - pi: 6, - si: 5, - reason: 4 - } - }); - - messenger.notifyCdmaInfoRecLineControl(0, 1, 0, 1, 255); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 0, - lineControl: { - polarityIncluded: 1, - toggle: 0, - reverse: 1, - powerDenial: 255 - } - }); - - messenger.notifyCdmaInfoRecClir(1, 256); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 1, - clirCause: 256 - }); - - messenger.notifyCdmaInfoRecAudioControl(0, 255, -1); - - equal_received_system_message("cdma-info-rec-received", { - clientId: 0, - audioControl: { - upLink: 255, - downLink: -1 - } - }); - - run_next_test(); -}); - -/** - * Verify Error Handling of StkProactiveCmdFactory.createCommand() - */ -add_test(function test_icc_stk_cmd_factory_create_command_error() { - let messenger = newRILSystemMessenger(); - - // Verify the protection of invalid typeOfCommand. - try { - gStkCmdFactory.createCommand({ - commandNumber: 0, - typeOfCommand: RIL.STK_CMD_MORE_TIME, // Invalid TypeOfCommand - commandQualifier: 0x00 - }); - - ok(false, "Failed to verify the protection of createCommand()!"); - } catch (e) { - ok(e.message.indexOf("Unknown Command Type") !== -1, - "Invalid typeOfCommand!"); - } - - run_next_test(); -}); - -/** - * Verify Error Handling of StkProactiveCmdFactory.createCommandMessage() - */ -add_test(function test_icc_stk_cmd_factory_create_system_msg_invalid_cmd_type() { - let messenger = newRILSystemMessenger(); - let iccId = "99887766554433221100"; - - // Verify the protection of invalid typeOfCommand. - try { - gStkCmdFactory.createCommandMessage({ - QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd]), - - // nsIStkProactiveCmd - commandNumber: 0, - typeOfCommand: RIL.STK_CMD_MORE_TIME, // Invalid TypeOfCommand - commandQualifier: 0 - }); - - ok(false, "Failed to identify invalid typeOfCommand!"); - } catch (e) { - ok(e.message.indexOf("Unknown Command Type") !== -1, - "Invalid typeOfCommand!"); - } - - run_next_test(); -}); - -/** - * Verify Error Handling of StkProactiveCmdFactory.createCommandMessage() - */ -add_test(function test_icc_stk_cmd_factory_create_system_msg_incorrect_cmd_type() { - let messenger = newRILSystemMessenger(); - let iccId = "99887766554433221100"; - - // Verify the protection of invalid typeOfCommand. - try { - gStkCmdFactory.createCommandMessage({ - QueryInterface: XPCOMUtils.generateQI([Ci.nsIStkProactiveCmd, - Ci.nsIStkProvideLocalInfoCmd]), - - // nsIStkProactiveCmd - commandNumber: 0, - typeOfCommand: RIL.STK_CMD_POLL_INTERVAL, // Incorrect typeOfCommand - commandQualifier: 0, - // nsIStkProvideLocalInfoCmd - localInfoType: 0x00, - }); - - ok(false, "Failed to identify incorrect typeOfCommand!"); - } catch (e) { - ok(e.message.indexOf("Failed to convert command into concrete class: ") !== -1); - } - - run_next_test(); -}); - -/** - * Verify RILSystemMessenger.notifyStkProactiveCommand() - */ -add_test(function test_icc_notify_stk_proactive_command() { - let messenger = newRILSystemMessenger(); - let iccId = "99887766554433221100"; - let WHT = 0xFFFFFFFF; - let BLK = 0x000000FF; - let RED = 0xFF0000FF; - let GRN = 0x00FF00FF; - let BLU = 0x0000FFFF; - let TSP = 0; - // Basic Image, see Anex B.1 in TS 31.102. - let basicIcon = { - width: 8, - height: 8, - codingScheme: "basic", - pixels: [WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT, - BLK, BLK, BLK, BLK, BLK, BLK, WHT, WHT, - WHT, BLK, WHT, BLK, BLK, WHT, BLK, WHT, - WHT, BLK, BLK, WHT, WHT, BLK, BLK, WHT, - WHT, BLK, BLK, WHT, WHT, BLK, BLK, WHT, - WHT, BLK, WHT, BLK, BLK, WHT, BLK, WHT, - WHT, WHT, BLK, BLK, BLK, BLK, WHT, WHT, - WHT, WHT, WHT, WHT, WHT, WHT, WHT, WHT] - }; - // Color Image, see Anex B.2 in TS 31.102. - let colorIcon = { - width: 8, - height: 8, - codingScheme: "color", - pixels: [BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU, - BLU, RED, RED, RED, RED, RED, RED, BLU, - BLU, RED, GRN, GRN, GRN, RED, RED, BLU, - BLU, RED, RED, GRN, GRN, RED, RED, BLU, - BLU, RED, RED, GRN, GRN, RED, RED, BLU, - BLU, RED, RED, GRN, GRN, GRN, RED, BLU, - BLU, RED, RED, RED, RED, RED, RED, BLU, - BLU, BLU, BLU, BLU, BLU, BLU, BLU, BLU] - }; - // Color Image with Transparency, see Anex B.2 in TS 31.102. - let colorTransparencyIcon = { - width: 8, - height: 8, - codingScheme: "color-transparency", - pixels: [TSP, TSP, TSP, TSP, TSP, TSP, TSP, TSP, - TSP, RED, RED, RED, RED, RED, RED, TSP, - TSP, RED, GRN, GRN, GRN, RED, RED, TSP, - TSP, RED, RED, GRN, GRN, RED, RED, TSP, - TSP, RED, RED, GRN, GRN, RED, RED, TSP, - TSP, RED, RED, GRN, GRN, GRN, RED, TSP, - TSP, RED, RED, RED, RED, RED, RED, TSP, - TSP, TSP, TSP, TSP, TSP, TSP, TSP, TSP] - }; - - let cmdCount = 0; - - // Test Messages: - let messages = [ - // STK_CMD_REFRESH - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_REFRESH, - commandQualifier: 0x04 // UICC Reset - }, - // STK_CMD_POLL_INTERVAL - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_POLL_INTERVAL, - commandQualifier: 0x00, // RFU - options: { - timeUnit: RIL.STK_TIME_UNIT_TENTH_SECOND, - timeInterval: 0x05 - } - }, - // STK_CMD_POLL_OFF - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_POLL_OFF, - commandQualifier: 0x00, // RFU - }, - // STK_CMD_PROVIDE_LOCAL_INFO - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_PROVIDE_LOCAL_INFO, - commandQualifier: 0x01, // IMEI of the terminal - options: { - localInfoType: 0x01 // IMEI of the terminal - } - }, - // STK_CMD_SET_UP_EVENT_LIST with eventList - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_EVENT_LIST, - commandQualifier: 0x00, // RFU - options: { - eventList: [ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C ] - } - }, - // STK_CMD_SET_UP_EVENT_LIST without eventList - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_EVENT_LIST, - commandQualifier: 0x00, // RFU - options: { - eventList: null - } - }, - // STK_CMD_SET_UP_MENU with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_MENU, - commandQualifier: 0x80, // bit 8: 1 = help information available - options: { - title: "Toolkit Menu 1", - items: [ - { identifier: 0x01, text: "Menu Item 1" }, - { identifier: 0x02, text: "Menu Item 2" }, - { identifier: 0x03, text: "Menu Item 3" } - ], - isHelpAvailable: true - } - }, - // STK_CMD_SET_UP_MENU with optional properties including: - // iconInfo for this menu, iconInfo for each item and nextActionList. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_MENU, - commandQualifier: 0x00, // bit 8: 0 = help information is not available - options: { - title: "Toolkit Menu 2", - items: [ - { identifier: 0x01, - text: "Menu Item 1", - iconSelfExplanatory: true, - icons: [basicIcon] - }, - { identifier: 0x02, - text: "Menu Item 2", - iconSelfExplanatory: false, - icons: [basicIcon, colorIcon] - }, - { identifier: 0x03, - text: "Menu Item 3", - iconSelfExplanatory: true, - icons: [basicIcon, colorIcon, colorTransparencyIcon] - }, - ], - nextActionList: [ - RIL.STK_NEXT_ACTION_END_PROACTIVE_SESSION, - RIL.STK_NEXT_ACTION_NULL, - RIL.STK_NEXT_ACTION_NULL, - RIL.STK_NEXT_ACTION_NULL - ], - iconSelfExplanatory: false, - icons: [basicIcon, colorIcon, colorTransparencyIcon], - isHelpAvailable: false - } - }, - // STK_CMD_SELECT_ITEM with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SELECT_ITEM, - commandQualifier: RIL.STK_PRESENTATION_TYPE_NOT_SPECIFIED, - options: { - title: null, - items: [ - { identifier: 0x01, text: "Menu Item 1" }, - { identifier: 0x02, text: "Menu Item 2" }, - { identifier: 0x03, text: "Menu Item 3" } - ], - presentationType: RIL.STK_PRESENTATION_TYPE_NOT_SPECIFIED, - isHelpAvailable: false - } - }, - // STK_CMD_SELECT_ITEM with optional properties including: - // title, iconInfo for this menu, iconInfo for each item and nextActionList. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SELECT_ITEM, - commandQualifier: RIL.STK_PRESENTATION_TYPE_NAVIGATION_OPTIONS, - options: { - title: "Selected Toolkit Menu", - items: [ - { identifier: 0x01, - text: "Menu Item 1", - iconSelfExplanatory: true, - icons: [basicIcon] - }, - { identifier: 0x02, - text: "Menu Item 2", - iconSelfExplanatory: false, - icons: [basicIcon, colorIcon] - }, - { identifier: 0x03, - text: "Menu Item 3", - iconSelfExplanatory: true, - icons: [basicIcon, colorIcon, colorTransparencyIcon] - }, - ], - nextActionList: [ - RIL.STK_NEXT_ACTION_END_PROACTIVE_SESSION, - RIL.STK_NEXT_ACTION_NULL, - RIL.STK_NEXT_ACTION_NULL, - RIL.STK_NEXT_ACTION_NULL - ], - defaultItem: 0x02, - iconSelfExplanatory: false, - icons: [basicIcon, colorIcon, colorTransparencyIcon], - presentationType: RIL.STK_PRESENTATION_TYPE_NAVIGATION_OPTIONS, - isHelpAvailable: false - } - }, - // STK_CMD_DISPLAY_TEXT with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_DISPLAY_TEXT, - commandQualifier: 0x01, // bit 1: High Priority - options: { - text: "Display Text 1", - isHighPriority: true, - userClear: false, - responseNeeded: false - } - }, - // STK_CMD_DISPLAY_TEXT with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_DISPLAY_TEXT, - commandQualifier: 0x80, // bit 8: User Clear - options: { - text: "Display Text 2", - isHighPriority: false, - userClear: true, - responseNeeded: true, - duration: { - timeUnit: RIL.STK_TIME_UNIT_TENTH_SECOND, - timeInterval: 0x05 - }, - iconSelfExplanatory: true, - icons: [basicIcon] - } - }, - // STK_CMD_SET_UP_IDLE_MODE_TEXT - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_IDLE_MODE_TEXT, - commandQualifier: 0x00, // RFU - options: { - text: "Setup Idle Mode Text" - } - }, - // STK_CMD_SEND_SS - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SEND_SS, - commandQualifier: 0x00, // RFU - options: { - text: "Send SS", - iconSelfExplanatory: true, - icons: [colorIcon] - } - }, - // STK_CMD_SEND_USSD - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SEND_USSD, - commandQualifier: 0x00, // RFU - options: { - text: "Send USSD" - } - }, - // STK_CMD_SEND_SMS - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SEND_SMS, - commandQualifier: 0x00, // RFU - options: { - text: "Send SMS", - iconSelfExplanatory: false, - icons: [colorTransparencyIcon] - } - }, - // STK_CMD_SEND_DTMF - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SEND_DTMF, - commandQualifier: 0x00, // RFU - options: { - text: "Send DTMF", - iconSelfExplanatory: true, - icons: [basicIcon] - } - }, - // STK_CMD_GET_INKEY - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_GET_INKEY, - commandQualifier: 0x84, // bit 3: isYesNoRequested, bit 8: isHelpAvailable - options: { - text: "Get Input Key", - minLength: 1, - maxLength: 1, - duration: { - timeUnit: RIL.STK_TIME_UNIT_SECOND, - timeInterval: 0x0A - }, - isAlphabet: false, - isUCS2: false, - isYesNoRequested: true, - isHelpAvailable: true, - defaultText: null, - iconSelfExplanatory: false, - icons: [colorIcon] - } - }, - // STK_CMD_GET_INPUT - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_GET_INPUT, - commandQualifier: 0x0F, // bit 1-4: isAlphabet, isUCS2, hideInput, isPacked - options: { - text: "Get Input Text", - minLength: 1, - maxLength: 255, - defaultText: "Default Input Text", - isAlphabet: true, - isUCS2: true, - hideInput: true, - isPacked: true, - isHelpAvailable: false, - defaultText: null, - iconSelfExplanatory: true, - icons: [basicIcon] - } - }, - // STK_CMD_SET_UP_CALL with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_CALL, - commandQualifier: 0x00, // RFU - options: { - address: "+0987654321" - } - }, - // STK_CMD_SET_UP_CALL with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SET_UP_CALL, - commandQualifier: 0x00, // RFU - options: { - address: "+0987654321", - confirmMessage: { - text: "Confirm Message", - iconSelfExplanatory: false, - icons: [colorIcon] - }, - callMessage: { - text: "Call Message", - iconSelfExplanatory: true, - icons: [basicIcon] - }, - duration: { - timeUnit: RIL.STK_TIME_UNIT_SECOND, - timeInterval: 0x0A - } - } - }, - // STK_CMD_LAUNCH_BROWSER with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_LAUNCH_BROWSER, - commandQualifier: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER, - options: { - url: "http://www.mozilla.org", - mode: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER - } - }, - // STK_CMD_LAUNCH_BROWSER with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_LAUNCH_BROWSER, - commandQualifier: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER, - options: { - url: "http://www.mozilla.org", - mode: RIL.STK_BROWSER_MODE_USING_NEW_BROWSER, - confirmMessage: { - text: "Confirm Message for Launch Browser", - iconSelfExplanatory: false, - icons: [colorTransparencyIcon] - } - } - }, - // STK_CMD_PLAY_TONE with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_PLAY_TONE, - commandQualifier: 0x01, // isVibrate - options: { - text: null, - isVibrate: true - } - }, - // STK_CMD_PLAY_TONE with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_PLAY_TONE, - commandQualifier: 0x00, // isVibrate = false - options: { - text: "Play Tone", - tone: RIL.STK_TONE_TYPE_CONGESTION, - isVibrate: false, - duration: { - timeUnit: RIL.STK_TIME_UNIT_SECOND, - timeInterval: 0x0A - }, - iconSelfExplanatory: true, - icons: [basicIcon] - } - }, - // STK_CMD_TIMER_MANAGEMENT with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_TIMER_MANAGEMENT, - commandQualifier: RIL.STK_TIMER_DEACTIVATE, - options: { - timerId: 0x08, - timerAction: RIL.STK_TIMER_DEACTIVATE - } - }, - // STK_CMD_TIMER_MANAGEMENT with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_TIMER_MANAGEMENT, - commandQualifier: RIL.STK_TIMER_START, - options: { - timerId: 0x01, - timerValue: (12 * 60 * 60) + (30 * 60) + (30), // 12:30:30 - timerAction: RIL.STK_TIMER_START - } - }, - // STK_CMD_OPEN_CHANNEL with mandatory properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_OPEN_CHANNEL, - commandQualifier: 0x00, //RFU - options: { - text: null, - } - }, - // STK_CMD_OPEN_CHANNEL with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_OPEN_CHANNEL, - commandQualifier: 0x00, //RFU - options: { - text: "Open Channel", - iconSelfExplanatory: false, - icons: [colorIcon] - } - }, - // STK_CMD_CLOSE_CHANNEL with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_CLOSE_CHANNEL, - commandQualifier: 0x00, //RFU - options: { - text: "Close Channel", - iconSelfExplanatory: true, - icons: [colorTransparencyIcon] - } - }, - // STK_CMD_SEND_DATA with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_SEND_DATA, - commandQualifier: 0x00, //RFU - options: { - text: null, - iconSelfExplanatory: false, - icons: [basicIcon] - } - }, - // STK_CMD_RECEIVE_DATA with optional properties. - { - commandNumber: ++cmdCount, - typeOfCommand: RIL.STK_CMD_RECEIVE_DATA, - commandQualifier: 0x00, //RFU - options: { - text: "Receive Data" - } - }, - null // Termination condition to run_next_test() - ]; - - messages.forEach(function(aMessage) { - if (!aMessage) { - run_next_test(); - return; - } - - messenger.notifyStkProactiveCommand(iccId, - gStkCmdFactory.createCommand(aMessage)); - - equal_received_system_message("icc-stkcommand", { - iccId: iccId, - command: aMessage - }); - }); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_barring_password.js b/dom/system/gonk/tests/test_ril_worker_barring_password.js deleted file mode 100644 index fcd3e4405..000000000 --- a/dom/system/gonk/tests/test_ril_worker_barring_password.js +++ /dev/null @@ -1,61 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -const PIN = "0000"; -const NEW_PIN = "1234"; - -add_test(function test_change_call_barring_password() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - - function do_test(facility, pin, newPin) { - buf.sendParcel = function fakeSendParcel () { - // Request Type. - equal(this.readInt32(), REQUEST_CHANGE_BARRING_PASSWORD); - - // Token : we don't care. - this.readInt32(); - - let parcel = this.readStringList(); - equal(parcel.length, 3); - equal(parcel[0], facility); - equal(parcel[1], pin); - equal(parcel[2], newPin); - }; - - let options = {facility: facility, pin: pin, newPin: newPin}; - context.RIL.changeCallBarringPassword(options); - } - - do_test(ICC_CB_FACILITY_BA_ALL, PIN, NEW_PIN); - - run_next_test(); -}); - -add_test(function test_check_change_call_barring_password_result() { - let barringPasswordOptions; - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - - let context = worker.ContextPool._contexts[0]; - context.RIL.changeCallBarringPassword = - function fakeChangeCallBarringPassword(options) { - barringPasswordOptions = options; - context.RIL[REQUEST_CHANGE_BARRING_PASSWORD](0, {}); - }; - - context.RIL.changeCallBarringPassword({pin: PIN, newPin: NEW_PIN}); - - let postedMessage = workerHelper.postedMessage; - equal(barringPasswordOptions.pin, PIN); - equal(barringPasswordOptions.newPin, NEW_PIN); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_buf.js b/dom/system/gonk/tests/test_ril_worker_buf.js deleted file mode 100644 index 30054a881..000000000 --- a/dom/system/gonk/tests/test_ril_worker_buf.js +++ /dev/null @@ -1,187 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function run_test() { - run_next_test(); -} - -/** - * Add test function with specified parcel and request handler. - * - * @param parcel - * Incoming parcel to be tested. - * @param handler - * Handler to be invoked as RIL request handler. - */ -function add_test_incoming_parcel(parcel, handler) { - add_test(function test_incoming_parcel() { - let worker = newWorker({ - postRILMessage: function(data) { - // do nothing - }, - postMessage: function(message) { - // do nothing - } - }); - - if (!parcel) { - parcel = newIncomingParcel(-1, - worker.RESPONSE_TYPE_UNSOLICITED, - worker.REQUEST_VOICE_REGISTRATION_STATE, - [0, 0, 0, 0]); - } - - let context = worker.ContextPool._contexts[0]; - // supports only requests less or equal than UINT8_MAX(255). - let buf = context.Buf; - let request = parcel[buf.PARCEL_SIZE_SIZE + buf.UINT32_SIZE]; - context.RIL[request] = function ril_request_handler() { - handler.apply(this, arguments); - }; - - worker.onRILMessage(0, parcel); - - // end of incoming parcel's trip, let's do next test. - run_next_test(); - }); -} - -// Test normal parcel handling. -add_test_incoming_parcel(null, - function test_normal_parcel_handling() { - let self = this; - try { - // reads exactly the same size, should not throw anything. - self.context.Buf.readInt32(); - } catch (e) { - ok(false, "Got exception: " + e); - } - } -); - -// Test parcel under read. -add_test_incoming_parcel(null, - function test_parcel_under_read() { - let self = this; - try { - // reads less than parcel size, should not throw. - self.context.Buf.readUint16(); - } catch (e) { - ok(false, "Got exception: " + e); - } - } -); - -// Test parcel over read. -add_test_incoming_parcel(null, - function test_parcel_over_read() { - let buf = this.context.Buf; - - // read all data available - while (buf.readAvailable > 0) { - buf.readUint8(); - } - - throws(function over_read_handler() { - // reads more than parcel size, should throw an error. - buf.readUint8(); - },"Trying to read data beyond the parcel end!"); - } -); - -// Test Bug 814761: buffer overwritten -add_test(function test_incoming_parcel_buffer_overwritten() { - let worker = newWorker({ - postRILMessage: function(data) { - // do nothing - }, - postMessage: function(message) { - // do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - // A convenient alias. - let buf = context.Buf; - - // Allocate an array of specified size and set each of its elements to value. - function calloc(length, value) { - let array = new Array(length); - for (let i = 0; i < length; i++) { - array[i] = value; - } - return array; - } - - // Do nothing in handleParcel(). - let request = worker.REQUEST_VOICE_REGISTRATION_STATE; - context.RIL[request] = null; - - // Prepare two parcels, whose sizes are both smaller than the incoming buffer - // size but larger when combined, to trigger the bug. - let pA_dataLength = buf.incomingBufferLength / 2; - let pA = newIncomingParcel(-1, - worker.RESPONSE_TYPE_UNSOLICITED, - request, - calloc(pA_dataLength, 1)); - let pA_parcelSize = pA.length - buf.PARCEL_SIZE_SIZE; - - let pB_dataLength = buf.incomingBufferLength * 3 / 4; - let pB = newIncomingParcel(-1, - worker.RESPONSE_TYPE_UNSOLICITED, - request, - calloc(pB_dataLength, 1)); - let pB_parcelSize = pB.length - buf.PARCEL_SIZE_SIZE; - - // First, send an incomplete pA and verifies related data pointer: - let p1 = pA.subarray(0, pA.length - 1); - worker.onRILMessage(0, p1); - // The parcel should not have been processed. - equal(buf.readAvailable, 0); - // buf.currentParcelSize should have been set because incoming data has more - // than 4 octets. - equal(buf.currentParcelSize, pA_parcelSize); - // buf.readIncoming should contains remaining unconsumed octets count. - equal(buf.readIncoming, p1.length - buf.PARCEL_SIZE_SIZE); - // buf.incomingWriteIndex should be ready to accept the last octet. - equal(buf.incomingWriteIndex, p1.length); - - // Second, send the last octet of pA and whole pB. The Buf should now expand - // to cover both pA & pB. - let p2 = new Uint8Array(1 + pB.length); - p2.set(pA.subarray(pA.length - 1), 0); - p2.set(pB, 1); - worker.onRILMessage(0, p2); - // The parcels should have been both consumed. - equal(buf.readAvailable, 0); - // No parcel data remains. - equal(buf.currentParcelSize, 0); - // No parcel data remains. - equal(buf.readIncoming, 0); - // The Buf should now expand to cover both pA & pB. - equal(buf.incomingWriteIndex, pA.length + pB.length); - - // end of incoming parcel's trip, let's do next test. - run_next_test(); -}); - -// Test Buf.readUint8Array. -add_test_incoming_parcel(null, - function test_buf_readUint8Array() { - let buf = this.context.Buf; - - let u8array = buf.readUint8Array(1); - equal(u8array instanceof Uint8Array, true); - equal(u8array.length, 1); - equal(buf.readAvailable, 3); - - u8array = buf.readUint8Array(2); - equal(u8array.length, 2); - equal(buf.readAvailable, 1); - - throws(function over_read_handler() { - // reads more than parcel size, should throw an error. - u8array = buf.readUint8Array(2); - }, "Trying to read data beyond the parcel end!"); - } -); diff --git a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js b/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js deleted file mode 100644 index 335c0c403..000000000 --- a/dom/system/gonk/tests/test_ril_worker_cdma_info_rec.js +++ /dev/null @@ -1,234 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Helper function. - */ -function newWorkerWithParcel(parcelBuf) { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let index = 0; // index for read - let buf = parcelBuf; - - let context = worker.ContextPool._contexts[0]; - context.Buf.readUint8 = function() { - return buf[index++]; - }; - - context.Buf.readUint16 = function() { - return buf[index++]; - }; - - context.Buf.readInt32 = function() { - return buf[index++]; - }; - - context.Buf.seekIncoming = function(offset) { - index += offset / context.Buf.UINT32_SIZE; - }; - - return worker; -} - -// Test CDMA information record decoder. - -/** - * Verify decoder for type DISPLAY - */ -add_test(function test_display() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x00, // type: display - 0x09, // length: 9 - 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66, - 0x6F, 0x00]); - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].display, "Test Info"); - - run_next_test(); -}); - -/** - * Verify decoder for type EXTENDED DISPLAY - */ -add_test(function test_extended_display() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x07, // type: extended display - 0x12, // length: 18 - 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, - 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 0x49, 0x6E, - 0x66, 0x6F, 0x00, 0x00]); - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].display, "Test Extended Info"); - - run_next_test(); -}); - -/** - * Verify decoder for mixed type - */ -add_test(function test_mixed() { - let worker = newWorkerWithParcel([ - 0x02, // two inforemation record - 0x00, // type: display - 0x0B, // length: 11 - 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66, - 0x6F, 0x20, 0x31, 0x00, - 0x07, // type: extended display - 0x0B, // length: 11 - 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66, - 0x6F, 0x20, 0x32, 0x00]); - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].display, "Test Info 1"); - equal(records[1].display, "Test Info 2"); - - run_next_test(); -}); - -/** - * Verify decoder for multiple types - */ -add_test(function test_multiple() { - let worker = newWorkerWithParcel([ - 0x02, // two inforemation record - 0x00, // type: display - 0x0B, // length: 11 - 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66, - 0x6F, 0x20, 0x31, 0x00, - 0x00, // type: display - 0x0B, // length: 11 - 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6E, 0x66, - 0x6F, 0x20, 0x32, 0x00]); - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].display, "Test Info 1"); - equal(records[1].display, "Test Info 2"); - - run_next_test(); -}); - -/** - * Verify decoder for Signal Type - */ -add_test(function test_signal() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x04, // type: signal - 0x01, // isPresent: non-zero - 0x00, // signalType: Tone signal (00) - 0x01, // alertPitch: High pitch - 0x03]); // signal: Abbreviated intercept (000011) - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].signal.type, 0x00); - equal(records[0].signal.alertPitch, 0x01); - equal(records[0].signal.signal, 0x03); - - run_next_test(); -}); - -/** - * Verify decoder for Signal Type for Not Presented - */ -add_test(function test_signal_not_present() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x04, // type: signal - 0x00, // isPresent: zero - 0x00, // signalType: Tone signal (00) - 0x01, // alertPitch: High pitch - 0x03]); // signal: Abbreviated intercept (000011) - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records.length, 0); - - run_next_test(); -}); - -/** - * Verify decoder for Line Control - */ -add_test(function test_line_control() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x06, // type: line control - 0x01, // polarity included - 0x00, // not toggled - 0x01, // reversed - 0xFF]); // Power denial timeout: 255 * 5 ms - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].lineControl.polarityIncluded, 1); - equal(records[0].lineControl.toggle, 0); - equal(records[0].lineControl.reverse, 1); - equal(records[0].lineControl.powerDenial, 255); - - run_next_test(); -}); - -/** - * Verify decoder for CLIR Cause - */ -add_test(function test_clir() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x08, // type: clir - 0x01]); // cause: Rejected by user - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].clirCause, 1); - - run_next_test(); -}); - -/** - * Verify decoder for Audio Control - */ -add_test(function test_clir() { - let worker = newWorkerWithParcel([ - 0x01, // one inforemation record - 0x0A, // type: audio control - 0x01, // uplink - 0xFF]); // downlink - let context = worker.ContextPool._contexts[0]; - let helper = context.CdmaPDUHelper; - let records = helper.decodeInformationRecord(); - - equal(records[0].audioControl.upLink, 1); - equal(records[0].audioControl.downLink, 255); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js b/dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js deleted file mode 100644 index d5645a3cf..000000000 --- a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_config.js +++ /dev/null @@ -1,470 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_ril_worker_cellbroadcast_activate() { - let worker = newWorker({ - postRILMessage: function(id, parcel) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - - let parcelTypes = []; - let org_newParcel = context.Buf.newParcel; - context.Buf.newParcel = function(type, options) { - parcelTypes.push(type); - org_newParcel.apply(this, arguments); - }; - - function setup(isCdma) { - context.RIL._isCdma = isCdma; - context.RIL.cellBroadcastDisabled = false; - context.RIL.mergedCellBroadcastConfig = [1, 2, 4, 7]; // 1, 4-6 - parcelTypes = []; - } - - function test(isCdma, expectedRequest) { - setup(isCdma); - context.RIL.setCellBroadcastDisabled({disabled: true}); - // Makesure that request parcel is sent out. - notEqual(parcelTypes.indexOf(expectedRequest), -1); - equal(context.RIL.cellBroadcastDisabled, true); - } - - test(false, REQUEST_GSM_SMS_BROADCAST_ACTIVATION); - test(true, REQUEST_CDMA_SMS_BROADCAST_ACTIVATION); - - run_next_test(); -}); - -add_test(function test_ril_worker_cellbroadcast_config() { - let currentParcel; - let worker = newWorker({ - postRILMessage: function(id, parcel) { - currentParcel = parcel; - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - - function U32ArrayFromParcelArray(pa) { - do_print(pa); - let out = []; - for (let i = 0; i < pa.length; i += 4) { - let data = pa[i] + (pa[i+1] << 8) + (pa[i+2] << 16) + (pa[i+3] << 24); - out.push(data); - } - return out; - } - - function test(isCdma, configs, expected) { - let parcelType = isCdma ? REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG - : REQUEST_GSM_SET_BROADCAST_SMS_CONFIG; - - let found = false; - worker.postRILMessage = function(id, parcel) { - let u32Parcel = U32ArrayFromParcelArray(Array.slice(parcel)); - if (u32Parcel[1] != parcelType) { - return; - } - - found = true; - // Check parcel. Data start from 4th word (32bit) - equal(u32Parcel.slice(3).toString(), expected); - }; - - context.RIL._isCdma = isCdma; - context.RIL.setSmsBroadcastConfig(configs); - - // Makesure that request parcel is sent out. - ok(found); - } - - // (GSM) RIL writes the following data to outgoing parcel: - // nums [(from, to, 0, 0xFF, 1), ... ] - test(false, - [1, 2, 4, 7] /* 1, 4-6 */, - ["2", "1,1,0,255,1", "4,6,0,255,1"].join()); - - // (CDMA) RIL writes the following data to outgoing parcel: - // nums [(id, 0, 1), ... ] - test(true, - [1, 2, 4, 7] /* 1, 4-6 */, - ["4", "1,0,1", "4,0,1", "5,0,1", "6,0,1"].join()); - - run_next_test(); -}); - -add_test(function test_ril_worker_cellbroadcast_merge_config() { - let worker = newWorker({ - postRILMessage: function(id, parcel) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - - function test(isCdma, configs, expected) { - context.RIL._isCdma = isCdma; - context.RIL.cellBroadcastConfigs = configs; - context.RIL._mergeAllCellBroadcastConfigs(); - equal(context.RIL.mergedCellBroadcastConfig.toString(), expected); - } - - let configs = { - MMI: [1, 2, 4, 7], // 1, 4-6 - CBMI: [6, 9], // 6-8 - CBMID: [8, 11], // 8-10 - CBMIR: [10, 13] // 10-12 - }; - - test(false, configs, "1,2,4,13"); - test(true, configs, "1,2,4,7"); - - run_next_test(); -}); - -add_test(function test_ril_worker_cellbroadcast_set_search_list() { - let worker = newWorker({ - postRILMessage: function(id, parcel) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - - function test(aIsCdma, aSearchList, aExpected) { - context.RIL._isCdma = aIsCdma; - - let options = { searchList: aSearchList }; - context.RIL.setCellBroadcastSearchList(options); - // Enforce the MMI result to string for comparison. - equal("" + context.RIL.cellBroadcastConfigs.MMI, aExpected); - do_check_eq(options.errorMsg, undefined); - } - - let searchListStr = "1,2,3,4"; - let searchList = { gsm: "1,2,3,4", cdma: "5,6,7,8" }; - - test(false, searchListStr, "1,2,2,3,3,4,4,5"); - test(true, searchListStr, "1,2,2,3,3,4,4,5"); - test(false, searchList, "1,2,2,3,3,4,4,5"); - test(true, searchList, "5,6,6,7,7,8,8,9"); - test(false, null, "null"); - test(true, null, "null"); - - run_next_test(); -}); - -add_test(function test_ril_worker_mergeCellBroadcastConfigs() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - function test(olist, from, to, expected) { - let result = ril._mergeCellBroadcastConfigs(olist, from, to); - equal(JSON.stringify(expected), JSON.stringify(result)); - } - - test(null, 0, 1, [0, 1]); - - test([10, 13], 7, 8, [ 7, 8, 10, 13]); - test([10, 13], 7, 9, [ 7, 9, 10, 13]); - test([10, 13], 7, 10, [ 7, 13]); - test([10, 13], 7, 11, [ 7, 13]); - test([10, 13], 7, 12, [ 7, 13]); - test([10, 13], 7, 13, [ 7, 13]); - test([10, 13], 7, 14, [ 7, 14]); - test([10, 13], 7, 15, [ 7, 15]); - test([10, 13], 7, 16, [ 7, 16]); - test([10, 13], 8, 9, [ 8, 9, 10, 13]); - test([10, 13], 8, 10, [ 8, 13]); - test([10, 13], 8, 11, [ 8, 13]); - test([10, 13], 8, 12, [ 8, 13]); - test([10, 13], 8, 13, [ 8, 13]); - test([10, 13], 8, 14, [ 8, 14]); - test([10, 13], 8, 15, [ 8, 15]); - test([10, 13], 8, 16, [ 8, 16]); - test([10, 13], 9, 10, [ 9, 13]); - test([10, 13], 9, 11, [ 9, 13]); - test([10, 13], 9, 12, [ 9, 13]); - test([10, 13], 9, 13, [ 9, 13]); - test([10, 13], 9, 14, [ 9, 14]); - test([10, 13], 9, 15, [ 9, 15]); - test([10, 13], 9, 16, [ 9, 16]); - test([10, 13], 10, 11, [10, 13]); - test([10, 13], 10, 12, [10, 13]); - test([10, 13], 10, 13, [10, 13]); - test([10, 13], 10, 14, [10, 14]); - test([10, 13], 10, 15, [10, 15]); - test([10, 13], 10, 16, [10, 16]); - test([10, 13], 11, 12, [10, 13]); - test([10, 13], 11, 13, [10, 13]); - test([10, 13], 11, 14, [10, 14]); - test([10, 13], 11, 15, [10, 15]); - test([10, 13], 11, 16, [10, 16]); - test([10, 13], 12, 13, [10, 13]); - test([10, 13], 12, 14, [10, 14]); - test([10, 13], 12, 15, [10, 15]); - test([10, 13], 12, 16, [10, 16]); - test([10, 13], 13, 14, [10, 14]); - test([10, 13], 13, 15, [10, 15]); - test([10, 13], 13, 16, [10, 16]); - test([10, 13], 14, 15, [10, 13, 14, 15]); - test([10, 13], 14, 16, [10, 13, 14, 16]); - test([10, 13], 15, 16, [10, 13, 15, 16]); - - test([10, 13, 14, 17], 7, 8, [ 7, 8, 10, 13, 14, 17]); - test([10, 13, 14, 17], 7, 9, [ 7, 9, 10, 13, 14, 17]); - test([10, 13, 14, 17], 7, 10, [ 7, 13, 14, 17]); - test([10, 13, 14, 17], 7, 11, [ 7, 13, 14, 17]); - test([10, 13, 14, 17], 7, 12, [ 7, 13, 14, 17]); - test([10, 13, 14, 17], 7, 13, [ 7, 13, 14, 17]); - test([10, 13, 14, 17], 7, 14, [ 7, 17]); - test([10, 13, 14, 17], 7, 15, [ 7, 17]); - test([10, 13, 14, 17], 7, 16, [ 7, 17]); - test([10, 13, 14, 17], 7, 17, [ 7, 17]); - test([10, 13, 14, 17], 7, 18, [ 7, 18]); - test([10, 13, 14, 17], 7, 19, [ 7, 19]); - test([10, 13, 14, 17], 8, 9, [ 8, 9, 10, 13, 14, 17]); - test([10, 13, 14, 17], 8, 10, [ 8, 13, 14, 17]); - test([10, 13, 14, 17], 8, 11, [ 8, 13, 14, 17]); - test([10, 13, 14, 17], 8, 12, [ 8, 13, 14, 17]); - test([10, 13, 14, 17], 8, 13, [ 8, 13, 14, 17]); - test([10, 13, 14, 17], 8, 14, [ 8, 17]); - test([10, 13, 14, 17], 8, 15, [ 8, 17]); - test([10, 13, 14, 17], 8, 16, [ 8, 17]); - test([10, 13, 14, 17], 8, 17, [ 8, 17]); - test([10, 13, 14, 17], 8, 18, [ 8, 18]); - test([10, 13, 14, 17], 8, 19, [ 8, 19]); - test([10, 13, 14, 17], 9, 10, [ 9, 13, 14, 17]); - test([10, 13, 14, 17], 9, 11, [ 9, 13, 14, 17]); - test([10, 13, 14, 17], 9, 12, [ 9, 13, 14, 17]); - test([10, 13, 14, 17], 9, 13, [ 9, 13, 14, 17]); - test([10, 13, 14, 17], 9, 14, [ 9, 17]); - test([10, 13, 14, 17], 9, 15, [ 9, 17]); - test([10, 13, 14, 17], 9, 16, [ 9, 17]); - test([10, 13, 14, 17], 9, 17, [ 9, 17]); - test([10, 13, 14, 17], 9, 18, [ 9, 18]); - test([10, 13, 14, 17], 9, 19, [ 9, 19]); - test([10, 13, 14, 17], 10, 11, [10, 13, 14, 17]); - test([10, 13, 14, 17], 10, 12, [10, 13, 14, 17]); - test([10, 13, 14, 17], 10, 13, [10, 13, 14, 17]); - test([10, 13, 14, 17], 10, 14, [10, 17]); - test([10, 13, 14, 17], 10, 15, [10, 17]); - test([10, 13, 14, 17], 10, 16, [10, 17]); - test([10, 13, 14, 17], 10, 17, [10, 17]); - test([10, 13, 14, 17], 10, 18, [10, 18]); - test([10, 13, 14, 17], 10, 19, [10, 19]); - test([10, 13, 14, 17], 11, 12, [10, 13, 14, 17]); - test([10, 13, 14, 17], 11, 13, [10, 13, 14, 17]); - test([10, 13, 14, 17], 11, 14, [10, 17]); - test([10, 13, 14, 17], 11, 15, [10, 17]); - test([10, 13, 14, 17], 11, 16, [10, 17]); - test([10, 13, 14, 17], 11, 17, [10, 17]); - test([10, 13, 14, 17], 11, 18, [10, 18]); - test([10, 13, 14, 17], 11, 19, [10, 19]); - test([10, 13, 14, 17], 12, 13, [10, 13, 14, 17]); - test([10, 13, 14, 17], 12, 14, [10, 17]); - test([10, 13, 14, 17], 12, 15, [10, 17]); - test([10, 13, 14, 17], 12, 16, [10, 17]); - test([10, 13, 14, 17], 12, 17, [10, 17]); - test([10, 13, 14, 17], 12, 18, [10, 18]); - test([10, 13, 14, 17], 12, 19, [10, 19]); - test([10, 13, 14, 17], 13, 14, [10, 17]); - test([10, 13, 14, 17], 13, 15, [10, 17]); - test([10, 13, 14, 17], 13, 16, [10, 17]); - test([10, 13, 14, 17], 13, 17, [10, 17]); - test([10, 13, 14, 17], 13, 18, [10, 18]); - test([10, 13, 14, 17], 13, 19, [10, 19]); - test([10, 13, 14, 17], 14, 15, [10, 13, 14, 17]); - test([10, 13, 14, 17], 14, 16, [10, 13, 14, 17]); - test([10, 13, 14, 17], 14, 17, [10, 13, 14, 17]); - test([10, 13, 14, 17], 14, 18, [10, 13, 14, 18]); - test([10, 13, 14, 17], 14, 19, [10, 13, 14, 19]); - test([10, 13, 14, 17], 15, 16, [10, 13, 14, 17]); - test([10, 13, 14, 17], 15, 17, [10, 13, 14, 17]); - test([10, 13, 14, 17], 15, 18, [10, 13, 14, 18]); - test([10, 13, 14, 17], 15, 19, [10, 13, 14, 19]); - test([10, 13, 14, 17], 16, 17, [10, 13, 14, 17]); - test([10, 13, 14, 17], 16, 18, [10, 13, 14, 18]); - test([10, 13, 14, 17], 16, 19, [10, 13, 14, 19]); - test([10, 13, 14, 17], 17, 18, [10, 13, 14, 18]); - test([10, 13, 14, 17], 17, 19, [10, 13, 14, 19]); - test([10, 13, 14, 17], 18, 19, [10, 13, 14, 17, 18, 19]); - - test([10, 13, 16, 19], 7, 14, [ 7, 14, 16, 19]); - test([10, 13, 16, 19], 7, 15, [ 7, 15, 16, 19]); - test([10, 13, 16, 19], 7, 16, [ 7, 19]); - test([10, 13, 16, 19], 8, 14, [ 8, 14, 16, 19]); - test([10, 13, 16, 19], 8, 15, [ 8, 15, 16, 19]); - test([10, 13, 16, 19], 8, 16, [ 8, 19]); - test([10, 13, 16, 19], 9, 14, [ 9, 14, 16, 19]); - test([10, 13, 16, 19], 9, 15, [ 9, 15, 16, 19]); - test([10, 13, 16, 19], 9, 16, [ 9, 19]); - test([10, 13, 16, 19], 10, 14, [10, 14, 16, 19]); - test([10, 13, 16, 19], 10, 15, [10, 15, 16, 19]); - test([10, 13, 16, 19], 10, 16, [10, 19]); - test([10, 13, 16, 19], 11, 14, [10, 14, 16, 19]); - test([10, 13, 16, 19], 11, 15, [10, 15, 16, 19]); - test([10, 13, 16, 19], 11, 16, [10, 19]); - test([10, 13, 16, 19], 12, 14, [10, 14, 16, 19]); - test([10, 13, 16, 19], 12, 15, [10, 15, 16, 19]); - test([10, 13, 16, 19], 12, 16, [10, 19]); - test([10, 13, 16, 19], 13, 14, [10, 14, 16, 19]); - test([10, 13, 16, 19], 13, 15, [10, 15, 16, 19]); - test([10, 13, 16, 19], 13, 16, [10, 19]); - test([10, 13, 16, 19], 14, 15, [10, 13, 14, 15, 16, 19]); - test([10, 13, 16, 19], 14, 16, [10, 13, 14, 19]); - test([10, 13, 16, 19], 15, 16, [10, 13, 15, 19]); - - run_next_test(); -}); - -add_test(function test_ril_consts_cellbroadcast_misc() { - // Must be 16 for indexing. - equal(CB_DCS_LANG_GROUP_1.length, 16); - equal(CB_DCS_LANG_GROUP_2.length, 16); - - // Array length must be even. - equal(CB_NON_MMI_SETTABLE_RANGES.length & 0x01, 0); - for (let i = 0; i < CB_NON_MMI_SETTABLE_RANGES.length;) { - let from = CB_NON_MMI_SETTABLE_RANGES[i++]; - let to = CB_NON_MMI_SETTABLE_RANGES[i++]; - equal(from < to, true); - } - - run_next_test(); -}); - -add_test(function test_ril_worker_checkCellBroadcastMMISettable() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - function test(from, to, expected) { - equal(expected, ril._checkCellBroadcastMMISettable(from, to)); - } - - test(-2, -1, false); - test(-1, 0, false); - test(0, 1, true); - test(1, 1, false); - test(2, 1, false); - test(65536, 65537, false); - - // We have both [4096, 4224), [4224, 4352), so it's actually [4096, 4352), - // and [61440, 65536), [65535, 65536), so it's actually [61440, 65536). - for (let i = 0; i < CB_NON_MMI_SETTABLE_RANGES.length;) { - let from = CB_NON_MMI_SETTABLE_RANGES[i++]; - let to = CB_NON_MMI_SETTABLE_RANGES[i++]; - if ((from != 4224) && (from != 65535)) { - test(from - 1, from, true); - } - test(from - 1, from + 1, false); - test(from - 1, to, false); - test(from - 1, to + 1, false); - test(from, from + 1, false); - test(from, to, false); - test(from, to + 1, false); - if ((from + 1) < to) { - test(from + 1, to, false); - test(from + 1, to + 1, false); - } - if ((to != 4224) && (to < 65535)) { - test(to, to + 1, true); - test(to + 1, to + 2, true); - } - } - - run_next_test(); -}); - -add_test(function test_ril_worker_CellBroadcastDisabled() { - let count = 0; - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - if (message.rilMessageType == "cellbroadcast-received") { - ok(true, "cellbroadcast-received: " + JSON.stringify(message)); - count++; - } - } - }); - - function buildPdu(aMessageId) { - return "C002" + aMessageId + "011154741914AFA7C76B9058" + - "FEBEBB41E6371EA4AEB7E173D0DB5E96" + - "83E8E832881DD6E741E4F7B9D168341A" + - "8D46A3D168341A8D46A3D168341A8D46" + - "A3D168341A8D46A3D168341A8D46A3D1" + - "68341A8D46A3D100"; - } - - worker.ContextPool._contexts[0].RIL.cellBroadcastDisabled = true; - - let networkAlertIds = [ - "1100", "1107", // ETWS - "1112", "112F", // CMAS - "1130", "18FF", // PWS - ]; - networkAlertIds.forEach(aMessageId => { - worker.onRILMessage( - 0, - newIncomingParcel( - -1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS, - hexStringToParcelByteArrayData(buildPdu(aMessageId)))); - }); - equal(count, networkAlertIds.length, "Alerts shall not be ignored."); - - count = 0; - let normalMsgIds = [ "0000", "03E7", "1108", "1901" ]; - normalMsgIds.forEach(aMessageId => { - worker.onRILMessage( - 0, - newIncomingParcel( - -1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS, - hexStringToParcelByteArrayData(buildPdu(aMessageId)))); - }); - equal(count, 0, "Normal messages shall be ignored."); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js b/dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js deleted file mode 100644 index b08b64135..000000000 --- a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_gsm.js +++ /dev/null @@ -1,230 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_ril_worker_GsmPDUHelper_readCbDataCodingScheme() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - function test_dcs(dcs, encoding, language, hasLanguageIndicator, messageClass) { - context.Buf.readUint8 = function() { - return dcs; - }; - - let msg = {}; - context.GsmPDUHelper.readCbDataCodingScheme(msg); - - equal(msg.dcs, dcs); - equal(msg.encoding, encoding); - equal(msg.language, language); - equal(msg.hasLanguageIndicator, hasLanguageIndicator); - equal(msg.messageClass, messageClass); - } - - function test_dcs_throws(dcs) { - context.Buf.readUint8 = function() { - return dcs; - }; - - throws(function() { - context.GsmPDUHelper.readCbDataCodingScheme({}); - }, "Unsupported CBS data coding scheme: " + dcs); - } - - // Group 0000 - for (let i = 0; i < 16; i++) { - test_dcs(i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, CB_DCS_LANG_GROUP_1[i], - false, GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - } - - // Group 0001 - // 0000 GSM 7 bit default alphabet; message preceded by language indication. - test_dcs(0x10, PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, true, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - // 0001 UCS2; message preceded by language indication. - test_dcs(0x11, PDU_DCS_MSG_CODING_16BITS_ALPHABET, null, true, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - - // Group 0010 - // 0000..0100 - for (let i = 0; i < 5; i++) { - test_dcs(0x20 + i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - CB_DCS_LANG_GROUP_2[i], false, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - } - // 0101..1111 Reserved - for (let i = 5; i < 16; i++) { - test_dcs(0x20 + i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, false, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - } - - // Group 0100, 0101, 1001 - for (let group of [0x40, 0x50, 0x90]) { - for (let i = 0; i < 16; i++) { - let encoding = i & 0x0C; - if (encoding == 0x0C) { - encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET; - } - let messageClass = GECKO_SMS_MESSAGE_CLASSES[i & PDU_DCS_MSG_CLASS_BITS]; - test_dcs(group + i, encoding, null, false, messageClass); - } - } - - // Group 1111 - for (let i = 0; i < 16; i ++) { - let encoding = i & 0x04 ? PDU_DCS_MSG_CODING_8BITS_ALPHABET - : PDU_DCS_MSG_CODING_7BITS_ALPHABET; - let messageClass; - switch(i & PDU_DCS_MSG_CLASS_BITS) { - case 0x01: messageClass = PDU_DCS_MSG_CLASS_USER_1; break; - case 0x02: messageClass = PDU_DCS_MSG_CLASS_USER_2; break; - case 0x03: messageClass = PDU_DCS_MSG_CLASS_3; break; - default: messageClass = PDU_DCS_MSG_CLASS_NORMAL; break; - } - test_dcs(0xF0 + i, encoding, null, false, - GECKO_SMS_MESSAGE_CLASSES[messageClass]); - } - - // Group 0011, 1000, 1010, 1011, 1100 - // 0000..1111 Reserved - for (let group of [0x30, 0x80, 0xA0, 0xB0, 0xC0]) { - for (let i = 0; i < 16; i++) { - test_dcs(group + i, PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, false, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - } - } - - // Group 0110, 0111, 1101, 1110 - // TODO: unsupported - for (let group of [0x60, 0x70, 0xD0, 0xE0]) { - for (let i = 0; i < 16; i++) { - test_dcs_throws(group + i); - } - } - - run_next_test(); -}); - -add_test(function test_ril_worker_GsmPDUHelper_readGsmCbData() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - function test_data(options, expected) { - let readIndex = 0; - context.Buf.readUint8 = function() { - return options[3][readIndex++]; - }; - context.Buf.readUint8Array = function(length) { - let array = new Uint8Array(length); - for (let i = 0; i < length; i++) { - array[i] = this.readUint8(); - } - return array; - }; - - let msg = { - encoding: options[0], - language: options[1], - hasLanguageIndicator: options[2] - }; - context.GsmPDUHelper.readGsmCbData(msg, options[3].length); - - equal(msg.body, expected[0]); - equal(msg.data == null, expected[1] == null); - if (expected[1] != null) { - equal(msg.data.length, expected[1].length); - for (let i = 0; i < expected[1].length; i++) { - equal(msg.data[i], expected[1][i]); - } - } - equal(msg.language, expected[2]); - } - - // We're testing Cell Broadcast message body with all zeros octet stream. As - // shown in 3GPP TS 23.038, septet 0x00 will be decoded as '@' when both - // langTableIndex and langShiftTableIndex equal to - // PDU_DCS_MSG_CODING_7BITS_ALPHABET. - - // PDU_DCS_MSG_CODING_7BITS_ALPHABET - test_data([PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, false, - [0]], - ["@", null, null]); - test_data([PDU_DCS_MSG_CODING_7BITS_ALPHABET, null, true, - [0, 0, 0, 0]], - ["@", null, "@@"]); - test_data([PDU_DCS_MSG_CODING_7BITS_ALPHABET, "@@", false, - [0]], - ["@", null, "@@"]); - - // PDU_DCS_MSG_CODING_8BITS_ALPHABET - test_data([PDU_DCS_MSG_CODING_8BITS_ALPHABET, null, false, - [0]], - [null, [0], null]); - - // PDU_DCS_MSG_CODING_16BITS_ALPHABET - test_data([PDU_DCS_MSG_CODING_16BITS_ALPHABET, null, false, - [0x00, 0x40]], - ["@", null, null]); - test_data([PDU_DCS_MSG_CODING_16BITS_ALPHABET, null, true, - [0x00, 0x00, 0x00, 0x40]], - ["@", null, "@@"]); - test_data([PDU_DCS_MSG_CODING_16BITS_ALPHABET, "@@", false, - [0x00, 0x40]], - ["@", null, "@@"]); - - run_next_test(); -}); - -add_test(function test_ril_worker_Sim_Download_Message() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - ok(message.rilMessageType !== "cellbroadcast-received", - "Data-Download message shall be ignored."); - } - }); - - function buildPdu(aMessageId) { - return "C002" + aMessageId + "011154741914AFA7C76B9058" + - "FEBEBB41E6371EA4AEB7E173D0DB5E96" + - "83E8E832881DD6E741E4F7B9D168341A" + - "8D46A3D168341A8D46A3D168341A8D46" + - "A3D168341A8D46A3D168341A8D46A3D1" + - "68341A8D46A3D100"; - } - - ["1000", "107F", "1080", "10FF"].forEach(aMessageId => { - worker.onRILMessage( - 0, - newIncomingParcel( - -1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS, - hexStringToParcelByteArrayData(buildPdu(aMessageId)))); - }); - - ok(true, "All Data-Download Messages are ingored."); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js b/dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js deleted file mode 100644 index 0380c4122..000000000 --- a/dom/system/gonk/tests/test_ril_worker_cellbroadcast_umts.js +++ /dev/null @@ -1,105 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -function buildHexStr(aNum, aNumSemiOctets) { - let str = aNum.toString(16); - while (str.length < aNumSemiOctets) { - str = "0" + str; - } - return str; -} - -/** - * Verify GsmPDUHelper#readUmtsCbMessage with numOfPages from 1 to 15. - */ -add_test(function test_GsmPDUHelper_readUmtsCbMessage_MultiParts() { - let CB_UMTS_MESSAGE_PAGE_SIZE = 82; - let CB_MAX_CONTENT_PER_PAGE_7BIT = 93; - let workerHelper = newInterceptWorker(), - worker = workerHelper.worker, - context = worker.ContextPool._contexts[0], - GsmPDUHelper = context.GsmPDUHelper; - - function test_MultiParts(aNumOfPages) { - let pdu = buildHexStr(CB_UMTS_MESSAGE_TYPE_CBS, 2) // msg_type - + buildHexStr(0, 4) // skip msg_id - + buildHexStr(0, 4) // skip SN - + buildHexStr(0, 2) // skip dcs - + buildHexStr(aNumOfPages, 2); // set num_of_pages - for (let i = 1; i <= aNumOfPages; i++) { - pdu = pdu + buildHexStr(0, CB_UMTS_MESSAGE_PAGE_SIZE * 2) - + buildHexStr(CB_UMTS_MESSAGE_PAGE_SIZE, 2); // msg_info_length - } - - worker.onRILMessage(0, newIncomingParcel(-1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS, - hexStringToParcelByteArrayData(pdu))); - - let postedMessage = workerHelper.postedMessage; - equal("cellbroadcast-received", postedMessage.rilMessageType); - equal(postedMessage.fullBody.length, - aNumOfPages * CB_MAX_CONTENT_PER_PAGE_7BIT); - } - - [1, 5, 15].forEach(function(i) { - test_MultiParts(i); - }); - - run_next_test(); -}); - -/** - * Verify GsmPDUHelper#readUmtsCbMessage with 8bit encoded. - */ -add_test(function test_GsmPDUHelper_readUmtsCbMessage_Binary() { - let CB_UMTS_MESSAGE_PAGE_SIZE = 82; - let CB_MAX_CONTENT_PER_PAGE_7BIT = 93; - let TEXT_BINARY = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFF"; - let workerHelper = newInterceptWorker(), - worker = workerHelper.worker, - context = worker.ContextPool._contexts[0], - GsmPDUHelper = context.GsmPDUHelper; - - function test_MultiPartsBinary(aNumOfPages) { - let pdu = buildHexStr(CB_UMTS_MESSAGE_TYPE_CBS, 2) // msg_type - + buildHexStr(0, 4) // skip msg_id - + buildHexStr(0, 4) // skip SN - + buildHexStr(68, 2) // set DCS to 8bit data - + buildHexStr(aNumOfPages, 2); // set num_of_pages - for (let i = 1; i <= aNumOfPages; i++) { - pdu = pdu + TEXT_BINARY - + buildHexStr(CB_UMTS_MESSAGE_PAGE_SIZE, 2); // msg_info_length - } - - worker.onRILMessage(0, newIncomingParcel(-1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_BROADCAST_SMS, - hexStringToParcelByteArrayData(pdu))); - - let postedMessage = workerHelper.postedMessage; - equal("cellbroadcast-received", postedMessage.rilMessageType); - equal(postedMessage.fullData.length, - aNumOfPages * CB_UMTS_MESSAGE_PAGE_SIZE); - for (let i = 0; i < postedMessage.fullData.length; i++) { - equal(postedMessage.fullData[i], 255); - } - } - - [1, 5, 15].forEach(function(i) { - test_MultiPartsBinary(i); - }); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_cf.js b/dom/system/gonk/tests/test_ril_worker_cf.js deleted file mode 100644 index b8db716b7..000000000 --- a/dom/system/gonk/tests/test_ril_worker_cf.js +++ /dev/null @@ -1,126 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -function toaFromString(number) { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - return context.RIL._toaFromString(number); -} - -add_test(function test_toaFromString_empty() { - let retval = toaFromString(""); - - equal(retval, TOA_UNKNOWN); - - run_next_test(); -}); - -add_test(function test_toaFromString_undefined() { - let retval = toaFromString(); - - equal(retval, TOA_UNKNOWN); - - run_next_test(); -}); - -add_test(function test_toaFromString_unknown() { - let retval = toaFromString("666222333"); - - equal(retval, TOA_UNKNOWN); - - run_next_test(); -}); - -add_test(function test_toaFromString_international() { - let retval = toaFromString("+34666222333"); - - equal(retval, TOA_INTERNATIONAL); - - run_next_test(); -}); - -add_test(function test_setCallForward_unconditional() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCallForward = function fakeSetCallForward(options) { - context.RIL[REQUEST_SET_CALL_FORWARD](0, {}); - }; - - context.RIL.setCallForward({ - action: CALL_FORWARD_ACTION_REGISTRATION, - reason: CALL_FORWARD_REASON_UNCONDITIONAL, - serviceClass: ICC_SERVICE_CLASS_VOICE, - number: "666222333", - timeSeconds: 10 - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - - run_next_test(); -}); - -add_test(function test_queryCallForwardStatus_unconditional() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCallForward = function fakeSetCallForward(options) { - context.RIL[REQUEST_SET_CALL_FORWARD](0, {}); - }; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.Buf.readString = function fakeReadString() { - return "+34666222333"; - }; - - context.RIL.queryCallForwardStatus = function fakeQueryCallForward(options) { - context.Buf.int32Array = [ - 0, // rules.timeSeconds - 145, // rules.toa - 49, // rules.serviceClass - CALL_FORWARD_REASON_UNCONDITIONAL, // rules.reason - 1, // rules.active - 1 // rulesLength - ]; - context.RIL[REQUEST_QUERY_CALL_FORWARD_STATUS](1, {}); - }; - - context.RIL.queryCallForwardStatus({ - action: CALL_FORWARD_ACTION_QUERY_STATUS, - reason: CALL_FORWARD_REASON_UNCONDITIONAL, - serviceClass: ICC_SERVICE_CLASS_VOICE, - number: "666222333", - timeSeconds: 10 - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - ok(Array.isArray(postedMessage.rules)); - do_print(postedMessage.rules.length); - equal(postedMessage.rules.length, 1); - ok(postedMessage.rules[0].active); - equal(postedMessage.rules[0].reason, CALL_FORWARD_REASON_UNCONDITIONAL); - equal(postedMessage.rules[0].number, "+34666222333"); - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_clip.js b/dom/system/gonk/tests/test_ril_worker_clip.js deleted file mode 100644 index d1ce5f617..000000000 --- a/dom/system/gonk/tests/test_ril_worker_clip.js +++ /dev/null @@ -1,59 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_queryCLIP_provisioned() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.RIL.queryCLIP = function fakeQueryCLIP(options) { - context.Buf.int32Array = [ - 1, // CLIP provisioned. - 1 // Length. - ]; - context.RIL[REQUEST_QUERY_CLIP](1, {}); - }; - - context.RIL.queryCLIP({}); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - equal(postedMessage.provisioned, 1); - run_next_test(); -}); - -add_test(function test_getCLIP_error_generic_failure_invalid_length() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.RIL.queryCLIP = function fakeQueryCLIP(options) { - context.Buf.int32Array = [ - 1, // CLIP provisioned. - 0 // Length. - ]; - context.RIL[REQUEST_QUERY_CLIP](1, {}); - }; - - context.RIL.queryCLIP({}); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_clir.js b/dom/system/gonk/tests/test_ril_worker_clir.js deleted file mode 100644 index 5882a3c4c..000000000 --- a/dom/system/gonk/tests/test_ril_worker_clir.js +++ /dev/null @@ -1,122 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -// Calling line identification restriction constants. - -// Uses subscription default value. -const CLIR_DEFAULT = 0; -// Restricts CLI presentation. -const CLIR_INVOCATION = 1; -// Allows CLI presentation. -const CLIR_SUPPRESSION = 2; - -function run_test() { - run_next_test(); -} - -add_test(function test_setCLIR_success() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCLIR = function fakeSetCLIR(options) { - context.RIL[REQUEST_SET_CLIR](0, { - rilMessageType: "setCLIR" - }); - }; - - context.RIL.setCLIR({ - clirMode: CLIR_DEFAULT - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - - run_next_test(); -}); - -add_test(function test_setCLIR_generic_failure() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCLIR = function fakeSetCLIR(options) { - context.RIL[REQUEST_SET_CLIR](0, { - rilMessageType: "setCLIR", - errorMsg: GECKO_ERROR_GENERIC_FAILURE - }); - }; - - context.RIL.setCLIR({ - clirMode: CLIR_DEFAULT - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); - - run_next_test(); -}); - -add_test(function test_getCLIR_n0_m1() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.RIL.getCLIR = function fakeGetCLIR(options) { - context.Buf.int32Array = [ - 1, // Presentation indicator is used according to the subscription - // of the CLIR service. - 0, // CLIR provisioned in permanent mode. - 2 // Length. - ]; - context.RIL[REQUEST_GET_CLIR](1, { - rilMessageType: "setCLIR" - }); - }; - - context.RIL.getCLIR({}); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - equal(postedMessage.n, 0); - equal(postedMessage.m, 1); - run_next_test(); -}); - -add_test(function test_getCLIR_error_generic_failure_invalid_length() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.RIL.getCLIR = function fakeGetCLIR(options) { - context.Buf.int32Array = [ - 1, // Presentation indicator is used according to the subscription - // of the CLIR service. - 0, // CLIR provisioned in permanent mode. - 0 // Length (invalid one). - ]; - context.RIL[REQUEST_GET_CLIR](1, { - rilMessageType: "setCLIR" - }); - }; - - context.RIL.getCLIR({}); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_cw.js b/dom/system/gonk/tests/test_ril_worker_cw.js deleted file mode 100644 index efa8b5c21..000000000 --- a/dom/system/gonk/tests/test_ril_worker_cw.js +++ /dev/null @@ -1,104 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_setCallWaiting_success() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCallWaiting = function fakeSetCallWaiting(options) { - context.RIL[REQUEST_SET_CALL_WAITING](0, {}); - }; - - context.RIL.setCallWaiting({ - enabled: true - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - - run_next_test(); -}); - -add_test(function test_setCallWaiting_generic_failure() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setCallWaiting = function fakeSetCallWaiting(options) { - context.RIL[REQUEST_SET_CALL_WAITING](0, { - errorMsg: GECKO_ERROR_GENERIC_FAILURE - }); - }; - - context.RIL.setCallWaiting({ - enabled: true - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); - - run_next_test(); -}); - -add_test(function test_queryCallWaiting_success_enabled_true() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) { - context.Buf.int32Array = [ - 1, // serviceClass - 1, // enabled - 2 // length - ]; - context.RIL[REQUEST_QUERY_CALL_WAITING](1, {}); - }; - - context.RIL.queryCallWaiting({}); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - equal(postedMessage.serviceClass, 1); - run_next_test(); -}); - -add_test(function test_queryCallWaiting_success_enabled_false() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32 = function fakeReadUint32() { - return context.Buf.int32Array.pop(); - }; - - context.RIL.queryCallWaiting = function fakeQueryCallWaiting(options) { - context.Buf.int32Array = [ - 1, // serviceClass - 0, // enabled - 2 // length - ]; - context.RIL[REQUEST_QUERY_CALL_WAITING](1, {}); - }; - - context.RIL.queryCallWaiting({}); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - equal(postedMessage.serviceClass, ICC_SERVICE_CLASS_NONE); - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_ecm.js b/dom/system/gonk/tests/test_ril_worker_ecm.js deleted file mode 100644 index d10cba9ec..000000000 --- a/dom/system/gonk/tests/test_ril_worker_ecm.js +++ /dev/null @@ -1,168 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -var timeoutCallback = null; -var timeoutDelayMs = 0; -const TIMER_ID = 1234; -const TIMEOUT_VALUE = 300000; // 5 mins. - -// No window in xpcshell-test. Create our own timer mechanism. - -function setTimeout(callback, timeoutMs) { - timeoutCallback = callback; - timeoutDelayMs = timeoutMs; - equal(timeoutMs, TIMEOUT_VALUE); - return TIMER_ID; -} - -function clearTimeout(timeoutId) { - equal(timeoutId, TIMER_ID); - timeoutCallback = null; -} - -function fireTimeout() { - notEqual(timeoutCallback, null); - if (timeoutCallback) { - timeoutCallback(); - timeoutCallback = null; - } -} - -add_test(function test_enter_emergencyCbMode() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - // Do it twice. Should always send the event. - for (let i = 0; i < 2; ++i) { - context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); - let postedMessage = workerHelper.postedMessage; - - // Should store the mode. - equal(context.RIL._isInEmergencyCbMode, true); - - // Should notify change. - equal(postedMessage.rilMessageType, "emergencyCbModeChange"); - equal(postedMessage.active, true); - equal(postedMessage.timeoutMs, TIMEOUT_VALUE); - - // Should start timer. - equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); - } - - run_next_test(); -}); - -add_test(function test_exit_emergencyCbMode() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); - context.RIL[UNSOLICITED_EXIT_EMERGENCY_CALLBACK_MODE](); - let postedMessage = workerHelper.postedMessage; - - // Should store the mode. - equal(context.RIL._isInEmergencyCbMode, false); - - // Should notify change. - equal(postedMessage.rilMessageType, "emergencyCbModeChange"); - equal(postedMessage.active, false); - - // Should clear timer. - equal(context.RIL._exitEmergencyCbModeTimeoutID, null); - - run_next_test(); -}); - -add_test(function test_request_exit_emergencyCbMode_when_timeout() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); - equal(context.RIL._isInEmergencyCbMode, true); - equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); - - let parcelTypes = []; - context.Buf.newParcel = function(type, options) { - parcelTypes.push(type); - }; - - // Timeout. - fireTimeout(); - - // Should clear timeout event. - equal(context.RIL._exitEmergencyCbModeTimeoutID, null); - - // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE. - notEqual(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1); - - run_next_test(); -}); - -add_test(function test_request_exit_emergencyCbMode_when_dial() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); - equal(context.RIL._isInEmergencyCbMode, true); - equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); - - let parcelTypes = []; - context.Buf.newParcel = function(type, options) { - parcelTypes.push(type); - }; - - // Dial non-emergency call. - context.RIL.dial({number: "0912345678", - isEmergency: false, - isDialEmergency: false}); - - // Should clear timeout event. - equal(context.RIL._exitEmergencyCbModeTimeoutID, null); - - // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE. - notEqual(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1); - - run_next_test(); -}); - -add_test(function test_request_exit_emergencyCbMode_explicitly() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL[UNSOLICITED_ENTER_EMERGENCY_CALLBACK_MODE](); - equal(context.RIL._isInEmergencyCbMode, true); - equal(context.RIL._exitEmergencyCbModeTimeoutID, TIMER_ID); - - let parcelTypes = []; - context.Buf.newParcel = function(type, options) { - parcelTypes.push(type); - }; - - context.RIL.handleChromeMessage({rilMessageType: "exitEmergencyCbMode"}); - context.RIL[REQUEST_EXIT_EMERGENCY_CALLBACK_MODE](1, { - rilMessageType: "exitEmergencyCbMode" - }); - let postedMessage = workerHelper.postedMessage; - - // Should clear timeout event. - equal(context.RIL._exitEmergencyCbModeTimeoutID, null); - - // Check indeed sent out REQUEST_EXIT_EMERGENCY_CALLBACK_MODE. - notEqual(parcelTypes.indexOf(REQUEST_EXIT_EMERGENCY_CALLBACK_MODE), -1); - - // Send back the response. - equal(postedMessage.rilMessageType, "exitEmergencyCbMode"); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js deleted file mode 100644 index 89fcd874d..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_BerTlvHelper.js +++ /dev/null @@ -1,87 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -// Test ICC_COMMAND_GET_RESPONSE with FCP template format. -/** - * Verify transparent structure with FCP template format. - */ -add_test(function test_fcp_template_for_transparent_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - - let tag_test = [ - 0x62, - 0x22, - 0x82, 0x02, 0x41, 0x21, - 0x83, 0x02, 0x2F, 0xE2, - 0xA5, 0x09, 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, - 0x8A, 0x01, 0x05, - 0x8B, 0x03, 0x2F, 0x06, 0x0B, - 0x80, 0x02, 0x00, 0x0A, - 0x88, 0x01, 0x10]; - - for (let i = 0; i < tag_test.length; i++) { - pduHelper.writeHexOctet(tag_test[i]); - } - - let berTlv = berHelper.decode(tag_test.length); - let iter = berTlv.value.values(); - let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); - equal(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_STRUCTURE_TRANSPARENT]); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); - equal(tlv.value.fileId, 0x2FE2); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); - equal(tlv.value.fileSizeData, 0x0A); - - run_next_test(); -}); - -/** - * Verify linear fixed structure with FCP template format. - */ -add_test(function test_fcp_template_for_linear_fixed_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - - let tag_test = [ - 0x62, - 0x1E, - 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, - 0x83, 0x02, 0x6F, 0x40, - 0xA5, 0x03, 0x92, 0x01, 0x00, - 0x8A, 0x01, 0x07, - 0x8B, 0x03, 0x6F, 0x06, 0x02, - 0x80, 0x02, 0x00, 0x1A, - 0x88, 0x00]; - - for (let i = 0; i < tag_test.length; i++) { - pduHelper.writeHexOctet(tag_test[i]); - } - - let berTlv = berHelper.decode(tag_test.length); - let iter = berTlv.value.values(); - let tlv = berHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG, iter); - equal(tlv.value.fileStructure, UICC_EF_STRUCTURE[EF_STRUCTURE_LINEAR_FIXED]); - equal(tlv.value.recordLength, 0x1A); - equal(tlv.value.numOfRecords, 0x01); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter); - equal(tlv.value.fileId, 0x6F40); - - tlv = berHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter); - equal(tlv.value.fileSizeData, 0x1A); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js b/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js deleted file mode 100644 index dc7eb93b9..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_CardLock.js +++ /dev/null @@ -1,282 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify RIL.iccGetCardLockEnabled - */ -add_test(function test_icc_get_card_lock_enabled() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let ril = context.RIL; - ril.aid = "123456789"; - - function do_test(aLock) { - const serviceClass = ICC_SERVICE_CLASS_VOICE | - ICC_SERVICE_CLASS_DATA | - ICC_SERVICE_CLASS_FAX; - - buf.sendParcel = function fakeSendParcel() { - // Request Type. - equal(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK) - - // Token : we don't care. - this.readInt32(); - - // Data - let parcel = this.readStringList(); - equal(parcel.length, 4); - equal(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]); - equal(parcel[1], ""); - equal(parcel[2], serviceClass.toString()); - equal(parcel[3], ril.aid); - }; - - ril.iccGetCardLockEnabled({lockType: aLock}); - } - - do_test(GECKO_CARDLOCK_PIN) - do_test(GECKO_CARDLOCK_FDN) - - run_next_test(); -}); - -add_test(function test_path_id_for_spid_and_spn() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - }}); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ICCFileHelper = context.ICCFileHelper; - - // Test SIM - RIL.appType = CARD_APPTYPE_SIM; - equal(ICCFileHelper.getEFPath(ICC_EF_SPDI), - EF_PATH_MF_SIM + EF_PATH_DF_GSM); - equal(ICCFileHelper.getEFPath(ICC_EF_SPN), - EF_PATH_MF_SIM + EF_PATH_DF_GSM); - - // Test USIM - RIL.appType = CARD_APPTYPE_USIM; - equal(ICCFileHelper.getEFPath(ICC_EF_SPDI), - EF_PATH_MF_SIM + EF_PATH_ADF_USIM); - equal(ICCFileHelper.getEFPath(ICC_EF_SPDI), - EF_PATH_MF_SIM + EF_PATH_ADF_USIM); - run_next_test(); -}); - -/** - * Verify RIL.iccSetCardLockEnabled - */ -add_test(function test_icc_set_card_lock_enabled() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let ril = context.RIL; - ril.aid = "123456789"; - - function do_test(aLock, aPassword, aEnabled) { - const serviceClass = ICC_SERVICE_CLASS_VOICE | - ICC_SERVICE_CLASS_DATA | - ICC_SERVICE_CLASS_FAX; - - buf.sendParcel = function fakeSendParcel() { - // Request Type. - equal(this.readInt32(), REQUEST_SET_FACILITY_LOCK); - - // Token : we don't care - this.readInt32(); - - // Data - let parcel = this.readStringList(); - equal(parcel.length, 5); - equal(parcel[0], GECKO_CARDLOCK_TO_FACILITY[aLock]); - equal(parcel[1], aEnabled ? "1" : "0"); - equal(parcel[2], aPassword); - equal(parcel[3], serviceClass.toString()); - equal(parcel[4], ril.aid); - }; - - ril.iccSetCardLockEnabled({ - lockType: aLock, - enabled: aEnabled, - password: aPassword}); - } - - do_test(GECKO_CARDLOCK_PIN, "1234", true); - do_test(GECKO_CARDLOCK_PIN, "1234", false); - do_test(GECKO_CARDLOCK_FDN, "4321", true); - do_test(GECKO_CARDLOCK_FDN, "4321", false); - - run_next_test(); -}); - -/** - * Verify RIL.iccChangeCardLockPassword - */ -add_test(function test_icc_change_card_lock_password() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let ril = context.RIL; - - - function do_test(aLock, aPassword, aNewPassword) { - let GECKO_CARDLOCK_TO_REQUEST = {}; - GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN] = REQUEST_CHANGE_SIM_PIN; - GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN2] = REQUEST_CHANGE_SIM_PIN2; - - buf.sendParcel = function fakeSendParcel() { - // Request Type. - equal(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]); - - // Token : we don't care - this.readInt32(); - - // Data - let parcel = this.readStringList(); - equal(parcel.length, 3); - equal(parcel[0], aPassword); - equal(parcel[1], aNewPassword); - equal(parcel[2], ril.aid); - }; - - ril.iccChangeCardLockPassword({ - lockType: aLock, - password: aPassword, - newPassword: aNewPassword}); - } - - do_test(GECKO_CARDLOCK_PIN, "1234", "4321"); - do_test(GECKO_CARDLOCK_PIN2, "1234", "4321"); - - run_next_test(); -}); - -/** - * Verify RIL.iccUnlockCardLock - PIN - */ -add_test(function test_icc_unlock_card_lock_pin() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let buf = context.Buf; - ril.aid = "123456789"; - - function do_test(aLock, aPassword) { - let GECKO_CARDLOCK_TO_REQUEST = {}; - GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN] = REQUEST_ENTER_SIM_PIN; - GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PIN2] = REQUEST_ENTER_SIM_PIN2; - - buf.sendParcel = function fakeSendParcel() { - // Request Type. - equal(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]); - - // Token : we don't care - this.readInt32(); - - // Data - let parcel = this.readStringList(); - equal(parcel.length, 2); - equal(parcel[0], aPassword); - equal(parcel[1], ril.aid); - }; - - ril.iccUnlockCardLock({ - lockType: aLock, - password: aPassword - }); - } - - do_test(GECKO_CARDLOCK_PIN, "1234"); - do_test(GECKO_CARDLOCK_PIN2, "1234"); - - run_next_test(); -}); - -/** - * Verify RIL.iccUnlockCardLock - PUK - */ -add_test(function test_icc_unlock_card_lock_puk() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let buf = context.Buf; - ril.aid = "123456789"; - - function do_test(aLock, aPassword, aNewPin) { - let GECKO_CARDLOCK_TO_REQUEST = {}; - GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PUK] = REQUEST_ENTER_SIM_PUK; - GECKO_CARDLOCK_TO_REQUEST[GECKO_CARDLOCK_PUK2] = REQUEST_ENTER_SIM_PUK2; - - buf.sendParcel = function fakeSendParcel() { - // Request Type. - equal(this.readInt32(), GECKO_CARDLOCK_TO_REQUEST[aLock]); - - // Token : we don't care - this.readInt32(); - - // Data - let parcel = this.readStringList(); - equal(parcel.length, 3); - equal(parcel[0], aPassword); - equal(parcel[1], aNewPin); - equal(parcel[2], ril.aid); - }; - - ril.iccUnlockCardLock({ - lockType: aLock, - password: aPassword, - newPin: aNewPin - }); - } - - do_test(GECKO_CARDLOCK_PUK, "12345678", "1234"); - do_test(GECKO_CARDLOCK_PUK2, "12345678", "1234"); - - run_next_test(); -}); - -/** - * Verify RIL.iccUnlockCardLock - Depersonalization - */ -add_test(function test_icc_unlock_card_lock_depersonalization() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let buf = context.Buf; - - function do_test(aPassword) { - buf.sendParcel = function fakeSendParcel() { - // Request Type. - equal(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE); - - // Token : we don't care - this.readInt32(); - - // Data - let parcel = this.readStringList(); - equal(parcel.length, 1); - equal(parcel[0], aPassword); - }; - - ril.iccUnlockCardLock({ - lockType: GECKO_CARDLOCK_NCK, - password: aPassword - }); - } - - do_test("12345678"); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_CardState.js b/dom/system/gonk/tests/test_ril_worker_icc_CardState.js deleted file mode 100644 index 788df5073..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_CardState.js +++ /dev/null @@ -1,210 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_personalization_state() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; - - function testPersonalization(isCdma, cardPersoState, geckoCardState) { - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: (!isCdma) ? 0 : -1, - cdmaSubscriptionAppIndex: (isCdma) ? 0 : -1, - apps: [ - { - app_state: CARD_APPSTATE_SUBSCRIPTION_PERSO, - perso_substate: cardPersoState - }], - }; - - ril._isCdma = isCdma; - ril._processICCStatus(iccStatus); - equal(ril.cardState, geckoCardState); - } - - // Test GSM personalization state. - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK, - Ci.nsIIcc.CARD_STATE_NETWORK_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET, - Ci.nsIIcc.CARD_STATE_NETWORK_SUBSET_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE, - Ci.nsIIcc.CARD_STATE_CORPORATE_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER, - Ci.nsIIcc.CARD_STATE_SERVICE_PROVIDER_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SIM, - Ci.nsIIcc.CARD_STATE_SIM_LOCKED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_PUK, - Ci.nsIIcc.CARD_STATE_NETWORK_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK, - Ci.nsIIcc.CARD_STATE_NETWORK_SUBSET_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_CORPORATE_PUK, - Ci.nsIIcc.CARD_STATE_CORPORATE_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK, - Ci.nsIIcc.CARD_STATE_SERVICE_PROVIDER_PUK_REQUIRED); - testPersonalization(false, CARD_PERSOSUBSTATE_SIM_SIM_PUK, - Ci.nsIIcc.CARD_STATE_SIM_PUK_REQUIRED); - - testPersonalization(false, CARD_PERSOSUBSTATE_UNKNOWN, - Ci.nsIIcc.CARD_STATE_UNKNOWN); - testPersonalization(false, CARD_PERSOSUBSTATE_IN_PROGRESS, - Ci.nsIIcc.CARD_STATE_PERSONALIZATION_IN_PROGRESS); - testPersonalization(false, CARD_PERSOSUBSTATE_READY, - Ci.nsIIcc.CARD_STATE_PERSONALIZATION_READY); - - // Test CDMA personalization state. - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1, - Ci.nsIIcc.CARD_STATE_NETWORK1_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2, - Ci.nsIIcc.CARD_STATE_NETWORK2_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD, - Ci.nsIIcc.CARD_STATE_HRPD_NETWORK_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE, - Ci.nsIIcc.CARD_STATE_RUIM_CORPORATE_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER, - Ci.nsIIcc.CARD_STATE_RUIM_SERVICE_PROVIDER_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM, - Ci.nsIIcc.CARD_STATE_RUIM_LOCKED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK1_PUK, - Ci.nsIIcc.CARD_STATE_NETWORK1_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_NETWORK2_PUK, - Ci.nsIIcc.CARD_STATE_NETWORK2_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_HRPD_PUK, - Ci.nsIIcc.CARD_STATE_HRPD_NETWORK_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_CORPORATE_PUK, - Ci.nsIIcc.CARD_STATE_RUIM_CORPORATE_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK, - Ci.nsIIcc.CARD_STATE_RUIM_SERVICE_PROVIDER_PUK_REQUIRED); - testPersonalization(true, CARD_PERSOSUBSTATE_RUIM_RUIM_PUK, - Ci.nsIIcc.CARD_STATE_RUIM_PUK_REQUIRED); - - testPersonalization(true, CARD_PERSOSUBSTATE_UNKNOWN, - Ci.nsIIcc.CARD_STATE_UNKNOWN); - testPersonalization(true, CARD_PERSOSUBSTATE_IN_PROGRESS, - Ci.nsIIcc.CARD_STATE_PERSONALIZATION_IN_PROGRESS); - testPersonalization(true, CARD_PERSOSUBSTATE_READY, - Ci.nsIIcc.CARD_STATE_PERSONALIZATION_READY); - - run_next_test(); -}); - -/** - * Verify SIM app_state in _processICCStatus - */ -add_test(function test_card_app_state() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; - - function testCardAppState(cardAppState, geckoCardState) { - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: 0, - apps: [ - { - app_state: cardAppState - }], - }; - - ril._processICCStatus(iccStatus); - equal(ril.cardState, geckoCardState); - } - - testCardAppState(CARD_APPSTATE_ILLEGAL, - Ci.nsIIcc.CARD_STATE_ILLEGAL); - testCardAppState(CARD_APPSTATE_PIN, - Ci.nsIIcc.CARD_STATE_PIN_REQUIRED); - testCardAppState(CARD_APPSTATE_PUK, - Ci.nsIIcc.CARD_STATE_PUK_REQUIRED); - testCardAppState(CARD_APPSTATE_READY, - Ci.nsIIcc.CARD_STATE_READY); - testCardAppState(CARD_APPSTATE_UNKNOWN, - Ci.nsIIcc.CARD_STATE_UNKNOWN); - testCardAppState(CARD_APPSTATE_DETECTED, - Ci.nsIIcc.CARD_STATE_UNKNOWN); - - run_next_test(); -}); - -/** - * Verify permanent blocked for ICC. - */ -add_test(function test_icc_permanent_blocked() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() {}; - - function testPermanentBlocked(pin1_replaced, universalPINState, pin1) { - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: 0, - universalPINState: universalPINState, - apps: [ - { - pin1_replaced: pin1_replaced, - pin1: pin1 - }] - }; - - ril._processICCStatus(iccStatus); - equal(ril.cardState, Ci.nsIIcc.CARD_STATE_PERMANENT_BLOCKED); - } - - testPermanentBlocked(1, - CARD_PINSTATE_ENABLED_PERM_BLOCKED, - CARD_PINSTATE_UNKNOWN); - testPermanentBlocked(1, - CARD_PINSTATE_ENABLED_PERM_BLOCKED, - CARD_PINSTATE_ENABLED_PERM_BLOCKED); - testPermanentBlocked(0, - CARD_PINSTATE_UNKNOWN, - CARD_PINSTATE_ENABLED_PERM_BLOCKED); - - run_next_test(); -}); - -/** - * Verify ICC without app index. - */ -add_test(function test_icc_without_app_index() { - const ICCID = "123456789"; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - let iccStatus = { - cardState: CARD_STATE_PRESENT, - gsmUmtsSubscriptionAppIndex: -1, - universalPINState: CARD_PINSTATE_DISABLED, - apps: [ - { - app_state: CARD_APPSTATE_READY - }] - }; - - context.ICCRecordHelper.readICCID = function fakeReadICCID() { - ril.iccInfo.iccid = ICCID; - }; - - ril._processICCStatus(iccStatus); - - // Should read icc id event if the app index is -1. - equal(ril.iccInfo.iccid, ICCID); - // cardState is "unknown" if the app index is -1. - equal(ril.cardState, GECKO_CARDSTATE_UNKNOWN); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js deleted file mode 100644 index 0d074da79..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_GsmPDUHelper.js +++ /dev/null @@ -1,79 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify GsmPDUHelper.writeTimestamp - */ -add_test(function test_write_timestamp() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - - // current date - let dateInput = new Date(); - let dateOutput = new Date(); - helper.writeTimestamp(dateInput); - dateOutput.setTime(helper.readTimestamp()); - - equal(dateInput.getFullYear(), dateOutput.getFullYear()); - equal(dateInput.getMonth(), dateOutput.getMonth()); - equal(dateInput.getDate(), dateOutput.getDate()); - equal(dateInput.getHours(), dateOutput.getHours()); - equal(dateInput.getMinutes(), dateOutput.getMinutes()); - equal(dateInput.getSeconds(), dateOutput.getSeconds()); - equal(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); - - // 2034-01-23 12:34:56 -0800 GMT - let time = Date.UTC(2034, 1, 23, 12, 34, 56); - time = time - (8 * 60 * 60 * 1000); - dateInput.setTime(time); - helper.writeTimestamp(dateInput); - dateOutput.setTime(helper.readTimestamp()); - - equal(dateInput.getFullYear(), dateOutput.getFullYear()); - equal(dateInput.getMonth(), dateOutput.getMonth()); - equal(dateInput.getDate(), dateOutput.getDate()); - equal(dateInput.getHours(), dateOutput.getHours()); - equal(dateInput.getMinutes(), dateOutput.getMinutes()); - equal(dateInput.getSeconds(), dateOutput.getSeconds()); - equal(dateInput.getTimezoneOffset(), dateOutput.getTimezoneOffset()); - - run_next_test(); -}); - -/** - * Verify GsmPDUHelper.octectToBCD and GsmPDUHelper.BCDToOctet - */ -add_test(function test_octect_BCD() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - - // 23 - let number = 23; - let octet = helper.BCDToOctet(number); - equal(helper.octetToBCD(octet), number); - - // 56 - number = 56; - octet = helper.BCDToOctet(number); - equal(helper.octetToBCD(octet), number); - - // 0x23 - octet = 0x23; - number = helper.octetToBCD(octet); - equal(helper.BCDToOctet(number), octet); - - // 0x56 - octet = 0x56; - number = helper.octetToBCD(octet); - equal(helper.BCDToOctet(number), octet); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js deleted file mode 100644 index 29b83b76a..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_ICCContactHelper.js +++ /dev/null @@ -1,1042 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Test error message returned in onerror for readICCContacts. - */ -add_test(function test_error_message_read_icc_contact () { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - function do_test(options, expectedErrorMsg) { - ril.sendChromeMessage = function(message) { - equal(message.errorMsg, expectedErrorMsg); - } - ril.readICCContacts(options); - } - - // Error 1, didn't specify correct contactType. - do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); - - // Error 2, specifying a non-supported contactType. - ril.appType = CARD_APPTYPE_USIM; - do_test({contactType: "foo"}, CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); - - // Error 3, suppose we update the supported PBR fields in USIM_PBR_FIELDS, - // but forget to add implemenetations for it. - USIM_PBR_FIELDS.push("pbc"); - do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN}, - CONTACT_ERR_FIELD_NOT_SUPPORTED); - - run_next_test(); -}); - -/** - * Test error message returned in onerror for updateICCContact. - */ -add_test(function test_error_message_update_icc_contact() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - - const ICCID = "123456789"; - ril.iccInfo.iccid = ICCID; - - function do_test(options, expectedErrorMsg) { - ril.sendChromeMessage = function(message) { - equal(message.errorMsg, expectedErrorMsg); - } - ril.updateICCContact(options); - } - - // Error 1, didn't specify correct contactType. - do_test({}, CONTACT_ERR_REQUEST_NOT_SUPPORTED); - - // Error 2, specifying a correct contactType, but without providing 'contact'. - do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN}, - CONTACT_ERR_REQUEST_NOT_SUPPORTED); - - // Error 3, specifying a non-supported contactType. - ril.appType = CARD_APPTYPE_USIM; - do_test({contactType: GECKO_CARDCONTACT_TYPE_SDN, contact: {}}, - CONTACT_ERR_CONTACT_TYPE_NOT_SUPPORTED); - - // Error 4, without supplying pin2. - do_test({contactType: GECKO_CARDCONTACT_TYPE_FDN, - contact: {contactId: ICCID + "1"}}, - GECKO_ERROR_SIM_PIN2); - - // Error 5, No free record found in EF_ADN. - let record = context.ICCRecordHelper; - record.readPBR = function(onsuccess, onerror) { - onsuccess([{adn: {fileId: 0x4f3a}}]); - }; - - let io = context.ICCIOHelper; - io.loadLinearFixedEF = function(options) { - options.totalRecords = 1; - options.p1 = 1; - options.callback(options); - }; - - do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, contact: {}}, - CONTACT_ERR_NO_FREE_RECORD_FOUND); - - // Error 6, ICC IO Error. - io.loadLinearFixedEF = function(options) { - ril[REQUEST_SIM_IO](0, { - errorMsg: GECKO_ERROR_GENERIC_FAILURE - }); - }; - do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, - contact: {contactId: ICCID + "1"}}, - GECKO_ERROR_GENERIC_FAILURE); - - // Error 7, suppose we update the supported PBR fields in USIM_PBR_FIELDS, - // but forget to add implemenetations for it. - USIM_PBR_FIELDS.push("pbc"); - do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, - contact: {contactId: ICCID + "1"}}, - CONTACT_ERR_FIELD_NOT_SUPPORTED); - - // Error 8, EF_PBR doesn't exist. - record.readPBR = function(onsuccess, onerror) { - onsuccess([]); - }; - - do_test({contactType: GECKO_CARDCONTACT_TYPE_ADN, - contact: {contactId: ICCID + "1"}}, - CONTACT_ERR_CANNOT_ACCESS_PHONEBOOK); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.readICCContacts - */ -add_test(function test_read_icc_contacts() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - let ril = context.RIL; - let test_data = [ - //Record 1. - { - comment: "Test read SIM adn contact", - rawData: { - simType: CARD_APPTYPE_SIM, - contactType: GECKO_CARDCONTACT_TYPE_ADN, - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - }, - expectedContact: [{ - recordId: 1, - alphaId: "name", - number: "111111" - }], - }, - //Record 2. - { - comment: "Test read SIM fdn contact", - rawData: { - simType: CARD_APPTYPE_SIM, - contactType: GECKO_CARDCONTACT_TYPE_FDN, - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - }, - expectedContact: [{ - recordId: 1, - alphaId: "name", - number: "111111" - }], - }, - //Record 3. - { - comment: "Test read USIM adn contact", - rawData: { - simType: CARD_APPTYPE_USIM, - contactType: GECKO_CARDCONTACT_TYPE_ADN, - pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}], - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - email: "hello@mail.com", - anr: "123456", - }, - expectedContact: [{ - pbrIndex: 0, - recordId: 1, - alphaId: "name", - number: "111111", - email: "hello@mail.com", - anr: ["123456"] - }], - }, - //Record 4. - { - comment: "Test read USIM adn contacts", - rawData: { - simType: CARD_APPTYPE_USIM, - contactType: GECKO_CARDCONTACT_TYPE_ADN, - pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}, - {adn:{fileId: 0x6f3b}, email: {}, anr0: {}}], - adnLike: [{recordId: 1, alphaId: "name1", number: "111111"}, - {recordId: 2, alphaId: "name2", number: "222222"}], - email: "hello@mail.com", - anr: "123456", - }, - expectedContact: [ - { - pbrIndex: 0, - recordId: 1, - alphaId: "name1", - number: "111111", - email: "hello@mail.com", - anr: ["123456"] - }, { - pbrIndex: 0, - recordId: 2, - alphaId: "name2", - number: "222222", - email: "hello@mail.com", - anr: ["123456"] - }, { - pbrIndex: 1, - recordId: 1, - alphaId: "name1", - number: "111111", - email: "hello@mail.com", - anr: ["123456"] - }, { - pbrIndex: 1, - recordId: 2, - alphaId: "name2", - number: "222222", - email: "hello@mail.com", - anr: ["123456"] - } - ], - }, - //Record 5. - { - comment: "Test read USIM fdn contact", - rawData: { - simType: CARD_APPTYPE_USIM, - contactType: GECKO_CARDCONTACT_TYPE_FDN, - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - }, - expectedContact: [{ - recordId: 1, - alphaId: "name", - number: "111111" - }], - }, - //Record 6. - { - comment: "Test read RUIM adn contact", - rawData: { - simType: CARD_APPTYPE_RUIM, - contactType: GECKO_CARDCONTACT_TYPE_ADN, - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - }, - expectedContact: [{ - recordId: 1, - alphaId: "name", - number: "111111" - }], - }, - //Record 7. - { - comment: "Test read RUIM fdn contact", - rawData: { - simType: CARD_APPTYPE_RUIM, - contactType: GECKO_CARDCONTACT_TYPE_FDN, - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - }, - expectedContact: [{ - recordId: 1, - alphaId: "name", - number: "111111" - }], - }, - //Record 8. - { - comment: "Test read RUIM adn contact with enhanced phone book", - rawData: { - simType: CARD_APPTYPE_RUIM, - contactType: GECKO_CARDCONTACT_TYPE_ADN, - pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}], - adnLike: [{recordId: 1, alphaId: "name", number: "111111"}], - email: "hello@mail.com", - anr: "123456", - enhancedPhoneBook: true, - }, - expectedContact: [{ - pbrIndex: 0, - recordId: 1, - alphaId: "name", - number: "111111", - email: "hello@mail.com", - anr: ["123456"] - }], - }, - //Record 9. - { - comment: "Test read RUIM adn contacts with enhanced phone book", - rawData: { - simType: CARD_APPTYPE_RUIM, - contactType: GECKO_CARDCONTACT_TYPE_ADN, - pbrs: [{adn:{fileId: 0x6f3a}, email: {}, anr0: {}}, - {adn:{fileId: 0x6f3b}, email: {}, anr0: {}}], - adnLike: [{recordId: 1, alphaId: "name1", number: "111111"}, - {recordId: 2, alphaId: "name2", number: "222222"}], - email: "hello@mail.com", - anr: "123456", - enhancedPhoneBook: true, - }, - expectedContact: [ - { - pbrIndex: 0, - recordId: 1, - alphaId: "name1", - number: "111111", - email: "hello@mail.com", - anr: ["123456"] - }, { - pbrIndex: 0, - recordId: 2, - alphaId: "name2", - number: "222222", - email: "hello@mail.com", - anr: ["123456"] - }, { - pbrIndex: 1, - recordId: 1, - alphaId: "name1", - number: "111111", - email: "hello@mail.com", - anr: ["123456"] - }, { - pbrIndex: 1, - recordId: 2, - alphaId: "name2", - number: "222222", - email: "hello@mail.com", - anr: ["123456"] - } - ], - }, - ]; - - function do_test(aTestData, aExpectedContact) { - ril.appType = aTestData.simType; - ril._isCdma = (aTestData.simType === CARD_APPTYPE_RUIM); - ril.iccInfoPrivate.cst = (aTestData.enhancedPhoneBook) ? - [0x20, 0x0C, 0x0, 0x0, 0x0]: - [0x20, 0x00, 0x0, 0x0, 0x0]; - - ril.iccInfoPrivate.sst = (aTestData.simType === CARD_APPTYPE_SIM)? - [0x20, 0x0, 0x0, 0x0, 0x0]: - [0x2, 0x0, 0x0, 0x0, 0x0]; - - // Override some functions to test. - contactHelper.getContactFieldRecordId = function(pbr, contact, field, onsuccess, onerror) { - onsuccess(1); - }; - - record.readPBR = function readPBR(onsuccess, onerror) { - onsuccess(JSON.parse(JSON.stringify(aTestData.pbrs))); - }; - - record.readADNLike = function readADNLike(fileId, extFileId, onsuccess, onerror) { - onsuccess(JSON.parse(JSON.stringify(aTestData.adnLike))); - }; - - record.readEmail = function readEmail(fileId, fileType, recordNumber, onsuccess, onerror) { - onsuccess(aTestData.email); - }; - - record.readANR = function readANR(fileId, fileType, recordNumber, onsuccess, onerror) { - onsuccess(aTestData.anr); - }; - - let onsuccess = function onsuccess(contacts) { - for (let i = 0; i < contacts.length; i++) { - do_print("check contacts[" + i + "]:" + JSON.stringify(contacts[i])); - deepEqual(contacts[i], aExpectedContact[i]); - } - }; - - let onerror = function onerror(errorMsg) { - do_print("readICCContacts failed: " + errorMsg); - ok(false); - }; - - contactHelper.readICCContacts(aTestData.simType, aTestData.contactType, onsuccess, onerror); - } - - for (let i = 0; i < test_data.length; i++) { - do_print(test_data[i].comment); - do_test(test_data[i].rawData, test_data[i].expectedContact); - } - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM. - */ -add_test(function test_update_icc_contact() { - const ADN_RECORD_ID = 100; - const ADN_SFI = 1; - const IAP_FILE_ID = 0x4f17; - const EMAIL_FILE_ID = 0x4f50; - const EMAIL_RECORD_ID = 20; - const ANR0_FILE_ID = 0x4f11; - const ANR0_RECORD_ID = 30; - const EXT_RECORD_ID = 0x01; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - let ril = context.RIL; - - function do_test(aSimType, aContactType, aContact, aPin2, aFileType, aHaveIapIndex, aEnhancedPhoneBook) { - ril.appType = aSimType; - ril._isCdma = (aSimType === CARD_APPTYPE_RUIM); - ril.iccInfoPrivate.cst = (aEnhancedPhoneBook) ? [0x20, 0x0C, 0x28, 0x0, 0x20] - : [0x20, 0x0, 0x28, 0x0, 0x20]; - ril.iccInfoPrivate.sst = (aSimType === CARD_APPTYPE_SIM)? - [0x20, 0x0, 0x28, 0x0, 0x20]: - [0x16, 0x0, 0x0, 0x0, 0x0]; - - recordHelper.readPBR = function(onsuccess, onerror) { - if (aFileType === ICC_USIM_TYPE1_TAG) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}, - ext1: {fileId: ICC_EF_EXT1} - - }]); - } else if (aFileType === ICC_USIM_TYPE2_TAG) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN, - sfi: ADN_SFI}, - iap: {fileId: IAP_FILE_ID}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 0}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 1}, - ext1: {fileId: ICC_EF_EXT1} - }]); - } - }; - - recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) { - if (aContactType === GECKO_CARDCONTACT_TYPE_FDN) { - equal(fileId, ICC_EF_FDN); - } else if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) { - equal(fileId, ICC_EF_ADN); - } - - if (aContact.number.length > ADN_MAX_NUMBER_DIGITS) { - equal(extRecordNumber, EXT_RECORD_ID); - } else { - equal(extRecordNumber, 0xff); - } - - equal(pin2, aPin2); - equal(contact.alphaId, aContact.alphaId); - equal(contact.number, aContact.number); - onsuccess({alphaId: contact.alphaId, - number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)}); - }; - - recordHelper.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) { - onsuccess(EXT_RECORD_ID); - }; - - recordHelper.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) { - onsuccess(); - }; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - onsuccess(EXT_RECORD_ID); - }; - - recordHelper.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) { - onsuccess(); - } - - recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { - equal(fileId, IAP_FILE_ID); - equal(recordNumber, ADN_RECORD_ID); - onsuccess((aHaveIapIndex) ? [EMAIL_RECORD_ID, ANR0_RECORD_ID] - : [0xff, 0xff]); - }; - - recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) { - equal(fileId, IAP_FILE_ID); - equal(recordNumber, ADN_RECORD_ID); - onsuccess(); - }; - - recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { - equal(pbr.email.fileId, EMAIL_FILE_ID); - if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { - equal(recordNumber, ADN_RECORD_ID); - } else if (pbr.email.fileType === ICC_USIM_TYPE2_TAG) { - equal(recordNumber, EMAIL_RECORD_ID); - } - equal(email, aContact.email); - onsuccess(email); - }; - - recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { - equal(pbr.anr0.fileId, ANR0_FILE_ID); - if (pbr.anr0.fileType === ICC_USIM_TYPE1_TAG) { - equal(recordNumber, ADN_RECORD_ID); - } else if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { - equal(recordNumber, ANR0_RECORD_ID); - } - if (Array.isArray(aContact.anr)) { - equal(number, aContact.anr[0]); - } - onsuccess(number); - }; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - let recordId = 0; - if (fileId === EMAIL_FILE_ID) { - recordId = EMAIL_RECORD_ID; - } else if (fileId === ANR0_FILE_ID) { - recordId = ANR0_RECORD_ID; - } - onsuccess(recordId); - }; - - let isSuccess = false; - let onsuccess = function onsuccess(updatedContact) { - equal(ADN_RECORD_ID, updatedContact.recordId); - equal(aContact.alphaId, updatedContact.alphaId); - equal(aContact.number.substring(0, ADN_MAX_NUMBER_DIGITS + EXT_MAX_NUMBER_DIGITS), - updatedContact.number); - if ((aSimType == CARD_APPTYPE_USIM || aSimType == CARD_APPTYPE_RUIM) && - (aFileType == ICC_USIM_TYPE1_TAG || aFileType == ICC_USIM_TYPE2_TAG)) { - if (aContact.hasOwnProperty('email')) { - equal(aContact.email, updatedContact.email); - } - - if (aContact.hasOwnProperty('anr')) { - equal(aContact.anr[0], updatedContact.anr[0]); - } - } else { - equal(updatedContact.email, null); - equal(updatedContact.anr, null); - } - - do_print("updateICCContact success"); - isSuccess = true; - }; - - let onerror = function onerror(errorMsg) { - do_print("updateICCContact failed: " + errorMsg); - }; - - contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror); - ok(isSuccess); - } - - let contacts = [ - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test", - number: "123456", - email: "test@mail.com", - anr: ["+654321"] - }, - // a contact without email and anr. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test2", - number: "123456", - }, - // a contact with email but no anr. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test3", - number: "123456", - email: "test@mail.com" - }, - // a contact with anr but no email. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test4", - number: "123456", - anr: ["+654321"] - }, - // a contact number over 20 digits. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test4", - number: "0123456789012345678901234567890123456789", - anr: ["+654321"] - }, - // a contact number over 40 digits. - { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test5", - number: "01234567890123456789012345678901234567890123456789", - anr: ["+654321"] - }]; - - for (let i = 0; i < contacts.length; i++) { - let contact = contacts[i]; - // SIM - do_print("Test update SIM adn contacts"); - do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, contact); - - do_print("Test update SIM fdn contacts"); - do_test(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234"); - - // USIM - do_print("Test update USIM adn contacts"); - do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, - ICC_USIM_TYPE1_TAG); - do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, - ICC_USIM_TYPE2_TAG, true); - do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, - ICC_USIM_TYPE2_TAG, false); - - do_print("Test update USIM fdn contacts"); - do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234"); - - // RUIM - do_print("Test update RUIM adn contacts"); - do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact); - - do_print("Test update RUIM fdn contacts"); - do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234"); - - // RUIM with enhanced phone book - do_print("Test update RUIM adn contacts with enhanced phone book"); - do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, - ICC_USIM_TYPE1_TAG, null,true); - do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, - ICC_USIM_TYPE2_TAG, true, true); - do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null, - ICC_USIM_TYPE2_TAG, false, true); - - do_print("Test update RUIM fdn contacts with enhanced phone book"); - do_test(CARD_APPTYPE_RUIM, GECKO_CARDCONTACT_TYPE_FDN, contact, "1234", - null, true); - } - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.updateICCContact with appType is CARD_APPTYPE_USIM and - * insufficient space to store Type 2 USIM contact fields. - */ -add_test(function test_update_icc_contact_full_email_and_anr_field() { - const ADN_RECORD_ID = 100; - const ADN_SFI = 1; - const IAP_FILE_ID = 0x4f17; - const EMAIL_FILE_ID = 0x4f50; - const EMAIL_RECORD_ID = 20; - const ANR0_FILE_ID = 0x4f11; - const ANR0_RECORD_ID = 30; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - let ril = context.RIL; - - function do_test(aSimType, aContactType, aContact, aPin2) { - ril.appType = CARD_APPTYPE_USIM; - ril.iccInfoPrivate.sst = [0x2, 0x0, 0x0, 0x0, 0x0]; - - recordHelper.readPBR = function(onsuccess, onerror) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN, - sfi: ADN_SFI}, - iap: {fileId: IAP_FILE_ID}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 0}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 1} - }]); - }; - - recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) { - if (aContactType === GECKO_CARDCONTACT_TYPE_ADN) { - equal(fileId, ICC_EF_ADN); - } - equal(pin2, aPin2); - equal(contact.alphaId, aContact.alphaId); - equal(contact.number, aContact.number); - onsuccess({alphaId: contact.alphaId, - number: contact.number}); - }; - - recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { - equal(fileId, IAP_FILE_ID); - equal(recordNumber, ADN_RECORD_ID); - onsuccess([0xff, 0xff]); - }; - - recordHelper.updateIAP = function(fileId, recordNumber, iap, onsuccess, onerror) { - equal(fileId, IAP_FILE_ID); - equal(recordNumber, ADN_RECORD_ID); - onsuccess(); - }; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - let recordId = 0; - // emulate email and anr don't have free record. - if (fileId === EMAIL_FILE_ID || fileId === ANR0_FILE_ID) { - onerror(CONTACT_ERR_NO_FREE_RECORD_FOUND); - } else { - onsuccess(recordId); - } - }; - - let isSuccess = false; - let onsuccess = function onsuccess(updatedContact) { - equal(ADN_RECORD_ID, updatedContact.recordId); - equal(aContact.alphaId, updatedContact.alphaId); - equal(updatedContact.email, null); - equal(updatedContact.anr, null); - - do_print("updateICCContact success"); - isSuccess = true; - }; - - let onerror = function onerror(errorMsg) { - do_print("updateICCContact failed: " + errorMsg); - }; - - contactHelper.updateICCContact(aSimType, aContactType, aContact, aPin2, onsuccess, onerror); - ok(isSuccess); - } - - let contact = { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test", - number: "123456", - email: "test@mail.com", - anr: ["+654321"] - }; - - // USIM - do_print("Test update USIM adn contacts"); - do_test(CARD_APPTYPE_USIM, GECKO_CARDCONTACT_TYPE_ADN, contact, null); - - run_next_test(); -}); - -/** - * Verify updateICCContact with removal of anr and email with File Type 1. - */ -add_test(function test_update_icc_contact_with_remove_type1_attr() { - const ADN_RECORD_ID = 100; - const IAP_FILE_ID = 0x4f17; - const EMAIL_FILE_ID = 0x4f50; - const EMAIL_RECORD_ID = 20; - const ANR0_FILE_ID = 0x4f11; - const ANR0_RECORD_ID = 30; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - - recordHelper.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) { - onsuccess({alphaId: contact.alphaId, - number: contact.number}); - }; - - let contact = { - pbrIndex: 0, - recordId: ADN_RECORD_ID, - alphaId: "test2", - number: "123456", - }; - - recordHelper.readIAP = function(fileId, recordNumber, onsuccess, onerror) { - onsuccess([EMAIL_RECORD_ID, ANR0_RECORD_ID]); - }; - - recordHelper.updateEmail = function(pbr, recordNumber, email, adnRecordId, onsuccess, onerror) { - ok(email == null); - onsuccess(email); - }; - - recordHelper.updateANR = function(pbr, recordNumber, number, adnRecordId, onsuccess, onerror) { - ok(number == null); - onsuccess(number); - }; - - function do_test(type) { - recordHelper.readPBR = function(onsuccess, onerror) { - if (type == ICC_USIM_TYPE1_TAG) { - onsuccess([{ - adn: {fileId: ICC_EF_ADN}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE1_TAG}}]); - } else { - onsuccess([{ - adn: {fileId: ICC_EF_ADN}, - iap: {fileId: IAP_FILE_ID}, - email: {fileId: EMAIL_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 0}, - anr0: {fileId: ANR0_FILE_ID, - fileType: ICC_USIM_TYPE2_TAG, - indexInIAP: 1}}]); - } - }; - - let successCb = function(updatedContact) { - equal(updatedContact.email, null); - equal(updatedContact.anr, null); - ok(true); - }; - - let errorCb = function(errorMsg) { - do_print(errorMsg); - ok(false); - }; - - contactHelper.updateICCContact(CARD_APPTYPE_USIM, - GECKO_CARDCONTACT_TYPE_ADN, - contact, null, successCb, errorCb); - } - - do_test(ICC_USIM_TYPE1_TAG); - do_test(ICC_USIM_TYPE2_TAG); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.findFreeICCContact in SIM - */ -add_test(function test_find_free_icc_contact_sim() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - // Correct record Id starts with 1, so put a null element at index 0. - let records = [null]; - const MAX_RECORDS = 3; - const PBR_INDEX = 0; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - if (records.length > MAX_RECORDS) { - onerror("No free record found."); - return; - } - - onsuccess(records.length); - }; - - let successCb = function(pbrIndex, recordId) { - equal(pbrIndex, PBR_INDEX); - records[recordId] = {}; - }; - - let errorCb = function(errorMsg) { - do_print(errorMsg); - ok(false); - }; - - for (let i = 0; i < MAX_RECORDS; i++) { - contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, - GECKO_CARDCONTACT_TYPE_ADN, - successCb, errorCb); - } - // The 1st element, records[0], is null. - equal(records.length - 1, MAX_RECORDS); - - // Now the EF is full, so finding a free one should result failure. - successCb = function(pbrIndex, recordId) { - ok(false); - }; - - errorCb = function(errorMsg) { - ok(errorMsg === "No free record found."); - }; - contactHelper.findFreeICCContact(CARD_APPTYPE_SIM, GECKO_CARDCONTACT_TYPE_ADN, - successCb, errorCb); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.findFreeICCContact in USIM - */ -add_test(function test_find_free_icc_contact_usim() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let recordHelper = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - const ADN1_FILE_ID = 0x6f3a; - const ADN2_FILE_ID = 0x6f3b; - const MAX_RECORDS = 3; - - // The adn in the first phonebook set has already two records, which means - // only 1 free record remained. - let pbrs = [{adn: {fileId: ADN1_FILE_ID, records: [null, {}, {}]}}, - {adn: {fileId: ADN2_FILE_ID, records: [null]}}]; - - recordHelper.readPBR = function readPBR(onsuccess, onerror) { - onsuccess(pbrs); - }; - - recordHelper.findFreeRecordId = function(fileId, onsuccess, onerror) { - let pbr = (fileId == ADN1_FILE_ID ? pbrs[0]: pbrs[1]); - if (pbr.adn.records.length > MAX_RECORDS) { - onerror("No free record found."); - return; - } - - onsuccess(pbr.adn.records.length); - }; - - let successCb = function(pbrIndex, recordId) { - equal(pbrIndex, 0); - pbrs[pbrIndex].adn.records[recordId] = {}; - }; - - let errorCb = function(errorMsg) { - ok(false); - }; - - contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, - GECKO_CARDCONTACT_TYPE_ADN, - successCb, errorCb); - - // Now the EF_ADN in the 1st phonebook set is full, so the next free contact - // will come from the 2nd phonebook set. - successCb = function(pbrIndex, recordId) { - equal(pbrIndex, 1); - equal(recordId, 1); - } - contactHelper.findFreeICCContact(CARD_APPTYPE_USIM, - GECKO_CARDCONTACT_TYPE_ADN, - successCb, errorCb); - - run_next_test(); -}); - -/** - * Verify ICCContactHelper.updateADNLikeWithExtension - */ -add_test(function test_update_adn_like_with_extension() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let record = context.ICCRecordHelper; - let contactHelper = context.ICCContactHelper; - ril.appType = CARD_APPTYPE_SIM; - // Correct record Id starts from 1, so put a null element at index 0. - // ext_records contains data at index 1, and it only has 1 free record at index 2. - let notFree = 0x01; - let ext_records = [null, notFree, null]; - - function do_test(contact, extRecordNumber, expectedExtRecordNumber, expectedNumber, expectedCleanEFRecord) { - // Override some functions to test. - record.getADNLikeExtensionRecordNumber = function(fileId, recordNumber, onsuccess, onerror) { - onsuccess(extRecordNumber); - } - - record.updateADNLike = function(fileId, extRecordNumber, contact, pin2, onsuccess, onerror) { - equal(extRecordNumber, expectedExtRecordNumber); - onsuccess({alphaId: contact.alphaId, - number: contact.number.substring(0, ADN_MAX_NUMBER_DIGITS)}); - } - - record.updateExtension = function(fileId, recordNumber, number, onsuccess, onerror) { - if (recordNumber > ext_records.length) { - onerror("updateExtension failed."); - return; - } - ext_records[recordNumber] = number; - onsuccess(); - } - - record.findFreeRecordId = function(fileId, onsuccess, onerror) { - for (let i = 1; i < ext_records.length; i++) { - if (!ext_records[i]) { - onsuccess(i); - return; - } - } - - onerror("No free record found."); - } - - let isCleanEFRecord = false; - record.cleanEFRecord = function(fileId, recordNumber, onsuccess, onerror) { - if (recordNumber > ext_records.length) { - onerror("cleanEFRecord failed."); - return; - } - ext_records[recordNumber] = null; - isCleanEFRecord = true; - onsuccess(); - } - - let successCb = function successCb(updatedContact) { - equal(updatedContact.number, expectedNumber); - }; - - let errorCb = function errorCb(errorMsg) { - do_print("updateADNLikeWithExtension failed, msg = " + errorMsg); - ok(false); - }; - - contactHelper.updateADNLikeWithExtension(ICC_EF_ADN, ICC_EF_EXT1, contact, null, successCb, errorCb); - - if (expectedCleanEFRecord) { - ok(isCleanEFRecord); - } - } - - // Update extension record with previous extension record number. - do_test({recordId: 1, alphaId: "test", number: "001122334455667788991234"}, 0x01, 0x01, "001122334455667788991234"); - // Update extension record and find a free record. - do_test({recordId: 1, alphaId: "test", number: "001122334455667788995678"}, 0xff, 0x02, "001122334455667788995678"); - // Update extension record with no free extension record. - do_test({recordId: 1, alphaId: "test", number: "001122334455667788994321"}, 0xff, 0xff, "00112233445566778899"); - // Update extension record with clean previous extension record. - do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0x01, 0xff, "00112233445566778899", true); - // Update extension record with no extension record and previous extension record. - do_test({recordId: 1, alphaId: "test", number: "00112233445566778899"}, 0xff, 0xff, "00112233445566778899"); - - run_next_test(); -});
\ No newline at end of file diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js deleted file mode 100644 index e690b1206..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_ICCIOHelper.js +++ /dev/null @@ -1,173 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify ICCIOHelper.loadLinearFixedEF with recordSize. - */ -add_test(function test_load_linear_fixed_ef() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let io = context.ICCIOHelper; - - io.getResponse = function fakeGetResponse(options) { - // When recordSize is provided, loadLinearFixedEF should call iccIO directly. - ok(false); - run_next_test(); - }; - - ril.iccIO = function fakeIccIO(options) { - ok(true); - run_next_test(); - }; - - io.loadLinearFixedEF({recordSize: 0x20}); -}); - -/** - * Verify ICCIOHelper.loadLinearFixedEF without recordSize. - */ -add_test(function test_load_linear_fixed_ef() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let io = context.ICCIOHelper; - - io.getResponse = function fakeGetResponse(options) { - ok(true); - run_next_test(); - }; - - ril.iccIO = function fakeIccIO(options) { - // When recordSize is not provided, loadLinearFixedEF should call getResponse. - ok(false); - run_next_test(); - }; - - io.loadLinearFixedEF({}); -}); - -/** - * Verify ICC IO Error. - */ -add_test(function test_process_icc_io_error() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - - function do_test(sw1, sw2, expectedErrorMsg) { - let called = false; - function errorCb(errorMsg) { - called = true; - equal(errorMsg, expectedErrorMsg); - } - - // Write sw1 and sw2 to buffer. - buf.writeInt32(sw1); - buf.writeInt32(sw2); - - context.RIL[REQUEST_SIM_IO](0, {fileId: 0xffff, - command: 0xff, - onerror: errorCb}); - - // onerror callback should be triggered. - ok(called); - } - - let TEST_DATA = [ - // [sw1, sw2, expectError] - [ICC_STATUS_ERROR_COMMAND_NOT_ALLOWED, 0xff, GECKO_ERROR_GENERIC_FAILURE], - [ICC_STATUS_ERROR_WRONG_PARAMETERS, 0xff, GECKO_ERROR_GENERIC_FAILURE], - ]; - - for (let i = 0; i < TEST_DATA.length; i++) { - do_test.apply(null, TEST_DATA[i]); - } - - run_next_test(); -}); - -/** - * Verify ICCIOHelper.processICCIOGetResponse for EF_TYPE_TRANSPARENT. - */ -add_test(function test_icc_io_get_response_for_transparent_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let iccioHelper = context.ICCIOHelper; - let pduHelper = context.GsmPDUHelper; - - let responseArray = [ - // SIM response. - [0x00, 0x00, 0x00, 0x0A, 0x2F, 0xE2, 0x04, 0x00, 0x0A, 0xA0, 0xAA, 0x00, - 0x02, 0x00, 0x00], - // USIM response. - [0x62, 0x22, 0x82, 0x02, 0x41, 0x21, 0x83, 0x02, 0x2F, 0xE2, 0xA5, 0x09, - 0xC1, 0x04, 0x40, 0x0F, 0xF5, 0x55, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x05, - 0x8B, 0x03, 0x2F, 0x06, 0x0B, 0x80, 0x02, 0x00, 0x0A, 0x88, 0x01, 0x10] - ]; - - for (let i = 0; i < responseArray.length; i++) { - let strLen = responseArray[i].length * 2; - buf.writeInt32(strLen); - for (let j = 0; j < responseArray[i].length; j++) { - pduHelper.writeHexOctet(responseArray[i][j]); - } - buf.writeStringDelimiter(strLen); - - let options = {fileId: ICC_EF_ICCID, - structure: EF_STRUCTURE_TRANSPARENT}; - iccioHelper.processICCIOGetResponse(options); - - equal(options.fileSize, 0x0A); - } - - run_next_test(); -}); - -/** - * Verify ICCIOHelper.processICCIOGetResponse for EF_TYPE_LINEAR_FIXED. - */ -add_test(function test_icc_io_get_response_for_linear_fixed_structure() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let iccioHelper = context.ICCIOHelper; - let pduHelper = context.GsmPDUHelper; - - let responseArray = [ - // SIM response. - [0x00, 0x00, 0x00, 0x1A, 0x6F, 0x40, 0x04, 0x00, 0x11, 0xA0, 0xAA, 0x00, - 0x02, 0x01, 0x1A], - // USIM response. - [0x62, 0x1E, 0x82, 0x05, 0x42, 0x21, 0x00, 0x1A, 0x01, 0x83, 0x02, 0x6F, - 0x40, 0xA5, 0x03, 0x92, 0x01, 0x00, 0x8A, 0x01, 0x07, 0x8B, 0x03, 0x6F, - 0x06, 0x02, 0x80, 0x02, 0x00, 0x1A, 0x88, 0x00] - ]; - - for (let i = 0; i < responseArray.length; i++) { - let strLen = responseArray[i].length * 2; - buf.writeInt32(strLen); - for (let j = 0; j < responseArray[i].length; j++) { - pduHelper.writeHexOctet(responseArray[i][j]); - } - buf.writeStringDelimiter(strLen); - - let options = {fileId: ICC_EF_MSISDN, - structure: EF_STRUCTURE_LINEAR_FIXED}; - iccioHelper.processICCIOGetResponse(options); - - equal(options.fileSize, 0x1A); - equal(options.recordSize, 0x1A); - equal(options.totalRecords, 0x01); - } - - run_next_test(); -}); - diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js deleted file mode 100644 index 91495b1b7..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_ICCPDUHelper.js +++ /dev/null @@ -1,652 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify ICCPDUHelper#readICCUCS2String() - */ -add_test(function test_read_icc_ucs2_string() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - // 0x80 - let text = "TEST"; - helper.writeUCS2String(text); - // Also write two unused octets. - let ffLen = 2; - for (let i = 0; i < ffLen; i++) { - helper.writeHexOctet(0xff); - } - equal(iccHelper.readICCUCS2String(0x80, (2 * text.length) + ffLen), text); - - // 0x81 - let array = [0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, - 0xff, 0xff]; - let len = array.length; - for (let i = 0; i < len; i++) { - helper.writeHexOctet(array[i]); - } - equal(iccHelper.readICCUCS2String(0x81, len), "Mozilla\u694a"); - - // 0x82 - let array2 = [0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, - 0xca, 0xff, 0xff]; - let len2 = array2.length; - for (let i = 0; i < len2; i++) { - helper.writeHexOctet(array2[i]); - } - equal(iccHelper.readICCUCS2String(0x82, len2), "Mozilla\u694a"); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#writeICCUCS2String() - */ -add_test(function test_write_icc_ucs2_string() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let alphaLen = 18; - let test_data = [ - { - encode: 0x80, - // string only contain one character. - data: "\u82b3" - }, { - encode: 0x80, - // 2 UCS2 character not located in the same half-page. - data: "Fire \u82b3\u8233" - }, { - encode: 0x80, - // 2 UCS2 character not located in the same half-page. - data: "\u694a\u704a" - }, { - encode: 0x81, - // 2 UCS2 character within same half-page. - data: "Fire \u6901\u697f" - }, { - encode: 0x81, - // 2 UCS2 character within same half-page. - data: "Fire \u6980\u69ff" - }, { - encode: 0x82, - // 2 UCS2 character within same half-page, but bit 8 is different. - data: "Fire \u0514\u0593" - }, { - encode: 0x82, - // 2 UCS2 character over 0x81 can encode range. - data: "Fire \u8000\u8001" - }, { - encode: 0x82, - // 2 UCS2 character over 0x81 can encode range. - data: "Fire \ufffd\ufffe" - }]; - - for (let i = 0; i < test_data.length; i++) { - let test = test_data[i]; - let writtenStr = iccHelper.writeICCUCS2String(alphaLen, test.data); - equal(writtenStr, test.data); - equal(helper.readHexOctet(), test.encode); - equal(iccHelper.readICCUCS2String(test.encode, alphaLen - 1), test.data); - } - - // This string use 0x80 encoded and the maximum capacity is 17 octets. - // Each alphabet takes 2 octets, thus the first 8 alphabets can be written. - let str = "Mozilla \u82b3\u8233 On Fire"; - let writtenStr = iccHelper.writeICCUCS2String(alphaLen, str); - equal(writtenStr, str.substring(0, 8)); - equal(helper.readHexOctet(), 0x80); - equal(iccHelper.readICCUCS2String(0x80, alphaLen - 1), str.substring(0, 8)); - - // This string use 0x81 encoded and the maximum capacity is 15 octets. - // Each alphabet takes 1 octets, thus the first 15 alphabets can be written. - str = "Mozilla \u6901\u697f On Fire"; - writtenStr = iccHelper.writeICCUCS2String(alphaLen, str); - equal(writtenStr, str.substring(0, 15)); - equal(helper.readHexOctet(), 0x81); - equal(iccHelper.readICCUCS2String(0x81, alphaLen - 1), str.substring(0, 15)); - - // This string use 0x82 encoded and the maximum capacity is 14 octets. - // Each alphabet takes 1 octets, thus the first 14 alphabets can be written. - str = "Mozilla \u0514\u0593 On Fire"; - writtenStr = iccHelper.writeICCUCS2String(alphaLen, str); - equal(writtenStr, str.substring(0, 14)); - equal(helper.readHexOctet(), 0x82); - equal(iccHelper.readICCUCS2String(0x82, alphaLen - 1), str.substring(0, 14)); - - run_next_test(); -}); -/** - * Verify ICCPDUHelper#readDiallingNumber - */ -add_test(function test_read_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let str = "123456789"; - - helper.readHexOctet = function() { - return 0x81; - }; - - helper.readSwappedNibbleExtendedBcdString = function(len) { - return str.substring(0, len); - }; - - for (let i = 0; i < str.length; i++) { - equal(str.substring(0, i - 1), // -1 for the TON - iccHelper.readDiallingNumber(i)); - } - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#read8BitUnpackedToString - */ -add_test(function test_read_8bit_unpacked_to_string() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - - // Test 1: Read GSM alphabets. - // Write alphabets before ESCAPE. - for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { - helper.writeHexOctet(i); - } - - // Write two ESCAPEs to make it become ' '. - helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); - helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); - - for (let i = PDU_NL_EXTENDED_ESCAPE + 1; i < langTable.length; i++) { - helper.writeHexOctet(i); - } - - // Also write two unused fields. - let ffLen = 2; - for (let i = 0; i < ffLen; i++) { - helper.writeHexOctet(0xff); - } - - equal(iccHelper.read8BitUnpackedToString(PDU_NL_EXTENDED_ESCAPE), - langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); - equal(iccHelper.read8BitUnpackedToString(2), " "); - equal(iccHelper.read8BitUnpackedToString(langTable.length - - PDU_NL_EXTENDED_ESCAPE - 1 + ffLen), - langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); - - // Test 2: Read GSM extended alphabets. - for (let i = 0; i < langShiftTable.length; i++) { - helper.writeHexOctet(PDU_NL_EXTENDED_ESCAPE); - helper.writeHexOctet(i); - } - - // Read string before RESERVED_CONTROL. - equal(iccHelper.read8BitUnpackedToString(PDU_NL_RESERVED_CONTROL * 2), - langShiftTable.substring(0, PDU_NL_RESERVED_CONTROL)); - // ESCAPE + RESERVED_CONTROL will become ' '. - equal(iccHelper.read8BitUnpackedToString(2), " "); - // Read string between RESERVED_CONTROL and EXTENDED_ESCAPE. - equal(iccHelper.read8BitUnpackedToString( - (PDU_NL_EXTENDED_ESCAPE - PDU_NL_RESERVED_CONTROL - 1) * 2), - langShiftTable.substring(PDU_NL_RESERVED_CONTROL + 1, - PDU_NL_EXTENDED_ESCAPE)); - // ESCAPE + ESCAPE will become ' '. - equal(iccHelper.read8BitUnpackedToString(2), " "); - // Read remaining string. - equal(iccHelper.read8BitUnpackedToString( - (langShiftTable.length - PDU_NL_EXTENDED_ESCAPE - 1) * 2), - langShiftTable.substring(PDU_NL_EXTENDED_ESCAPE + 1)); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#writeStringTo8BitUnpacked. - * - * Test writing GSM 8 bit alphabets. - */ -add_test(function test_write_string_to_8bit_unpacked() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - // Length of trailing 0xff. - let ffLen = 2; - let str; - - // Test 1, write GSM alphabets. - let writtenStr = iccHelper.writeStringTo8BitUnpacked(langTable.length + ffLen, langTable); - equal(writtenStr, langTable); - - for (let i = 0; i < langTable.length; i++) { - equal(helper.readHexOctet(), i); - } - - for (let i = 0; i < ffLen; i++) { - equal(helper.readHexOctet(), 0xff); - } - - // Test 2, write GSM extended alphabets. - str = "\u000c\u20ac"; - writtenStr = iccHelper.writeStringTo8BitUnpacked(4, str); - equal(writtenStr, str); - equal(iccHelper.read8BitUnpackedToString(4), str); - - // Test 3, write GSM and GSM extended alphabets. - // \u000c, \u20ac are from gsm extended alphabets. - // \u00a3 is from gsm alphabet. - str = "\u000c\u20ac\u00a3"; - - // 2 octets * 2 = 4 octets for 2 gsm extended alphabets, - // 1 octet for 1 gsm alphabet, - // 2 octes for trailing 0xff. - // "Totally 7 octets are to be written." - writtenStr = iccHelper.writeStringTo8BitUnpacked(7, str); - equal(writtenStr, str); - equal(iccHelper.read8BitUnpackedToString(7), str); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper#writeStringTo8BitUnpacked with maximum octets written. - */ -add_test(function test_write_string_to_8bit_unpacked_with_max_octets_written() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - - // The maximum of the number of octets that can be written is 3. - // Only 3 characters shall be written even the length of the string is 4. - let writtenStr = iccHelper.writeStringTo8BitUnpacked(3, langTable.substring(0, 4)); - equal(writtenStr, langTable.substring(0, 3)); - helper.writeHexOctet(0xff); // dummy octet. - for (let i = 0; i < 3; i++) { - equal(helper.readHexOctet(), i); - } - ok(helper.readHexOctet() != 4); - - // \u000c is GSM extended alphabet, 2 octets. - // \u00a3 is GSM alphabet, 1 octet. - let str = "\u000c\u00a3"; - writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str); - equal(writtenStr, str.substring(0, 2)); - equal(iccHelper.read8BitUnpackedToString(3), str); - - str = "\u00a3\u000c"; - writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str); - equal(writtenStr, str.substring(0, 2)); - equal(iccHelper.read8BitUnpackedToString(3), str); - - // 2 GSM extended alphabets cost 4 octets, but maximum is 3, so only the 1st - // alphabet can be written. - str = "\u000c\u000c"; - writtenStr = iccHelper.writeStringTo8BitUnpacked(3, str); - helper.writeHexOctet(0xff); // dummy octet. - equal(writtenStr, str.substring(0, 1)); - equal(iccHelper.read8BitUnpackedToString(4), str.substring(0, 1)); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.readAlphaIdentifier - */ -add_test(function test_read_alpha_identifier() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - // UCS2: 0x80 - let text = "TEST"; - helper.writeHexOctet(0x80); - helper.writeUCS2String(text); - // Also write two unused octets. - let ffLen = 2; - for (let i = 0; i < ffLen; i++) { - helper.writeHexOctet(0xff); - } - equal(iccHelper.readAlphaIdentifier(1 + (2 * text.length) + ffLen), text); - - // UCS2: 0x81 - let array = [0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; - for (let i = 0; i < array.length; i++) { - helper.writeHexOctet(array[i]); - } - equal(iccHelper.readAlphaIdentifier(array.length), "Mozilla\u694a"); - - // UCS2: 0x82 - let array2 = [0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff]; - for (let i = 0; i < array2.length; i++) { - helper.writeHexOctet(array2[i]); - } - equal(iccHelper.readAlphaIdentifier(array2.length), "Mozilla\u694a"); - - // GSM 8 Bit Unpacked - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - for (let i = 0; i < PDU_NL_EXTENDED_ESCAPE; i++) { - helper.writeHexOctet(i); - } - equal(iccHelper.readAlphaIdentifier(PDU_NL_EXTENDED_ESCAPE), - langTable.substring(0, PDU_NL_EXTENDED_ESCAPE)); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeAlphaIdentifier - */ -add_test(function test_write_alpha_identifier() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - // Length of trailing 0xff. - let ffLen = 2; - - // Removal - let writenAlphaId = iccHelper.writeAlphaIdentifier(10, null); - equal(writenAlphaId, ""); - equal(iccHelper.readAlphaIdentifier(10), ""); - - // GSM 8 bit - let str = "Mozilla"; - writenAlphaId = iccHelper.writeAlphaIdentifier(str.length + ffLen, str); - equal(writenAlphaId , str); - equal(iccHelper.readAlphaIdentifier(str.length + ffLen), str); - - // UCS2 - str = "Mozilla\u8000"; - writenAlphaId = iccHelper.writeAlphaIdentifier(str.length * 2 + ffLen, str); - equal(writenAlphaId , str); - // * 2 for each character will be encoded to UCS2 alphabets. - equal(iccHelper.readAlphaIdentifier(str.length * 2 + ffLen), str); - - // Test with maximum octets written. - // 1 coding scheme (0x80) and 1 UCS2 character, total 3 octets. - str = "\u694a"; - writenAlphaId = iccHelper.writeAlphaIdentifier(3, str); - equal(writenAlphaId , str); - equal(iccHelper.readAlphaIdentifier(3), str); - - // 1 coding scheme (0x80) and 2 UCS2 characters, total 5 octets. - // numOctets is limited to 4, so only 1 UCS2 character can be written. - str = "\u694a\u69ca"; - writenAlphaId = iccHelper.writeAlphaIdentifier(4, str); - helper.writeHexOctet(0xff); // dummy octet. - equal(writenAlphaId , str.substring(0, 1)); - equal(iccHelper.readAlphaIdentifier(5), str.substring(0, 1)); - - // Write 0 octet. - writenAlphaId = iccHelper.writeAlphaIdentifier(0, "1"); - helper.writeHexOctet(0xff); // dummy octet. - equal(writenAlphaId, ""); - equal(iccHelper.readAlphaIdentifier(1), ""); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.readAlphaIdDiallingNumber - */ -add_test(function test_read_alpha_id_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let buf = context.Buf; - const recordSize = 32; - - function testReadAlphaIdDiallingNumber(contact) { - iccHelper.readAlphaIdentifier = function() { - return contact.alphaId; - }; - - iccHelper.readNumberWithLength = function() { - return contact.number; - }; - - let strLen = recordSize * 2; - buf.writeInt32(strLen); // fake length - helper.writeHexOctet(0xff); // fake CCP - helper.writeHexOctet(0xff); // fake EXT1 - buf.writeStringDelimiter(strLen); - - let contactR = iccHelper.readAlphaIdDiallingNumber(recordSize); - if (contact.alphaId == "" && contact.number == "") { - equal(contactR, null); - } else { - equal(contactR.alphaId, contact.alphaId); - equal(contactR.number, contact.number); - } - } - - testReadAlphaIdDiallingNumber({alphaId: "AlphaId", number: "0987654321"}); - testReadAlphaIdDiallingNumber({alphaId: "", number: ""}); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeAlphaIdDiallingNumber - */ -add_test(function test_write_alpha_id_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.ICCPDUHelper; - const recordSize = 32; - - // Write a normal contact. - let contactW = { - alphaId: "Mozilla", - number: "1234567890" - }; - - let writtenContact = helper.writeAlphaIdDiallingNumber(recordSize, - contactW.alphaId, - contactW.number, 0xff); - - let contactR = helper.readAlphaIdDiallingNumber(recordSize); - equal(writtenContact.alphaId, contactR.alphaId); - equal(writtenContact.number, contactR.number); - equal(0xff, contactR.extRecordNumber); - - // Write a contact with alphaId encoded in UCS2 and number has '+'. - let contactUCS2 = { - alphaId: "火狐", - number: "+1234567890" - }; - - writtenContact = helper.writeAlphaIdDiallingNumber(recordSize, - contactUCS2.alphaId, - contactUCS2.number, 0xff); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - equal(writtenContact.alphaId, contactR.alphaId); - equal(writtenContact.number, contactR.number); - equal(0xff, contactR.extRecordNumber); - - // Write a null contact (Removal). - writtenContact = helper.writeAlphaIdDiallingNumber(recordSize); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - equal(contactR, null); - equal(writtenContact.alphaId, ""); - equal(writtenContact.number, ""); - - // Write a longer alphaId/dialling number - // Dialling Number : Maximum 20 digits(10 octets). - // Alpha Identifier: 32(recordSize) - 14 (10 octets for Dialling Number, 1 - // octet for TON/NPI, 1 for number length octet, and 2 for - // Ext) = Maximum 18 octets. - let longContact = { - alphaId: "AAAAAAAAABBBBBBBBBCCCCCCCCC", - number: "123456789012345678901234567890", - }; - - writtenContact = helper.writeAlphaIdDiallingNumber(recordSize, - longContact.alphaId, - longContact.number, 0xff); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - equal(writtenContact.alphaId, contactR.alphaId); - equal(writtenContact.number, contactR.number); - equal(0xff, contactR.extRecordNumber); - - // Add '+' to number and test again. - longContact.number = "+123456789012345678901234567890"; - writtenContact = helper.writeAlphaIdDiallingNumber(recordSize, - longContact.alphaId, - longContact.number, 0xff); - contactR = helper.readAlphaIdDiallingNumber(recordSize); - equal(writtenContact.alphaId, contactR.alphaId); - equal(writtenContact.number, contactR.number); - equal(0xff, contactR.extRecordNumber); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeDiallingNumber - */ -add_test(function test_write_dialling_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.ICCPDUHelper; - - // with + - let number = "+123456"; - let len = 4; - helper.writeDiallingNumber(number); - equal(helper.readDiallingNumber(len), number); - - // without + - number = "987654"; - len = 4; - helper.writeDiallingNumber(number); - equal(helper.readDiallingNumber(len), number); - - number = "9876543"; - len = 5; - helper.writeDiallingNumber(number); - equal(helper.readDiallingNumber(len), number); - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.readNumberWithLength - */ -add_test(function test_read_number_with_length() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - let numbers = [ - { - number: "123456789", - expectedNumber: "123456789" - }, - { - number: "", - expectedNumber: "" - }, - // Invalid length of BCD number/SSC contents - { - number: "12345678901234567890123", - expectedNumber: "" - }, - ]; - - // To avoid obtaining wrong buffer content. - context.Buf.seekIncoming = function(offset) { - }; - - function do_test(aNumber, aExpectedNumber) { - iccHelper.readDiallingNumber = function(numLen) { - return aNumber.substring(0, numLen); - }; - - if (aNumber) { - helper.writeHexOctet(aNumber.length + 1); - } else { - helper.writeHexOctet(0xff); - } - - equal(iccHelper.readNumberWithLength(), aExpectedNumber); - } - - for (let i = 0; i < numbers.length; i++) { - do_test(numbers[i].number, numbers[i].expectedNumber); - } - - run_next_test(); -}); - -/** - * Verify ICCPDUHelper.writeNumberWithLength - */ -add_test(function test_write_number_with_length() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - function test(number, expectedNumber) { - expectedNumber = expectedNumber || number; - let writeNumber = iccHelper.writeNumberWithLength(number); - equal(writeNumber, expectedNumber); - let numLen = helper.readHexOctet(); - equal(expectedNumber, iccHelper.readDiallingNumber(numLen)); - for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES - numLen); i++) { - equal(0xff, helper.readHexOctet()); - } - } - - // without + - test("123456789"); - - // with + - test("+987654321"); - - // extended BCD coding - test("1*2#3,4*5#6,"); - - // with + and extended BCD coding - test("+1*2#3,4*5#6,"); - - // non-supported characters should not be written. - test("(1)23-456+789", "123456789"); - - test("++(01)2*3-4#5,6+7(8)9*0#1,", "+012*34#5,6789*0#1,"); - - // over maximum 20 digits should be truncated. - test("012345678901234567890123456789", "01234567890123456789"); - - // null - iccHelper.writeNumberWithLength(null); - for (let i = 0; i < (ADN_MAX_BCD_NUMBER_BYTES + 1); i++) { - equal(0xff, helper.readHexOctet()); - } - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js deleted file mode 100644 index 00c55873d..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_ICCRecordHelper.js +++ /dev/null @@ -1,1080 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify ICCRecordHelper.readPBR - */ -add_test(function test_read_pbr() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let pbr_1 = [ - 0xa8, 0x05, 0xc0, 0x03, 0x4f, 0x3a, 0x01 - ]; - - // Write data size - buf.writeInt32(pbr_1.length * 2); - - // Write pbr - for (let i = 0; i < pbr_1.length; i++) { - helper.writeHexOctet(pbr_1[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(pbr_1.length * 2); - - options.totalRecords = 2; - if (options.callback) { - options.callback(options); - } - }; - - io.loadNextRecord = function fakeLoadNextRecord(options) { - let pbr_2 = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - ]; - - options.p1++; - if (options.callback) { - options.callback(options); - } - }; - - let successCb = function successCb(pbrs) { - equal(pbrs[0].adn.fileId, 0x4f3a); - equal(pbrs.length, 1); - }; - - let errorCb = function errorCb(errorMsg) { - do_print("Reading EF_PBR failed, msg = " + errorMsg); - ok(false); - }; - - record.readPBR(successCb, errorCb); - - // Check cache pbrs when 2nd call - let ifLoadEF = false; - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - ifLoadEF = true; - } - record.readPBR(successCb, errorCb); - ok(!ifLoadEF); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.readEmail - */ -add_test(function test_read_email() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let recordSize; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let email_1 = [ - 0x65, 0x6D, 0x61, 0x69, 0x6C, - 0x00, 0x6D, 0x6F, 0x7A, 0x69, - 0x6C, 0x6C, 0x61, 0x2E, 0x63, - 0x6F, 0x6D, 0x02, 0x23]; - - // Write data size - buf.writeInt32(email_1.length * 2); - - // Write email - for (let i = 0; i < email_1.length; i++) { - helper.writeHexOctet(email_1[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(email_1.length * 2); - - recordSize = email_1.length; - options.recordSize = recordSize; - if (options.callback) { - options.callback(options); - } - }; - - function doTestReadEmail(type, expectedResult) { - let fileId = 0x6a75; - let recordNumber = 1; - - // fileId and recordNumber are dummy arguments. - record.readEmail(fileId, type, recordNumber, function(email) { - equal(email, expectedResult); - }); - }; - - doTestReadEmail(ICC_USIM_TYPE1_TAG, "email@mozilla.com$#"); - doTestReadEmail(ICC_USIM_TYPE2_TAG, "email@mozilla.com"); - equal(record._emailRecordSize, recordSize); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.updateEmail - */ -add_test(function test_update_email() { - const recordSize = 0x20; - const recordNumber = 1; - const fileId = 0x4f50; - const NUM_TESTS = 2; - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let pbr = {email: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, - adn: {sfi: 1}}; - let count = 0; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(pbr, expectedEmail, expectedAdnRecordId) { - buf.sendParcel = function() { - count++; - - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), fileId); - - // pathId. - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - - // p1. - equal(this.readInt32(), recordNumber); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - let email; - if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) { - email = iccHelper.read8BitUnpackedToString(recordSize); - } else { - email = iccHelper.read8BitUnpackedToString(recordSize - 2); - equal(pduHelper.readHexOctet(), pbr.adn.sfi); - equal(pduHelper.readHexOctet(), expectedAdnRecordId); - } - this.readStringDelimiter(strLen); - equal(email, expectedEmail); - - // pin2. - equal(this.readString(), null); - - // AID. Ignore because it's from modem. - this.readInt32(); - - if (count == NUM_TESTS) { - run_next_test(); - } - }; - recordHelper.updateEmail(pbr, recordNumber, expectedEmail, expectedAdnRecordId); - } - - do_test(pbr, "test@mail.com"); - pbr.email.fileType = ICC_USIM_TYPE2_TAG; - do_test(pbr, "test@mail.com", 1); -}); - -/** - * Verify ICCRecordHelper.readANR - */ -add_test(function test_read_anr() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let recordSize; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let anr_1 = [ - 0x01, 0x05, 0x81, 0x10, 0x32, - 0x54, 0xF6, 0xFF, 0xFF]; - - // Write data size - buf.writeInt32(anr_1.length * 2); - - // Write anr - for (let i = 0; i < anr_1.length; i++) { - helper.writeHexOctet(anr_1[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(anr_1.length * 2); - - recordSize = anr_1.length; - options.recordSize = recordSize; - if (options.callback) { - options.callback(options); - } - }; - - function doTestReadAnr(fileType, expectedResult) { - let fileId = 0x4f11; - let recordNumber = 1; - - // fileId and recordNumber are dummy arguments. - record.readANR(fileId, fileType, recordNumber, function(anr) { - equal(anr, expectedResult); - }); - }; - - doTestReadAnr(ICC_USIM_TYPE1_TAG, "0123456"); - equal(record._anrRecordSize, recordSize); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.updateANR - */ -add_test(function test_update_anr() { - const recordSize = 0x20; - const recordNumber = 1; - const fileId = 0x4f11; - const NUM_TESTS = 2; - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let pbr = {anr0: {fileId: fileId, fileType: ICC_USIM_TYPE1_TAG}, - adn: {sfi: 1}}; - let count = 0; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(pbr, expectedANR, expectedAdnRecordId) { - buf.sendParcel = function() { - count++; - - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), fileId); - - // pathId. - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - - // p1. - equal(this.readInt32(), recordNumber); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - // EF_AAS, ignore. - pduHelper.readHexOctet(); - equal(iccHelper.readNumberWithLength(), expectedANR); - // EF_CCP, ignore. - pduHelper.readHexOctet(); - // EF_EXT1, ignore. - pduHelper.readHexOctet(); - if (pbr.anr0.fileType === ICC_USIM_TYPE2_TAG) { - equal(pduHelper.readHexOctet(), pbr.adn.sfi); - equal(pduHelper.readHexOctet(), expectedAdnRecordId); - } - this.readStringDelimiter(strLen); - - // pin2. - equal(this.readString(), null); - - // AID. Ignore because it's from modem. - this.readInt32(); - - if (count == NUM_TESTS) { - run_next_test(); - } - }; - recordHelper.updateANR(pbr, recordNumber, expectedANR, expectedAdnRecordId); - } - - do_test(pbr, "+123456789"); - pbr.anr0.fileType = ICC_USIM_TYPE2_TAG; - do_test(pbr, "123456789", 1); -}); - -/** - * Verify ICCRecordHelper.readIAP - */ -add_test(function test_read_iap() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let recordSize; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let iap_1 = [0x01, 0x02]; - - // Write data size/ - buf.writeInt32(iap_1.length * 2); - - // Write iap. - for (let i = 0; i < iap_1.length; i++) { - helper.writeHexOctet(iap_1[i]); - } - - // Write string delimiter. - buf.writeStringDelimiter(iap_1.length * 2); - - recordSize = iap_1.length; - options.recordSize = recordSize; - if (options.callback) { - options.callback(options); - } - }; - - function doTestReadIAP(expectedIAP) { - const fileId = 0x4f17; - const recordNumber = 1; - - let successCb = function successCb(iap) { - for (let i = 0; i < iap.length; i++) { - equal(expectedIAP[i], iap[i]); - } - run_next_test(); - }.bind(this); - - let errorCb = function errorCb(errorMsg) { - do_print(errorMsg); - ok(false); - run_next_test(); - }.bind(this); - - record.readIAP(fileId, recordNumber, successCb, errorCb); - }; - - doTestReadIAP([1, 2]); -}); - -/** - * Verify ICCRecordHelper.updateIAP - */ -add_test(function test_update_iap() { - const recordSize = 2; - const recordNumber = 1; - const fileId = 0x4f17; - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let count = 0; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(expectedIAP) { - buf.sendParcel = function() { - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), fileId); - - // pathId. - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - - // p1. - equal(this.readInt32(), recordNumber); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - for (let i = 0; i < recordSize; i++) { - equal(expectedIAP[i], pduHelper.readHexOctet()); - } - this.readStringDelimiter(strLen); - - // pin2. - equal(this.readString(), null); - - // AID. Ignore because it's from modem. - this.readInt32(); - - run_next_test(); - }; - recordHelper.updateIAP(fileId, recordNumber, expectedIAP); - } - - do_test([1, 2]); -}); - -/** - * Verify ICCRecordHelper.readADNLike. - */ -add_test(function test_read_adn_like() { - const RECORD_SIZE = 0x20; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let ril = context.RIL; - - function do_test(extFileId, rawEF, expectedExtRecordNumber, expectedNumber) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(rawEF.length * 2); - - // Write adn - for (let i = 0; i < rawEF.length; i += 2) { - helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16)); - } - - // Write string delimiter - buf.writeStringDelimiter(rawEF.length * 2); - - options.p1 = 1; - options.recordSize = RECORD_SIZE; - options.totalRecords = 1; - if (options.callback) { - options.callback(options); - } - }; - - record.readExtension = function(fileId, recordNumber, onsuccess, onerror) { - onsuccess("1234"); - } - - let successCb = function successCb(contacts) { - ok(contacts[0].number == expectedNumber); - }; - - let errorCb = function errorCb(errorMsg) { - do_print("Reading ADNLike failed, msg = " + errorMsg); - ok(false); - }; - - record.readADNLike(ICC_EF_ADN, extFileId, successCb, errorCb); - } - - ril.appType = CARD_APPTYPE_SIM; - // Valid extension - do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01", - 0x01,"998877665544332211001234"); - // Empty extension - do_test(ICC_EF_EXT1,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff", - 0xff, "99887766554433221100"); - // Unsupport extension - do_test(null,"436f6e74616374303031ffffffffffffffff0b8199887766554433221100ffff", - 0xff, "99887766554433221100"); - // Empty dialling number contact - do_test(null,"436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff", - 0xff, ""); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.updateADNLike. - */ -add_test(function test_update_adn_like() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let record = context.ICCRecordHelper; - let io = context.ICCIOHelper; - let pdu = context.ICCPDUHelper; - let buf = context.Buf; - - ril.appType = CARD_APPTYPE_SIM; - const recordSize = 0x20; - let fileId; - - // Override. - io.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - buf.sendParcel = function() { - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), fileId); - - // pathId. - equal(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM); - - // p1. - equal(this.readInt32(), 1); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), 0x20); - - // data. - let contact = pdu.readAlphaIdDiallingNumber(0x20); - equal(contact.alphaId, "test"); - equal(contact.number, "123456"); - equal(contact.extRecordNumber, "0xff"); - - // pin2. - if (fileId == ICC_EF_ADN) { - equal(this.readString(), null); - } else { - equal(this.readString(), "1111"); - } - - // AID. Ignore because it's from modem. - this.readInt32(); - - if (fileId == ICC_EF_FDN) { - run_next_test(); - } - }; - - fileId = ICC_EF_ADN; - record.updateADNLike(fileId, 0xff, - {recordId: 1, alphaId: "test", number: "123456"}); - - fileId = ICC_EF_FDN; - record.updateADNLike(fileId, 0xff, - {recordId: 1, alphaId: "test", number: "123456"}, - "1111"); -}); - -/** - * Verify ICCRecordHelper.findFreeRecordId. - */ -add_test(function test_find_free_record_id() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let ril = context.RIL; - - function writeRecord(record) { - // Write data size - buf.writeInt32(record.length * 2); - - for (let i = 0; i < record.length; i++) { - pduHelper.writeHexOctet(record[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(record.length * 2); - } - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Some random data. - let record = [0x12, 0x34, 0x56, 0x78, 0x90]; - options.p1 = 1; - options.totalRecords = 2; - writeRecord(record); - if (options.callback) { - options.callback(options); - } - }; - - ril.iccIO = function fakeIccIO(options) { - // Unused bytes. - let record = [0xff, 0xff, 0xff, 0xff, 0xff]; - writeRecord(record); - if (options.callback) { - options.callback(options); - } - }; - - let fileId = 0x0000; // Dummy. - recordHelper.findFreeRecordId( - fileId, - function(recordId) { - equal(recordId, 2); - run_next_test(); - }.bind(this), - function(errorMsg) { - do_print(errorMsg); - ok(false); - run_next_test(); - }.bind(this)); -}); - -/** - * Verify ICCRecordHelper.fetchICCRecords. - */ -add_test(function test_fetch_icc_recodes() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let iccRecord = context.ICCRecordHelper; - let simRecord = context.SimRecordHelper; - let ruimRecord = context.RuimRecordHelper; - let fetchTag = 0x00; - - simRecord.fetchSimRecords = function() { - fetchTag = 0x01; - }; - - ruimRecord.fetchRuimRecords = function() { - fetchTag = 0x02; - }; - - RIL.appType = CARD_APPTYPE_SIM; - iccRecord.fetchICCRecords(); - equal(fetchTag, 0x01); - - RIL.appType = CARD_APPTYPE_RUIM; - iccRecord.fetchICCRecords(); - equal(fetchTag, 0x02); - - RIL.appType = CARD_APPTYPE_USIM; - iccRecord.fetchICCRecords(); - equal(fetchTag, 0x01); - - run_next_test(); -}); - -/** - * Verify reading EF_ICCID. - */ -add_test(function test_handling_iccid() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.ICCRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - ril.reportStkServiceIsRunning = function fakeReportStkServiceIsRunning() { - }; - - function do_test(rawICCID, expectedICCID) { - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(rawICCID.length); - - // Write data - for (let i = 0; i < rawICCID.length; i += 2) { - helper.writeHexOctet(parseInt(rawICCID.substr(i, 2), 16)); - } - - // Write string delimiter - buf.writeStringDelimiter(rawICCID.length); - - if (options.callback) { - options.callback(options); - } - }; - - record.readICCID(); - - equal(ril.iccInfo.iccid, expectedICCID); - } - - // Invalid value 0xE at high nibbile + low nibbile contains 0xF. - do_test("9868002E90909F001519", "89860020909"); - // Invalid value 0xD at low nibbile. - do_test("986800D2909090001519", "8986002090909005191"); - // Invalid value 0xC at low nibbile. - do_test("986800C2909090001519", "8986002090909005191"); - // Invalid value 0xB at low nibbile. - do_test("986800B2909090001519", "8986002090909005191"); - // Invalid value 0xA at low nibbile. - do_test("986800A2909090001519", "8986002090909005191"); - // Valid ICCID. - do_test("98101430121181157002", "89014103211118510720"); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.readExtension - */ -add_test(function test_read_extension() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function do_test(rawExtension, expectedExtensionNumber) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(rawExtension.length * 2); - - // Write ext - for (let i = 0; i < rawExtension.length; i += 2) { - helper.writeHexOctet(parseInt(rawExtension.substr(i, 2), 16)); - } - - // Write string delimiter - buf.writeStringDelimiter(rawExtension.length); - - if (options.callback) { - options.callback(options); - } - }; - - let successCb = function successCb(number) { - do_print("extension number:" + number); - equal(number, expectedExtensionNumber); - }; - - let errorCb = function errorCb() { - ok(expectedExtensionNumber == null); - }; - - record.readExtension(0x6f4a, 1, successCb, errorCb); - } - - // Test unsupported record type 0x01 - do_test("010a10325476981032547698ff", ""); - // Test invalid length 0xc1 - do_test("020c10325476981032547698ff", null); - // Test extension chain which we don't support - do_test("020a1032547698103254769802", "01234567890123456789"); - // Test valid Extension - do_test("020a10325476981032547698ff", "01234567890123456789"); - // Test valid Extension - do_test("0209103254769810325476ffff", "012345678901234567"); - // Test empty Extension - do_test("02ffffffffffffffffffffffff", ""); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.updateExtension - */ -add_test(function test_update_extension() { - const RECORD_SIZE = 13; - const RECORD_NUMBER = 1; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = RECORD_SIZE; - ril.iccIO(options); - }; - - function do_test(fileId, number, expectedNumber) { - buf.sendParcel = function() { - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), fileId); - - // pathId. - if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) { - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM); - } else{ - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - } - - // p1. - equal(this.readInt32(), RECORD_NUMBER); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), RECORD_SIZE); - - // data. - let strLen = this.readInt32(); - // Extension record - let recordType = pduHelper.readHexOctet(); - - equal(recordType, 0x02); - equal(pduHelper.readHexOctet(), 10); - equal( - pduHelper.readSwappedNibbleExtendedBcdString(EXT_MAX_NUMBER_DIGITS - 1), - expectedNumber); - - this.readStringDelimiter(strLen); - - // pin2. - equal(this.readString(), null); - - // AID. Ignore because it's from modem. - this.readInt32(); - }; - - recordHelper.updateExtension(fileId, RECORD_NUMBER, number); - } - - ril.appType = CARD_APPTYPE_SIM; - do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789"); - // We don't support extension chain. - do_test(ICC_EF_EXT1, "012345678901234567891234", "01234567890123456789"); - - ril.appType = CARD_APPTYPE_USIM; - do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789"); - - ril.appType = CARD_APPTYPE_RUIM; - do_test(ICC_EF_EXT1, "01234567890123456789", "01234567890123456789"); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.cleanEFRecord - */ -add_test(function test_clean_ef_record() { - const RECORD_SIZE = 13; - const RECORD_NUMBER = 1; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - let recordHelper = context.ICCRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - - // Override. - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = RECORD_SIZE; - ril.iccIO(options); - }; - - function do_test(fileId) { - buf.sendParcel = function() { - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), fileId); - - // pathId. - if (ril.appType == CARD_APPTYPE_SIM || ril.appType == CARD_APPTYPE_RUIM) { - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM); - } else{ - equal(this.readString(), - EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK); - } - - // p1. - equal(this.readInt32(), RECORD_NUMBER); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), RECORD_SIZE); - - // data. - let strLen = this.readInt32(); - // Extension record - for (let i = 0; i < RECORD_SIZE; i++) { - equal(pduHelper.readHexOctet(), 0xff); - } - - this.readStringDelimiter(strLen); - - // pin2. - equal(this.readString(), null); - - // AID. Ignore because it's from modem. - this.readInt32(); - }; - - recordHelper.cleanEFRecord(fileId, RECORD_NUMBER); - } - - ril.appType = CARD_APPTYPE_SIM; - do_test(ICC_EF_EXT1); - - run_next_test(); -}); - -/** - * Verify ICCRecordHelper.getADNLikeExtensionRecordNumber - */ -add_test(function test_get_adn_like_extension_record_number() { - const RECORD_SIZE = 0x20; - - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let record = context.ICCRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function do_test(rawEF, expectedRecordNumber) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(rawEF.length * 2); - - // Write ext - for (let i = 0; i < rawEF.length; i += 2) { - helper.writeHexOctet(parseInt(rawEF.substr(i, 2), 16)); - } - - // Write string delimiter - buf.writeStringDelimiter(rawEF.length); - options.recordSize = RECORD_SIZE; - if (options.callback) { - options.callback(options); - } - }; - - let isSuccess = false; - let successCb = function successCb(number) { - equal(number, expectedRecordNumber); - isSuccess = true; - }; - - let errorCb = function errorCb(errorMsg) { - do_print("Reading ADNLike failed, msg = " + errorMsg); - ok(false); - }; - - record.getADNLikeExtensionRecordNumber(ICC_EF_ADN, 1, successCb, errorCb); - ok(isSuccess); - } - - // Valid Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001", - // Dialling Number: 99887766554433221100, Ext1: 0x01 - do_test("436f6e74616374303031ffffffffffffffff0b8199887766554433221100ff01", 0x01); - // Empty Extension, Alpha Id(Encoded with GSM 8 bit): "Contact001", Ext1: 0xff - do_test("436f6e74616374303031ffffffffffffffffffffffffffffffffffffffffffff", 0xff); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js deleted file mode 100644 index b23d0b598..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_ICCUtilsHelper.js +++ /dev/null @@ -1,326 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify ICCUtilsHelper.isICCServiceAvailable. - */ -add_test(function test_is_icc_service_available() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ICCUtilsHelper = context.ICCUtilsHelper; - let RIL = context.RIL; - - function test_table(sst, geckoService, simEnabled, usimEnabled) { - RIL.iccInfoPrivate.sst = sst; - RIL.appType = CARD_APPTYPE_SIM; - equal(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled); - RIL.appType = CARD_APPTYPE_USIM; - equal(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled); - } - - test_table([0x08], "ADN", true, false); - test_table([0x08], "FDN", false, false); - test_table([0x08], "SDN", false, true); - - run_next_test(); -}); - -/** - * Verify ICCUtilsHelper.isGsm8BitAlphabet - */ -add_test(function test_is_gsm_8bit_alphabet() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ICCUtilsHelper = context.ICCUtilsHelper; - const langTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - const langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - - equal(ICCUtilsHelper.isGsm8BitAlphabet(langTable), true); - equal(ICCUtilsHelper.isGsm8BitAlphabet(langShiftTable), true); - equal(ICCUtilsHelper.isGsm8BitAlphabet("\uaaaa"), false); - - run_next_test(); -}); - -/** - * Verify ICCUtilsHelper.parsePbrTlvs - */ -add_test(function test_parse_pbr_tlvs() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - - let pbrTlvs = [ - {tag: ICC_USIM_TYPE1_TAG, - length: 0x0F, - value: [{tag: ICC_USIM_EFADN_TAG, - length: 0x03, - value: [0x4F, 0x3A, 0x02]}, - {tag: ICC_USIM_EFIAP_TAG, - length: 0x03, - value: [0x4F, 0x25, 0x01]}, - {tag: ICC_USIM_EFPBC_TAG, - length: 0x03, - value: [0x4F, 0x09, 0x04]}] - }, - {tag: ICC_USIM_TYPE2_TAG, - length: 0x05, - value: [{tag: ICC_USIM_EFEMAIL_TAG, - length: 0x03, - value: [0x4F, 0x50, 0x0B]}, - {tag: ICC_USIM_EFANR_TAG, - length: 0x03, - value: [0x4F, 0x11, 0x02]}, - {tag: ICC_USIM_EFANR_TAG, - length: 0x03, - value: [0x4F, 0x12, 0x03]}] - }, - {tag: ICC_USIM_TYPE3_TAG, - length: 0x0A, - value: [{tag: ICC_USIM_EFCCP1_TAG, - length: 0x03, - value: [0x4F, 0x3D, 0x0A]}, - {tag: ICC_USIM_EFEXT1_TAG, - length: 0x03, - value: [0x4F, 0x4A, 0x03]}] - }, - ]; - - let pbr = context.ICCUtilsHelper.parsePbrTlvs(pbrTlvs); - equal(pbr.adn.fileId, 0x4F3a); - equal(pbr.iap.fileId, 0x4F25); - equal(pbr.pbc.fileId, 0x4F09); - equal(pbr.email.fileId, 0x4F50); - equal(pbr.anr0.fileId, 0x4f11); - equal(pbr.anr1.fileId, 0x4f12); - equal(pbr.ccp1.fileId, 0x4F3D); - equal(pbr.ext1.fileId, 0x4F4A); - - run_next_test(); -}); - -/** - * Verify MCC and MNC parsing - */ -add_test(function test_mcc_mnc_parsing() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.ICCUtilsHelper; - - function do_test(imsi, mncLength, expectedMcc, expectedMnc) { - let result = helper.parseMccMncFromImsi(imsi, mncLength); - - if (!imsi) { - equal(result, null); - return; - } - - equal(result.mcc, expectedMcc); - equal(result.mnc, expectedMnc); - } - - // Test the imsi is null. - do_test(null, null, null, null); - - // Test MCC is Taiwan - do_test("466923202422409", 0x02, "466", "92"); - do_test("466923202422409", 0x03, "466", "923"); - do_test("466923202422409", null, "466", "92"); - - // Test MCC is US - do_test("310260542718417", 0x02, "310", "26"); - do_test("310260542718417", 0x03, "310", "260"); - do_test("310260542718417", null, "310", "260"); - - run_next_test(); -}); - -add_test(function test_get_network_name_from_icc() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ICCUtilsHelper = context.ICCUtilsHelper; - - function testGetNetworkNameFromICC(operatorData, expectedResult) { - let result = ICCUtilsHelper.getNetworkNameFromICC(operatorData.mcc, - operatorData.mnc, - operatorData.lac); - - if (expectedResult == null) { - equal(result, expectedResult); - } else { - equal(result.fullName, expectedResult.longName); - equal(result.shortName, expectedResult.shortName); - } - } - - // Before EF_OPL and EF_PNN have been loaded. - testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000}, null); - testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x2000}, null); - - // Set HPLMN - RIL.iccInfo.mcc = "123"; - RIL.iccInfo.mnc = "456"; - - RIL.voiceRegistrationState = { - cell: { - gsmLocationAreaCode: 0x1000 - } - }; - RIL.operator = {}; - - // Set EF_PNN - RIL.iccInfoPrivate = { - PNN: [ - {"fullName": "PNN1Long", "shortName": "PNN1Short"}, - {"fullName": "PNN2Long", "shortName": "PNN2Short"}, - {"fullName": "PNN3Long", "shortName": "PNN3Short"}, - {"fullName": "PNN4Long", "shortName": "PNN4Short"}, - {"fullName": "PNN5Long", "shortName": "PNN5Short"}, - {"fullName": "PNN6Long", "shortName": "PNN6Short"}, - {"fullName": "PNN7Long", "shortName": "PNN7Short"}, - {"fullName": "PNN8Long", "shortName": "PNN8Short"} - ] - }; - - // EF_OPL isn't available - ICCUtilsHelper.isICCServiceAvailable = function fakeIsICCServiceAvailable(service) { - return false; - }; - - // EF_OPL isn't available and current isn't in HPLMN, - testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x1000}, null); - - // EF_OPL isn't available and current is in HPLMN, - // the first record of PNN should be returned. - testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000}, - {longName: "PNN1Long", shortName: "PNN1Short"}); - - // EF_OPL is available - ICCUtilsHelper.isICCServiceAvailable = function fakeIsICCServiceAvailable(service) { - return service === "OPL"; - }; - - // Set EF_OPL - RIL.iccInfoPrivate.OPL = [ - { - "mcc": "123", - "mnc": "456", - "lacTacStart": 0, - "lacTacEnd": 0xFFFE, - "pnnRecordId": 4 - }, - { - "mcc": "321", - "mnc": "654", - "lacTacStart": 0, - "lacTacEnd": 0x0010, - "pnnRecordId": 3 - }, - { - "mcc": "321", - "mnc": "654", - "lacTacStart": 0x0100, - "lacTacEnd": 0x1010, - "pnnRecordId": 2 - }, - { - "mcc": ";;;", - "mnc": "01", - "lacTacStart": 0, - "lacTacEnd": 0xFFFE, - "pnnRecordId": 5 - }, - { - "mcc": "00;", - "mnc": "02", - "lacTacStart": 0, - "lacTacEnd": 0xFFFE, - "pnnRecordId": 6 - }, - { - "mcc": "001", - "mnc": ";;", - "lacTacStart": 0, - "lacTacEnd": 0xFFFE, - "pnnRecordId": 7 - }, - { - "mcc": "002", - "mnc": "0;", - "lacTacStart": 0, - "lacTacEnd": 0xFFFE, - "pnnRecordId": 8 - } - ]; - - // Both EF_PNN and EF_OPL are presented, and current PLMN is HPLMN, - testGetNetworkNameFromICC({mcc: "123", mnc: "456", lac: 0x1000}, - {longName: "PNN4Long", shortName: "PNN4Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the second PNN record. - testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x1000}, - {longName: "PNN2Long", shortName: "PNN2Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the thrid PNN record. - testGetNetworkNameFromICC({mcc: "321", mnc: "654", lac: 0x0001}, - {longName: "PNN3Long", shortName: "PNN3Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the 5th PNN record after wild char (ie: ';') handling. - testGetNetworkNameFromICC({mcc: "001", mnc: "01", lac: 0x0001}, - {longName: "PNN5Long", shortName: "PNN5Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the 6th PNN record after wild char (ie: ';') handling. - testGetNetworkNameFromICC({mcc: "001", mnc: "02", lac: 0x0001}, - {longName: "PNN6Long", shortName: "PNN6Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the 7th PNN record after wild char (ie: ';') handling. - testGetNetworkNameFromICC({mcc: "001", mnc: "03", lac: 0x0001}, - {longName: "PNN7Long", shortName: "PNN7Short"}); - - // Current PLMN is not HPLMN, and according to LAC, we should get - // the 8th PNN record after wild char (ie: ';') handling. - testGetNetworkNameFromICC({mcc: "002", mnc: "03", lac: 0x0001}, - {longName: "PNN8Long", shortName: "PNN8Short"}); - - run_next_test(); -}); - -/** - * Verify ICCUtilsHelper.isCphsServiceAvailable. - */ -add_test(function test_is_cphs_service_available() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ICCUtilsHelper = context.ICCUtilsHelper; - let RIL = context.RIL; - RIL.iccInfoPrivate.cphsSt = new Uint8Array(2); - - function test_table(cphsSt, geckoService) { - RIL.iccInfoPrivate.cphsSt.set(cphsSt); - - for (let service in GECKO_ICC_SERVICES.cphs) { - equal(ICCUtilsHelper.isCphsServiceAvailable(service), - geckoService == service); - } - } - - test_table([0x03, 0x00], "CSP"); - test_table([0x0C, 0x00], "SST"); - test_table([0x30, 0x00], "MBN"); - test_table([0xC0, 0x00], "ONSF"); - test_table([0x00, 0x03], "INFO_NUM"); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js b/dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js deleted file mode 100644 index 8bcd26ffe..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_IconLoader.js +++ /dev/null @@ -1,771 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify IconLoader.loadIcons with recordNumbers array length being 1. - * Query images of one record at a time. - */ -add_test(function test_load_icon_basic() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let iconLoader = context.IconLoader; - let simRecordHelper = context.SimRecordHelper; - - let test_data = [ - {rawData: [ - {codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - width: 0x10, - height: 0x10, - body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b, - 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0xff, 0xff]}], - expected: [ - {width: 0x10, - height: 0x10, - pixels: [/* 1st byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 2nd byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 3rd byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 4th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 5th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 6th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 7th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 8th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 9th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 10th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 11th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 12th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 13th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 14th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 15th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 16th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 17th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 18th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 19th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 20th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 21th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 22th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 23th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 24th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 25th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 26th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 27th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 28th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 29th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 30th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 31th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 32th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff]}]}, - {rawData: [ - {codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - width: 0x10, - height: 0x10, - bitsPerImgPoint: 0x04, - numOfClutEntries: 0x10, - body: [0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xcf, 0xfc, 0xcc, 0xfc, 0xcc, - 0xcf, 0xcf, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, - 0xcc, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcc, - 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, - 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, 0xcf, - 0xfc, 0xcc, 0xfc, 0xcc, 0xcf, 0xcf, 0xfc, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99], - clut: [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, - 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, - 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff]}], - expected: [ - {width: 0x10, - height: 0x10, - pixels: [0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, - 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff]}]}, - {rawData: [ - {codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - width: 0x03, - height: 0x03, - bitsPerImgPoint: 0x05, - numOfClutEntries: 0x20, - body: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, - 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f]}, - {codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - width: 0x10, - height: 0x10, - body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b, - 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0xff, 0xff]}], - expected: [ - {width: 0x03, - height: 0x03, - pixels: [0x000102ff, 0x060708ff, 0x0c0d0eff, 0x121314ff, 0x18191aff, - 0x1e1f20ff, 0x242526ff, 0x2a2b2cff, 0x333435ff]}, - {width: 0x10, - height: 0x10, - pixels: [/* 1st byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 2nd byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 3rd byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 4th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 5th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 6th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 7th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 8th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 9th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 10th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 11th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 12th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 13th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 14th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 15th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 16th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 17th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 18th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 19th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 20th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 21th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 22th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 23th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 24th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 25th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 26th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 27th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 28th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 29th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 30th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 31th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 32th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff]}]}, - {rawData: [ - {codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, - width: 0x04, - height: 0x04, - bitsPerImgPoint: 0x04, - numOfClutEntries: 0x10, - body: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88], - clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, - 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f]}], - expected: [ - {width: 0x04, - height: 0x04, - pixels: [0x00000000, 0x00000000, 0x2a2b2cff, 0x2a2b2cff, 0x272829ff, - 0x272829ff, 0x242526ff, 0x242526ff, 0x212223ff, 0x212223ff, - 0x1e1f20ff, 0x1e1f20ff, 0x1b1c1dff, 0x1b1c1dff, 0x18191aff, - 0x18191aff]}]}]; - - function do_test(test_data, expected) { - simRecordHelper.readIMG = function fakeReadIMG(recordNumber, onsuccess, onerror) { - onsuccess(test_data); - }; - - let onsuccess = function(icons) { - // Query one record at a time. - equal(icons.length, 1); - equal(icons[0].length, expected.length); - for (let i = 0; i < icons[0].length; i++) { - // Read the i_th image of the record. - let icon = icons[0][i]; - let exp = expected[i]; - equal(icon.width, exp.width); - equal(icon.height, exp.height); - equal(icon.pixels.length, exp.pixels.length); - for (let j = 0; j < icon.pixels.length; j++) { - equal(icon.pixels[j], exp.pixels[j]); - } - } - }; - - iconLoader.loadIcons([0], onsuccess); - } - - for (let i = 0; i < test_data.length; i++) { - do_test(test_data[i].rawData, test_data[i].expected); - } - - run_next_test(); -}); - -/** - * Verify IconLoader.loadIcons. - */ -add_test(function test_load_icons() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let iconLoader = context.IconLoader; - let simRecordHelper = context.SimRecordHelper; - - let test_data = { - rawData: [ - // Record 1. - [{codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - width: 0x10, - height: 0x10, - body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b, - 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0xff, 0xff]}], - // Record 2. - [{codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - width: 0x10, - height: 0x10, - bitsPerImgPoint: 0x04, - numOfClutEntries: 0x10, - body: [0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xcf, 0xfc, 0xcc, 0xfc, 0xcc, - 0xcf, 0xcf, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, - 0xcc, 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcc, - 0xfc, 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, - 0xcf, 0xcf, 0xff, 0xfc, 0xff, 0xcf, 0xcf, 0xcc, 0xcf, - 0xfc, 0xcc, 0xfc, 0xcc, 0xcf, 0xcf, 0xfc, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99], - clut: [0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, - 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, - 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff]}], - // Record 3. - [{codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - width: 0x03, - height: 0x03, - bitsPerImgPoint: 0x05, - numOfClutEntries: 0x20, - body: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, - 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f]}, - {codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - width: 0x10, - height: 0x10, - body: [0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x9d, 0xe9, 0xa1, 0x2d, 0xa1, 0x2d, 0xa1, 0x2b, - 0xa1, 0x2b, 0x9d, 0xe9, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0xff, 0xff]}], - // Record 4. - [{codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, - width: 0x04, - height: 0x04, - bitsPerImgPoint: 0x04, - numOfClutEntries: 0x10, - body: [0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88], - clut: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, - 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, - 0x2d, 0x2e, 0x2f]}]], - expected: [ - // Record 1. - [{width: 0x10, - height: 0x10, - pixels: [/* 1st byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 2nd byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 3rd byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 4th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 5th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 6th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 7th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 8th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 9th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 10th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 11th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 12th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 13th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 14th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 15th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 16th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 17th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 18th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 19th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 20th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 21th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 22th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 23th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 24th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 25th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 26th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 27th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 28th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 29th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 30th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 31th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 32th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff]}], - // Record 2. - [{width: 0x10, - height: 0x10, - pixels: [0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, 0x0000ffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0000ffff, - 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, - 0xffffffff, 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, - 0x0000ffff, 0xffffffff, 0x0000ffff, 0xffffffff, 0xffffffff, - 0x0000ffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, - 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, 0xff0000ff, - 0xff0000ff]}], - // Record 3. - [{width: 0x03, - height: 0x03, - pixels: [0x000102ff, 0x060708ff, 0x0c0d0eff, 0x121314ff, 0x18191aff, - 0x1e1f20ff, 0x242526ff, 0x2a2b2cff, 0x333435ff]}, - {width: 0x10, - height: 0x10, - pixels: [/* 1st byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 2nd byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 3rd byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 4th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 5th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 6th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 7th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 8th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 9th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 10th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 11th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 12th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 13th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 14th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 15th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 16th byte of body: 0x2d */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 17th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 18th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 19th byte of body: 0xa1 */ - 0xffffffff, 0x000000ff, 0xffffffff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 20th byte of body: 0x2b */ - 0x000000ff, 0x000000ff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0xffffffff, 0xffffffff, - /* 21th byte of body: 0x9d */ - 0xffffffff, 0x000000ff, 0x000000ff, 0xffffffff, 0xffffffff, - 0xffffffff, 0x000000ff, 0xffffffff, - /* 22th byte of body: 0xe9 */ - 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0xffffffff, - 0x000000ff, 0x000000ff, 0xffffffff, - /* 23th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 24th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 25th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 26th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 27th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 28th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 29th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 30th byte of body: 0x00 */ - 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, - 0x000000ff, 0x000000ff, 0x000000ff, - /* 31th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, - /* 32th byte of body: 0xff */ - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff]}], - // Record 4. - [{width: 0x04, - height: 0x04, - pixels: [0x00000000, 0x00000000, 0x2a2b2cff, 0x2a2b2cff, 0x272829ff, - 0x272829ff, 0x242526ff, 0x242526ff, 0x212223ff, 0x212223ff, - 0x1e1f20ff, 0x1e1f20ff, 0x1b1c1dff, 0x1b1c1dff, 0x18191aff, - 0x18191aff]}]]}; - - function do_test() { - simRecordHelper.readIMG = function fakeReadIMG(recordNumber, onsuccess, onerror) { - onsuccess(test_data.rawData[recordNumber]); - }; - - let onsuccess = function(icons) { - equal(icons.length, test_data.expected.length); - for (let i = 0; i < icons.length; i++) { - for (let j = 0; j < icons[i].length; j++) { - // Read the j_th image from the i_th record. - let icon = icons[i][j]; - let expected = test_data.expected[i][j]; - equal(icon.width, expected.width); - equal(icon.height, expected.height); - equal(icon.pixels.length, expected.pixels.length); - for (let k = 0; k < icon.pixels.length; k++) { - equal(icon.pixels[k], expected.pixels[k]); - } - } - } - }; - - let recordNumbers = [0, 1, 2, 3]; - iconLoader.loadIcons(recordNumbers, onsuccess); - } - - do_test(); - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js b/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js deleted file mode 100644 index 6500cc663..000000000 --- a/dom/system/gonk/tests/test_ril_worker_icc_SimRecordHelper.js +++ /dev/null @@ -1,1648 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify reading EF_AD and parsing MCC/MNC - */ -add_test(function test_reading_ad_and_parsing_mcc_mnc() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function do_test(mncLengthInEf, imsi, expectedMcc, expectedMnc) { - ril.iccInfoPrivate.imsi = imsi; - - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - let ad = [0x00, 0x00, 0x00]; - if (typeof mncLengthInEf === 'number') { - ad.push(mncLengthInEf); - } - - // Write data size - buf.writeInt32(ad.length * 2); - - // Write data - for (let i = 0; i < ad.length; i++) { - helper.writeHexOctet(ad[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(ad.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - record.readAD(); - - equal(ril.iccInfo.mcc, expectedMcc); - equal(ril.iccInfo.mnc, expectedMnc); - } - - do_test(undefined, "466923202422409", "466", "92" ); - do_test(0x00, "466923202422409", "466", "92" ); - do_test(0x01, "466923202422409", "466", "92" ); - do_test(0x02, "466923202422409", "466", "92" ); - do_test(0x03, "466923202422409", "466", "923"); - do_test(0x04, "466923202422409", "466", "92" ); - do_test(0xff, "466923202422409", "466", "92" ); - - do_test(undefined, "310260542718417", "310", "260"); - do_test(0x00, "310260542718417", "310", "260"); - do_test(0x01, "310260542718417", "310", "260"); - do_test(0x02, "310260542718417", "310", "26" ); - do_test(0x03, "310260542718417", "310", "260"); - do_test(0x04, "310260542718417", "310", "260"); - do_test(0xff, "310260542718417", "310", "260"); - - run_next_test(); -}); - -add_test(function test_reading_optional_efs() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let gsmPdu = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function buildSST(supportedEf) { - let sst = []; - let len = supportedEf.length; - for (let i = 0; i < len; i++) { - let index, bitmask, iccService; - if (ril.appType === CARD_APPTYPE_SIM) { - iccService = GECKO_ICC_SERVICES.sim[supportedEf[i]]; - iccService -= 1; - index = Math.floor(iccService / 4); - bitmask = 2 << ((iccService % 4) << 1); - } else if (ril.appType === CARD_APPTYPE_USIM){ - iccService = GECKO_ICC_SERVICES.usim[supportedEf[i]]; - iccService -= 1; - index = Math.floor(iccService / 8); - bitmask = 1 << ((iccService % 8) << 0); - } - - if (sst) { - sst[index] |= bitmask; - } - } - return sst; - } - - ril.updateCellBroadcastConfig = function fakeUpdateCellBroadcastConfig() { - // Ignore updateCellBroadcastConfig after reading SST - }; - - function do_test(sst, supportedEf) { - // Clone supportedEf to local array for testing - let testEf = supportedEf.slice(0); - - record.readMSISDN = function fakeReadMSISDN() { - testEf.splice(testEf.indexOf("MSISDN"), 1); - }; - - record.readMBDN = function fakeReadMBDN() { - testEf.splice(testEf.indexOf("MDN"), 1); - }; - - record.readMWIS = function fakeReadMWIS() { - testEf.splice(testEf.indexOf("MWIS"), 1); - }; - - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(sst.length * 2); - - // Write data - for (let i = 0; i < sst.length; i++) { - gsmPdu.writeHexOctet(sst[i] || 0); - } - - // Write string delimiter - buf.writeStringDelimiter(sst.length * 2); - - if (options.callback) { - options.callback(options); - } - - if (testEf.length !== 0) { - do_print("Un-handled EF: " + JSON.stringify(testEf)); - ok(false); - } - }; - - record.readSST(); - } - - // TODO: Add all necessary optional EFs eventually - let supportedEf = ["MSISDN", "MDN", "MWIS"]; - ril.appType = CARD_APPTYPE_SIM; - do_test(buildSST(supportedEf), supportedEf); - ril.appType = CARD_APPTYPE_USIM; - do_test(buildSST(supportedEf), supportedEf); - - run_next_test(); -}); - -/** - * Verify fetchSimRecords. - */ -add_test(function test_fetch_sim_records() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let iccRecord = context.ICCRecordHelper; - let simRecord = context.SimRecordHelper; - - function testFetchSimRecordes(expectCalled, expectCphsSuccess) { - let ifCalled = []; - - RIL.getIMSI = function() { - ifCalled.push("getIMSI"); - }; - - simRecord.readAD = function() { - ifCalled.push("readAD"); - }; - - simRecord.readCphsInfo = function(onsuccess, onerror) { - ifCalled.push("readCphsInfo"); - if (expectCphsSuccess) { - onsuccess(); - } else { - onerror(); - } - }; - - simRecord.readSST = function() { - ifCalled.push("readSST"); - }; - - simRecord.fetchSimRecords(); - - for (let i = 0; i < expectCalled.length; i++ ) { - if (ifCalled[i] != expectCalled[i]) { - do_print(expectCalled[i] + " is not called."); - ok(false); - } - } - } - - let expectCalled = ["getIMSI", "readAD", "readCphsInfo", "readSST"]; - testFetchSimRecordes(expectCalled, true); - testFetchSimRecordes(expectCalled, false); - - run_next_test(); -}); - -/** - * Verify SimRecordHelper.readMWIS - */ -add_test(function test_read_mwis() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let recordHelper = context.SimRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let mwisData; - let postedMessage; - - worker.postMessage = function fakePostMessage(message) { - postedMessage = message; - }; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - if (mwisData) { - // Write data size - buf.writeInt32(mwisData.length * 2); - - // Write MWIS - for (let i = 0; i < mwisData.length; i++) { - helper.writeHexOctet(mwisData[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(mwisData.length * 2); - - options.recordSize = mwisData.length; - if (options.callback) { - options.callback(options); - } - } else { - do_print("mwisData[] is not set."); - } - }; - - function buildMwisData(isActive, msgCount) { - if (msgCount < 0 || msgCount === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) { - msgCount = 0; - } else if (msgCount > 255) { - msgCount = 255; - } - - mwisData = [ (isActive) ? 0x01 : 0x00, - msgCount, - 0xFF, 0xFF, 0xFF ]; - } - - function do_test(isActive, msgCount) { - buildMwisData(isActive, msgCount); - recordHelper.readMWIS(); - - equal("iccmwis", postedMessage.rilMessageType); - equal(isActive, postedMessage.mwi.active); - equal((isActive) ? msgCount : 0, postedMessage.mwi.msgCount); - } - - do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); - do_test(true, 1); - do_test(true, 255); - - do_test(false, 0); - do_test(false, 255); // Test the corner case when mwi is disable with incorrect msgCount. - - run_next_test(); -}); - -/** - * Verify SimRecordHelper.updateMWIS - */ -add_test(function test_update_mwis() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - ril.appType = CARD_APPTYPE_USIM; - ril.iccInfoPrivate.mwis = [0x00, 0x00, 0x00, 0x00, 0x00]; - let recordHelper = context.SimRecordHelper; - let buf = context.Buf; - let ioHelper = context.ICCIOHelper; - let recordSize = ril.iccInfoPrivate.mwis.length; - let recordNum = 1; - - ioHelper.updateLinearFixedEF = function(options) { - options.pathId = context.ICCFileHelper.getEFPath(options.fileId); - options.command = ICC_COMMAND_UPDATE_RECORD; - options.p1 = options.recordNumber; - options.p2 = READ_RECORD_ABSOLUTE_MODE; - options.p3 = recordSize; - ril.iccIO(options); - }; - - function do_test(isActive, count) { - let mwis = ril.iccInfoPrivate.mwis; - let isUpdated = false; - - function buildMwisData() { - let result = mwis.slice(0); - result[0] = isActive? (mwis[0] | 0x01) : (mwis[0] & 0xFE); - result[1] = (count === GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN) ? 0 : count; - - return result; - } - - buf.sendParcel = function() { - isUpdated = true; - - // Request Type. - equal(this.readInt32(), REQUEST_SIM_IO); - - // Token : we don't care - this.readInt32(); - - // command. - equal(this.readInt32(), ICC_COMMAND_UPDATE_RECORD); - - // fileId. - equal(this.readInt32(), ICC_EF_MWIS); - - // pathId. - equal(this.readString(), - EF_PATH_MF_SIM + ((ril.appType === CARD_APPTYPE_USIM) ? EF_PATH_ADF_USIM : EF_PATH_DF_GSM)); - - // p1. - equal(this.readInt32(), recordNum); - - // p2. - equal(this.readInt32(), READ_RECORD_ABSOLUTE_MODE); - - // p3. - equal(this.readInt32(), recordSize); - - // data. - let strLen = this.readInt32(); - equal(recordSize * 2, strLen); - let expectedMwis = buildMwisData(); - for (let i = 0; i < recordSize; i++) { - equal(expectedMwis[i], pduHelper.readHexOctet()); - } - this.readStringDelimiter(strLen); - - // pin2. - equal(this.readString(), null); - - // AID. Ignore because it's from modem. - this.readInt32(); - }; - - ok(!isUpdated); - - recordHelper.updateMWIS({ active: isActive, - msgCount: count }); - - ok((ril.iccInfoPrivate.mwis) ? isUpdated : !isUpdated); - } - - do_test(true, GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN); - do_test(true, 1); - do_test(true, 255); - - do_test(false, 0); - - // Test if Path ID is correct for SIM. - ril.appType = CARD_APPTYPE_SIM; - do_test(false, 0); - - // Test if loadLinearFixedEF() is not invoked in updateMWIS() when - // EF_MWIS is not loaded/available. - delete ril.iccInfoPrivate.mwis; - do_test(false, 0); - - run_next_test(); -}); - -/** - * Verify the call flow of receiving Class 2 SMS stored in SIM: - * 1. UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM. - * 2. SimRecordHelper.readSMS(). - * 3. sendChromeMessage() with rilMessageType == "sms-received". - */ -add_test(function test_read_new_sms_on_sim() { - // Instead of reusing newUint8Worker defined in this file, - // we define our own worker to fake the methods in WorkerBuffer dynamically. - function newSmsOnSimWorkerHelper() { - let _postedMessage; - let _worker = newWorker({ - postRILMessage: function(data) { - }, - postMessage: function(message) { - _postedMessage = message; - } - }); - - _worker.debug = do_print; - - return { - get postedMessage() { - return _postedMessage; - }, - get worker() { - return _worker; - }, - fakeWokerBuffer: function() { - let context = _worker.ContextPool._contexts[0]; - let index = 0; // index for read - let buf = []; - context.Buf.writeUint8 = function(value) { - buf.push(value); - }; - context.Buf.readUint8 = function() { - return buf[index++]; - }; - context.Buf.seekIncoming = function(offset) { - index += offset; - }; - context.Buf.getReadAvailable = function() { - return buf.length - index; - }; - } - }; - } - - let workerHelper = newSmsOnSimWorkerHelper(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.ICCIOHelper.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // SimStatus: Unread, SMSC:+0123456789, Sender: +9876543210, Text: How are you? - let SimSmsPduHex = "0306911032547698040A9189674523010000208062917314080CC8F71D14969741F977FD07" - // In 4.2.25 EF_SMS Short Messages of 3GPP TS 31.102: - // 1. Record length == 176 bytes. - // 2. Any bytes in the record following the TPDU shall be filled with 'FF'. - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"; - - workerHelper.fakeWokerBuffer(); - - context.Buf.writeString(SimSmsPduHex); - - options.recordSize = 176; // Record length is fixed to 176 bytes. - if (options.callback) { - options.callback(options); - } - }; - - function newSmsOnSimParcel() { - let data = new Uint8Array(4 + 4); // Int32List with 1 element. - let offset = 0; - - function writeInt(value) { - data[offset++] = value & 0xFF; - data[offset++] = (value >> 8) & 0xFF; - data[offset++] = (value >> 16) & 0xFF; - data[offset++] = (value >> 24) & 0xFF; - } - - writeInt(1); // Length of Int32List - writeInt(1); // RecordNum = 1. - - return newIncomingParcel(-1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_SMS_ON_SIM, - data); - } - - function do_test() { - worker.onRILMessage(0, newSmsOnSimParcel()); - - let postedMessage = workerHelper.postedMessage; - - equal("sms-received", postedMessage.rilMessageType); - equal("+0123456789", postedMessage.SMSC); - equal("+9876543210", postedMessage.sender); - equal("How are you?", postedMessage.body); - } - - do_test(); - - run_next_test(); -}); - -/** - * Verify the result of updateDisplayCondition after reading EF_SPDI | EF_SPN. - */ -add_test(function test_update_display_condition() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function do_test_spdi() { - // No EF_SPN, but having EF_SPDI. - // It implies "ril.iccInfoPrivate.spnDisplayCondition = undefined;". - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // PLMN lists are : 234-136 and 466-92. - let spdi = [0xA3, 0x0B, 0x80, 0x09, 0x32, 0x64, 0x31, 0x64, 0x26, 0x9F, - 0xFF, 0xFF, 0xFF]; - - // Write data size. - buf.writeInt32(spdi.length * 2); - - // Write data. - for (let i = 0; i < spdi.length; i++) { - helper.writeHexOctet(spdi[i]); - } - - // Write string delimiter. - buf.writeStringDelimiter(spdi.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - record.readSPDI(); - - equal(ril.iccInfo.isDisplayNetworkNameRequired, true); - equal(ril.iccInfo.isDisplaySpnRequired, false); - } - - function do_test_spn(displayCondition, - expectedPlmnNameDisplay, - expectedSpnDisplay) { - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // "Android" as Service Provider Name. - let spn = [0x41, 0x6E, 0x64, 0x72, 0x6F, 0x69, 0x64]; - if (typeof displayCondition === 'number') { - spn.unshift(displayCondition); - } - - // Write data size. - buf.writeInt32(spn.length * 2); - - // Write data. - for (let i = 0; i < spn.length; i++) { - helper.writeHexOctet(spn[i]); - } - - // Write string delimiter. - buf.writeStringDelimiter(spn.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - record.readSPN(); - - equal(ril.iccInfo.isDisplayNetworkNameRequired, expectedPlmnNameDisplay); - equal(ril.iccInfo.isDisplaySpnRequired, expectedSpnDisplay); - } - - // Create empty operator object. - ril.operator = {}; - // Setup SIM MCC-MNC to 310-260 as home network. - ril.iccInfo.mcc = 310; - ril.iccInfo.mnc = 260; - - do_test_spdi(); - - // No network. - do_test_spn(0x00, true, true); - do_test_spn(0x01, true, true); - do_test_spn(0x02, true, false); - do_test_spn(0x03, true, false); - - // Home network. - ril.operator.mcc = 310; - ril.operator.mnc = 260; - do_test_spn(0x00, false, true); - do_test_spn(0x01, true, true); - do_test_spn(0x02, false, true); - do_test_spn(0x03, true, true); - - // Not HPLMN but in PLMN list. - ril.iccInfoPrivate.SPDI = [{"mcc":"234","mnc":"136"},{"mcc":"466","mnc":"92"}]; - ril.operator.mcc = 466; - ril.operator.mnc = 92; - do_test_spn(0x00, false, true); - do_test_spn(0x01, true, true); - do_test_spn(0x02, false, true); - do_test_spn(0x03, true, true); - ril.iccInfoPrivate.SPDI = null; // reset SPDI to null; - - // Non-Home network. - ril.operator.mcc = 466; - ril.operator.mnc = 01; - do_test_spn(0x00, true, true); - do_test_spn(0x01, true, true); - do_test_spn(0x02, true, false); - do_test_spn(0x03, true, false); - - run_next_test(); -}); - -/** - * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_BASIC - */ -add_test(function test_reading_img_basic() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [ - {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06], - iidf: [ - [/* Header */ - 0x05, 0x05, - /* Image body */ - 0x11, 0x33, 0x55, 0xfe]], - expected: [ - {width: 0x05, - height: 0x05, - codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - body: [0x11, 0x33, 0x55, 0xfe]}]}, - {img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06, - /* Padding */ - 0xff, 0xff], - iidf: [ - [/* Header */ - 0x05, 0x05, - /* Image body */ - 0x11, 0x33, 0x55, 0xfe]], - expected: [ - {width: 0x05, - height: 0x05, - codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - body: [0x11, 0x33, 0x55, 0xfe]}]}, - {img: [0x02, 0x10, 0x01, 0x11, 0x4f, 0x04, 0x00, 0x05, 0x00, 0x04, 0x10, - 0x01, 0x11, 0x4f, 0x05, 0x00, 0x05, 0x00, 0x04], - iidf: [ - [/* Data offset */ - 0xff, 0xff, 0xff, 0xff, 0xff, - /* Header */ - 0x10, 0x01, - /* Image body */ - 0x11, 0x99, - /* Trailing data */ - 0xff, 0xff, 0xff], - [/* Data offset */ - 0xff, 0xff, 0xff, 0xff, 0xff, - /* Header */ - 0x10, 0x01, - /* Image body */ - 0x99, 0x11]], - expected: [ - {width: 0x10, - height: 0x01, - codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - body: [0x11, 0x99]}, - {width: 0x10, - height: 0x01, - codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - body: [0x99, 0x11]}]}, - {img: [0x01, 0x28, 0x20, 0x11, 0x4f, 0xac, 0x00, 0x0b, 0x00, 0xa2], - iidf: [ - [/* Data offset */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* Header */ - 0x28, 0x20, - /* Image body */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, - 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, - 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, - 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]], - expected: [ - {width: 0x28, - height: 0x20, - codingScheme: ICC_IMG_CODING_SCHEME_BASIC, - body: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x00, 0x01, 0x02, 0x03, - 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, - 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, - 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f]}]}]; - - function do_test(img, iidf, expected) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(img.length * 2); - - // Write data - for (let i = 0; i < img.length; i++) { - helper.writeHexOctet(img[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(img.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - let instanceIndex = 0; - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(iidf[instanceIndex].length * 2); - - // Write data - for (let i = 0; i < iidf[instanceIndex].length; i++) { - helper.writeHexOctet(iidf[instanceIndex][i]); - } - - // Write string delimiter - buf.writeStringDelimiter(iidf[instanceIndex].length * 2); - - instanceIndex++; - - if (options.callback) { - options.callback(options); - } - }; - - let onsuccess = function(icons) { - equal(icons.length, expected.length); - for (let i = 0; i < icons.length; i++) { - let icon = icons[i]; - let exp = expected[i]; - equal(icon.width, exp.width); - equal(icon.height, exp.height); - equal(icon.codingScheme, exp.codingScheme); - - equal(icon.body.length, exp.body.length); - for (let j = 0; j < icon.body.length; j++) { - equal(icon.body[j], exp.body[j]); - } - } - }; - record.readIMG(0, onsuccess); - } - - for (let i = 0; i< test_data.length; i++) { - do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected); - } - run_next_test(); -}); - -/** - * Verify reading EF_IMG and EF_IIDF with the case data length is not enough - */ -add_test(function test_reading_img_length_error() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [ - {/* Offset length not enough, should be 4. */ - img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x04, 0x00, 0x06], - iidf: [0xff, 0xff, 0xff, // Offset. - 0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]}, - {/* iidf data length not enough, should be 6. */ - img: [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06], - iidf: [0x05, 0x05, 0x11, 0x22, 0x33]}]; - - function do_test(img, iidf) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(img.length * 2); - - // Write data - for (let i = 0; i < img.length; i++) { - helper.writeHexOctet(img[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(img.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(iidf.length * 2); - - // Write data - for (let i = 0; i < iidf.length; i++) { - helper.writeHexOctet(iidf[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(iidf.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - let onsuccess = function() { - do_print("onsuccess shouldn't be called."); - ok(false); - }; - - let onerror = function() { - do_print("onerror called as expected."); - ok(true); - }; - - record.readIMG(0, onsuccess, onerror); - } - - for (let i = 0; i < test_data.length; i++) { - do_test(test_data[i].img, test_data[i].iidf); - } - run_next_test(); -}); - -/** - * Verify reading EF_IMG and EF_IIDF with an invalid fileId - */ -add_test(function test_reading_img_invalid_fileId() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - // Test invalid fileId: 0x5f00. - let img_test = [0x01, 0x05, 0x05, 0x11, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x06]; - let iidf_test = [0x05, 0x05, 0x11, 0x22, 0x33, 0xfe]; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(img_test.length * 2); - - // Write data - for (let i = 0; i < img_test.length; i++) { - helper.writeHexOctet(img_test[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(img_test.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(iidf_test.length * 2); - - // Write data - for (let i = 0; i < iidf_test.length; i++) { - helper.writeHexOctet(iidf_test[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(iidf_test.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - let onsuccess = function() { - do_print("onsuccess shouldn't be called."); - ok(false); - }; - - let onerror = function() { - do_print("onerror called as expected."); - ok(true); - }; - - record.readIMG(0, onsuccess, onerror); - - run_next_test(); -}); - -/** - * Verify reading EF_IMG with a wrong record length - */ -add_test(function test_reading_img_wrong_record_length() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [ - [0x01, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00], - [0x02, 0x05, 0x05, 0x11, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x06]]; - - function do_test(img) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(img.length * 2); - - // Write data - for (let i = 0; i < img.length; i++) { - helper.writeHexOctet(img[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(img.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - let onsuccess = function() { - do_print("onsuccess shouldn't be called."); - ok(false); - }; - - let onerror = function() { - do_print("onerror called as expected."); - ok(true); - }; - - record.readIMG(0, onsuccess, onerror); - } - - for (let i = 0; i < test_data.length; i++) { - do_test(test_data[i]); - } - run_next_test(); -}); - -/** - * Verify reading EF_IMG and EF_IIDF with ICC_IMG_CODING_SCHEME_COLOR - */ -add_test(function test_reading_img_color() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [ - {img: [0x01, 0x05, 0x05, 0x21, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13], - iidf: [ - [/* Header */ - 0x05, 0x05, 0x03, 0x08, 0x00, 0x13, - /* Image body */ - 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, - 0xb0, 0xc0, 0xd0, - /* Clut entries */ - 0x00, 0x01, 0x02, - 0x10, 0x11, 0x12, - 0x20, 0x21, 0x22, - 0x30, 0x31, 0x32, - 0x40, 0x41, 0x42, - 0x50, 0x51, 0x52, - 0x60, 0x61, 0x62, - 0x70, 0x71, 0x72]], - expected: [ - {width: 0x05, - height: 0x05, - codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - bitsPerImgPoint: 0x03, - numOfClutEntries: 0x08, - body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, - 0xc0, 0xd0], - clut: [0x00, 0x01, 0x02, - 0x10, 0x11, 0x12, - 0x20, 0x21, 0x22, - 0x30, 0x31, 0x32, - 0x40, 0x41, 0x42, - 0x50, 0x51, 0x52, - 0x60, 0x61, 0x62, - 0x70, 0x71, 0x72]}]}, - {img: [0x02, 0x01, 0x06, 0x21, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01, - 0x06, 0x21, 0x4f, 0x44, 0x00, 0x02, 0x00, 0x08], - iidf: [ - [/* Data offset */ - 0xff, 0xff, - /* Header */ - 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, - /* Image body */ - 0x40, 0x50, - /* Clut offset */ - 0xaa, 0xbb, 0xcc, - /* Clut entries */ - 0x01, 0x03, 0x05, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65], - [/* Data offset */ - 0xff, 0xff, - /* Header */ - 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, - /* Image body */ - 0x4f, 0x5f, - /* Clut offset */ - 0xaa, 0xbb, 0xcc, - /* Clut entries */ - 0x11, 0x13, 0x15, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65]], - expected: [ - {width: 0x01, - height: 0x06, - codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - bitsPerImgPoint: 0x02, - numOfClutEntries: 0x04, - body: [0x40, 0x50], - clut: [0x01, 0x03, 0x05, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65]}, - {width: 0x01, - height: 0x06, - codingScheme: ICC_IMG_CODING_SCHEME_COLOR, - bitsPerImgPoint: 0x02, - numOfClutEntries: 0x04, - body: [0x4f, 0x5f], - clut: [0x11, 0x13, 0x15, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65]}]}]; - - function do_test(img, iidf, expected) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(img.length * 2); - - // Write data - for (let i = 0; i < img.length; i++) { - helper.writeHexOctet(img[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(img.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - let instanceIndex = 0; - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(iidf[instanceIndex].length * 2); - - // Write data - for (let i = 0; i < iidf[instanceIndex].length; i++) { - helper.writeHexOctet(iidf[instanceIndex][i]); - } - - // Write string delimiter - buf.writeStringDelimiter(iidf[instanceIndex].length * 2); - - instanceIndex++; - - if (options.callback) { - options.callback(options); - } - }; - - let onsuccess = function(icons) { - equal(icons.length, expected.length); - for (let i = 0; i < icons.length; i++) { - let icon = icons[i]; - let exp = expected[i]; - equal(icon.width, exp.width); - equal(icon.height, exp.height); - equal(icon.codingScheme, exp.codingScheme); - - equal(icon.body.length, exp.body.length); - for (let j = 0; j < icon.body.length; j++) { - equal(icon.body[j], exp.body[j]); - } - - equal(icon.clut.length, exp.clut.length); - for (let j = 0; j < icon.clut.length; j++) { - equal(icon.clut[j], exp.clut[j]); - } - } - }; - - record.readIMG(0, onsuccess); - } - - for (let i = 0; i< test_data.length; i++) { - do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected); - } - run_next_test(); -}); - -/** - * Verify reading EF_IMG and EF_IIDF with - * ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY - */ -add_test(function test_reading_img_color() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let helper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [ - {img: [0x01, 0x05, 0x05, 0x22, 0x4f, 0x11, 0x00, 0x00, 0x00, 0x13], - iidf: [ - [/* Header */ - 0x05, 0x05, 0x03, 0x08, 0x00, 0x13, - /* Image body */ - 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, - 0xb0, 0xc0, 0xd0, - /* Clut entries */ - 0x00, 0x01, 0x02, - 0x10, 0x11, 0x12, - 0x20, 0x21, 0x22, - 0x30, 0x31, 0x32, - 0x40, 0x41, 0x42, - 0x50, 0x51, 0x52, - 0x60, 0x61, 0x62, - 0x70, 0x71, 0x72]], - expected: [ - {width: 0x05, - height: 0x05, - codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, - bitsPerImgPoint: 0x03, - numOfClutEntries: 0x08, - body: [0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, - 0xa0, 0xb0, 0xc0, 0xd0], - clut: [0x00, 0x01, 0x02, - 0x10, 0x11, 0x12, - 0x20, 0x21, 0x22, - 0x30, 0x31, 0x32, - 0x40, 0x41, 0x42, - 0x50, 0x51, 0x52, - 0x60, 0x61, 0x62, - 0x70, 0x71, 0x72]}]}, - {img: [0x02, 0x01, 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08, 0x01, - 0x06, 0x22, 0x4f, 0x33, 0x00, 0x02, 0x00, 0x08], - iidf: [ - [/* Data offset */ - 0xff, 0xff, - /* Header */ - 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, - /* Image body */ - 0x40, 0x50, - /* Clut offset */ - 0x0a, 0x0b, 0x0c, - /* Clut entries */ - 0x01, 0x03, 0x05, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65], - [/* Data offset */ - 0xff, 0xff, - /* Header */ - 0x01, 0x06, 0x02, 0x04, 0x00, 0x0d, - /* Image body */ - 0x4f, 0x5f, - /* Clut offset */ - 0x0a, 0x0b, 0x0c, - /* Clut entries */ - 0x11, 0x13, 0x15, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65]], - expected: [ - {width: 0x01, - height: 0x06, - codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, - bitsPerImgPoint: 0x02, - numOfClutEntries: 0x04, - body: [0x40, 0x50], - clut: [0x01, 0x03, 0x05, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65]}, - {width: 0x01, - height: 0x06, - codingScheme: ICC_IMG_CODING_SCHEME_COLOR_TRANSPARENCY, - bitsPerImgPoint: 0x02, - numOfClutEntries: 0x04, - body: [0x4f, 0x5f], - clut: [0x11, 0x13, 0x15, - 0x21, 0x23, 0x25, - 0x41, 0x43, 0x45, - 0x61, 0x63, 0x65]}]}]; - - function do_test(img, iidf, expected) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size - buf.writeInt32(img.length * 2); - - // Write data - for (let i = 0; i < img.length; i++) { - helper.writeHexOctet(img[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(img.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - let instanceIndex = 0; - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(iidf[instanceIndex].length * 2); - - // Write data - for (let i = 0; i < iidf[instanceIndex].length; i++) { - helper.writeHexOctet(iidf[instanceIndex][i]); - } - - // Write string delimiter - buf.writeStringDelimiter(iidf[instanceIndex].length * 2); - - instanceIndex++; - - if (options.callback) { - options.callback(options); - } - }; - - let onsuccess = function(icons) { - equal(icons.length, expected.length); - for (let i = 0; i < icons.length; i++) { - let icon = icons[i]; - let exp = expected[i]; - equal(icon.width, exp.width); - equal(icon.height, exp.height); - equal(icon.codingScheme, exp.codingScheme); - - equal(icon.body.length, exp.body.length); - for (let j = 0; j < icon.body.length; j++) { - equal(icon.body[j], exp.body[j]); - } - - equal(icon.clut.length, exp.clut.length); - for (let j = 0; j < icon.clut.length; j++) { - equal(icon.clut[j], exp.clut[j]); - } - } - }; - - record.readIMG(0, onsuccess); - } - - for (let i = 0; i< test_data.length; i++) { - do_test(test_data[i].img, test_data[i].iidf, test_data[i].expected); - } - run_next_test(); -}); - -/** - * Verify SimRecordHelper.readCphsInfo - */ -add_test(function test_read_cphs_info() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let pduHelper = context.GsmPDUHelper; - let recordHelper = context.SimRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let cphsPDU = new Uint8Array(3); - - io.loadTransparentEF = function(options) { - if (cphsPDU) { - // Write data size - buf.writeInt32(cphsPDU.length * 2); - - // Write CPHS INFO - for (let i = 0; i < cphsPDU.length; i++) { - pduHelper.writeHexOctet(cphsPDU[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(cphsPDU.length * 2); - - if (options.callback) { - options.callback(options); - } - } else { - do_print("cphsPDU[] is not set."); - } - }; - - function do_test(cphsInfo, cphsSt) { - let onsuccess = false; - let onerror = false; - - delete RIL.iccInfoPrivate.cphsSt; - cphsPDU.set(cphsInfo); - recordHelper.readCphsInfo(() => { onsuccess = true; }, - () => { onerror = true; }); - - ok((cphsSt) ? onsuccess : onerror); - ok(!((cphsSt) ? onerror : onsuccess)); - if (cphsSt) { - equal(RIL.iccInfoPrivate.cphsSt.length, cphsSt.length); - for (let i = 0; i < cphsSt.length; i++) { - equal(RIL.iccInfoPrivate.cphsSt[i], cphsSt[i]); - } - } else { - equal(RIL.iccInfoPrivate.cphsSt, cphsSt); - } - } - - do_test([ - 0x01, // Phase 1 - 0xFF, // All available & activated - 0x03 // All available & activated - ], - [ - 0x3F, // All services except ONSF(bit 8-7) are available and activated. - 0x00 // INFO_NUM shall not be available & activated. - ]); - - do_test([ - 0x02, // Phase 2 - 0xFF, // All available & activated - 0x03 // All available & activated - ], - [ - 0xF3, // All services except ONSF are available and activated. - 0x03 // INFO_NUM shall not be available & activated. - ]); - - do_test([ - 0x03, // Phase 3 - 0xFF, // All available & activated - 0x03 // All available & activated - ], - undefined); // RIL.iccInfoPrivate.cphsSt shall be remained as 'undefined'. - - run_next_test(); -}); - -/** - * Verify SimRecordHelper.readMBDN/SimRecordHelper.readCphsMBN - */ -add_test(function test_read_voicemail_number() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let pduHelper = context.GsmPDUHelper; - let recordHelper = context.SimRecordHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - let postedMessage; - - worker.postMessage = function(message) { - postedMessage = message; - }; - - io.loadLinearFixedEF = function(options) { - let mbnData = [ - 0x56, 0x6F, 0x69, 0x63, 0x65, 0x6D, 0x61, 0x69, - 0x6C, 0xFF, // Alpha Identifier: Voicemail - 0x03, // Length of BCD number: 3 - 0x80, // TOA: Unknown - 0x11, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, // Dialing Number: 111 - 0xFF, // Capability/Configuration Record Identifier - 0xFF // Extension Record Identifier - ]; - - // Write data size - buf.writeInt32(mbnData.length * 2); - - // Write MBN - for (let i = 0; i < mbnData.length; i++) { - pduHelper.writeHexOctet(mbnData[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(mbnData.length * 2); - - options.recordSize = mbnData.length; - if (options.callback) { - options.callback(options); - } - }; - - function do_test(funcName, msgCount) { - postedMessage = null; - delete RIL.iccInfoPrivate.mbdn; - recordHelper[funcName](); - - equal("iccmbdn", postedMessage.rilMessageType); - equal("Voicemail", postedMessage.alphaId); - equal("111", postedMessage.number); - } - - do_test("readMBDN"); - do_test("readCphsMBN"); - - run_next_test(); -}); - -/** - * Verify the recovery from SimRecordHelper.readCphsMBN() if MBDN is not valid - * or is empty after SimRecordHelper.readMBDN(). - */ -add_test(function test_read_mbdn_recovered_from_cphs_mbn() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let pduHelper = context.GsmPDUHelper; - let recordHelper = context.SimRecordHelper; - let iccUtilsHelper = context.ICCUtilsHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - io.loadLinearFixedEF = function(options) { - let mbnData = [ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF - ]; - - // Write data size - buf.writeInt32(mbnData.length * 2); - - // Write MBN - for (let i = 0; i < mbnData.length; i++) { - pduHelper.writeHexOctet(mbnData[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(mbnData.length * 2); - - options.recordSize = mbnData.length; - if (options.callback) { - options.callback(options); - } - }; - - iccUtilsHelper.isCphsServiceAvailable = function(geckoService) { - return geckoService == "MBN"; - }; - - let isRecovered = false; - recordHelper.readCphsMBN = function(onComplete) { - isRecovered = true; - }; - - recordHelper.readMBDN(); - - equal(RIL.iccInfoPrivate.mbdn, undefined); - ok(isRecovered); - - run_next_test(); -}); - -/** - * Verify reading EF_PNN with different coding scheme. - */ -add_test(function test_pnn_with_different_coding_scheme() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [{ - // Cell Broadcast data coding scheme - "Test1" - pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03], - expectedResult: "Test1" - },{ - // UCS2 with 0x80 - "Test1" - pnn: [0x43, 0x0C, 0x90, 0x80, 0x00, 0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31], - expectedResult: "Test1" - },{ - // UCS2 with 0x81 - "Mozilla\u694a" - pnn: [0x43, 0x0E, 0x90, 0x81, 0x08, 0xd2, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff], - expectedResult: "Mozilla\u694a" - },{ - // UCS2 with 0x82 - "Mozilla\u694a" - pnn: [0x43, 0x0F, 0x90, 0x82, 0x08, 0x69, 0x00, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0xca, 0xff, 0xff], - expectedResult: "Mozilla\u694a" - }]; - - function do_test_pnn(pnn, expectedResult) { - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - // Write data size. - buf.writeInt32(pnn.length * 2); - - // Write data. - for (let i = 0; i < pnn.length; i++) { - pduHelper.writeHexOctet(pnn[i]); - } - - // Write string delimiter. - buf.writeStringDelimiter(pnn.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - record.readPNN(); - - equal(ril.iccInfoPrivate.PNN[0].fullName, expectedResult); - // Reset PNN info for next test - ril.iccInfoPrivate.PNN = null; - } - - ril.appType = CARD_APPTYPE_SIM; - for (let i = 0; i < test_data.length; i++) { - do_test_pnn(test_data[i].pnn, test_data[i].expectedResult); - } - - run_next_test(); -}); - -/** - * Verify reading EF_PNN with different content. - */ -add_test(function test_pnn_with_different_content() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let record = context.SimRecordHelper; - let pduHelper = context.GsmPDUHelper; - let ril = context.RIL; - let buf = context.Buf; - let io = context.ICCIOHelper; - - let test_data = [{ - // [0]: {"fullName":"Test1","shortName":"Test1"} - pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03, - 0x45, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x1E, 0x03], - expectedResult: {"fullName": "Test1","shortName": "Test1"} - },{ - // [1]: {"fullName":"Test2"} - pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x2E, 0x03], - expectedResult: {"fullName": "Test2"} - },{ - // [2]: undefined - pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], - },{ - // [3]: {"fullName": "Test4"} - pnn: [0x43, 0x06, 0x85, 0xD4, 0xF2, 0x9C, 0x4E, 0x03], - expectedResult: {"fullName": "Test4"} - },{ - // [4]: undefined - pnn: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], - }]; - - function do_test_pnn() { - ril.iccIO = function fakeIccIO(options) { - let index = options.p1 - 1; - let pnn = test_data[index].pnn; - - // Write data size. - buf.writeInt32(pnn.length * 2); - - // Write data. - for (let i = 0; i < pnn.length; i++) { - pduHelper.writeHexOctet(pnn[i]); - } - - // Write string delimiter. - buf.writeStringDelimiter(pnn.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - options.p1 = 1; - options.totalRecords = test_data.length; - - ril.iccIO(options); - }; - - record.readPNN(); - - equal(test_data.length, ril.iccInfoPrivate.PNN.length); - for (let i = 0; i < test_data.length; i++) { - if (test_data[i].expectedResult) { - equal(test_data[i].expectedResult.fullName, - ril.iccInfoPrivate.PNN[i].fullName); - equal(test_data[i].expectedResult.shortName, - ril.iccInfoPrivate.PNN[i].shortName); - } else { - equal(test_data[i].expectedResult, ril.iccInfoPrivate.PNN[i]); - } - } - } - - ril.appType = CARD_APPTYPE_SIM; - do_test_pnn(); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_ruim.js b/dom/system/gonk/tests/test_ril_worker_ruim.js deleted file mode 100644 index 0ddc10f29..000000000 --- a/dom/system/gonk/tests/test_ril_worker_ruim.js +++ /dev/null @@ -1,328 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify RUIM Service. - */ -add_test(function test_is_ruim_service_available() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - context.RIL._isCdma = true; - context.RIL.appType = CARD_APPTYPE_RUIM; - - function test_table(cst, geckoService, enabled) { - context.RIL.iccInfoPrivate.cst = cst; - equal(context.ICCUtilsHelper.isICCServiceAvailable(geckoService), - enabled); - } - - test_table([0x0, 0x0, 0x0, 0x0, 0x03], "SPN", true); - test_table([0x0, 0x0, 0x0, 0x03, 0x0], "SPN", false); - test_table([0x0, 0x0C, 0x0, 0x0, 0x0], "ENHANCED_PHONEBOOK", true); - test_table([0x0, 0x0, 0x0, 0x0, 0x0], "ENHANCED_PHONEBOOK", false); - - run_next_test(); -}); - -/** - * Verify EF_PATH for RUIM file. - */ -add_test(function test_ruim_file_path_id() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ICCFileHelper = context.ICCFileHelper; - - RIL.appType = CARD_APPTYPE_RUIM; - equal(ICCFileHelper.getEFPath(ICC_EF_CSIM_CST), - EF_PATH_MF_SIM + EF_PATH_DF_CDMA); - - run_next_test(); -}); - -add_test(function test_fetch_ruim_recodes() { - let worker = newWorker(); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ruimHelper = context.RuimRecordHelper; - - function testFetchRuimRecordes(expectCalled) { - let ifCalled = []; - - ruimHelper.getIMSI_M = function() { - ifCalled.push("getIMSI_M"); - }; - - ruimHelper.readCST = function() { - ifCalled.push("readCST"); - }; - - ruimHelper.readCDMAHome = function() { - ifCalled.push("readCDMAHome"); - }; - - RIL.getCdmaSubscription = function() { - ifCalled.push("getCdmaSubscription"); - }; - - ruimHelper.fetchRuimRecords(); - - for (let i = 0; i < expectCalled.length; i++ ) { - if (ifCalled[i] != expectCalled[i]) { - do_print(expectCalled[i] + " is not called."); - ok(false); - } - } - } - - let expectCalled = ["getIMSI_M", "readCST", "readCDMAHome", - "getCdmaSubscription"]; - testFetchRuimRecordes(expectCalled); - - run_next_test(); -}); - -/** - * Verify RuimRecordHelper.decodeIMSIValue - */ -add_test(function test_decode_imsi_value() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - - function testDecodeImsiValue(encoded, length, expect) { - let decoded = context.RuimRecordHelper.decodeIMSIValue(encoded, length); - - equal(expect, decoded); - } - - testDecodeImsiValue( 99, 2, "00"); - testDecodeImsiValue( 90, 2, "01"); - testDecodeImsiValue( 19, 2, "20"); - testDecodeImsiValue( 23, 2, "34"); - testDecodeImsiValue(999, 3, "000"); - testDecodeImsiValue(990, 3, "001"); - testDecodeImsiValue(909, 3, "010"); - testDecodeImsiValue( 99, 3, "100"); - testDecodeImsiValue(901, 3, "012"); - testDecodeImsiValue( 19, 3, "120"); - testDecodeImsiValue( 91, 3, "102"); - testDecodeImsiValue(199, 3, "200"); - testDecodeImsiValue(123, 3, "234"); - testDecodeImsiValue(578, 3, "689"); - - run_next_test(); -}); - -/** - * Verify RuimRecordHelper.getIMSI_M - */ -add_test(function test_get_imsi_m() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function testDecodeImsi(encodedImsi, expectedImsi) { - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(encodedImsi.length * 2); - - // Write imsi - for (let i = 0; i < encodedImsi.length; i++) { - helper.writeHexOctet(encodedImsi[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(encodedImsi.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - context.RuimRecordHelper.getIMSI_M(); - let imsi = context.RIL.iccInfoPrivate.imsi; - - equal(expectedImsi, imsi) - } - - let imsi_1 = "466050081062861"; - testDecodeImsi([0x0, 0xe5, 0x03, 0xee, 0xca, 0x17, 0x5e, 0x80, 0x63, 0x01], imsi_1); - - let imsi_2 = "460038351175976"; - testDecodeImsi([0x0, 0xd4, 0x02, 0x61, 0x97, 0x01, 0x5c, 0x80, 0x67, 0x01], imsi_2); - - run_next_test(); -}); - -/** - * Verify RuimRecordHelper.readCDMAHome - */ -add_test(function test_read_cdmahome() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - io.loadLinearFixedEF = function fakeLoadLinearFixedEF(options) { - let cdmaHome = [0xc1, 0x34, 0xff, 0xff, 0x00]; - - // Write data size - buf.writeInt32(cdmaHome.length * 2); - - // Write cdma home file. - for (let i = 0; i < cdmaHome.length; i++) { - helper.writeHexOctet(cdmaHome[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(cdmaHome.length * 2); - - // We just have 1 test record. - - options.totalRecords = 1; - if (options.callback) { - options.callback(options); - } - }; - - function testCdmaHome(expectedSystemIds, expectedNetworkIds) { - context.RuimRecordHelper.readCDMAHome(); - let cdmaHome = context.RIL.cdmaHome; - for (let i = 0; i < expectedSystemIds.length; i++) { - equal(cdmaHome.systemId[i], expectedSystemIds[i]); - equal(cdmaHome.networkId[i], expectedNetworkIds[i]); - } - equal(cdmaHome.systemId.length, expectedSystemIds.length); - equal(cdmaHome.networkId.length, expectedNetworkIds.length); - } - - testCdmaHome([13505], [65535]); - - run_next_test(); -}); - -/** - * Verify reading CDMA EF_SPN - */ -add_test(function test_read_cdmaspn() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let buf = context.Buf; - let io = context.ICCIOHelper; - - function testReadSpn(file, expectedSpn, expectedDisplayCondition) { - io.loadTransparentEF = function fakeLoadTransparentEF(options) { - // Write data size - buf.writeInt32(file.length * 2); - - // Write file. - for (let i = 0; i < file.length; i++) { - helper.writeHexOctet(file[i]); - } - - // Write string delimiter - buf.writeStringDelimiter(file.length * 2); - - if (options.callback) { - options.callback(options); - } - }; - - context.RuimRecordHelper.readSPN(); - equal(context.RIL.iccInfo.spn, expectedSpn); - equal(context.RIL.iccInfoPrivate.spnDisplayCondition, - expectedDisplayCondition); - } - - testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96, - 0xfb, 0x4f, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff], - String.fromCharCode(0x4e9e) + - String.fromCharCode(0x592a) + - String.fromCharCode(0x96fb) + - String.fromCharCode(0x4fe1), - 0x1); - - // Test when there's no tailing 0xff in spn string. - testReadSpn([0x01, 0x04, 0x06, 0x4e, 0x9e, 0x59, 0x2a, 0x96, - 0xfb, 0x4f, 0xe1], - String.fromCharCode(0x4e9e) + - String.fromCharCode(0x592a) + - String.fromCharCode(0x96fb) + - String.fromCharCode(0x4fe1), - 0x1); - - run_next_test(); -}); - -/** - * Verify display condition for CDMA. - */ -add_test(function test_cdma_spn_display_condition() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - let RIL = context.RIL; - let ICCUtilsHelper = context.ICCUtilsHelper; - - // Set cdma. - RIL._isCdma = true; - - // Test updateDisplayCondition runs before any of SIM file is ready. - equal(ICCUtilsHelper.updateDisplayCondition(), true); - equal(RIL.iccInfo.isDisplayNetworkNameRequired, true); - equal(RIL.iccInfo.isDisplaySpnRequired, false); - - // Test with value. - function testDisplayCondition(ruimDisplayCondition, - homeSystemIds, homeNetworkIds, - currentSystemId, currentNetworkId, - expectUpdateDisplayCondition, - expectIsDisplaySPNRequired) { - RIL.iccInfoPrivate.spnDisplayCondition = ruimDisplayCondition; - RIL.cdmaHome = { - systemId: homeSystemIds, - networkId: homeNetworkIds - }; - RIL.voiceRegistrationState.cell = { - cdmaSystemId: currentSystemId, - cdmaNetworkId: currentNetworkId - }; - - equal(ICCUtilsHelper.updateDisplayCondition(), expectUpdateDisplayCondition); - equal(RIL.iccInfo.isDisplayNetworkNameRequired, false); - equal(RIL.iccInfo.isDisplaySpnRequired, expectIsDisplaySPNRequired); - }; - - // SPN is not required when ruimDisplayCondition is false. - testDisplayCondition(0x0, [123], [345], 123, 345, true, false); - - // System id and network id are all match. - testDisplayCondition(0x1, [123], [345], 123, 345, true, true); - - // Network is 65535, we should only need to match system id. - testDisplayCondition(0x1, [123], [65535], 123, 345, false, true); - - // Not match. - testDisplayCondition(0x1, [123], [456], 123, 345, true, false); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_sms.js b/dom/system/gonk/tests/test_ril_worker_sms.js deleted file mode 100644 index 7c1b972a7..000000000 --- a/dom/system/gonk/tests/test_ril_worker_sms.js +++ /dev/null @@ -1,273 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() { - let ns = {}; - Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns); - return ns.SmsSegmentHelper; -}); - -const ESCAPE = "\uffff"; -const RESCTL = "\ufffe"; - -function run_test() { - run_next_test(); -} - -/** - * Verify receiving SMS-DELIVERY messages - */ - -function hexToNibble(nibble) { - nibble &= 0x0f; - if (nibble < 10) { - nibble += 48; // ASCII '0' - } else { - nibble += 55; // ASCII 'A' - } - return nibble; -} - -function pduToParcelData(pdu) { - let dataLength = 4 + pdu.length * 4 + 4; - let data = new Uint8Array(dataLength); - let offset = 0; - - // String length - data[offset++] = pdu.length & 0xFF; - data[offset++] = (pdu.length >> 8) & 0xFF; - data[offset++] = (pdu.length >> 16) & 0xFF; - data[offset++] = (pdu.length >> 24) & 0xFF; - - // PDU data - for (let i = 0; i < pdu.length; i++) { - let hi = (pdu[i] >>> 4) & 0x0F; - let lo = pdu[i] & 0x0F; - - data[offset++] = hexToNibble(hi); - data[offset++] = 0; - data[offset++] = hexToNibble(lo); - data[offset++] = 0; - } - - // String delimitor - data[offset++] = 0; - data[offset++] = 0; - data[offset++] = 0; - data[offset++] = 0; - - return data; -} - -function compose7bitPdu(lst, sst, data, septets) { - if ((lst == 0) && (sst == 0)) { - return [0x00, // SMSC - PDU_MTI_SMS_DELIVER, // firstOctet - 1, 0x00, 0, // senderAddress - 0x00, // protocolIdentifier - PDU_DCS_MSG_CODING_7BITS_ALPHABET, // dataCodingScheme - 0, 0, 0, 0, 0, 0, 0, // y m d h m s tz - septets] // userDataLength - .concat(data); - } - - return [0x00, // SMSC - PDU_MTI_SMS_DELIVER | PDU_UDHI, // firstOctet - 1, 0x00, 0, // senderAddress - 0x00, // protocolIdentifier - PDU_DCS_MSG_CODING_7BITS_ALPHABET, // dataCodingScheme - 0, 0, 0, 0, 0, 0, 0, // y m d h m s tz - 8 + septets, // userDataLength - 6, // user data header length - PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT, 1, lst, // PDU_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT - PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT, 1, sst] // PDU_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT - .concat(data); -} - -function composeUcs2Pdu(rawBytes) { - return [0x00, // SMSC - PDU_MTI_SMS_DELIVER, // firstOctet - 1, 0x00, 0, // senderAddress - 0x00, // protocolIdentifier - PDU_DCS_MSG_CODING_16BITS_ALPHABET, // dataCodingScheme - 0, 0, 0, 0, 0, 0, 0, // y m d h m s tz - rawBytes.length] // userDataLength - .concat(rawBytes); -} - -function newSmsParcel(pdu) { - return newIncomingParcel(-1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_NEW_SMS, - pduToParcelData(pdu)); -} - -function removeSpecialChar(str, needle) { - for (let i = 0; i < needle.length; i++) { - let pos; - while ((pos = str.indexOf(needle[i])) >= 0) { - str = str.substring(0, pos) + str.substring(pos + 1); - } - } - return str; -} - -function newWriteHexOctetAsUint8Worker() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - context.GsmPDUHelper.writeHexOctet = function(value) { - context.Buf.writeUint8(value); - }; - - return worker; -} - -function add_test_receiving_sms(expected, pdu) { - add_test(function test_receiving_sms() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - do_print("fullBody: " + message.fullBody); - equal(expected, message.fullBody) - } - }); - - do_print("expect: " + expected); - do_print("pdu: " + pdu); - worker.onRILMessage(0, newSmsParcel(pdu)); - - run_next_test(); - }); -} - -var test_receiving_7bit_alphabets__worker; -function test_receiving_7bit_alphabets(lst, sst) { - if (!test_receiving_7bit_alphabets__worker) { - test_receiving_7bit_alphabets__worker = newWriteHexOctetAsUint8Worker(); - } - let worker = test_receiving_7bit_alphabets__worker; - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let buf = context.Buf; - - function get7bitRawBytes(expected) { - buf.outgoingIndex = 0; - helper.writeStringAsSeptets(expected, 0, lst, sst); - - let subArray = buf.outgoingBytes.subarray(0, buf.outgoingIndex); - return Array.slice(subArray); - } - - let langTable = PDU_NL_LOCKING_SHIFT_TABLES[lst]; - let langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[sst]; - - let text = removeSpecialChar(langTable + langShiftTable, ESCAPE + RESCTL); - for (let i = 0; i < text.length;) { - let len = Math.min(70, text.length - i); - let expected = text.substring(i, i + len); - let septets = - gSmsSegmentHelper.countGsm7BitSeptets(expected, langTable, langShiftTable); - let rawBytes = get7bitRawBytes(expected); - let pdu = compose7bitPdu(lst, sst, rawBytes, septets); - add_test_receiving_sms(expected, pdu); - - i += len; - } -} - -function test_receiving_ucs2_alphabets(text) { - let worker = test_receiving_7bit_alphabets__worker; - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - - function getUCS2RawBytes(expected) { - buf.outgoingIndex = 0; - context.GsmPDUHelper.writeUCS2String(expected); - - let subArray = buf.outgoingBytes.subarray(0, buf.outgoingIndex); - return Array.slice(subArray); - } - - for (let i = 0; i < text.length;) { - let len = Math.min(70, text.length - i); - let expected = text.substring(i, i + len); - let rawBytes = getUCS2RawBytes(expected); - let pdu = composeUcs2Pdu(rawBytes); - add_test_receiving_sms(expected, pdu); - - i += len; - } -} - -var ucs2str = ""; -for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) { - ucs2str += PDU_NL_LOCKING_SHIFT_TABLES[lst]; - for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) { - test_receiving_7bit_alphabets(lst, sst); - - if (lst == 0) { - ucs2str += PDU_NL_SINGLE_SHIFT_TABLES[sst]; - } - } -} -test_receiving_ucs2_alphabets(ucs2str); - -// Bug 820220: B2G SMS: wrong order and truncated content in multi-part messages -add_test(function test_sendSMS_UCS2_without_langIndex_langShiftIndex_defined() { - let worker = newWriteHexOctetAsUint8Worker(); - let context = worker.ContextPool._contexts[0]; - - context.Buf.sendParcel = function() { - // Each sendParcel() call represents one outgoing segment of a multipart - // SMS message. Here, we have the first segment send, so it's "Hello " - // only. - // - // 4(parcel size) + 4(request type) + 4(token) - // + 4(two messages) + 4(null SMSC) + 4(message string length) - // + 1(first octet) + 1(message reference) - // + 2(DA len, TOA) + 4(addr) - // + 1(pid) + 1(dcs) - // + 1(UDL) + 6(UDHL, type, len, ref, max, seq) - // + 12(2 * strlen("Hello ")) - // + 4(two delimitors) = 57 - // - // If we have additional 6(type, len, langIndex, type len, langShiftIndex) - // octets here, then bug 809553 is not fixed. - equal(this.outgoingIndex, 57); - - run_next_test(); - }; - - context.RIL.sendSMS({ - number: "1", - segmentMaxSeq: 2, - fullBody: "Hello World!", - dcs: PDU_DCS_MSG_CODING_16BITS_ALPHABET, - segmentRef16Bit: false, - userDataHeaderLength: 5, - requestStatusReport: true, - segments: [ - { - body: "Hello ", - encodedBodyLength: 12, - }, { - body: "World!", - encodedBodyLength: 12, - } - ], - }); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_sms_cdma.js b/dom/system/gonk/tests/test_ril_worker_sms_cdma.js deleted file mode 100644 index 85d0b6e0c..000000000 --- a/dom/system/gonk/tests/test_ril_worker_sms_cdma.js +++ /dev/null @@ -1,298 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/* - * Helper function to covert a HEX string to a byte array. - * - * @param hexString - * A hexadecimal string of which the length is even. - */ -function hexStringToBytes(hexString) { - let bytes = []; - - let length = hexString.length; - - for (let i = 0; i < length; i += 2) { - bytes.push(Number.parseInt(hexString.substr(i, 2), 16)); - } - - return bytes; -} - -/* - * Helper function to covert a byte array to a HEX string. - * - * @param bytes - * Could be a regular byte array or Uint8Array. - */ -function bytesToHexString(bytes) { - let hexString = ""; - let hex; - - for (let i = 0; i < bytes.length; i++) { - hex = bytes[i].toString(16).toUpperCase(); - if (hex.length === 1) { - hexString += "0"; - } - hexString += hex; - } - - return hexString; -} - -/* - * Helper function to ecode Opaque UserData - * - * @param msg_type - * PDU_CDMA_MSG_TYPE_SUBMIT or PDU_CDMA_MSG_TYPE_DELIVER - * @param data - * The byte array of opaque data to be encoded. - */ -function encodeOpaqueUserData(bitBufferHelper, options) { - let bearerDataBuffer = []; - bitBufferHelper.startWrite(bearerDataBuffer); - - // Msg-Id - bitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_MSG_ID, 8); - bitBufferHelper.writeBits(3, 8); - bitBufferHelper.writeBits(options.msg_type, 4); // MSG_TYPE - bitBufferHelper.writeBits(1, 16); // MSG_ID - bitBufferHelper.flushWithPadding(); // HEADER_IND (1) + RESERVED (3) - - // User Data - bitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_BODY, 8); - let dataLength = options.data.length; - bitBufferHelper.writeBits(2 + dataLength, 8); // 2 bytes for MSG_ENCODING, NUM_FIELDS - bitBufferHelper.writeBits(PDU_CDMA_MSG_CODING_OCTET, 5); //MSG_ENCODING - // MSG_TYPE is omitted if MSG_ENCODING is CODING_OCTET - bitBufferHelper.writeBits(dataLength, 8); // NUM_FIELDS - for (let i = 0; i < dataLength; i++) { // CHARi - bitBufferHelper.writeBits(options.data[i], 8); - } - bitBufferHelper.flushWithPadding(); // RESERVED (3 filling bits) - - return bearerDataBuffer; -} - -function newSmsParcel(cdmaPduHelper, pdu) { - return newIncomingParcel(-1, - RESPONSE_TYPE_UNSOLICITED, - UNSOLICITED_RESPONSE_CDMA_NEW_SMS, - pduToParcelData(cdmaPduHelper, pdu)); -} - -/* - * Helper function to encode PDU into Parcel. - * See ril_cdma_sms.h for the structure definition of RIL_CDMA_SMS_Message - * - * @param teleservice - * The Teleservice-Id of this PDU. - * See PDU_CDMA_MSG_TELESERIVCIE_ID_XXX in ril_const.js. - * @param address - * The Orginating or Destinating address. - * @param bearerData - * The byte array of the encoded bearer data. - */ -function pduToParcelData(cdmaPduHelper, pdu) { - - let addrInfo = cdmaPduHelper.encodeAddr(pdu.address); - // Teleservice, isServicePresent, ServiceCategory, - // addrInfo {digitMode, numberMode, numberType, numberPlan, address.length, address} - // Sub Address - // bearerData length, bearerData. - let dataLength = 4 + 4 + 4 - + (5 + addrInfo.address.length) * 4 - + 3 * 4 - + 4 + pdu.bearerData.length * 4; - - let data = new Uint8Array(dataLength); - let offset = 0; - - function writeInt(value) { - data[offset++] = value & 0xFF; - data[offset++] = (value >> 8) & 0xFF; - data[offset++] = (value >> 16) & 0xFF; - data[offset++] = (value >> 24) & 0xFF; - } - - function writeByte(value) { - data[offset++] = value & 0xFF; - data[offset++] = 0; - data[offset++] = 0; - data[offset++] = 0; - } - - // Teleservice - writeInt(pdu.teleservice); - - // isServicePresent - writeByte(0); - - // ServiceCategory - writeInt(PDU_CDMA_MSG_CATEGORY_UNSPEC); - - // AddrInfo - writeByte(addrInfo.digitMode); - writeByte(addrInfo.numberMode); - writeByte(addrInfo.numberType); - writeByte(addrInfo.numberPlan); - let addressLength = addrInfo.address.length; - writeByte(addressLength); - for (let i = 0; i < addressLength; i++) { - writeByte(addrInfo.address[i]); - } - - // Subaddress - writeByte(0); - writeByte(0); - writeByte(0); - - // Bearer Data Length - dataLength = pdu.bearerData.length; - writeByte(dataLength); - - // Bearer Data - for (let i = 0; i < dataLength; i++) { - writeByte(pdu.bearerData[i]); - } - - return data; -} - -/** - * Verify CDMA SMS Delivery ACK Message. - */ -add_test(function test_processCdmaSmsStatusReport() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - function test_StatusReport(errorClass, msgStatus) { - let msgId = 0; - let sentSmsMap = context.RIL._pendingSentSmsMap; - - sentSmsMap[msgId] = {}; - - let message = { - SMSC: "", - mti: 0, - udhi: 0, - sender: "0987654321", - recipient: null, - pid: PDU_PID_DEFAULT, - epid: PDU_PID_DEFAULT, - dcs: 0, - mwi: null, - replace: false, - header: null, - body: "Status: Sent, Dest: 0987654321", - data: null, - timestamp: new Date().valueOf(), - language: null, - status: null, - scts: null, - dt: null, - encoding: PDU_CDMA_MSG_CODING_7BITS_ASCII, - messageClass: GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - messageType: PDU_CDMA_MSG_TYPE_P2P, - serviceCategory: 0, - subMsgType: PDU_CDMA_MSG_TYPE_DELIVER_ACK, - msgId: msgId, - errorClass: errorClass, - msgStatus: msgStatus - }; - - context.RIL._processCdmaSmsStatusReport(message); - - let postedMessage = workerHelper.postedMessage; - - // Check if pending token is removed. - ok((errorClass === 2) ? !!sentSmsMap[msgId] : !sentSmsMap[msgId]); - - // Check the response message accordingly. - if (errorClass === -1) { - // Check if the report is treated as normal incoming SMS - equal("sms-received", postedMessage.rilMessageType); - } else if (errorClass === 2) { - // Do nothing. - } else { - // Check Delivery Status - if (errorClass === 0) { - equal(postedMessage.deliveryStatus, GECKO_SMS_DELIVERY_STATUS_SUCCESS); - } else { - equal(postedMessage.deliveryStatus, GECKO_SMS_DELIVERY_STATUS_ERROR); - } - } - } - - test_StatusReport(-1, -1); // Message Status Sub-parameter is absent. - test_StatusReport(0, 0); // 00|000000: no error|Message accepted - test_StatusReport(2, 4); // 10|000100: temporary condition|Network congestion - test_StatusReport(3, 5); // 11|000101: permanent condition|Network error - - run_next_test(); -}); - -/** - * Verify WAP Push over CDMA SMS Message. - */ -add_test(function test_processCdmaSmsWapPush() { - let workerHelper = newInterceptWorker(), - worker = workerHelper.worker, - context = worker.ContextPool._contexts[0], - bitBufferHelper = context.BitBufferHelper, - cdmaPduHelper = context.CdmaPDUHelper; - - function test_CdmaSmsWapPdu(wdpData, reversed) { - let orig_address = "0987654321", - hexString, - fullDataHexString = ""; - - for (let i = 0; i < wdpData.length; i++) { - let dataIndex = (reversed) ? (wdpData.length - i - 1) : i; - hexString = "00"; // MSG_TYPE - hexString += bytesToHexString([wdpData.length]); // TOTAL_SEG - hexString += bytesToHexString([dataIndex]); // SEG_NUM (zero-based) - if ((dataIndex === 0)) { - hexString += "23F00B84"; // SOURCE_PORT, DEST_PORT for 1st segment - } - hexString += wdpData[dataIndex]; // WDP DATA - - do_print("hexString: " + hexString); - - fullDataHexString += wdpData[i]; - - let pdu = { - teleservice: PDU_CDMA_MSG_TELESERIVCIE_ID_WAP, - address: orig_address, - bearerData: encodeOpaqueUserData(bitBufferHelper, - { msg_type: PDU_CDMA_MSG_TYPE_DELIVER, - data: hexStringToBytes(hexString) }) - }; - - worker.onRILMessage(0, newSmsParcel(cdmaPduHelper, pdu)); - } - - let postedMessage = workerHelper.postedMessage; - - do_print("fullDataHexString: " + fullDataHexString); - - equal("sms-received", postedMessage.rilMessageType); - equal(PDU_CDMA_MSG_TELESERIVCIE_ID_WAP, postedMessage.teleservice); - equal(orig_address, postedMessage.sender); - equal(0x23F0, postedMessage.header.originatorPort); - equal(0x0B84, postedMessage.header.destinationPort); - equal(fullDataHexString, bytesToHexString(postedMessage.data)); - } - - // Verify Single WAP PDU - test_CdmaSmsWapPdu(["000102030405060708090A0B0C0D0E0F"]); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js b/dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js deleted file mode 100644 index 276728f2f..000000000 --- a/dom/system/gonk/tests/test_ril_worker_sms_cdmapduhelper.js +++ /dev/null @@ -1,210 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify CdmaPDUHelper#encodeUserDataReplyOption. - */ -add_test(function test_CdmaPDUHelper_encodeUserDataReplyOption() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - - let testDataBuffer = []; - context.BitBufferHelper.startWrite(testDataBuffer); - - let helper = context.CdmaPDUHelper; - helper.encodeUserDataReplyOption({requestStatusReport: true}); - - let expectedDataBuffer = [PDU_CDMA_MSG_USERDATA_REPLY_OPTION, 0x01, 0x40]; - - equal(testDataBuffer.length, expectedDataBuffer.length); - - for (let i = 0; i < expectedDataBuffer.length; i++) { - equal(testDataBuffer[i], expectedDataBuffer[i]); - } - - run_next_test(); -}); - -/** - * Verify CdmaPDUHelper#cdma_decodeUserDataMsgStatus. - */ -add_test(function test_CdmaPDUHelper_decodeUserDataMsgStatus() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - - let helper = context.CdmaPDUHelper; - function test_MsgStatus(octet) { - let testDataBuffer = [octet]; - context.BitBufferHelper.startRead(testDataBuffer); - let result = helper.decodeUserDataMsgStatus(); - - equal(result.errorClass, octet >>> 6); - equal(result.msgStatus, octet & 0x3F); - } - - // 00|000000: no error|Message accepted - test_MsgStatus(0x00); - - // 10|000100: temporary condition|Network congestion - test_MsgStatus(0x84); - - // 11|000101: permanent condition|Network error - test_MsgStatus(0xC5); - - run_next_test(); -}); - -/** - * Verify CdmaPDUHelper#decodeCdmaPDUMsg. - * - encoding by shift-jis - */ -add_test(function test_CdmaPDUHelper_decodeCdmaPDUMsg_Shift_jis() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - let context = worker.ContextPool._contexts[0]; - - let helper = context.CdmaPDUHelper; - function test_decodePDUMsg(testDataBuffer, expected, encoding, msgType, msgBodySize) { - context.BitBufferHelper.startRead(testDataBuffer); - let result = helper.decodeCdmaPDUMsg(encoding, msgType, msgBodySize); - equal(result, expected); - } - - // Shift-JIS has 1 byte and 2 byte code for one character and has some types of characters: - // Hiragana, Kanji, Katakana(fullwidth, halfwidth)... - // This test is a combination of 1 byte and 2 byte code and types of characters. - - // test case 1 - let testDataBuffer1 = [0x82, 0x58, 0x33, 0x41, 0x61, 0x33, 0x82, 0x60, - 0x82, 0x81, 0x33, 0xB1, 0xAF, 0x33, 0x83, 0x41, - 0x83, 0x96, 0x33, 0x82, 0xA0, 0x33, 0x93, 0xFA, - 0x33, 0x3A, 0x3C, 0x33, 0x81, 0x80, 0x81, 0x8E, - 0x33, 0x31, 0x82, 0x51, 0x41, 0x61, 0x82, 0x51, - 0x82, 0x60, 0x82, 0x81, 0x82, 0x51, 0xB1, 0xAF, - 0x82, 0x51, 0x83, 0x41, 0x83, 0x96, 0x82, 0x51, - 0x82, 0xA0, 0x82, 0x51, 0x93, 0xFA, 0x82, 0x51, - 0x3A, 0x3C, 0x82, 0x51, 0x81, 0x80, 0x81, 0x8E, - 0x82, 0x51]; - - test_decodePDUMsg( - testDataBuffer1, - "\uFF19\u0033\u0041\u0061\u0033\uFF21\uFF41\u0033\uFF71\uFF6F\u0033\u30A2\u30F6\u0033\u3042\u0033\u65E5\u0033\u003A\u003C\u0033\u00F7\u2103\u0033\u0031\uFF12\u0041\u0061\uFF12\uFF21\uFF41\uFF12\uFF71\uFF6F\uFF12\u30A2\u30F6\uFF12\u3042\uFF12\u65E5\uFF12\u003A\u003C\uFF12\u00F7\u2103\uFF12", - PDU_CDMA_MSG_CODING_SHIFT_JIS, - undefined, - testDataBuffer1.length - ); - - // test case 2 - let testDataBuffer2 = [0x31, 0x51, 0x63, 0x82, 0x58, 0x51, 0x63, 0x82, - 0x60, 0x82, 0x81, 0x51, 0x63, 0xB1, 0xAF, 0x51, - 0x63, 0x83, 0x41, 0x83, 0x96, 0x51, 0x63, 0x82, - 0xA0, 0x51, 0x63, 0x93, 0xFA, 0x51, 0x63, 0x3A, - 0x3C, 0x51, 0x63, 0x81, 0x80, 0x81, 0x8E, 0x51, - 0x63, 0x31, 0x82, 0x70, 0x82, 0x85, 0x82, 0x58, - 0x82, 0x70, 0x82, 0x85, 0x41, 0x61, 0x82, 0x70, - 0x82, 0x85, 0xB1, 0xAF, 0x82, 0x70, 0x82, 0x85, - 0x83, 0x41, 0x83, 0x96, 0x82, 0x70, 0x82, 0x85, - 0x82, 0xA0, 0x82, 0x70, 0x82, 0x85, 0x93, 0xFA, - 0x82, 0x70, 0x82, 0x85, 0x3A, 0x3C, 0x82, 0x70, - 0x82, 0x85, 0x81, 0x80, 0x81, 0x8E, 0x82, 0x70, - 0x82, 0x85]; - - test_decodePDUMsg( - testDataBuffer2, - "\u0031\u0051\u0063\uFF19\u0051\u0063\uFF21\uFF41\u0051\u0063\uFF71\uFF6F\u0051\u0063\u30A2\u30F6\u0051\u0063\u3042\u0051\u0063\u65E5\u0051\u0063\u003A\u003C\u0051\u0063\u00F7\u2103\u0051\u0063\u0031\uFF31\uFF45\uFF19\uFF31\uFF45\u0041\u0061\uFF31\uFF45\uFF71\uFF6F\uFF31\uFF45\u30A2\u30F6\uFF31\uFF45\u3042\uFF31\uFF45\u65E5\uFF31\uFF45\u003A\u003C\uFF31\uFF45\u00F7\u2103\uFF31\uFF45", - PDU_CDMA_MSG_CODING_SHIFT_JIS, - undefined, - testDataBuffer2.length - ); - - // test case 3 - let testDataBuffer3 = [0x31, 0xC2, 0xDF, 0x82, 0x58, 0xC2, 0xDF, 0x41, - 0x61, 0xC2, 0xDF, 0x82, 0x60, 0x82, 0x81, 0xC2, - 0xDF, 0x83, 0x41, 0x83, 0x96, 0xC2, 0xDF, 0x82, - 0xA0, 0xC2, 0xDF, 0x93, 0xFA, 0xC2, 0xDF, 0x3A, - 0x3C, 0xC2, 0xDF, 0x81, 0x80, 0x81, 0x8E, 0xC2, - 0xDF, 0x31, 0x83, 0x51, 0x83, 0x87, 0x82, 0x58, - 0x83, 0x51, 0x83, 0x87, 0x41, 0x61, 0x83, 0x51, - 0x83, 0x87, 0x82, 0x60, 0x82, 0x81, 0x83, 0x51, - 0x83, 0x87, 0xB1, 0xAF, 0x83, 0x51, 0x83, 0x87, - 0x82, 0xA0, 0x83, 0x51, 0x83, 0x87, 0x93, 0xFA, - 0x83, 0x51, 0x83, 0x87, 0x3A, 0x3C, 0x83, 0x51, - 0x83, 0x87, 0x81, 0x80, 0x81, 0x8E, 0x83, 0x51, - 0x83, 0x87]; - - test_decodePDUMsg( - testDataBuffer3, - "\u0031\uFF82\uFF9F\uFF19\uFF82\uFF9F\u0041\u0061\uFF82\uFF9F\uFF21\uFF41\uFF82\uFF9F\u30A2\u30F6\uFF82\uFF9F\u3042\uFF82\uFF9F\u65E5\uFF82\uFF9F\u003A\u003C\uFF82\uFF9F\u00F7\u2103\uFF82\uFF9F\u0031\u30B2\u30E7\uFF19\u30B2\u30E7\u0041\u0061\u30B2\u30E7\uFF21\uFF41\u30B2\u30E7\uFF71\uFF6F\u30B2\u30E7\u3042\u30B2\u30E7\u65E5\u30B2\u30E7\u003A\u003C\u30B2\u30E7\u00F7\u2103\u30B2\u30E7", - PDU_CDMA_MSG_CODING_SHIFT_JIS, - undefined, - testDataBuffer3.length - ); - - // test case 4 - let testDataBuffer4 = [0x31, 0x82, 0xB0, 0x82, 0x58, 0x82, 0xB0, 0x41, - 0x61, 0x82, 0xB0, 0x82, 0x60, 0x82, 0x81, 0x82, - 0xB0, 0xB1, 0xAF, 0x82, 0xB0, 0x83, 0x41, 0x83, - 0x96, 0x82, 0xB0, 0x93, 0xFA, 0x82, 0xB0, 0x3A, - 0x3C, 0x82, 0xB0, 0x81, 0x80, 0x81, 0x8E, 0x82, - 0xB0, 0x31, 0x88, 0xA4, 0x82, 0x58, 0x88, 0xA4, - 0x41, 0x61, 0x88, 0xA4, 0x82, 0x60, 0x82, 0x81, - 0x88, 0xA4, 0xB1, 0xAF, 0x88, 0xA4, 0x83, 0x41, - 0x83, 0x96, 0x88, 0xA4, 0x82, 0xA0, 0x88, 0xA4, - 0x3A, 0x3C, 0x88, 0xA4, 0x81, 0x80, 0x81, 0x8E, - 0x88, 0xA4]; - - test_decodePDUMsg( - testDataBuffer4, - "\u0031\u3052\uFF19\u3052\u0041\u0061\u3052\uFF21\uFF41\u3052\uFF71\uFF6F\u3052\u30A2\u30F6\u3052\u65E5\u3052\u003A\u003C\u3052\u00F7\u2103\u3052\u0031\u611B\uFF19\u611B\u0041\u0061\u611B\uFF21\uFF41\u611B\uFF71\uFF6F\u611B\u30A2\u30F6\u611B\u3042\u611B\u003A\u003C\u611B\u00F7\u2103\u611B", - PDU_CDMA_MSG_CODING_SHIFT_JIS, - undefined, - testDataBuffer4.length - ); - - // test case 5 - let testDataBuffer5 = [0x31, 0x40, 0x82, 0x58, 0x40, 0x41, 0x61, 0x40, - 0x82, 0x60, 0x82, 0x81, 0x40, 0xB1, 0xAF, 0x40, - 0x83, 0x41, 0x83, 0x96, 0x40, 0x82, 0xA0, 0x40, - 0x93, 0xFA, 0x40, 0x81, 0x80, 0x81, 0x8E, 0x40, - 0x31, 0x81, 0x9B, 0x82, 0x58, 0x81, 0x9B, 0x41, - 0x61, 0x81, 0x9B, 0x82, 0x60, 0x82, 0x81, 0x81, - 0x9B, 0xB1, 0xAF, 0x81, 0x9B, 0x83, 0x41, 0x83, - 0x96, 0x81, 0x9B, 0x82, 0xA0, 0x81, 0x9B, 0x93, - 0xFA, 0x81, 0x9B, 0x3A, 0x3C, 0x81, 0x9B]; - - test_decodePDUMsg( - testDataBuffer5, - "\u0031\u0040\uFF19\u0040\u0041\u0061\u0040\uFF21\uFF41\u0040\uFF71\uFF6F\u0040\u30A2\u30F6\u0040\u3042\u0040\u65E5\u0040\u00F7\u2103\u0040\u0031\u25CB\uFF19\u25CB\u0041\u0061\u25CB\uFF21\uFF41\u25CB\uFF71\uFF6F\u25CB\u30A2\u30F6\u25CB\u3042\u25CB\u65E5\u25CB\u003A\u003C\u25CB", - PDU_CDMA_MSG_CODING_SHIFT_JIS, - undefined, - testDataBuffer5.length - ); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js b/dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js deleted file mode 100644 index f52c64cf8..000000000 --- a/dom/system/gonk/tests/test_ril_worker_sms_gsmpduhelper.js +++ /dev/null @@ -1,282 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Verify GsmPDUHelper#readDataCodingScheme. - */ -add_test(function test_GsmPDUHelper_readDataCodingScheme() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - function test_dcs(dcs, encoding, messageClass, mwi) { - helper.readHexOctet = function() { - return dcs; - } - - let msg = {}; - helper.readDataCodingScheme(msg); - - equal(msg.dcs, dcs); - equal(msg.encoding, encoding); - equal(msg.messageClass, messageClass); - equal(msg.mwi == null, mwi == null); - if (mwi != null) { - equal(msg.mwi.active, mwi.active); - equal(msg.mwi.discard, mwi.discard); - equal(msg.mwi.msgCount, mwi.msgCount); - } - } - - // Group 00xx - // Bit 3 and 2 indicate the character set being used. - test_dcs(0x00, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0x04, PDU_DCS_MSG_CODING_8BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0x08, PDU_DCS_MSG_CODING_16BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0x0C, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - // Bit 4, if set to 0, indicates that bits 1 to 0 are reserved and have no - // message class meaning. - test_dcs(0x01, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0x02, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0x03, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - // Bit 4, if set to 1, indicates that bits 1 to 0 have a message class meaning. - test_dcs(0x10, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]); - test_dcs(0x11, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]); - test_dcs(0x12, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]); - test_dcs(0x13, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]); - - // Group 01xx - test_dcs(0x50, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]); - - // Group 1000..1011: reserved - test_dcs(0x8F, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0x9F, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0xAF, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - test_dcs(0xBF, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL]); - - // Group 1100: Message Waiting Indication Group: Discard Message - // Bit 3 indicates Indication Sense: - test_dcs(0xC0, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: false, discard: true, msgCount: 0}); - test_dcs(0xC8, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: true, discard: true, msgCount: -1}); - // Bit 2 is reserved, and set to 0: - test_dcs(0xCC, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: true, discard: true, msgCount: -1}); - - // Group 1101: Message Waiting Indication Group: Store Message - // Bit 3 indicates Indication Sense: - test_dcs(0xD0, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: false, discard: false, msgCount: 0}); - test_dcs(0xD8, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: true, discard: false, msgCount: -1}); - // Bit 2 is reserved, and set to 0: - test_dcs(0xDC, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: true, discard: false, msgCount: -1}); - - // Group 1110: Message Waiting Indication Group: Store Message, UCS2 - // Bit 3 indicates Indication Sense: - test_dcs(0xE0, PDU_DCS_MSG_CODING_16BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: false, discard: false, msgCount: 0}); - test_dcs(0xE8, PDU_DCS_MSG_CODING_16BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: true, discard: false, msgCount: -1}); - // Bit 2 is reserved, and set to 0: - test_dcs(0xEC, PDU_DCS_MSG_CODING_16BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], - {active: true, discard: false, msgCount: -1}); - - // Group 1111 - test_dcs(0xF0, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]); - test_dcs(0xF1, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]); - test_dcs(0xF2, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]); - test_dcs(0xF3, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]); - test_dcs(0xF4, PDU_DCS_MSG_CODING_8BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]); - test_dcs(0xF5, PDU_DCS_MSG_CODING_8BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1]); - test_dcs(0xF6, PDU_DCS_MSG_CODING_8BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]); - test_dcs(0xF7, PDU_DCS_MSG_CODING_8BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3]); - // Bit 3 is reserved and should be set to 0, but if it doesn't we should - // ignore it. - test_dcs(0xF8, PDU_DCS_MSG_CODING_7BITS_ALPHABET, - GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0]); - - run_next_test(); -}); - -/** - * Verify GsmPDUHelper#writeStringAsSeptets() padding bits handling. - */ -add_test(function test_GsmPDUHelper_writeStringAsSeptets() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - helper.resetOctetWritten = function() { - helper.octetsWritten = 0; - }; - helper.writeHexOctet = function() { - helper.octetsWritten++; - }; - - let base = "AAAAAAAA"; // Base string of 8 characters long - for (let len = 0; len < 8; len++) { - let str = base.substring(0, len); - - for (let paddingBits = 0; paddingBits < 8; paddingBits++) { - do_print("Verifying GsmPDUHelper.writeStringAsSeptets(" - + str + ", " + paddingBits + ", <default>, <default>)"); - helper.resetOctetWritten(); - helper.writeStringAsSeptets(str, paddingBits, PDU_NL_IDENTIFIER_DEFAULT, - PDU_NL_IDENTIFIER_DEFAULT); - equal(Math.ceil(((len * 7) + paddingBits) / 8), - helper.octetsWritten); - } - } - - run_next_test(); -}); - -/** - * Verify that encoding with Spanish locking shift table generates the same - * septets as with GSM default alphabet table. - * - * Bug 1138841 - Incorrect Spanish national language locking shift table - * definition. - */ -add_test(function test_GsmPDUHelper_writeStringAsSeptets_spanish_fallback() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - let buf = []; - helper.writeHexOctet = function(octet) { - buf.push(octet); - } - - // Simple message string which is covered by GSM default alphabet. - let msg = "The quick brown fox jumps over the lazy dog"; - - // Encoded with GSM default alphabet. - helper.writeStringAsSeptets(msg, 0 /* paddingBits */, - PDU_NL_IDENTIFIER_DEFAULT, PDU_NL_IDENTIFIER_DEFAULT); - let octetsWithDefaultTable = buf; - buf = []; - - // Encoded with Spanish locking shift table. - helper.writeStringAsSeptets(msg, 0 /* paddingBits */, - PDU_NL_IDENTIFIER_SPANISH, PDU_NL_IDENTIFIER_SPANISH); - - // The length and content should be equal to what encoded with GSM default - // alphabet. - equal(octetsWithDefaultTable.length, buf.length); - for (let i = 0; i < buf.length; i++) { - equal(octetsWithDefaultTable[i], buf[i]); - } - - run_next_test(); -}); - -/** - * Verify GsmPDUHelper#readAddress - */ -add_test(function test_GsmPDUHelper_readAddress() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - function test_address(addrHex, addrString) { - let uint16Array = []; - let ix = 0; - for (let i = 0; i < addrHex.length; ++i) { - uint16Array[i] = addrHex[i].charCodeAt(); - } - - context.Buf.readUint16 = function(){ - if(ix >= uint16Array.length) { - do_throw("out of range in uint16Array"); - } - return uint16Array[ix++]; - } - let length = helper.readHexOctet(); - let parsedAddr = helper.readAddress(length); - equal(parsedAddr, addrString); - } - - // For AlphaNumeric - test_address("04D01100", "_@"); - test_address("04D01000", "\u0394@"); - - // Direct prepand - test_address("0B914151245584F6", "+14154255486"); - test_address("0E914151245584B633", "+14154255486#33"); - - // PDU_TOA_NATIONAL - test_address("0BA14151245584F6", "14154255486"); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js b/dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js deleted file mode 100644 index 32bc5dc2a..000000000 --- a/dom/system/gonk/tests/test_ril_worker_sms_nl_tables.js +++ /dev/null @@ -1,77 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -const ESCAPE = "\uffff"; -const RESCTL = "\ufffe"; -const LF = "\n"; -const CR = "\r"; -const SP = " "; -const FF = "\u000c"; - -function run_test() { - run_next_test(); -} - -/** - * Verify validity of the national language tables - */ -add_test(function test_nl_locking_shift_tables_validity() { - for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) { - do_print("Verifying PDU_NL_LOCKING_SHIFT_TABLES[" + lst + "]"); - - let table = PDU_NL_LOCKING_SHIFT_TABLES[lst]; - - // Make sure table length is 128, or it will break table lookup algorithm. - equal(table.length, 128); - - // Make sure special values are preserved. - equal(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE); - equal(table[PDU_NL_LINE_FEED], LF); - equal(table[PDU_NL_CARRIAGE_RETURN], CR); - equal(table[PDU_NL_SPACE], SP); - } - - run_next_test(); -}); - -add_test(function test_nl_single_shift_tables_validity() { - for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) { - do_print("Verifying PDU_NL_SINGLE_SHIFT_TABLES[" + sst + "]"); - - let table = PDU_NL_SINGLE_SHIFT_TABLES[sst]; - - // Make sure table length is 128, or it will break table lookup algorithm. - equal(table.length, 128); - - // Make sure special values are preserved. - equal(table[PDU_NL_EXTENDED_ESCAPE], ESCAPE); - equal(table[PDU_NL_PAGE_BREAK], FF); - equal(table[PDU_NL_RESERVED_CONTROL], RESCTL); - } - - run_next_test(); -}); - -add_test(function test_gsm_sms_strict_7bit_charmap_validity() { - let defaultTable = PDU_NL_LOCKING_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - let defaultShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[PDU_NL_IDENTIFIER_DEFAULT]; - for (let from in GSM_SMS_STRICT_7BIT_CHARMAP) { - let to = GSM_SMS_STRICT_7BIT_CHARMAP[from]; - do_print("Verifying GSM_SMS_STRICT_7BIT_CHARMAP[\"\\u0x" - + from.charCodeAt(0).toString(16) + "\"] => \"\\u" - + to.charCodeAt(0).toString(16) + "\""); - - // Make sure "from" is not in default table - equal(defaultTable.indexOf(from), -1); - equal(defaultShiftTable.indexOf(from), -1); - // Make sure "to" is in default table - if ((defaultTable.indexOf(to) < 0) - && (defaultShiftTable.indexOf(to) < 0)) { - equal(false, true); - } - } - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js b/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js deleted file mode 100644 index 2b29ac60e..000000000 --- a/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js +++ /dev/null @@ -1,115 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() { - let ns = {}; - Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns); - return ns.SmsSegmentHelper; -}); - -const ESCAPE = "\uffff"; -const RESCTL = "\ufffe"; - -function run_test() { - run_next_test(); -} - -/** - * Verify SmsSegmentHelper#countGsm7BitSeptets() and - * GsmPDUHelper#writeStringAsSeptets() algorithm match each other. - */ -add_test(function test_SmsSegmentHelper__countGsm7BitSeptets() { - let worker = newWorker({ - postRILMessage: function(data) { - // Do nothing - }, - postMessage: function(message) { - // Do nothing - } - }); - - let context = worker.ContextPool._contexts[0]; - let helper = context.GsmPDUHelper; - helper.resetOctetWritten = function() { - helper.octetsWritten = 0; - }; - helper.writeHexOctet = function() { - helper.octetsWritten++; - }; - - function do_check_calc(str, expectedCalcLen, lst, sst, strict7BitEncoding, strToWrite) { - equal(expectedCalcLen, - gSmsSegmentHelper - .countGsm7BitSeptets(str, - PDU_NL_LOCKING_SHIFT_TABLES[lst], - PDU_NL_SINGLE_SHIFT_TABLES[sst], - strict7BitEncoding)); - - helper.resetOctetWritten(); - strToWrite = strToWrite || str; - helper.writeStringAsSeptets(strToWrite, 0, lst, sst); - equal(Math.ceil(expectedCalcLen * 7 / 8), helper.octetsWritten); - } - - // Test calculation encoded message length using both locking/single shift tables. - for (let lst = 0; lst < PDU_NL_LOCKING_SHIFT_TABLES.length; lst++) { - let langTable = PDU_NL_LOCKING_SHIFT_TABLES[lst]; - - let str = langTable.substring(0, PDU_NL_EXTENDED_ESCAPE) - + langTable.substring(PDU_NL_EXTENDED_ESCAPE + 1); - - for (let sst = 0; sst < PDU_NL_SINGLE_SHIFT_TABLES.length; sst++) { - let langShiftTable = PDU_NL_SINGLE_SHIFT_TABLES[sst]; - - // <escape>, <resctrl> should be ignored. - do_check_calc(ESCAPE + RESCTL, 0, lst, sst); - - // Characters defined in locking shift table should be encoded directly. - do_check_calc(str, str.length, lst, sst); - - let [str1, str2] = ["", ""]; - for (let i = 0; i < langShiftTable.length; i++) { - if ((i == PDU_NL_EXTENDED_ESCAPE) || (i == PDU_NL_RESERVED_CONTROL)) { - continue; - } - - let c = langShiftTable[i]; - if (langTable.indexOf(c) >= 0) { - str1 += c; - } else { - str2 += c; - } - } - - // Characters found in both locking/single shift tables should be - // directly encoded. - do_check_calc(str1, str1.length, lst, sst); - - // Characters found only in single shift tables should be encoded as - // <escape><code>, therefore doubles its original length. - do_check_calc(str2, str2.length * 2, lst, sst); - } - } - - // Bug 790192: support strict GSM SMS 7-Bit encoding - let str = "", strToWrite = "", gsmLen = 0; - for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) { - str += c; - strToWrite += GSM_SMS_STRICT_7BIT_CHARMAP[c]; - if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) { - gsmLen += 1; - } else { - gsmLen += 2; - } - } - do_check_calc(str, gsmLen, - PDU_NL_IDENTIFIER_DEFAULT, PDU_NL_IDENTIFIER_DEFAULT, - true, strToWrite); - - run_next_test(); -}); - diff --git a/dom/system/gonk/tests/test_ril_worker_smsc_address.js b/dom/system/gonk/tests/test_ril_worker_smsc_address.js deleted file mode 100644 index c8c283b7c..000000000 --- a/dom/system/gonk/tests/test_ril_worker_smsc_address.js +++ /dev/null @@ -1,112 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -const SMSC_ATT = '+13123149810'; -const SMSC_ATT_TYPO = '+++1312@@@314$$$9,8,1,0'; -const SMSC_ATT_TEXT = '"+13123149810",145'; -const SMSC_ATT_TEXT_INCORRECT_TOA = '"+13123149810",129'; -const SMSC_ATT_PDU = '07913121139418F0'; -const SMSC_O2 = '+447802000332'; -const SMSC_O2_TEXT = '"+447802000332",145'; -const SMSC_O2_PDU = '0791448720003023'; -const SMSC_EMPTY = ''; -const SMSC_TON_UNKNOWN = '0407485455' -const SMSC_TON_UNKNOWN_TEXT = '"0407485455",129'; -const SMSC_TON_UNKNOWN_TEXT_NO_TOA = '"0407485455"'; -const SMSC_TON_UNKNOWN_TEXT_INVALID_TOA = '"0407485455",abc'; -const SMSC_TON_UNKNOWN_PDU = '06814070844555'; -const SMSC_EMPTY_PDU = 'FFFFFFFFFFFFFFFFFFFFFFFF'; -const SMSC_EMPTY_TEXT = ''; - -function run_test() { - run_next_test(); -} - -function setSmsc(context, smsc, ton, npi, expected) { - context.Buf.postRILMessage = function() { - equal(this.readString(), expected); - }; - - context.RIL.setSmscAddress({ - smscAddress: smsc, - typeOfNumber: ton, - numberPlanIdentification: npi - }); -} - -function getSmsc(worker, context, raw, smsc, ton, npi) { - worker.postMessage = function(message) { - equal(message.smscAddress, smsc); - equal(message.typeOfNumber, ton); - equal(message.numberPlanIdentification, npi); - } - - context.Buf.writeString(raw); - context.RIL[REQUEST_GET_SMSC_ADDRESS](0, { rilMessageType: "getSmscAddress"}); -} - -add_test(function test_setSmscAddress() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let parcelTypes = []; - context.Buf.newParcel = (type, options) => parcelTypes.push(type); - - // Test text mode. - worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "text"; - - setSmsc(context, SMSC_ATT, 1, 1, SMSC_ATT_TEXT); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - setSmsc(context, SMSC_O2, 1, 1, SMSC_O2_TEXT); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - setSmsc(context, SMSC_ATT_TYPO, 1, 1, SMSC_ATT_TEXT); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - setSmsc(context, SMSC_TON_UNKNOWN, 0, 1, SMSC_TON_UNKNOWN_TEXT); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - // Test pdu mode. - worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "pdu"; - - setSmsc(context, SMSC_ATT, 1, 1, SMSC_ATT_PDU); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - setSmsc(context, SMSC_O2, 1, 1, SMSC_O2_PDU); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - setSmsc(context, SMSC_ATT_TYPO, 1, 1, SMSC_ATT_PDU); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - setSmsc(context, SMSC_TON_UNKNOWN, 0, 1, SMSC_TON_UNKNOWN_PDU); - equal(parcelTypes.pop(), REQUEST_SET_SMSC_ADDRESS); - - run_next_test(); -}); - -add_test(function test_getSmscAddress() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - - // Test text mode. - worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "text"; - getSmsc(worker, context, SMSC_ATT_TEXT, SMSC_ATT, 1, 1); - getSmsc(worker, context, SMSC_ATT_TEXT_INCORRECT_TOA, SMSC_ATT, 1, 1); - getSmsc(worker, context, SMSC_O2_TEXT, SMSC_O2, 1, 1); - getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT, SMSC_TON_UNKNOWN, 0, 1); - getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT_NO_TOA, SMSC_TON_UNKNOWN, 0, 1); - getSmsc(worker, context, SMSC_TON_UNKNOWN_TEXT_INVALID_TOA, SMSC_TON_UNKNOWN, - 0, 1); - getSmsc(worker, context, SMSC_EMPTY_TEXT, SMSC_EMPTY, 0, 1); - - // Test pdu mode. - worker.RILQUIRKS_SMSC_ADDRESS_FORMAT = "pdu"; - getSmsc(worker, context, SMSC_ATT_PDU, SMSC_ATT, 1, 1); - getSmsc(worker, context, SMSC_O2_PDU, SMSC_O2, 1, 1); - getSmsc(worker, context, SMSC_TON_UNKNOWN_PDU, SMSC_TON_UNKNOWN, 0, 1); - getSmsc(worker, context, SMSC_EMPTY_PDU, SMSC_EMPTY, 0, 1); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_ssn.js b/dom/system/gonk/tests/test_ril_worker_ssn.js deleted file mode 100644 index ea0a2a599..000000000 --- a/dom/system/gonk/tests/test_ril_worker_ssn.js +++ /dev/null @@ -1,104 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_notification() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - function Call(callIndex, number) { - this.callIndex = callIndex; - this.number = number; - } - - Call.prototype = { - // Should use CALL_STATE_ACTIVE. - // Any new outgoing call (state = dialing or alerting) will be drop if there - // is no pending outgoing call created before. - state: CALL_STATE_ACTIVE, - //callIndex: 0, - toa: 0, - isMpty: false, - isMT: false, - als: 0, - isVoice: true, - isVoicePrivacy: false, - //number: null, - numberPresentation: 0, - name: null, - namePresentation: 0, - uusInfo: null - }; - - let oneCall = { - 0: new Call(0, '00000') - }; - - let twoCalls = { - 0: new Call(0, '00000'), - 1: new Call(1, '11111') - }; - - function testNotification(calls, code, number, resultNotification) { - - let testInfo = {calls: calls, code: code, number: number, - resultNotification: resultNotification}; - do_print('Test case info: ' + JSON.stringify(testInfo)); - - // Set current calls. - context.RIL.sendChromeMessage({ - rilMessageType: "currentCalls", - calls: calls - }); - - let notificationInfo = { - notificationType: 1, // MT - code: code, - index: 0, - type: 0, - number: number - }; - - context.RIL._processSuppSvcNotification(notificationInfo); - - let postedMessage = workerHelper.postedMessage; - equal(postedMessage.rilMessageType, 'suppSvcNotification'); - equal(postedMessage.number, number); - equal(postedMessage.notification, resultNotification); - - // Clear all existed calls. - context.RIL.sendChromeMessage({ - rilMessageType: "currentCalls", - calls: {} - }); - } - - testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, null, - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD); - - testNotification(oneCall, SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED, null, - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED); - - testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, null, - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD); - - testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_RETRIEVED, null, - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_RESUMED); - - testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, '00000', - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD); - - testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, '11111', - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD); - - testNotification(twoCalls, SUPP_SVC_NOTIFICATION_CODE2_PUT_ON_HOLD, '22222', - GECKO_SUPP_SVC_NOTIFICATION_REMOTE_HELD); - - run_next_test(); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_stk.js b/dom/system/gonk/tests/test_ril_worker_stk.js deleted file mode 100644 index 49b914e89..000000000 --- a/dom/system/gonk/tests/test_ril_worker_stk.js +++ /dev/null @@ -1,1698 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -/** - * Helper function. - */ -function newUint8SupportOutgoingIndexWorker() { - let worker = newWorker(); - let index = 4; // index for read - let buf = [0, 0, 0, 0]; // Preserved parcel size - let context = worker.ContextPool._contexts[0]; - - context.Buf.writeUint8 = function(value) { - if (context.Buf.outgoingIndex >= buf.length) { - buf.push(value); - } else { - buf[context.Buf.outgoingIndex] = value; - } - - context.Buf.outgoingIndex++; - }; - - context.Buf.readUint8 = function() { - return buf[index++]; - }; - - context.Buf.seekIncoming = function(offset) { - index += offset; - }; - - worker.debug = do_print; - - return worker; -} - -// Test RIL requests related to STK. -/** - * Verify if RIL.sendStkTerminalProfile be called. - */ -add_test(function test_if_send_stk_terminal_profile() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let profileSend = false; - context.RIL.sendStkTerminalProfile = function(data) { - profileSend = true; - }; - - let iccStatus = { - gsmUmtsSubscriptionAppIndex: 0, - apps: [{ - app_state: CARD_APPSTATE_READY, - app_type: CARD_APPTYPE_USIM - }], - }; - worker.RILQUIRKS_SEND_STK_PROFILE_DOWNLOAD = false; - - context.RIL._processICCStatus(iccStatus); - - equal(profileSend, false); - - run_next_test(); -}); - -/** - * Verify RIL.sendStkTerminalProfile - */ -add_test(function test_send_stk_terminal_profile() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let ril = context.RIL; - let buf = context.Buf; - - ril.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE); - - buf.seekIncoming(8); - let profile = buf.readString(); - for (let i = 0; i < STK_SUPPORTED_TERMINAL_PROFILE.length; i++) { - equal(parseInt(profile.substring(2 * i, 2 * i + 2), 16), - STK_SUPPORTED_TERMINAL_PROFILE[i]); - } - - run_next_test(); -}); - -/** - * Verify STK terminal response - */ -add_test(function test_stk_terminal_response() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE); - - // Token : we don't care - this.readInt32(); - - // Data Size, 44 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) + - // TLV_DEVICE_ID_SIZE(4) + - // TLV_RESULT_SIZE(3) + - // TEXT LENGTH(10)) - equal(this.readInt32(), 44); - - // Command Details, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 3); - equal(pduHelper.readHexOctet(), 0x01); - equal(pduHelper.readHexOctet(), STK_CMD_PROVIDE_LOCAL_INFO); - equal(pduHelper.readHexOctet(), STK_LOCAL_INFO_NNA); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Result - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_RESULT_OK); - - // Text - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 8); - equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_7BIT_PACKED); - equal(pduHelper.readSeptetsToString(7, 0, PDU_NL_IDENTIFIER_DEFAULT, - PDU_NL_IDENTIFIER_DEFAULT), "Mozilla"); - - run_next_test(); - }; - - let response = { - command: { - commandNumber: 0x01, - typeOfCommand: STK_CMD_PROVIDE_LOCAL_INFO, - commandQualifier: STK_LOCAL_INFO_NNA, - options: { - isPacked: true - } - }, - input: "Mozilla", - resultCode: STK_RESULT_OK - }; - context.RIL.sendStkTerminalResponse(response); -}); - -/** - * Verify STK terminal response : GET INPUT with empty string. - * - * @See |TERMINAL RESPONSE: GET INPUT 1.9.1A| of 27.22.4.3.1 GET INPUT (normal) - * in TS 102 384. - */ -add_test(function test_stk_terminal_response_get_input_empty_string() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE); - - // Token : we don't care - this.readInt32(); - - // Data Size, 30 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) + - // TLV_DEVICE_ID_SIZE(4) + - // TLV_RESULT_SIZE(3) + - // TEXT LENGTH(3)) - equal(this.readInt32(), 30); - - // Command Details, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 3); - equal(pduHelper.readHexOctet(), 0x01); - equal(pduHelper.readHexOctet(), STK_CMD_GET_INPUT); - equal(pduHelper.readHexOctet(), 0x00); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Result - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_RESULT_OK); - - // Text - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT); - - run_next_test(); - }; - - let response = { - command: { - commandNumber: 0x01, - typeOfCommand: STK_CMD_GET_INPUT, - commandQualifier: 0x00, - options: { - minLength: 0, - maxLength: 1, - defaultText: "<SEND>" - } - }, - input: "", - resultCode: STK_RESULT_OK - }; - context.RIL.sendStkTerminalResponse(response); -}); - -/** - * Verify STK terminal response : GET INPUT with 160 unpacked characters. - * - * @See |TERMINAL RESPONSE: GET INPUT 1.8.1| of 27.22.4.3.1 GET INPUT (normal) - * in TS 102 384. - */ -add_test(function test_stk_terminal_response_get_input_160_unpacked_characters() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - let iccPduHelper = context.ICCPDUHelper; - let TEST_TEXT_STRING = "***1111111111###" + - "***2222222222###" + - "***3333333333###" + - "***4444444444###" + - "***5555555555###" + - "***6666666666###" + - "***7777777777###" + - "***8888888888###" + - "***9999999999###" + - "***0000000000###"; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE); - - // Token : we don't care - this.readInt32(); - - // Data Size, 352 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) + - // TLV_DEVICE_ID_SIZE(4) + - // TLV_RESULT_SIZE(3) + - // TEXT LENGTH(164)) - equal(this.readInt32(), 352); - - // Command Details, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 3); - equal(pduHelper.readHexOctet(), 0x01); - equal(pduHelper.readHexOctet(), STK_CMD_GET_INPUT); - equal(pduHelper.readHexOctet(), 0x00); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Result - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_RESULT_OK); - - // Text - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING | - COMPREHENSIONTLV_FLAG_CR); - // C-TLV Length Encoding: 161 = 0x81 0xA1 - equal(pduHelper.readHexOctet(), 0x81); - equal(pduHelper.readHexOctet(), 0xA1); - equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT); - equal(iccPduHelper.read8BitUnpackedToString(160), TEST_TEXT_STRING); - - run_next_test(); - }; - - let response = { - command: { - commandNumber: 0x01, - typeOfCommand: STK_CMD_GET_INPUT, - commandQualifier: 0x00, - options: { - minLength: 160, - maxLength: 160, - text: TEST_TEXT_STRING - } - }, - input: TEST_TEXT_STRING, - resultCode: STK_RESULT_OK - }; - context.RIL.sendStkTerminalResponse(response); -}); - -/** - * Verify STK terminal response : GET_INKEY - NO_RESPONSE_FROM_USER with - * duration provided. - * - * @See |27.22.4.2.8 GET INKEY (Variable Time out)| in TS 102 384. - */ -add_test(function test_stk_terminal_response_get_inkey_no_response_from_user() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE); - - // Token : we don't care - this.readInt32(); - - // Data Size, 32 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) + - // TLV_DEVICE_ID_SIZE(4) + - // TLV_RESULT_SIZE(3) + - // DURATION(4)) - equal(this.readInt32(), 32); - - // Command Details, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 3); - equal(pduHelper.readHexOctet(), 0x01); - equal(pduHelper.readHexOctet(), STK_CMD_GET_INKEY); - equal(pduHelper.readHexOctet(), 0x00); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Result - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_RESULT_NO_RESPONSE_FROM_USER); - - // Duration, Type-Length-Value(Time unit, Time interval) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DURATION); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_TIME_UNIT_SECOND); - equal(pduHelper.readHexOctet(), 10); - - run_next_test(); - }; - - let response = { - command: { - commandNumber: 0x01, - typeOfCommand: STK_CMD_GET_INKEY, - commandQualifier: 0x00, - options: { - duration: { - timeUnit: STK_TIME_UNIT_SECOND, - timeInterval: 10 - }, - text: 'Enter "+"' - } - }, - resultCode: STK_RESULT_NO_RESPONSE_FROM_USER - }; - context.RIL.sendStkTerminalResponse(response); -}); - -/** - * Verify STK terminal response : GET_INKEY - YES/NO request - */ -add_test(function test_stk_terminal_response_get_inkey() { - function do_test(isYesNo) { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE); - - // Token : we don't care - this.readInt32(); - - // Data Size, 32 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) + - // TLV_DEVICE_ID_SIZE(4) + - // TLV_RESULT_SIZE(3) + - // TEXT LENGTH(4)) - equal(this.readInt32(), 32); - - // Command Details, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 3); - equal(pduHelper.readHexOctet(), 0x01); - equal(pduHelper.readHexOctet(), STK_CMD_GET_INKEY); - equal(pduHelper.readHexOctet(), 0x04); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Result - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_RESULT_OK); - - // Yes/No response - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_TEXT_STRING | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_TEXT_CODING_GSM_8BIT); - equal(pduHelper.readHexOctet(), isYesNo ? 0x01 : 0x00); - }; - - let response = { - command: { - commandNumber: 0x01, - typeOfCommand: STK_CMD_GET_INKEY, - commandQualifier: 0x04, - options: { - isYesNoRequested: true - } - }, - isYesNo: isYesNo, - resultCode: STK_RESULT_OK - }; - - context.RIL.sendStkTerminalResponse(response); - }; - - // Test "Yes" response - do_test(true); - // Test "No" response - do_test(false); - - run_next_test(); -}); - -/** - * Verify STK terminal response with additional information. - */ -add_test(function test_stk_terminal_response_with_additional_info() { - function do_test(aInfo) { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE); - - // Token : we don't care - this.readInt32(); - - // Data Length 26 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) + - // TLV_DEVICE_ID_SIZE(4) + - // TLV_RESULT_SIZE(4)) - equal(this.readInt32(), 26); - - // Command Details, Type-Length-Value(commandNumber, typeOfCommand, commandQualifier) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 3); - equal(pduHelper.readHexOctet(), 0x01); - equal(pduHelper.readHexOctet(), STK_CMD_DISPLAY_TEXT); - equal(pduHelper.readHexOctet(), 0x01); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Result, Type-Length-Value(General result, Additional information on result) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_RESULT | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS); - equal(pduHelper.readHexOctet(), aInfo); - }; - - let response = { - command: { - commandNumber: 0x01, - typeOfCommand: STK_CMD_DISPLAY_TEXT, - commandQualifier: 0x01, - options: { - isHighPriority: true - } - }, - resultCode: STK_RESULT_TERMINAL_CRNTLY_UNABLE_TO_PROCESS, - additionalInformation: aInfo - }; - - context.RIL.sendStkTerminalResponse(response); - }; - - do_test(0x01); // 'Screen is busy' - - run_next_test(); -}); - -// Test ComprehensionTlvHelper - -/** - * Verify ComprehensionTlvHelper.writeLocationInfoTlv - */ -add_test(function test_write_location_info_tlv() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let tlvHelper = context.ComprehensionTlvHelper; - - // Test with 2-digit mnc, and gsmCellId obtained from UMTS network. - let loc = { - mcc: "466", - mnc: "92", - gsmLocationAreaCode : 10291, - gsmCellId: 19072823 - }; - tlvHelper.writeLocationInfoTlv(loc); - - let tag = pduHelper.readHexOctet(); - equal(tag, COMPREHENSIONTLV_TAG_LOCATION_INFO | - COMPREHENSIONTLV_FLAG_CR); - - let length = pduHelper.readHexOctet(); - equal(length, 9); - - let mcc_mnc = pduHelper.readSwappedNibbleBcdString(3); - equal(mcc_mnc, "46692"); - - let lac = (pduHelper.readHexOctet() << 8) | pduHelper.readHexOctet(); - equal(lac, 10291); - - let cellId = (pduHelper.readHexOctet() << 24) | - (pduHelper.readHexOctet() << 16) | - (pduHelper.readHexOctet() << 8) | - (pduHelper.readHexOctet()); - equal(cellId, 19072823); - - // Test with 1-digit mnc, and gsmCellId obtained from GSM network. - loc = { - mcc: "466", - mnc: "02", - gsmLocationAreaCode : 10291, - gsmCellId: 65534 - }; - tlvHelper.writeLocationInfoTlv(loc); - - tag = pduHelper.readHexOctet(); - equal(tag, COMPREHENSIONTLV_TAG_LOCATION_INFO | - COMPREHENSIONTLV_FLAG_CR); - - length = pduHelper.readHexOctet(); - equal(length, 7); - - mcc_mnc = pduHelper.readSwappedNibbleBcdString(3); - equal(mcc_mnc, "46602"); - - lac = (pduHelper.readHexOctet() << 8) | pduHelper.readHexOctet(); - equal(lac, 10291); - - cellId = (pduHelper.readHexOctet() << 8) | (pduHelper.readHexOctet()); - equal(cellId, 65534); - - // Test with 3-digit mnc, and gsmCellId obtained from GSM network. - loc = { - mcc: "466", - mnc: "222", - gsmLocationAreaCode : 10291, - gsmCellId: 65534 - }; - tlvHelper.writeLocationInfoTlv(loc); - - tag = pduHelper.readHexOctet(); - equal(tag, COMPREHENSIONTLV_TAG_LOCATION_INFO | - COMPREHENSIONTLV_FLAG_CR); - - length = pduHelper.readHexOctet(); - equal(length, 7); - - mcc_mnc = pduHelper.readSwappedNibbleBcdString(3); - equal(mcc_mnc, "466222"); - - lac = (pduHelper.readHexOctet() << 8) | pduHelper.readHexOctet(); - equal(lac, 10291); - - cellId = (pduHelper.readHexOctet() << 8) | (pduHelper.readHexOctet()); - equal(cellId, 65534); - - run_next_test(); -}); - -/** - * Verify ComprehensionTlvHelper.writeErrorNumber - */ -add_test(function test_write_disconnecting_cause() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let tlvHelper = context.ComprehensionTlvHelper; - - tlvHelper.writeCauseTlv(RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BUSY]); - let tag = pduHelper.readHexOctet(); - equal(tag, COMPREHENSIONTLV_TAG_CAUSE | COMPREHENSIONTLV_FLAG_CR); - let len = pduHelper.readHexOctet(); - equal(len, 2); // We have one cause. - let standard = pduHelper.readHexOctet(); - equal(standard, 0x60); - let cause = pduHelper.readHexOctet(); - equal(cause, 0x80 | CALL_FAIL_BUSY); - - run_next_test(); -}); - -/** - * Verify ComprehensionTlvHelper.getSizeOfLengthOctets - */ -add_test(function test_get_size_of_length_octets() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let tlvHelper = context.ComprehensionTlvHelper; - - let length = 0x70; - equal(tlvHelper.getSizeOfLengthOctets(length), 1); - - length = 0x80; - equal(tlvHelper.getSizeOfLengthOctets(length), 2); - - length = 0x180; - equal(tlvHelper.getSizeOfLengthOctets(length), 3); - - length = 0x18000; - equal(tlvHelper.getSizeOfLengthOctets(length), 4); - - run_next_test(); -}); - -/** - * Verify ComprehensionTlvHelper.writeLength - */ -add_test(function test_write_length() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let tlvHelper = context.ComprehensionTlvHelper; - - let length = 0x70; - tlvHelper.writeLength(length); - equal(pduHelper.readHexOctet(), length); - - length = 0x80; - tlvHelper.writeLength(length); - equal(pduHelper.readHexOctet(), 0x81); - equal(pduHelper.readHexOctet(), length); - - length = 0x180; - tlvHelper.writeLength(length); - equal(pduHelper.readHexOctet(), 0x82); - equal(pduHelper.readHexOctet(), (length >> 8) & 0xff); - equal(pduHelper.readHexOctet(), length & 0xff); - - length = 0x18000; - tlvHelper.writeLength(length); - equal(pduHelper.readHexOctet(), 0x83); - equal(pduHelper.readHexOctet(), (length >> 16) & 0xff); - equal(pduHelper.readHexOctet(), (length >> 8) & 0xff); - equal(pduHelper.readHexOctet(), length & 0xff); - - run_next_test(); -}); - -// Test Proactive commands. - -function test_stk_proactive_command(aOptions) { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - let stkHelper = context.StkProactiveCmdHelper; - let stkFactory = context.StkCommandParamsFactory; - - let testPdu = aOptions.pdu; - let testTypeOfCommand = aOptions.typeOfCommand; - let testIcons = aOptions.icons; - let testFunc = aOptions.testFunc; - - if (testIcons) { - let ril = context.RIL; - ril.iccInfoPrivate.sst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30]; //IMG: 39 - ril.appType = CARD_APPTYPE_SIM; - - // skip asynchornous process in IconLoader.loadIcons(). - let iconLoader = context.IconLoader; - iconLoader.loadIcons = (recordNumbers, onsuccess, onerror) => { - onsuccess(testIcons); - }; - } - - for(let i = 0 ; i < testPdu.length; i++) { - pduHelper.writeHexOctet(testPdu[i]); - } - - let berTlv = berHelper.decode(testPdu.length); - let ctlvs = berTlv.value; - let ctlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs); - let cmdDetails = ctlv.value; - equal(cmdDetails.typeOfCommand, testTypeOfCommand); - - stkFactory.createParam(cmdDetails, ctlvs, (aResult) => { - cmdDetails.options = aResult; - testFunc(context, cmdDetails, ctlvs); - }); -} - -/** - * Verify Proactive command helper : searchForSelectedTags - */ -add_test(function test_stk_proactive_command_search_for_selected_tags() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - let stkHelper = context.StkProactiveCmdHelper; - - let tag_test = [ - 0xD0, - 0x3E, - 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x31, - 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x32, - 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x33, - 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x34, - 0x85, 0x0A, 0x61, 0x6C, 0x70, 0x68, 0x61, 0x20, 0x69, 0x64, 0x20, 0x35, - 0x85, 0x00]; - - for (let i = 0; i < tag_test.length; i++) { - pduHelper.writeHexOctet(tag_test[i]); - } - - let berTlv = berHelper.decode(tag_test.length); - let selectedCtlvs = - stkHelper.searchForSelectedTags(berTlv.value, [COMPREHENSIONTLV_TAG_ALPHA_ID]); - let tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - equal(tlv.value.identifier, "alpha id 1"); - - tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - equal(tlv.value.identifier, "alpha id 2"); - - tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - equal(tlv.value.identifier, "alpha id 3"); - - tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - equal(tlv.value.identifier, "alpha id 4"); - - tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - equal(tlv.value.identifier, "alpha id 5"); - - // emulate that the alpha identifier is provided and is a null data object, - // which is converted to an empty string in ICCPDUHelper. - tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - strictEqual(tlv.value.identifier, ""); - - // emulate that the alpha identifier is not provided - tlv = selectedCtlvs.retrieve(COMPREHENSIONTLV_TAG_ALPHA_ID); - strictEqual(tlv, undefined); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Refresh - */ -add_test(function test_stk_proactive_command_refresh() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x10, - 0x81, 0x03, 0x01, 0x01, 0x01, - 0x82, 0x02, 0x81, 0x82, - 0x92, 0x05, 0x01, 0x3F, 0x00, 0x2F, 0xE2 - ], - typeOfCommand: STK_CMD_REFRESH, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let stkHelper = context.StkProactiveCmdHelper; - let ctlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_FILE_LIST, ctlvs); - equal(ctlv.value.fileList, "3F002FE2"); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Play Tone - */ -add_test(function test_stk_proactive_command_play_tone() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x1F, - 0x81, 0x03, 0x01, 0x20, 0x00, - 0x82, 0x02, 0x81, 0x03, - 0x85, 0x09, 0x44, 0x69, 0x61, 0x6C, 0x20, 0x54, 0x6F, 0x6E, 0x65, - 0x8E, 0x01, 0x01, - 0x84, 0x02, 0x01, 0x05, - 0x9E, 0x02, 0x00, 0x01 - ], - typeOfCommand: STK_CMD_PLAY_TONE, - icons: [1], - testFunc: (context, cmdDetails, ctlvs) => { - let playTone = cmdDetails.options; - - equal(playTone.text, "Dial Tone"); - equal(playTone.tone, STK_TONE_TYPE_DIAL_TONE); - equal(playTone.duration.timeUnit, STK_TIME_UNIT_SECOND); - equal(playTone.duration.timeInterval, 5); - equal(playTone.iconSelfExplanatory, true); - equal(playTone.icons, 1); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Poll Interval - */ -add_test(function test_stk_proactive_command_poll_interval() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x0D, - 0x81, 0x03, 0x01, 0x03, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x84, 0x02, 0x01, 0x14 - ], - typeOfCommand: STK_CMD_POLL_INTERVAL, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let interval = cmdDetails.options; - - equal(interval.timeUnit, STK_TIME_UNIT_SECOND); - equal(interval.timeInterval, 0x14); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command: Display Text - */ -add_test(function test_stk_proactive_command_display_text() { - test_stk_proactive_command({ - pdu: [ - 0xd0, - 0x2c, - 0x81, 0x03, 0x01, 0x21, 0x80, - 0x82, 0x02, 0x81, 0x02, - 0x0d, 0x1d, 0x00, 0xd3, 0x30, 0x9b, 0xfc, 0x06, 0xc9, 0x5c, 0x30, 0x1a, - 0xa8, 0xe8, 0x02, 0x59, 0xc3, 0xec, 0x34, 0xb9, 0xac, 0x07, 0xc9, 0x60, - 0x2f, 0x58, 0xed, 0x15, 0x9b, 0xb9, 0x40, - 0x9e, 0x02, 0x00, 0x01 - ], - typeOfCommand: STK_CMD_DISPLAY_TEXT, - icons: [1], - testFunc: (context, cmdDetails, ctlvs) => { - let textMsg = cmdDetails.options; - - equal(textMsg.text, "Saldo 2.04 E. Validez 20/05/13. "); - equal(textMsg.iconSelfExplanatory, true); - equal(textMsg.icons, 1); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command: Set Up Event List. - */ -add_test(function test_stk_proactive_command_event_list() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x0F, - 0x81, 0x03, 0x01, 0x05, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x99, 0x04, 0x00, 0x01, 0x02, 0x03 - ], - typeOfCommand: STK_CMD_SET_UP_EVENT_LIST, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let event = cmdDetails.options; - - equal(Array.isArray(event.eventList), true); - - for (let i = 0; i < event.eventList.length; i++) { - equal(event.eventList[i], i); - } - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Get Input - */ -add_test(function test_stk_proactive_command_get_input() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x22, - 0x81, 0x03, 0x01, 0x23, 0x8F, - 0x82, 0x02, 0x81, 0x82, - 0x8D, 0x05, 0x04, 0x54, 0x65, 0x78, 0x74, - 0x91, 0x02, 0x01, 0x10, - 0x17, 0x08, 0x04, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, - 0x9E, 0x02, 0x00, 0x01 - ], - typeOfCommand: STK_CMD_GET_INPUT, - icons: [1], - testFunc: (context, cmdDetails, ctlvs) => { - let input = cmdDetails.options; - - equal(input.text, "Text"); - equal(input.isAlphabet, true); - equal(input.isUCS2, true); - equal(input.hideInput, true); - equal(input.isPacked, true); - equal(input.isHelpAvailable, true); - equal(input.minLength, 0x01); - equal(input.maxLength, 0x10); - equal(input.defaultText, "Default"); - equal(input.iconSelfExplanatory, true); - equal(input.icons, 1); - } - }); - - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x11, - 0x81, 0x03, 0x01, 0x23, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x8D, 0x00, - 0x91, 0x02, 0x01, 0x10, - 0x17, 0x00 - ], - typeOfCommand: STK_CMD_GET_INPUT, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let input = cmdDetails.options; - - equal(input.text, null); - equal(input.minLength, 0x01); - equal(input.maxLength, 0x10); - equal(input.defaultText, null); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : More Time - */ -add_test(function test_stk_proactive_command_more_time() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - let stkHelper = context.StkProactiveCmdHelper; - - let more_time_1 = [ - 0xD0, - 0x09, - 0x81, 0x03, 0x01, 0x02, 0x00, - 0x82, 0x02, 0x81, 0x82]; - - for(let i = 0 ; i < more_time_1.length; i++) { - pduHelper.writeHexOctet(more_time_1[i]); - } - - let berTlv = berHelper.decode(more_time_1.length); - let ctlvs = berTlv.value; - let tlv = stkHelper.searchForTag(COMPREHENSIONTLV_TAG_COMMAND_DETAILS, ctlvs); - equal(tlv.value.commandNumber, 0x01); - equal(tlv.value.typeOfCommand, STK_CMD_MORE_TIME); - equal(tlv.value.commandQualifier, 0x00); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Select Item - */ -add_test(function test_stk_proactive_command_select_item() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x3D, - 0x81, 0x03, 0x01, 0x24, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65, - 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31, - 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32, - 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33, - 0x18, 0x03, 0x10, 0x15, 0x20, - 0x90, 0x01, 0x01, - 0x9E, 0x02, 0x00, 0x01, - 0x9F, 0x04, 0x00, 0x01, 0x02, 0x03 - ], - typeOfCommand: STK_CMD_SELECT_ITEM, - icons: [1, 1, 2, 3], - testFunc: (context, cmdDetails, ctlvs) => { - let menu = cmdDetails.options; - - equal(menu.title, "Title"); - equal(menu.iconSelfExplanatory, true); - equal(menu.icons, 1); - equal(menu.items[0].identifier, 1); - equal(menu.items[0].text, "item 1"); - equal(menu.items[0].iconSelfExplanatory, true); - equal(menu.items[0].icons, 1); - equal(menu.items[1].identifier, 2); - equal(menu.items[1].text, "item 2"); - equal(menu.items[1].iconSelfExplanatory, true); - equal(menu.items[1].icons, 2); - equal(menu.items[2].identifier, 3); - equal(menu.items[2].text, "item 3"); - equal(menu.items[2].iconSelfExplanatory, true); - equal(menu.items[2].icons, 3); - equal(menu.nextActionList[0], STK_CMD_SET_UP_CALL); - equal(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER); - equal(menu.nextActionList[2], STK_CMD_PLAY_TONE); - equal(menu.defaultItem, 0x00); - } - }); - - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x33, - 0x81, 0x03, 0x01, 0x24, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65, - 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31, - 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32, - 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33, - 0x18, 0x03, 0x00, 0x15, 0x81, - 0x90, 0x01, 0x03 - ], - typeOfCommand: STK_CMD_SELECT_ITEM, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let menu = cmdDetails.options; - - equal(menu.title, "Title"); - equal(menu.items[0].identifier, 1); - equal(menu.items[0].text, "item 1"); - equal(menu.items[1].identifier, 2); - equal(menu.items[1].text, "item 2"); - equal(menu.items[2].identifier, 3); - equal(menu.items[2].text, "item 3"); - equal(menu.nextActionList[0], STK_NEXT_ACTION_NULL); - equal(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER); - equal(menu.nextActionList[2], STK_NEXT_ACTION_END_PROACTIVE_SESSION); - equal(menu.defaultItem, 0x02); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Set Up Menu - */ -add_test(function test_stk_proactive_command_set_up_menu() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x3A, - 0x81, 0x03, 0x01, 0x25, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65, - 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31, - 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32, - 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33, - 0x18, 0x03, 0x10, 0x15, 0x20, - 0x9E, 0x02, 0x00, 0x01, - 0x9F, 0x04, 0x00, 0x01, 0x02, 0x03 - ], - typeOfCommand: STK_CMD_SET_UP_MENU, - icons: [1, 1, 2, 3], - testFunc: (context, cmdDetails, ctlvs) => { - let menu = cmdDetails.options; - - equal(menu.title, "Title"); - equal(menu.iconSelfExplanatory, true); - equal(menu.icons, 1); - equal(menu.items[0].identifier, 1); - equal(menu.items[0].text, "item 1"); - equal(menu.items[0].iconSelfExplanatory, true); - equal(menu.items[0].icons, 1); - equal(menu.items[1].identifier, 2); - equal(menu.items[1].text, "item 2"); - equal(menu.items[1].iconSelfExplanatory, true); - equal(menu.items[1].icons, 2); - equal(menu.items[2].identifier, 3); - equal(menu.items[2].text, "item 3"); - equal(menu.items[2].iconSelfExplanatory, true); - equal(menu.items[2].icons, 3); - equal(menu.nextActionList[0], STK_CMD_SET_UP_CALL); - equal(menu.nextActionList[1], STK_CMD_LAUNCH_BROWSER); - equal(menu.nextActionList[2], STK_CMD_PLAY_TONE); - } - }); - - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x30, - 0x81, 0x03, 0x01, 0x25, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x05, 0x54, 0x69, 0x74, 0x6C, 0x65, - 0x8F, 0x07, 0x01, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x31, - 0x8F, 0x07, 0x02, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x32, - 0x8F, 0x07, 0x03, 0x69, 0x74, 0x65, 0x6D, 0x20, 0x33, - 0x18, 0x03, 0x81, 0x00, 0x00 - ], - typeOfCommand: STK_CMD_SET_UP_MENU, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let menu = cmdDetails.options; - - equal(menu.title, "Title"); - equal(menu.items[0].identifier, 1); - equal(menu.items[0].text, "item 1"); - equal(menu.items[1].identifier, 2); - equal(menu.items[1].text, "item 2"); - equal(menu.items[2].identifier, 3); - equal(menu.items[2].text, "item 3"); - equal(menu.nextActionList[0], STK_NEXT_ACTION_END_PROACTIVE_SESSION); - equal(menu.nextActionList[1], STK_NEXT_ACTION_NULL); - equal(menu.nextActionList[2], STK_NEXT_ACTION_NULL); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Set Up Call - */ -add_test(function test_stk_proactive_command_set_up_call() { - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x31, - 0x81, 0x03, 0x01, 0x10, 0x04, - 0x82, 0x02, 0x81, 0x82, - 0x05, 0x0A, 0x44, 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, - 0x86, 0x09, 0x81, 0x10, 0x32, 0x04, 0x21, 0x43, 0x65, 0x1C, 0x2C, - 0x05, 0x07, 0x4D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x9E, 0x02, 0x00, 0x01, - 0x9E, 0x02, 0x01, 0x02 - ], - typeOfCommand: STK_CMD_SET_UP_CALL, - icons: [1, 2], - testFunc: (context, cmdDetails, ctlvs) => { - let setupCall = cmdDetails.options; - - equal(setupCall.address, "012340123456,1,2"); - equal(setupCall.confirmMessage.text, "Disconnect"); - equal(setupCall.confirmMessage.iconSelfExplanatory, true); - equal(setupCall.confirmMessage.icons, 1); - equal(setupCall.callMessage.text, "Message"); - equal(setupCall.callMessage.iconSelfExplanatory, false); - equal(setupCall.callMessage.icons, 2); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Timer Management - */ -add_test(function test_stk_proactive_command_timer_management() { - // Timer Management - Start - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x11, - 0x81, 0x03, 0x01, 0x27, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0xA4, 0x01, 0x01, - 0xA5, 0x03, 0x10, 0x20, 0x30 - ], - typeOfCommand: STK_CMD_TIMER_MANAGEMENT, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - equal(cmdDetails.commandQualifier, STK_TIMER_START); - - let timer = cmdDetails.options; - - equal(timer.timerId, 0x01); - equal(timer.timerValue, (0x01 * 60 * 60) + (0x02 * 60) + 0x03); - } - }); - - // Timer Management - Deactivate - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x0C, - 0x81, 0x03, 0x01, 0x27, 0x01, - 0x82, 0x02, 0x81, 0x82, - 0xA4, 0x01, 0x01 - ], - typeOfCommand: STK_CMD_TIMER_MANAGEMENT, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - equal(cmdDetails.commandQualifier, STK_TIMER_DEACTIVATE); - - let timer = cmdDetails.options; - - equal(timer.timerId, 0x01); - ok(timer.timerValue === undefined); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive Command : Provide Local Information - */ -add_test(function test_stk_proactive_command_provide_local_information() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - let stkHelper = context.StkProactiveCmdHelper; - let stkCmdHelper = context.StkCommandParamsFactory; - - // Verify IMEI - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x09, - 0x81, 0x03, 0x01, 0x26, 0x01, - 0x82, 0x02, 0x81, 0x82 - ], - typeOfCommand: STK_CMD_PROVIDE_LOCAL_INFO, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - equal(cmdDetails.commandQualifier, STK_LOCAL_INFO_IMEI); - - let provideLocalInfo = cmdDetails.options; - equal(provideLocalInfo.localInfoType, STK_LOCAL_INFO_IMEI); - } - }); - - // Verify Date and Time Zone - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x09, - 0x81, 0x03, 0x01, 0x26, 0x03, - 0x82, 0x02, 0x81, 0x82 - ], - typeOfCommand: STK_CMD_PROVIDE_LOCAL_INFO, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - equal(cmdDetails.commandQualifier, STK_LOCAL_INFO_DATE_TIME_ZONE); - - let provideLocalInfo = cmdDetails.options; - equal(provideLocalInfo.localInfoType, STK_LOCAL_INFO_DATE_TIME_ZONE); - } - }); - - run_next_test(); -}); - -/** - * Verify Proactive command : BIP Messages - */ -add_test(function test_stk_proactive_command_open_channel() { - let worker = newUint8Worker(); - let context = worker.ContextPool._contexts[0]; - let pduHelper = context.GsmPDUHelper; - let berHelper = context.BerTlvHelper; - let stkHelper = context.StkProactiveCmdHelper; - let stkCmdHelper = context.StkCommandParamsFactory; - - // Open Channel - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x0F, - 0x81, 0x03, 0x01, 0x40, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x04, 0x4F, 0x70, 0x65, 0x6E //alpha id: "Open" - ], - typeOfCommand: STK_CMD_OPEN_CHANNEL, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let bipMsg = cmdDetails.options; - - equal(bipMsg.text, "Open"); - } - }); - - // Close Channel - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x10, - 0x81, 0x03, 0x01, 0x41, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x05, 0x43, 0x6C, 0x6F, 0x73, 0x65 //alpha id: "Close" - ], - typeOfCommand: STK_CMD_CLOSE_CHANNEL, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let bipMsg = cmdDetails.options; - - equal(bipMsg.text, "Close"); - } - }); - - // Receive Data - test_stk_proactive_command({ - pdu: [ - 0XD0, - 0X12, - 0x81, 0x03, 0x01, 0x42, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x07, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65 //alpha id: "Receive" - ], - typeOfCommand: STK_CMD_RECEIVE_DATA, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let bipMsg = cmdDetails.options; - - equal(bipMsg.text, "Receive"); - } - }); - - // Send Data - test_stk_proactive_command({ - pdu: [ - 0xD0, - 0x0F, - 0x81, 0x03, 0x01, 0x43, 0x00, - 0x82, 0x02, 0x81, 0x82, - 0x85, 0x04, 0x53, 0x65, 0x6E, 0x64 //alpha id: "Send" - ], - typeOfCommand: STK_CMD_SEND_DATA, - icons: null, - testFunc: (context, cmdDetails, ctlvs) => { - let bipMsg = cmdDetails.options; - - equal(bipMsg.text, "Send"); - } - }); - - run_next_test(); -}); - -/** - * Verify Event Download Command : Location Status - */ -add_test(function test_stk_event_download_location_status() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND); - - // Token : we don't care - this.readInt32(); - - // Data Size, 42 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + - // TLV_EVENT_LIST_SIZE(3) + - // TLV_LOCATION_STATUS_SIZE(3) + - // TLV_LOCATION_INFO_GSM_SIZE(9)) - equal(this.readInt32(), 42); - - // BER tag - equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG); - - // BER length, 19 = TLV_DEVICE_ID_SIZE(4) + - // TLV_EVENT_LIST_SIZE(3) + - // TLV_LOCATION_STATUS_SIZE(3) + - // TLV_LOCATION_INFO_GSM_SIZE(9) - equal(pduHelper.readHexOctet(), 19); - - // Event List, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_LOCATION_STATUS); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Location Status, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LOCATION_STATUS | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_SERVICE_STATE_NORMAL); - - // Location Info, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LOCATION_INFO | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 7); - - equal(pduHelper.readHexOctet(), 0x21); // MCC + MNC - equal(pduHelper.readHexOctet(), 0x63); - equal(pduHelper.readHexOctet(), 0x54); - equal(pduHelper.readHexOctet(), 0); // LAC - equal(pduHelper.readHexOctet(), 0); - equal(pduHelper.readHexOctet(), 0); // Cell ID - equal(pduHelper.readHexOctet(), 0); - - run_next_test(); - }; - - let event = { - eventType: STK_EVENT_TYPE_LOCATION_STATUS, - locationStatus: STK_SERVICE_STATE_NORMAL, - locationInfo: { - mcc: "123", - mnc: "456", - gsmLocationAreaCode: 0, - gsmCellId: 0 - } - }; - context.RIL.sendStkEventDownload({ - event: event - }); -}); - -// Test Event Download commands. - -/** - * Verify Event Download Command : Language Selection - */ -add_test(function test_stk_event_download_language_selection() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - let iccHelper = context.ICCPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND); - - // Token : we don't care - this.readInt32(); - - // Data Size, 26 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + - // TLV_EVENT_LIST_SIZE(3) + - // TLV_LANGUAGE(4)) - equal(this.readInt32(), 26); - - // BER tag - equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG); - - // BER length, 19 = TLV_DEVICE_ID_SIZE(4) + - // TLV_EVENT_LIST_SIZE(3) + - // TLV_LANGUAGE(4) - equal(pduHelper.readHexOctet(), 11); - - // Event List, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_LANGUAGE_SELECTION); - - // Device Identifies, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Language, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_LANGUAGE); - equal(pduHelper.readHexOctet(), 2); - equal(iccHelper.read8BitUnpackedToString(2), "zh"); - - run_next_test(); - }; - - let event = { - eventType: STK_EVENT_TYPE_LANGUAGE_SELECTION, - language: "zh" - }; - context.RIL.sendStkEventDownload({ - event: event - }); -}); - -/** - * Verify Event Download Command : User Activity - */ -add_test(function test_stk_event_download_user_activity() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND); - - // Token : we don't care - this.readInt32(); - - // Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3)) - equal(this.readInt32(), 18); - - // BER tag - equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG); - - // BER length, 7 = TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3) - equal(pduHelper.readHexOctet(), 7); - - // Event List, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_USER_ACTIVITY); - - // Device Identities, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - run_next_test(); - }; - - let event = { - eventType: STK_EVENT_TYPE_USER_ACTIVITY - }; - context.RIL.sendStkEventDownload({ - event: event - }); -}); - -/** - * Verify Event Download Command : Idle Screen Available - */ -add_test(function test_stk_event_download_idle_screen_available() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND); - - // Token : we don't care - this.readInt32(); - - // Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3)) - equal(this.readInt32(), 18); - - // BER tag - equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG); - - // BER length, 7 = TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3) - equal(pduHelper.readHexOctet(), 7); - - // Event List, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE); - - // Device Identities, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_DISPLAY); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - run_next_test(); - }; - - let event = { - eventType: STK_EVENT_TYPE_IDLE_SCREEN_AVAILABLE - }; - context.RIL.sendStkEventDownload({ - event: event - }); -}); - -/** - * Verify Event Downloaded Command :Browser Termination - */ -add_test(function test_stk_event_download_browser_termination() { - let worker = newUint8SupportOutgoingIndexWorker(); - let context = worker.ContextPool._contexts[0]; - let buf = context.Buf; - let pduHelper = context.GsmPDUHelper; - - buf.sendParcel = function() { - // Type - equal(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND); - - // Token : we don't care - this.readInt32(); - - // Data Size, 24 = 2 * ( 2+TLV_DEVICE_ID(4)+TLV_EVENT_LIST_SIZE(3) - // +TLV_BROWSER_TERMINATION_CAUSE(3) ) - equal(this.readInt32(), 24); - - // BER tag - equal(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG); - - // BER length, 10 = TLV_DEVICE_ID(4)+TLV_EVENT_LIST_SIZE(3) - // ++TLV_BROWSER_TERMINATION_CAUSE(3) - equal(pduHelper.readHexOctet(), 10); - - // Event List, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_EVENT_LIST | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_EVENT_TYPE_BROWSER_TERMINATION); - - // Device Identities, Type-Length-Value(Source ID-Destination ID) - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_DEVICE_ID | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 2); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_ME); - equal(pduHelper.readHexOctet(), STK_DEVICE_ID_SIM); - - // Browser Termination Case, Type-Length-Value - equal(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_BROWSER_TERMINATION_CAUSE | - COMPREHENSIONTLV_FLAG_CR); - equal(pduHelper.readHexOctet(), 1); - equal(pduHelper.readHexOctet(), STK_BROWSER_TERMINATION_CAUSE_USER); - - run_next_test(); - }; - - let event = { - eventType: STK_EVENT_TYPE_BROWSER_TERMINATION, - terminationCause: STK_BROWSER_TERMINATION_CAUSE_USER - }; - context.RIL.sendStkEventDownload({ - event: event - }); -}); diff --git a/dom/system/gonk/tests/test_ril_worker_voiceprivacy.js b/dom/system/gonk/tests/test_ril_worker_voiceprivacy.js deleted file mode 100644 index 21829da22..000000000 --- a/dom/system/gonk/tests/test_ril_worker_voiceprivacy.js +++ /dev/null @@ -1,94 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); - -function run_test() { - run_next_test(); -} - -add_test(function test_setVoicePrivacyMode_success() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setVoicePrivacyMode = function fakeSetVoicePrivacyMode(options) { - context.RIL[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE](0, {}); - }; - - context.RIL.setVoicePrivacyMode({ - enabled: true - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - - run_next_test(); -}); - -add_test(function test_setVoicePrivacyMode_generic_failure() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.RIL.setVoicePrivacyMode = function fakeSetVoicePrivacyMode(options) { - context.RIL[REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE](0, { - errorMsg: GECKO_ERROR_GENERIC_FAILURE - }); - }; - - context.RIL.setVoicePrivacyMode({ - enabled: true - }); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, GECKO_ERROR_GENERIC_FAILURE); - - run_next_test(); -}); - -add_test(function test_queryVoicePrivacyMode_success_enabled_true() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32List = function fakeReadUint32List() { - return [1]; - }; - - context.RIL.queryVoicePrivacyMode = function fakeQueryVoicePrivacyMode(options) { - context.RIL[REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE](1, {}); - }; - - context.RIL.queryVoicePrivacyMode(); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - ok(postedMessage.enabled); - run_next_test(); -}); - -add_test(function test_queryVoicePrivacyMode_success_enabled_false() { - let workerHelper = newInterceptWorker(); - let worker = workerHelper.worker; - let context = worker.ContextPool._contexts[0]; - - context.Buf.readInt32List = function fakeReadUint32List() { - return [0]; - }; - - context.RIL.queryVoicePrivacyMode = function fakeQueryVoicePrivacyMode(options) { - context.RIL[REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE](1, {}); - }; - - context.RIL.queryVoicePrivacyMode(); - - let postedMessage = workerHelper.postedMessage; - - equal(postedMessage.errorMsg, undefined); - ok(!postedMessage.enabled); - run_next_test(); -}); diff --git a/dom/system/gonk/tests/xpcshell.ini b/dom/system/gonk/tests/xpcshell.ini deleted file mode 100644 index 1e8b798a3..000000000 --- a/dom/system/gonk/tests/xpcshell.ini +++ /dev/null @@ -1,43 +0,0 @@ -[DEFAULT] -head = header_helpers.js -tail = - -[test_ril_worker_buf.js] -[test_ril_worker_icc_CardLock.js] -[test_ril_worker_icc_CardState.js] -[test_ril_worker_icc_BerTlvHelper.js] -[test_ril_worker_icc_GsmPDUHelper.js] -[test_ril_worker_icc_ICCContactHelper.js] -[test_ril_worker_icc_ICCIOHelper.js] -[test_ril_worker_icc_ICCPDUHelper.js] -[test_ril_worker_icc_ICCRecordHelper.js] -[test_ril_worker_icc_IconLoader.js] -[test_ril_worker_icc_ICCUtilsHelper.js] -[test_ril_worker_icc_SimRecordHelper.js] -[test_ril_worker_sms.js] -# Bug 916067 - B2G RIL: test_ril_worker_sms.js takes too long to finish -skip-if = true -[test_ril_worker_sms_cdma.js] -[test_ril_worker_sms_cdmapduhelper.js] -[test_ril_worker_sms_nl_tables.js] -[test_ril_worker_sms_gsmpduhelper.js] -[test_ril_worker_sms_segment_info.js] -[test_ril_worker_smsc_address.js] -[test_ril_worker_cf.js] -[test_ril_worker_cellbroadcast_config.js] -[test_ril_worker_cellbroadcast_gsm.js] -[test_ril_worker_cellbroadcast_umts.js] -[test_ril_worker_ruim.js] -[test_ril_worker_cw.js] -[test_ril_worker_clir.js] -[test_ril_worker_clip.js] -[test_ril_worker_ssn.js] -[test_ril_worker_voiceprivacy.js] -[test_ril_worker_ecm.js] -[test_ril_worker_stk.js] -requesttimeoutfactor = 4 -[test_ril_worker_barring_password.js] -[test_ril_worker_cdma_info_rec.js] -[test_ril_system_messenger.js] -# header_helpers.js is not needed for test_ril_system_messenger.js -head = |