Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added equiv. New assertion module.

  • Loading branch information...
commit b4506f5dc54bb2fbadaabf5fe91a68e791b658aa 1 parent 59f012d
@atesgoral authored
Showing with 525 additions and 0 deletions.
  1. +332 −0 assert.js
  2. +193 −0 equiv_and_hoozit.js
View
332 assert.js
@@ -0,0 +1,332 @@
+assert = typeof exports === "undefined" ? {} : exports;
+
+assert.AssertionError = function (message, actual, expected) {
+ this.message = message;
+ this.actual = actual;
+ this.expected = expected;
+};
+
+assert.error = function (block, message) {
+ try {
+ block();
+ } catch (e) {
+ return;
+ }
+
+ throw new assert.AssertionError(message, block);
+};
+
+assert.is = function (expected, actual, message) {
+ if (actual !== expected) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.isnt = function (expected, actual, message) {
+ if (actual === expected) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.isTrue = function (actual, message) {
+ assert.is(true, actual, message);
+};
+
+assert.isFalse = function (actual, message) {
+ assert.is(false, actual, message);
+};
+
+assert.match = function (expected, actual, message) {
+ if (!expected.test(actual)) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.notMatch = function (expected, actual, message) {
+ if (expected.test(actual)) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.typeOf = function (expected, actual, message) {
+ if (typeof actual !== expected) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.notTypeOf = function (expected, actual, message) {
+ if (typeof actual === expected) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.instanceOf = function (cls, actual, message) {
+ if (!(actual instanceof expected)) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+NotInstanceOf: function (cls, actual, message) {
+ if (actual instanceof cls) {
+ throw fmt("?: (?) is an instance of (?)",
+ message || "assertNotInstanceOf", actual, cls);
+ }
+},
+
+assert.isNull = function (actual, message) {
+ if (actual !== null) {
+ throw fmt("?: (?) is not null",
+ message || "assertNull", actual);
+ }
+};
+
+assert.isntNull = function (actual, message) {
+ if (actual === null) {
+ throw fmt("?: (?) is null",
+ message || "assertNotNull", actual);
+ }
+};
+
+assert.isUndefined = function (actual, message) {
+ if (actual !== undefined) {
+ throw fmt("?: (?) is not undefined",
+ message || "assertUndefined", actual);
+ }
+};
+
+assert.isntUndefined = function (actual, message) {
+ if (actual === undefined) {
+ throw fmt("?: (?) is undefined",
+ message || "assertNotUndefined", actual);
+ }
+};
+
+assert.isNaN = function (actual, message) {
+ if (!isNaN(actual)) {
+ throw fmt("?: (?) is not NaN",
+ message || "assertNaN", actual);
+ }
+};
+
+assert.isntNaN = function (actual, message) {
+ if (isNaN(actual)) {
+ throw fmt("?: (?) is NaN",
+ message || "assertNotNaN", actual);
+ }
+};
+
+assert.fail = function (message) {
+ throw new assert.AssertionError(message);
+};
+
+//assert.AssertionError.prototype = Error;
+
+(function () {
+
+// Determine what is o.
+function hoozit(o) {
+ if (o.constructor === String) {
+ return "string";
+
+ } else if (o.constructor === Boolean) {
+ return "boolean";
+
+ } else if (o.constructor === Number) {
+
+ if (isNaN(o)) {
+ return "nan";
+ } else {
+ return "number";
+ }
+
+ } else if (typeof o === "undefined") {
+ return "undefined";
+
+ // consider: typeof null === object
+ } else if (o === null) {
+ return "null";
+
+ // consider: typeof [] === object
+ } else if (o instanceof Array) {
+ return "array";
+
+ // consider: typeof new Date() === object
+ } else if (o instanceof Date) {
+ return "date";
+
+ // consider: /./ instanceof Object;
+ // /./ instanceof RegExp;
+ // typeof /./ === "function"; // => false in IE and Opera,
+ // true in FF and Safari
+ } else if (o instanceof RegExp) {
+ return "regexp";
+
+ } else if (typeof o === "object") {
+ return "object";
+
+ } else if (o instanceof Function) {
+ return "function";
+ } else {
+ return undefined;
+ }
+}
+
+// Call the o related callback with the given arguments.
+function bindCallbacks(o, callbacks, args) {
+ var prop = hoozit(o);
+ if (prop) {
+ if (hoozit(callbacks[prop]) === "function") {
+ return callbacks[prop].apply(callbacks, args);
+ } else {
+ return callbacks[prop]; // or undefined
+ }
+ }
+}
+// Test for equality any JavaScript type.
+// Discussions and reference: http://philrathe.com/articles/equiv
+// Test suites: http://philrathe.com/tests/equiv
+// Author: Philippe Rathé <prathe@gmail.com>
+
+var equiv = function () {
+
+ var innerEquiv; // the real equiv function
+ var callers = []; // stack to decide between skip/abort functions
+
+
+ var callbacks = function () {
+
+ // for string, boolean, number and null
+ function useStrictEquality(b, a) {
+ if (b instanceof a.constructor || a instanceof b.constructor) {
+ // to catch short annotaion VS 'new' annotation of a declaration
+ // e.g. var i = 1;
+ // var j = new Number(1);
+ return a == b;
+ } else {
+ return a === b;
+ }
+ }
+
+ return {
+ "string": useStrictEquality,
+ "boolean": useStrictEquality,
+ "number": useStrictEquality,
+ "null": useStrictEquality,
+ "undefined": useStrictEquality,
+
+ "nan": function (b) {
+ return isNaN(b);
+ },
+
+ "date": function (b, a) {
+ return hoozit(b) === "date" && a.valueOf() === b.valueOf();
+ },
+
+ "regexp": function (b, a) {
+ return hoozit(b) === "regexp" &&
+ a.source === b.source && // the regex itself
+ a.global === b.global && // and its modifers (gmi) ...
+ a.ignoreCase === b.ignoreCase &&
+ a.multiline === b.multiline;
+ },
+
+ // - skip when the property is a method of an instance (OOP)
+ // - abort otherwise,
+ // initial === would have catch identical references anyway
+ "function": function () {
+ var caller = callers[callers.length - 1];
+ return caller !== Object &&
+ typeof caller !== "undefined";
+ },
+
+ "array": function (b, a) {
+ var i;
+ var len;
+
+ // b could be an object literal here
+ if ( ! (hoozit(b) === "array")) {
+ return false;
+ }
+
+ len = a.length;
+ if (len !== b.length) { // safe and faster
+ return false;
+ }
+ for (i = 0; i < len; i++) {
+ if( ! innerEquiv(a[i], b[i])) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "object": function (b, a) {
+ var i;
+ var eq = true; // unless we can proove it
+ var aProperties = [], bProperties = []; // collection of strings
+
+ // comparing constructors is more strict than using instanceof
+ if ( a.constructor !== b.constructor) {
+ return false;
+ }
+
+ // stack constructor before traversing properties
+ callers.push(a.constructor);
+
+ for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
+
+ aProperties.push(i); // collect a's properties
+
+ if ( ! innerEquiv(a[i], b[i])) {
+ eq = false;
+ }
+ }
+
+ callers.pop(); // unstack, we are done
+
+ for (i in b) {
+ bProperties.push(i); // collect b's properties
+ }
+
+ // Ensures identical properties name
+ return eq && innerEquiv(aProperties.sort(), bProperties.sort());
+ }
+ };
+ }();
+
+ innerEquiv = function () { // can take multiple arguments
+ var args = Array.prototype.slice.apply(arguments);
+ if (args.length < 2) {
+ return true; // end transition
+ }
+
+ return (function (a, b) {
+ if (a === b) {
+ return true; // catch the most you can
+ } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || hoozit(a) !== hoozit(b)) {
+ return false; // don't lose time with error prone cases
+ } else {
+ return bindCallbacks(a, callbacks, [b, a]);
+ }
+
+ // apply transition with (1..n) arguments
+ })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
+ };
+
+ return innerEquiv;
+
+}();
+
+assert.eq = function (expected, actual, message) {
+ if (!equiv(expected, actual)) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+assert.neq = function (expected, actual, message) {
+ if (equiv(expected, actual)) {
+ throw new assert.AssertionError(message, actual, expected);
+ }
+};
+
+})();
View
193 equiv_and_hoozit.js
@@ -0,0 +1,193 @@
+// Determine what is o.
+function hoozit(o) {
+ if (o.constructor === String) {
+ return "string";
+
+ } else if (o.constructor === Boolean) {
+ return "boolean";
+
+ } else if (o.constructor === Number) {
+
+ if (isNaN(o)) {
+ return "nan";
+ } else {
+ return "number";
+ }
+
+ } else if (typeof o === "undefined") {
+ return "undefined";
+
+ // consider: typeof null === object
+ } else if (o === null) {
+ return "null";
+
+ // consider: typeof [] === object
+ } else if (o instanceof Array) {
+ return "array";
+
+ // consider: typeof new Date() === object
+ } else if (o instanceof Date) {
+ return "date";
+
+ // consider: /./ instanceof Object;
+ // /./ instanceof RegExp;
+ // typeof /./ === "function"; // => false in IE and Opera,
+ // true in FF and Safari
+ } else if (o instanceof RegExp) {
+ return "regexp";
+
+ } else if (typeof o === "object") {
+ return "object";
+
+ } else if (o instanceof Function) {
+ return "function";
+ } else {
+ return undefined;
+ }
+}
+
+// Call the o related callback with the given arguments.
+function bindCallbacks(o, callbacks, args) {
+ var prop = hoozit(o);
+ if (prop) {
+ if (hoozit(callbacks[prop]) === "function") {
+ return callbacks[prop].apply(callbacks, args);
+ } else {
+ return callbacks[prop]; // or undefined
+ }
+ }
+}
+// Test for equality any JavaScript type.
+// Discussions and reference: http://philrathe.com/articles/equiv
+// Test suites: http://philrathe.com/tests/equiv
+// Author: Philippe Rathé <prathe@gmail.com>
+
+var equiv = function () {
+
+ var innerEquiv; // the real equiv function
+ var callers = []; // stack to decide between skip/abort functions
+
+
+ var callbacks = function () {
+
+ // for string, boolean, number and null
+ function useStrictEquality(b, a) {
+ if (b instanceof a.constructor || a instanceof b.constructor) {
+ // to catch short annotaion VS 'new' annotation of a declaration
+ // e.g. var i = 1;
+ // var j = new Number(1);
+ return a == b;
+ } else {
+ return a === b;
+ }
+ }
+
+ return {
+ "string": useStrictEquality,
+ "boolean": useStrictEquality,
+ "number": useStrictEquality,
+ "null": useStrictEquality,
+ "undefined": useStrictEquality,
+
+ "nan": function (b) {
+ return isNaN(b);
+ },
+
+ "date": function (b, a) {
+ return hoozit(b) === "date" && a.valueOf() === b.valueOf();
+ },
+
+ "regexp": function (b, a) {
+ return hoozit(b) === "regexp" &&
+ a.source === b.source && // the regex itself
+ a.global === b.global && // and its modifers (gmi) ...
+ a.ignoreCase === b.ignoreCase &&
+ a.multiline === b.multiline;
+ },
+
+ // - skip when the property is a method of an instance (OOP)
+ // - abort otherwise,
+ // initial === would have catch identical references anyway
+ "function": function () {
+ var caller = callers[callers.length - 1];
+ return caller !== Object &&
+ typeof caller !== "undefined";
+ },
+
+ "array": function (b, a) {
+ var i;
+ var len;
+
+ // b could be an object literal here
+ if ( ! (hoozit(b) === "array")) {
+ return false;
+ }
+
+ len = a.length;
+ if (len !== b.length) { // safe and faster
+ return false;
+ }
+ for (i = 0; i < len; i++) {
+ if( ! innerEquiv(a[i], b[i])) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "object": function (b, a) {
+ var i;
+ var eq = true; // unless we can proove it
+ var aProperties = [], bProperties = []; // collection of strings
+
+ // comparing constructors is more strict than using instanceof
+ if ( a.constructor !== b.constructor) {
+ return false;
+ }
+
+ // stack constructor before traversing properties
+ callers.push(a.constructor);
+
+ for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
+
+ aProperties.push(i); // collect a's properties
+
+ if ( ! innerEquiv(a[i], b[i])) {
+ eq = false;
+ }
+ }
+
+ callers.pop(); // unstack, we are done
+
+ for (i in b) {
+ bProperties.push(i); // collect b's properties
+ }
+
+ // Ensures identical properties name
+ return eq && innerEquiv(aProperties.sort(), bProperties.sort());
+ }
+ };
+ }();
+
+ innerEquiv = function () { // can take multiple arguments
+ var args = Array.prototype.slice.apply(arguments);
+ if (args.length < 2) {
+ return true; // end transition
+ }
+
+ return (function (a, b) {
+ if (a === b) {
+ return true; // catch the most you can
+ } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || hoozit(a) !== hoozit(b)) {
+ return false; // don't lose time with error prone cases
+ } else {
+ return bindCallbacks(a, callbacks, [b, a]);
+ }
+
+ // apply transition with (1..n) arguments
+ })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
+ };
+
+ return innerEquiv;
+
+}();
Please sign in to comment.
Something went wrong with that request. Please try again.