aboutsummaryrefslogtreecommitdiff
path: root/tools/addon-sdk-1.3/packages/api-utils/lib/test/assert.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/addon-sdk-1.3/packages/api-utils/lib/test/assert.js')
-rw-r--r--tools/addon-sdk-1.3/packages/api-utils/lib/test/assert.js360
1 files changed, 360 insertions, 0 deletions
diff --git a/tools/addon-sdk-1.3/packages/api-utils/lib/test/assert.js b/tools/addon-sdk-1.3/packages/api-utils/lib/test/assert.js
new file mode 100644
index 0000000..0c29d62
--- /dev/null
+++ b/tools/addon-sdk-1.3/packages/api-utils/lib/test/assert.js
@@ -0,0 +1,360 @@
+/* vim:ts=2:sts=2:sw=2:
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Jetpack.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Irakli Gozalishvili <gozala@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+"use strict";
+
+const { isFunction, isNull, isObject, isString, isRegExp, isArray, isDate,
+ isPrimitive, isUndefined, instanceOf, source } = require("../type");
+
+/**
+ * The `AssertionError` is defined in assert.
+ * @extends Error
+ * @example
+ * new assert.AssertionError({
+ * message: message,
+ * actual: actual,
+ * expected: expected
+ * })
+ */
+function AssertionError(options) {
+ let assertionError = Object.create(AssertionError.prototype);
+
+ if (isString(options))
+ options = { message: options };
+ if ("actual" in options)
+ assertionError.actual = options.actual;
+ if ("expected" in options)
+ assertionError.expected = options.expected;
+ if ("operator" in options)
+ assertionError.operator = options.operator;
+
+ assertionError.message = options.message;
+ assertionError.stack = new Error().stack;
+ return assertionError;
+}
+AssertionError.prototype = Object.create(Error.prototype, {
+ constructor: { value: AssertionError },
+ name: { value: "AssertionError", enumerable: true },
+ toString: { value: function toString() {
+ let value;
+ if (this.message) {
+ value = this.name + " : " + this.message;
+ }
+ else {
+ value = [
+ this.name + " : ",
+ source(this.expected),
+ this.operator,
+ source(this.actual)
+ ].join(" ");
+ }
+ return value;
+ }}
+});
+exports.AssertionError = AssertionError;
+
+function Assert(logger) {
+ return Object.create(Assert.prototype, { _log: { value: logger }});
+}
+Assert.prototype = {
+ fail: function fail(e) {
+ this._log.fail(e.message);
+ },
+ pass: function pass(message) {
+ this._log.pass(message);
+ },
+ error: function error(e) {
+ this._log.exception(e);
+ },
+ ok: function ok(value, message) {
+ if (!!!value) {
+ this.fail({
+ actual: value,
+ expected: true,
+ message: message,
+ operator: "=="
+ });
+ }
+ else {
+ this.pass(message);
+ }
+ },
+
+ /**
+ * The equality assertion tests shallow, coercive equality with `==`.
+ * @example
+ * assert.equal(1, 1, "one is one");
+ */
+ equal: function equal(actual, expected, message) {
+ if (actual == expected) {
+ this.pass(message);
+ }
+ else {
+ this.fail({
+ actual: actual,
+ expected: expected,
+ message: message,
+ operator: "=="
+ });
+ }
+ },
+
+ /**
+ * The non-equality assertion tests for whether two objects are not equal
+ * with `!=`.
+ * @example
+ * assert.notEqual(1, 2, "one is not two");
+ */
+ notEqual: function notEqual(actual, expected, message) {
+ if (actual != expected) {
+ this.pass(message);
+ }
+ else {
+ this.fail({
+ actual: actual,
+ expected: expected,
+ message: message,
+ operator: "!=",
+ });
+ }
+ },
+
+ /**
+ * The equivalence assertion tests a deep (with `===`) equality relation.
+ * @example
+ * assert.deepEqual({ a: "foo" }, { a: "foo" }, "equivalent objects")
+ */
+ deepEqual: function deepEqual(actual, expected, message) {
+ if (isDeepEqual(actual, expected)) {
+ this.pass(message);
+ }
+ else {
+ this.fail({
+ actual: actual,
+ expected: expected,
+ message: message,
+ operator: "deepEqual"
+ });
+ }
+ },
+
+ /**
+ * The non-equivalence assertion tests for any deep (with `===`) inequality.
+ * @example
+ * assert.notDeepEqual({ a: "foo" }, Object.create({ a: "foo" }),
+ * "object's inherit from different prototypes");
+ */
+ notDeepEqual: function notDeepEqual(actual, expected, message) {
+ if (!isDeepEqual(actual, expected)) {
+ this.pass(message);
+ }
+ else {
+ this.fail({
+ actual: actual,
+ expected: expected,
+ message: message,
+ operator: "notDeepEqual"
+ });
+ }
+ },
+
+ /**
+ * The strict equality assertion tests strict equality, as determined by
+ * `===`.
+ * @example
+ * assert.strictEqual(null, null, "`null` is `null`")
+ */
+ strictEqual: function strictEqual(actual, expected, message) {
+ if (actual === expected) {
+ this.pass(message);
+ }
+ else {
+ this.fail({
+ actual: actual,
+ expected: expected,
+ message: message,
+ operator: "==="
+ });
+ }
+ },
+
+ /**
+ * The strict non-equality assertion tests for strict inequality, as
+ * determined by `!==`.
+ * @example
+ * assert.notStrictEqual(null, undefined, "`null` is not `undefined`");
+ */
+ notStrictEqual: function notStrictEqual(actual, expected, message) {
+ if (actual !== expected) {
+ this.pass(message);
+ }
+ else {
+ this.fail({
+ actual: actual,
+ expected: expected,
+ message: message,
+ operator: "!=="
+ })
+ }
+ },
+
+ /**
+ * The assertion whether or not given `block` throws an exception. If optional
+ * `Error` argument is provided and it's type of function thrown error is
+ * asserted to be an instance of it, if type of `Error` is string then message
+ * of throw exception is asserted to contain it.
+ * @param {Function} block
+ * Function that is expected to throw.
+ * @param {Error|RegExp} [Error]
+ * Error constructor that is expected to be thrown or a string that
+ * must be contained by a message of the thrown exception, or a RegExp
+ * matching a message of the thrown exception.
+ * @param {String} message
+ * Description message
+ *
+ * @examples
+ *
+ * assert.throws(function block() {
+ * doSomething(4)
+ * }, "Object is expected", "Incorrect argument is passed");
+ *
+ * assert.throws(function block() {
+ * Object.create(5)
+ * }, TypeError, "TypeError is thrown");
+ */
+ throws: function throws(block, Error, message) {
+ let threw = false;
+ let exception = null;
+
+ // If third argument is not provided and second argument is a string it
+ // means that optional `Error` argument was not passed, so we shift
+ // arguments.
+ if (isString(Error) && isUndefined(message)) {
+ message = Error;
+ Error = undefined;
+ }
+
+ // Executing given `block`.
+ try {
+ block();
+ }
+ catch (e) {
+ threw = true;
+ exception = e;
+ }
+
+ // If exception was thrown and `Error` argument was not passed assert is
+ // passed.
+ if (threw && (isUndefined(Error) ||
+ // If passed `Error` is RegExp using it's test method to
+ // assert thrown exception message.
+ (isRegExp(Error) && Error.test(exception.message)) ||
+ // If passed `Error` is a constructor function testing if
+ // thrown exception is an instance of it.
+ (isFunction(Error) && instanceOf(exception, Error))))
+ {
+ this.pass(message);
+ }
+
+ // Otherwise we report assertion failure.
+ else {
+ let failure = {
+ message: message,
+ operator: "throws"
+ };
+
+ if (exception)
+ failure.actual = exception;
+
+ if (Error)
+ failure.expected = Error;
+
+ this.fail(failure);
+ }
+ }
+};
+exports.Assert = Assert;
+
+function isDeepEqual(actual, expected) {
+
+ // 7.1. All identical values are equivalent, as determined by ===.
+ if (actual === expected) {
+ 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 (isDate(actual) && isDate(expected)) {
+ return actual.getTime() === expected.getTime();
+ }
+
+ // XXX specification bug: this should be specified
+ else if (isPrimitive(actual) || isPrimitive(expected)) {
+ return expected === actual;
+ }
+
+ // 7.3. Other pairs that do not both pass typeof value == "object",
+ // equivalence is determined by ==.
+ else if (!isObject(actual) && !isObject(expected)) {
+ 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 actual.prototype === expected.prototype &&
+ isEquivalent(actual, expected);
+ }
+}
+
+function isEquivalent(a, b, stack) {
+ return isArrayEquivalent(Object.keys(a).sort(),
+ Object.keys(b).sort()) &&
+ Object.keys(a).every(function(key) {
+ return isDeepEqual(a[key], b[key], stack)
+ });
+}
+
+function isArrayEquivalent(a, b, stack) {
+ return isArray(a) && isArray(b) &&
+ a.every(function(value, index) {
+ return isDeepEqual(value, b[index]);
+ });
+}