Created
May 29, 2014 09:11
-
-
Save gobwas/f3f92a394b9aa5610c96 to your computer and use it in GitHub Desktop.
assert.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(global) { "use strict"; | |
var each = function(obj, iterator, context) { | |
if (obj == null) return; | |
if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) { | |
obj.forEach(iterator, context); | |
} else if (isArray(obj)) { | |
for (var i = 0, l = obj.length; i < l; i++) { | |
if (iterator.call(context, obj[i], i, obj) === {}) return; | |
} | |
} else { | |
for (var key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
if (iterator.call(context, obj[key], key, obj) === {}) return; | |
} | |
} | |
} | |
}; | |
/** | |
* Extends one object by multiple others. | |
* | |
* @param {object} to | |
* | |
* @returns {object} | |
*/ | |
var extend = function(to) { | |
each(Array.prototype.slice.call(arguments, 1), function(source) { | |
// underscore uses here for in loop, | |
// here we loop over just self props of source (aka hasOwnProperty); | |
each(source, function(value, prop) { | |
to[prop] = value; | |
}); | |
}); | |
return to; | |
}; | |
/** | |
* Inheritance function. | |
* | |
* @see https://gist.github.com/gobwas/6973933 | |
* @param {function} Parent | |
* @param {object} [protoProps] | |
* @param {object} [staticProps] | |
* | |
* @returns {function} | |
*/ | |
var inherits = function(Parent, protoProps, staticProps) { | |
var Child; | |
protoProps || (protoProps = {}); | |
staticProps || (staticProps = {}); | |
if (protoProps.hasOwnProperty("constructor") && typeof protoProps.constructor === 'function') { | |
Child = protoProps.constructor; | |
} else { | |
Child = function Child(){Parent.apply(this, arguments);}; | |
} | |
// set the static props to the new Enum | |
extend(Child, Parent, staticProps); | |
// create prototype of Child, that created with Parent prototype | |
// (without making Child.prototype = new Parent()) | |
// | |
// __proto__ <---- __proto__ | |
// ^ ^ | |
// | | | |
// Parent Child | |
// | |
function Surrogate(){} | |
Surrogate.prototype = Parent.prototype; | |
Child.prototype = new Surrogate(); | |
// extend prototype | |
extend(Child.prototype, protoProps, {constructor: Child}); | |
// link to Parent prototype | |
Child.__super__ = Parent.prototype; | |
return Child; | |
}; | |
var isArray = function(obj) { | |
return (Array.prototype.isArray && Array.prototype.isArray.call(obj)) || Object.prototype.toString.call(obj) === '[object Array]'; | |
}; | |
var isObject = function(obj) { | |
return Object.prototype.toString.call(obj) === '[object Object]'; | |
}; | |
var isFunction = function(obj) { | |
return Object.prototype.toString.call(obj) === '[object Function]'; | |
}; | |
var isString = function(obj) { | |
return Object.prototype.toString.call(obj) === '[object String]'; | |
}; | |
var isBoolean = function(obj) { | |
return Object.prototype.toString.call(obj) === '[object Boolean]'; | |
}; | |
var AssertionError = global.AssertionError = inherits(Error, { | |
constructor: function AssertionError() { | |
var error = Error.apply(null, arguments); | |
this.__error = error; | |
this.message = error.message; | |
this.stack = error.stack; | |
}, | |
name: "AssertionError", | |
message: "" | |
}); | |
function assert() { | |
var callback, description, assertion, valid = true; | |
assertion = Array.prototype.slice.call(arguments, 0); | |
if (assertion.length == 0) { | |
throw new Error("Empty assertion"); | |
} | |
if (isObject(assertion[0])) { | |
assertion = assertion[0].assertion; | |
description = assertion[0].description; | |
callback = assertion[0].callback; | |
} | |
each(assertion, function(assertion) { | |
if (isBoolean(assertion)) { | |
valid = valid && assertion; | |
} else if (isString(assertion)) { | |
description = assertion; | |
} else if (isFunction(assertion)) { | |
callback = assertion; | |
} | |
}); | |
if (valid === false) { | |
var err = new AssertionError(description || "Assertion failed"); | |
if (!isFunction(callback)) { | |
throw err; | |
} else { | |
callback.call(global, err, description); | |
return false; | |
} | |
} | |
return true; | |
} | |
// module registration | |
var isNode = typeof module !== "undefined" && module.exports, | |
isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd; | |
if (isNode) { | |
module.exports = assert; | |
} else if (isAMD) { | |
define([], function() {return assert;}); | |
} else { | |
global.assert = assert; | |
} | |
})(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment