duo-test
Version:
Duo's testing utility.
555 lines (458 loc) • 11.2 kB
JavaScript
(function outer(modules, cache, entries){
/**
* Global
*/
var global = (function(){ return this; })();
/**
* Require `name`.
*
* @param {String} name
* @param {Boolean} jumped
* @api public
*/
function require(name, jumped){
if (cache[name]) return cache[name].exports;
if (modules[name]) return call(name, require);
throw new Error('cannot find module "' + name + '"');
}
/**
* Call module `id` and cache it.
*
* @param {Number} id
* @param {Function} require
* @return {Function}
* @api private
*/
function call(id, require){
var m = cache[id] = { exports: {} };
var mod = modules[id];
var name = mod[2];
var fn = mod[0];
fn.call(m.exports, function(req){
var dep = modules[id][1][req];
return require(dep ? dep : req);
}, m, m.exports, outer, modules, cache, entries);
// expose as `name`.
if (name) cache[name] = cache[id];
return cache[id].exports;
}
/**
* Require all entries exposing them on global if needed.
*/
for (var id in entries) {
if (entries[id]) {
global[entries[id]] = require(id);
} else {
require(id);
}
}
/**
* Duo flag.
*/
require.duo = true;
/**
* Expose cache.
*/
require.cache = cache;
/**
* Expose modules
*/
require.modules = modules;
/**
* Return newest require.
*/
return require;
})({
1: [function(require, module, exports) {
describe('add', function(){
var assert = require('component/assert');
var add = require('../index');
it('should skip');
it('should add some numbers', function(){
assert.equal(2, add(1, 1));
});
it('should error', function(){
throw new Error('boom');
});
})
}, {"component/assert":2,"../index":3}],
2: [function(require, module, exports) {
/**
* Module dependencies.
*/
var equals = require('equals');
var fmt = require('fmt');
var stack = require('stack');
/**
* Assert `expr` with optional failure `msg`.
*
* @param {Mixed} expr
* @param {String} [msg]
* @api public
*/
module.exports = exports = function (expr, msg) {
if (expr) return;
throw new Error(msg || message());
};
/**
* Assert `actual` is weak equal to `expected`.
*
* @param {Mixed} actual
* @param {Mixed} expected
* @param {String} [msg]
* @api public
*/
exports.equal = function (actual, expected, msg) {
if (actual == expected) return;
throw new Error(msg || fmt('Expected %o to equal %o.', actual, expected));
};
/**
* Assert `actual` is not weak equal to `expected`.
*
* @param {Mixed} actual
* @param {Mixed} expected
* @param {String} [msg]
* @api public
*/
exports.notEqual = function (actual, expected, msg) {
if (actual != expected) return;
throw new Error(msg || fmt('Expected %o not to equal %o.', actual, expected));
};
/**
* Assert `actual` is deep equal to `expected`.
*
* @param {Mixed} actual
* @param {Mixed} expected
* @param {String} [msg]
* @api public
*/
exports.deepEqual = function (actual, expected, msg) {
if (equals(actual, expected)) return;
throw new Error(msg || fmt('Expected %o to deeply equal %o.', actual, expected));
};
/**
* Assert `actual` is not deep equal to `expected`.
*
* @param {Mixed} actual
* @param {Mixed} expected
* @param {String} [msg]
* @api public
*/
exports.notDeepEqual = function (actual, expected, msg) {
if (!equals(actual, expected)) return;
throw new Error(msg || fmt('Expected %o not to deeply equal %o.', actual, expected));
};
/**
* Assert `actual` is strict equal to `expected`.
*
* @param {Mixed} actual
* @param {Mixed} expected
* @param {String} [msg]
* @api public
*/
exports.strictEqual = function (actual, expected, msg) {
if (actual === expected) return;
throw new Error(msg || fmt('Expected %o to strictly equal %o.', actual, expected));
};
/**
* Assert `actual` is not strict equal to `expected`.
*
* @param {Mixed} actual
* @param {Mixed} expected
* @param {String} [msg]
* @api public
*/
exports.notStrictEqual = function (actual, expected, msg) {
if (actual !== expected) return;
throw new Error(msg || fmt('Expected %o not to strictly equal %o.', actual, expected));
};
/**
* Assert `block` throws an `error`.
*
* @param {Function} block
* @param {Function} [error]
* @param {String} [msg]
* @api public
*/
exports.throws = function (block, error, msg) {
var err;
try {
block();
} catch (e) {
err = e;
}
if (!err) throw new Error(msg || fmt('Expected %s to throw an error.', block.toString()));
if (error && !(err instanceof error)) {
throw new Error(msg || fmt('Expected %s to throw an %o.', block.toString(), error));
}
};
/**
* Assert `block` doesn't throw an `error`.
*
* @param {Function} block
* @param {Function} [error]
* @param {String} [msg]
* @api public
*/
exports.doesNotThrow = function (block, error, msg) {
var err;
try {
block();
} catch (e) {
err = e;
}
if (err) throw new Error(msg || fmt('Expected %s not to throw an error.', block.toString()));
if (error && (err instanceof error)) {
throw new Error(msg || fmt('Expected %s not to throw an %o.', block.toString(), error));
}
};
/**
* Create a message from the call stack.
*
* @return {String}
* @api private
*/
function message() {
if (!Error.captureStackTrace) return 'assertion failed';
var callsite = stack()[2];
var fn = callsite.getFunctionName();
var file = callsite.getFileName();
var line = callsite.getLineNumber() - 1;
var col = callsite.getColumnNumber() - 1;
var src = get(file);
line = src.split('\n')[line].slice(col);
var m = line.match(/assert\((.*)\)/);
return m && m[1].trim();
}
/**
* Load contents of `script`.
*
* @param {String} script
* @return {String}
* @api private
*/
function get(script) {
var xhr = new XMLHttpRequest;
xhr.open('GET', script, false);
xhr.send(null);
return xhr.responseText;
}
}, {"equals":4,"fmt":5,"stack":6}],
4: [function(require, module, exports) {
var type = require('type')
/**
* expose equals
*/
module.exports = equals
equals.compare = compare
/**
* assert all values are equal
*
* @param {Any} [...]
* @return {Boolean}
*/
function equals(){
var i = arguments.length - 1
while (i > 0) {
if (!compare(arguments[i], arguments[--i])) return false
}
return true
}
// (any, any, [array]) -> boolean
function compare(a, b, memos){
// All identical values are equivalent
if (a === b) return true
var fnA = types[type(a)]
var fnB = types[type(b)]
return fnA && fnA === fnB
? fnA(a, b, memos)
: false
}
var types = {}
// (Number) -> boolean
types.number = function(a){
// NaN check
return a !== a
}
// (function, function, array) -> boolean
types['function'] = function(a, b, memos){
return a.toString() === b.toString()
// Functions can act as objects
&& types.object(a, b, memos)
&& compare(a.prototype, b.prototype)
}
// (date, date) -> boolean
types.date = function(a, b){
return +a === +b
}
// (regexp, regexp) -> boolean
types.regexp = function(a, b){
return a.toString() === b.toString()
}
// (DOMElement, DOMElement) -> boolean
types.element = function(a, b){
return a.outerHTML === b.outerHTML
}
// (textnode, textnode) -> boolean
types.textnode = function(a, b){
return a.textContent === b.textContent
}
// decorate `fn` to prevent it re-checking objects
// (function) -> function
function memoGaurd(fn){
return function(a, b, memos){
if (!memos) return fn(a, b, [])
var i = memos.length, memo
while (memo = memos[--i]) {
if (memo[0] === a && memo[1] === b) return true
}
return fn(a, b, memos)
}
}
types['arguments'] =
types.array = memoGaurd(compareArrays)
// (array, array, array) -> boolean
function compareArrays(a, b, memos){
var i = a.length
if (i !== b.length) return false
memos.push([a, b])
while (i--) {
if (!compare(a[i], b[i], memos)) return false
}
return true
}
types.object = memoGaurd(compareObjects)
// (object, object, array) -> boolean
function compareObjects(a, b, memos) {
var ka = getEnumerableProperties(a)
var kb = getEnumerableProperties(b)
var i = ka.length
// same number of properties
if (i !== kb.length) return false
// although not necessarily the same order
ka.sort()
kb.sort()
// cheap key test
while (i--) if (ka[i] !== kb[i]) return false
// remember
memos.push([a, b])
// iterate again this time doing a thorough check
i = ka.length
while (i--) {
var key = ka[i]
if (!compare(a[key], b[key], memos)) return false
}
return true
}
// (object) -> array
function getEnumerableProperties (object) {
var result = []
for (var k in object) if (k !== 'constructor') {
result.push(k)
}
return result
}
}, {"type":7}],
7: [function(require, module, exports) {
var toString = {}.toString
var DomNode = typeof window != 'undefined'
? window.Node
: Function
/**
* Return the type of `val`.
*
* @param {Mixed} val
* @return {String}
* @api public
*/
module.exports = exports = function(x){
var type = typeof x
if (type != 'object') return type
type = types[toString.call(x)]
if (type) return type
if (x instanceof DomNode) switch (x.nodeType) {
case 1: return 'element'
case 3: return 'text-node'
case 9: return 'document'
case 11: return 'document-fragment'
default: return 'dom-node'
}
}
var types = exports.types = {
'[object Function]': 'function',
'[object Date]': 'date',
'[object RegExp]': 'regexp',
'[object Arguments]': 'arguments',
'[object Array]': 'array',
'[object String]': 'string',
'[object Null]': 'null',
'[object Undefined]': 'undefined',
'[object Number]': 'number',
'[object Boolean]': 'boolean',
'[object Object]': 'object',
'[object Text]': 'text-node',
'[object Uint8Array]': 'bit-array',
'[object Uint16Array]': 'bit-array',
'[object Uint32Array]': 'bit-array',
'[object Uint8ClampedArray]': 'bit-array',
'[object Error]': 'error',
'[object FormData]': 'form-data',
'[object File]': 'file',
'[object Blob]': 'blob'
}
}, {}],
5: [function(require, module, exports) {
/**
* Export `fmt`
*/
module.exports = fmt;
/**
* Formatters
*/
fmt.o = JSON.stringify;
fmt.s = String;
fmt.d = parseInt;
/**
* Format the given `str`.
*
* @param {String} str
* @param {...} args
* @return {String}
* @api public
*/
function fmt(str){
var args = [].slice.call(arguments, 1);
var j = 0;
return str.replace(/%([a-z])/gi, function(_, f){
return fmt[f]
? fmt[f](args[j++])
: _ + f;
});
}
}, {}],
6: [function(require, module, exports) {
/**
* Expose `stack()`.
*/
module.exports = stack;
/**
* Return the stack.
*
* @return {Array}
* @api public
*/
function stack() {
var orig = Error.prepareStackTrace;
Error.prepareStackTrace = function(_, stack){ return stack; };
var err = new Error;
Error.captureStackTrace(err, arguments.callee);
var stack = err.stack;
Error.prepareStackTrace = orig;
return stack;
}
}, {}],
3: [function(require, module, exports) {
module.exports = function(a, b){
return a + b;
};
}, {}]}, {}, {"1":""})