UNPKG

jack-chai

Version:

Chai.js assertions for Jack.js test doubles

1,370 lines (1,170 loc) 32.3 kB
;(function(){ /** * Require the given path. * * @param {String} path * @return {Object} exports * @api public */ function require(path, parent, orig) { var resolved = require.resolve(path); // lookup failed if (null == resolved) { orig = orig || path; parent = parent || 'root'; var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); err.path = orig; err.parent = parent; err.require = true; throw err; } var module = require.modules[resolved]; // perform real require() // by invoking the module's // registered function if (!module._resolving && !module.exports) { var mod = {}; mod.exports = {}; mod.client = mod.component = true; module._resolving = true; module.call(this, mod.exports, require.relative(resolved), mod); delete module._resolving; module.exports = mod.exports; } return module.exports; } /** * Registered modules. */ require.modules = {}; /** * Registered aliases. */ require.aliases = {}; /** * Resolve `path`. * * Lookup: * * - PATH/index.js * - PATH.js * - PATH * * @param {String} path * @return {String} path or null * @api private */ require.resolve = function(path) { if (path.charAt(0) === '/') path = path.slice(1); var paths = [ path, path + '.js', path + '.json', path + '/index.js', path + '/index.json' ]; for (var i = 0; i < paths.length; i++) { var path = paths[i]; if (require.modules.hasOwnProperty(path)) return path; if (require.aliases.hasOwnProperty(path)) return require.aliases[path]; } }; /** * Normalize `path` relative to the current path. * * @param {String} curr * @param {String} path * @return {String} * @api private */ require.normalize = function(curr, path) { var segs = []; if ('.' != path.charAt(0)) return path; curr = curr.split('/'); path = path.split('/'); for (var i = 0; i < path.length; ++i) { if ('..' == path[i]) { curr.pop(); } else if ('.' != path[i] && '' != path[i]) { segs.push(path[i]); } } return curr.concat(segs).join('/'); }; /** * Register module at `path` with callback `definition`. * * @param {String} path * @param {Function} definition * @api private */ require.register = function(path, definition) { require.modules[path] = definition; }; /** * Alias a module definition. * * @param {String} from * @param {String} to * @api private */ require.alias = function(from, to) { if (!require.modules.hasOwnProperty(from)) { throw new Error('Failed to alias "' + from + '", it does not exist'); } require.aliases[to] = from; }; /** * Return a require function relative to the `parent` path. * * @param {String} parent * @return {Function} * @api private */ require.relative = function(parent) { var p = require.normalize(parent, '..'); /** * lastIndexOf helper. */ function lastIndexOf(arr, obj) { var i = arr.length; while (i--) { if (arr[i] === obj) return i; } return -1; } /** * The relative require() itself. */ function localRequire(path) { var resolved = localRequire.resolve(path); return require(resolved, parent, path); } /** * Resolve relative to the parent. */ localRequire.resolve = function(path) { var c = path.charAt(0); if ('/' == c) return path.slice(1); if ('.' == c) return require.normalize(p, path); // resolve deps by returning // the dep in the nearest "deps" // directory var segs = parent.split('/'); var i = lastIndexOf(segs, 'deps') + 1; if (!i) i = 0; path = segs.slice(0, i + 1).join('/') + '/deps/' + path; return path; }; /** * Check if module is defined at `path`. */ localRequire.exists = function(path) { return require.modules.hasOwnProperty(localRequire.resolve(path)); }; return localRequire; }; require.register("chaijs-type-detect/lib/type.js", function(exports, require, module){ /*! * type-detect * Copyright(c) 2013 jake luer <jake@alogicalparadox.com> * MIT Licensed */ /*! * Primary Exports */ var exports = module.exports = getType; /*! * Detectable javascript natives */ var natives = { '[object Array]': 'array' , '[object RegExp]': 'regexp' , '[object Function]': 'function' , '[object Arguments]': 'arguments' , '[object Date]': 'date' }; /** * ### typeOf (obj) * * Use several different techniques to determine * the type of object being tested. * * * @param {Mixed} object * @return {String} object type * @api public */ function getType (obj) { var str = Object.prototype.toString.call(obj); if (natives[str]) return natives[str]; if (obj === null) return 'null'; if (obj === undefined) return 'undefined'; if (obj === Object(obj)) return 'object'; return typeof obj; } exports.Library = Library; /** * ### Library * * Create a repository for custom type detection. * * ```js * var lib = new type.Library; * ``` * */ function Library () { this.tests = {}; } /** * #### .of (obj) * * Expose replacement `typeof` detection to the library. * * ```js * if ('string' === lib.of('hello world')) { * // ... * } * ``` * * @param {Mixed} object to test * @return {String} type */ Library.prototype.of = getType; /** * #### .define (type, test) * * Add a test to for the `.test()` assertion. * * Can be defined as a regular expression: * * ```js * lib.define('int', /^[0-9]+$/); * ``` * * ... or as a function: * * ```js * lib.define('bln', function (obj) { * if ('boolean' === lib.of(obj)) return true; * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); * return !! ~blns.indexOf(obj); * }); * ``` * * @param {String} type * @param {RegExp|Function} test * @api public */ Library.prototype.define = function (type, test) { if (arguments.length === 1) return this.tests[type]; this.tests[type] = test; return this; }; /** * #### .test (obj, test) * * Assert that an object is of type. Will first * check natives, and if that does not pass it will * use the user defined custom tests. * * ```js * assert(lib.test('1', 'int')); * assert(lib.test('yes', 'bln')); * ``` * * @param {Mixed} object * @param {String} type * @return {Boolean} result * @api public */ Library.prototype.test = function (obj, type) { if (type === getType(obj)) return true; var test = this.tests[type]; if (test && 'regexp' === getType(test)) { return test.test(obj); } else if (test && 'function' === getType(test)) { return test(obj); } else { throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); } }; }); require.register("chaijs-deep-eql/lib/eql.js", function(exports, require, module){ /*! * deep-eql * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /*! * Module dependencies */ var type = require('type-detect'); /*! * Buffer.isBuffer browser shim */ var Buffer; try { Buffer = require('buffer').Buffer; } catch(ex) { Buffer = {}; Buffer.isBuffer = function() { return false; } } /*! * Primary Export */ module.exports = deepEqual; /** * Assert super-strict (egal) equality between * two objects of any type. * * @param {Mixed} a * @param {Mixed} b * @param {Array} memoised (optional) * @return {Boolean} equal match */ function deepEqual(a, b, m) { if (sameValue(a, b)) { return true; } else if ('date' === type(a)) { return dateEqual(a, b); } else if ('regexp' === type(a)) { return regexpEqual(a, b); } else if (Buffer.isBuffer(a)) { return bufferEqual(a, b); } else if ('arguments' === type(a)) { return argumentsEqual(a, b, m); } else if (!typeEqual(a, b)) { return false; } else if (('object' !== type(a) && 'object' !== type(b)) && ('array' !== type(a) && 'array' !== type(b))) { return sameValue(a, b); } else { return objectEqual(a, b, m); } } /*! * Strict (egal) equality test. Ensures that NaN always * equals NaN and `-0` does not equal `+0`. * * @param {Mixed} a * @param {Mixed} b * @return {Boolean} equal match */ function sameValue(a, b) { if (a === b) return a !== 0 || 1 / a === 1 / b; return a !== a && b !== b; } /*! * Compare the types of two given objects and * return if they are equal. Note that an Array * has a type of `array` (not `object`) and arguments * have a type of `arguments` (not `array`/`object`). * * @param {Mixed} a * @param {Mixed} b * @return {Boolean} result */ function typeEqual(a, b) { return type(a) === type(b); } /*! * Compare two Date objects by asserting that * the time values are equal using `saveValue`. * * @param {Date} a * @param {Date} b * @return {Boolean} result */ function dateEqual(a, b) { if ('date' !== type(b)) return false; return sameValue(a.getTime(), b.getTime()); } /*! * Compare two regular expressions by converting them * to string and checking for `sameValue`. * * @param {RegExp} a * @param {RegExp} b * @return {Boolean} result */ function regexpEqual(a, b) { if ('regexp' !== type(b)) return false; return sameValue(a.toString(), b.toString()); } /*! * Assert deep equality of two `arguments` objects. * Unfortunately, these must be sliced to arrays * prior to test to ensure no bad behavior. * * @param {Arguments} a * @param {Arguments} b * @param {Array} memoize (optional) * @return {Boolean} result */ function argumentsEqual(a, b, m) { if ('arguments' !== type(b)) return false; a = [].slice.call(a); b = [].slice.call(b); return deepEqual(a, b, m); } /*! * Get enumerable properties of a given object. * * @param {Object} a * @return {Array} property names */ function enumerable(a) { var res = []; for (var key in a) res.push(key); return res; } /*! * Simple equality for flat iterable objects * such as Arrays or Node.js buffers. * * @param {Iterable} a * @param {Iterable} b * @return {Boolean} result */ function iterableEqual(a, b) { if (a.length !== b.length) return false; var i = 0; var match = true; for (; i < a.length; i++) { if (a[i] !== b[i]) { match = false; break; } } return match; } /*! * Extension to `iterableEqual` specifically * for Node.js Buffers. * * @param {Buffer} a * @param {Mixed} b * @return {Boolean} result */ function bufferEqual(a, b) { if (!Buffer.isBuffer(b)) return false; return iterableEqual(a, b); } /*! * Block for `objectEqual` ensuring non-existing * values don't get in. * * @param {Mixed} object * @return {Boolean} result */ function isValue(a) { return a !== null && a !== undefined; } /*! * Recursively check the equality of two objects. * Once basic sameness has been established it will * defer to `deepEqual` for each enumerable key * in the object. * * @param {Mixed} a * @param {Mixed} b * @return {Boolean} result */ function objectEqual(a, b, m) { if (!isValue(a) || !isValue(b)) { return false; } if (a.prototype !== b.prototype) { return false; } var i; if (m) { for (i = 0; i < m.length; i++) { if ((m[i][0] === a && m[i][1] === b) || (m[i][0] === b && m[i][1] === a)) { return true; } } } else { m = []; } try { var ka = enumerable(a); var kb = enumerable(b); } catch (ex) { return false; } ka.sort(); kb.sort(); if (!iterableEqual(ka, kb)) { return false; } m.push([ a, b ]); var key; for (i = ka.length - 1; i >= 0; i--) { key = ka[i]; if (!deepEqual(a[key], b[key], m)) { return false; } } return true; } }); require.register("chaijs-loupe/lib/loupe.js", function(exports, require, module){ // This is (almost) directly from Node.js utils // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js var getName = require('./getName'); var getProperties = require('./getProperties'); var getEnumerableProperties = require('./getEnumerableProperties'); module.exports = inspect; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Boolean} showHidden Flag that shows hidden (not enumerable) * properties of objects. * @param {Number} depth Depth in which to descend in object. Default is 2. * @param {Boolean} colors Flag to turn on ANSI escape codes to color the * output. Default is false (no coloring). */ function inspect(obj, showHidden, depth, colors) { var ctx = { showHidden: showHidden, seen: [], stylize: function (str) { return str; } }; return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); } // https://gist.github.com/1044128/ var getOuterHTML = function(element) { if ('outerHTML' in element) return element.outerHTML; var ns = "http://www.w3.org/1999/xhtml"; var container = document.createElementNS(ns, '_'); var elemProto = (window.HTMLElement || window.Element).prototype; var xmlSerializer = new XMLSerializer(); var html; if (document.xmlVersion) { return xmlSerializer.serializeToString(element); } else { container.appendChild(element.cloneNode(false)); html = container.innerHTML.replace('><', '>' + element.innerHTML + '<'); container.innerHTML = ''; return html; } }; // Returns true if object is a DOM element. var isDOMElement = function (object) { if (typeof HTMLElement === 'object') { return object instanceof HTMLElement; } else { return object && typeof object === 'object' && object.nodeType === 1 && typeof object.nodeName === 'string'; } }; function formatValue(ctx, 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.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { var ret = value.inspect(recurseTimes); if (typeof ret !== 'string') { ret = formatValue(ctx, ret, recurseTimes); } return ret; } // Primitive types cannot have properties var primitive = formatPrimitive(ctx, value); if (primitive) { return primitive; } // If it's DOM elem, get outer HTML. if (isDOMElement(value)) { return getOuterHTML(value); } // Look up the keys of the object. var visibleKeys = getEnumerableProperties(value); var keys = ctx.showHidden ? getProperties(value) : visibleKeys; // Some type of object without properties can be shortcutted. // In IE, errors have a single `stack` property, or if they are vanilla `Error`, // a `stack` plus `description` property; ignore those for consistency. if (keys.length === 0 || (isError(value) && ( (keys.length === 1 && keys[0] === 'stack') || (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') ))) { if (typeof value === 'function') { var name = getName(value); var nameSuffix = name ? ': ' + name : ''; return ctx.stylize('[Function' + nameSuffix + ']', 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } if (isDate(value)) { return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); } if (isError(value)) { return formatError(value); } } var base = '', array = false, braces = ['{', '}']; // Make Array say that they are Array if (isArray(value)) { array = true; braces = ['[', ']']; } // Make functions say that they are functions if (typeof value === 'function') { var name = getName(value); var nameSuffix = name ? ': ' + name : ''; base = ' [Function' + nameSuffix + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + Date.prototype.toUTCString.call(value); } // Make error with message first say the error if (isError(value)) { return formatError(value); } if (keys.length === 0 && (!array || value.length == 0)) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { return ctx.stylize('[Object]', 'special'); } } ctx.seen.push(value); var output; if (array) { output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { output = keys.map(function(key) { return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } ctx.seen.pop(); return reduceToSingleString(output, base, braces); } function formatPrimitive(ctx, value) { switch (typeof value) { case 'undefined': return ctx.stylize('undefined', 'undefined'); case 'string': var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; return ctx.stylize(simple, 'string'); case 'number': return ctx.stylize('' + value, 'number'); case 'boolean': return ctx.stylize('' + value, 'boolean'); } // For some reason typeof null is "object", so special case here. if (value === null) { return ctx.stylize('null', 'null'); } } function formatError(value) { return '[' + Error.prototype.toString.call(value) + ']'; } function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; for (var i = 0, l = value.length; i < l; ++i) { if (Object.prototype.hasOwnProperty.call(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); } else { output.push(''); } } keys.forEach(function(key) { if (!key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } }); return output; } function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { var name, str; if (value.__lookupGetter__) { if (value.__lookupGetter__(key)) { if (value.__lookupSetter__(key)) { str = ctx.stylize('[Getter/Setter]', 'special'); } else { str = ctx.stylize('[Getter]', 'special'); } } else { if (value.__lookupSetter__(key)) { str = ctx.stylize('[Setter]', 'special'); } } } if (visibleKeys.indexOf(key) < 0) { name = '[' + key + ']'; } if (!str) { if (ctx.seen.indexOf(value[key]) < 0) { if (recurseTimes === null) { str = formatValue(ctx, value[key], null); } else { str = formatValue(ctx, value[key], recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (array) { 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 = ctx.stylize('[Circular]', 'special'); } } if (typeof name === 'undefined') { if (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 = ctx.stylize(name, 'name'); } else { name = name.replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"); name = ctx.stylize(name, 'string'); } } return name + ': ' + str; } function reduceToSingleString(output, base, braces) { 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 > 60) { return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1]; } return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } function isArray(ar) { return Array.isArray(ar) || (typeof ar === 'object' && objectToString(ar) === '[object Array]'); } function isRegExp(re) { return typeof re === 'object' && objectToString(re) === '[object RegExp]'; } function isDate(d) { return typeof d === 'object' && objectToString(d) === '[object Date]'; } function isError(e) { return typeof e === 'object' && objectToString(e) === '[object Error]'; } function objectToString(o) { return Object.prototype.toString.call(o); } }); require.register("chaijs-loupe/lib/getEnumerableProperties.js", function(exports, require, module){ /*! * Chai - getEnumerableProperties utility * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * ### .getEnumerableProperties(object) * * This allows the retrieval of enumerable property names of an object, * inherited or not. * * @param {Object} object * @returns {Array} * @name getEnumerableProperties * @api public */ module.exports = function getEnumerableProperties(object) { var result = []; for (var name in object) { result.push(name); } return result; }; }); require.register("chaijs-loupe/lib/getName.js", function(exports, require, module){ /*! * Chai - getName utility * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * # getName(func) * * Gets the name of a function, in a cross-browser way. * * @param {Function} a function (usually a constructor) */ module.exports = function (func) { if (func.name) return func.name; var match = /^\s?function ([^(]*)\(/.exec(func); return match && match[1] ? match[1] : ""; }; }); require.register("chaijs-loupe/lib/getProperties.js", function(exports, require, module){ /*! * Chai - getProperties utility * Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * ### .getProperties(object) * * This allows the retrieval of property names of an object, enumerable or not, * inherited or not. * * @param {Object} object * @returns {Array} * @name getProperties * @api public */ module.exports = function getProperties(object) { var result = Object.getOwnPropertyNames(subject); function addProperty(property) { if (result.indexOf(property) === -1) { result.push(property); } } var proto = Object.getPrototypeOf(subject); while (proto !== null) { Object.getOwnPropertyNames(proto).forEach(addProperty); proto = Object.getPrototypeOf(proto); } return result; }; }); require.register("jackjs-jack-util/index.js", function(exports, require, module){ /** * External dependencies. */ var eql = require('deep-eql'); var inspect = require('loupe'); /** * Error messages. */ var MESSAGES = { testDouble: [ 'expected $0 to be a test double', 'expected $0 to not be a test double' ], invoked: [ 'expected $0 to have been invoked', 'expected $0 to have not been invoked' ], min: [ 'expected $0 to have been called min $1 time(s), got $2', 'expected $0 to have not been called min $1 time(s), got $2' ], max: [ 'expected $0 to have been called max $1 time(s), got $2', 'expected $0 to have not been called max $1 time(s), got $2' ], exactly: [ 'expected $0 to have been called exactly $1 time(s), got $2', 'expected $0 to have not been called exactly $1 time(s), got $2' ], once: [ 'expected $0 to have been called once, got $1', 'expected $0 to have not been called once, got $1' ], twice: [ 'expected $0 to have been called twice, got $1', 'expected $0 to have not been called twice, got $1' ], on: [ 'expected $0 to have been called on $1', 'expected $0 to have not been called on $1' ], args: [ 'expected $0 to have been called with $1', 'expected $0 to have not been called with $1' ] }; /** * Verify that `fn` has been called with * given `args`. * * @param {Function} test double * @param {Array} arguments * @returns {Object} * @api public */ exports.args = function(fn, args) { var ret = msg('args', fn, inspect(args)); ret.expr = false; for (var i = 0, len = fn.calls.length; i < len; i++) { if (eql(fn.calls[i].args, args)) ret.expr = true; } return ret; }; /** * Verify that `fn` has been called * exactly `n` times. * * @param {Function} test double * @param {Number} times * @returns {Object} * @api public */ exports.exactly = function(fn, n) { var ret = msg('exactly', fn, n, fn.calls.length); ret.expr = fn.calls.length === n; return ret; }; /** * Verify that `fn` has been invoked. * * @param {Function} test double * @returns {Object} * @api public */ exports.invoked = function(fn) { var ret = msg('invoked', fn); ret.expr = fn.calls.length > 0; return ret; }; /** * Verify that `fn` has been called * at most `n` times. * * @param {Function} test double * @param {Number} times * @returns {Object} * @api public */ exports.max = function(fn, n) { var ret = msg('max', fn, n, fn.calls.length); ret.expr = fn.calls.length <= n; return ret; }; /** * Verify that `fn` has been called * at least `n` times. * * @param {Function} test double * @param {Number} times * @returns {Object} * @api public */ exports.min = function(fn, n) { var ret = msg('min', fn, n, fn.calls.length); ret.expr = fn.calls.length >= n; return ret; }; /** * Verify that `fn` has been called * on `ctx`. * * @param {Function} test double * @param {Object} context * @returns {Object} * @api public */ exports.on = function(fn, ctx) { var ret = msg('on', fn, inspect(ctx)); ret.expr = false; for (var i = 0, len = fn.calls.length; i < len; i++) { if (eql(fn.calls[i].context, ctx)) ret.expr = true; } return ret; }; /** * Verify that `fn` has been called exactly twice. * * @param {Function} test double * @returns {Object} * @api public */ exports.once = function(fn) { var ret = msg('once', fn, fn.calls.length); ret.expr = fn.calls.length === 1; return ret; }; /** * Verify that `fn` is a test double. * * @param {Function} test double * @returns {Object} * @api public */ exports.testDouble = function(fn) { var ret = msg('testDouble', fn); ret.expr = fn && typeof fn.double !== 'undefined'; return ret; }; /** * Verify that `fn` has been called exactly twice. * * @param {Function} test double * @returns {Object} * @api public */ exports.twice = function(fn) { var ret = msg('twice', fn, fn.calls.length); ret.expr = fn.calls.length === 2; return ret; }; /** * Return a message for given `type`. * * @param {String} type * @param {Mixed} arg1 * @param {Mixed} ... * @returns {Object} * @api private */ function msg() { var args = [].slice.call(arguments); var type = args.shift(); var msgs = MESSAGES[type]; if (!msgs) throw new Error('Invalid message type: ' + type); msgs = msgs.slice(0); for (var i = 0, len = args.length; i < len; i++) { msgs[0] = msgs[0].replace('$' + i, args[i] + ''); msgs[1] = msgs[1].replace('$' + i, args[i] + ''); } return { msg: msgs[0], negateMsg: msgs[1] }; } }); require.register("jackjs-jack-assertions/index.js", function(exports, require, module){ /** * External dependencies. */ var util = require('jack-util'); module.exports = function(Assertion, key, wrap) { wrap = wrap || function(ret) { return ret; }; Assertion.prototype.testDouble = function() { var ret = wrap(util.testDouble(this[key])); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.invoked = function() { new Assertion(this[key]).testDouble(); var ret = wrap(util.invoked(this[key])); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.min = function(min) { new Assertion(this[key]).testDouble(); var ret = wrap(util.min(this[key], min)); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.max = function(max) { new Assertion(this[key]).testDouble(); var ret = wrap(util.max(this[key], max)); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.exactly = function(times) { new Assertion(this[key]).testDouble(); var ret = wrap(util.exactly(this[key], times)); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.once = function() { new Assertion(this[key]).testDouble(); var ret = wrap(util.once(this[key])); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.twice = function() { new Assertion(this[key]).testDouble(); var ret = wrap(util.twice(this[key])); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.on = function(ctx) { new Assertion(this[key]).testDouble(); var ret = wrap(util.on(this[key], ctx)); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; Assertion.prototype.withArgs = Assertion.prototype.args = function() { var args = [].slice.call(arguments); new Assertion(this[key]).testDouble(); var ret = wrap(util.args(this[key], args)); this.assert(ret.expr, ret.msg, ret.negateMsg); return this; }; }; }); require.register("jack-chai/index.js", function(exports, require, module){ /** * External dependencies. */ var assertions = require('jack-assertions'); /** * Register as chai.js plugin. * * @param {Object} chai * @api public */ module.exports = function(chai) { assertions(chai.Assertion, '_obj'); chai.Assertion.addProperty('called', function() { return this; }); }; }); require.alias("jackjs-jack-assertions/index.js", "jack-chai/deps/jack-assertions/index.js"); require.alias("jackjs-jack-assertions/index.js", "jack-chai/deps/jack-assertions/index.js"); require.alias("jackjs-jack-assertions/index.js", "jack-assertions/index.js"); require.alias("jackjs-jack-util/index.js", "jackjs-jack-assertions/deps/jack-util/index.js"); require.alias("jackjs-jack-util/lib/jack-util.js", "jackjs-jack-assertions/deps/jack-util/index.js"); require.alias("chaijs-deep-eql/lib/eql.js", "jackjs-jack-util/deps/deep-eql/lib/eql.js"); require.alias("chaijs-deep-eql/lib/eql.js", "jackjs-jack-util/deps/deep-eql/index.js"); require.alias("chaijs-type-detect/lib/type.js", "chaijs-deep-eql/deps/type-detect/lib/type.js"); require.alias("chaijs-type-detect/lib/type.js", "chaijs-deep-eql/deps/type-detect/index.js"); require.alias("chaijs-type-detect/lib/type.js", "chaijs-type-detect/index.js"); require.alias("chaijs-deep-eql/lib/eql.js", "chaijs-deep-eql/index.js"); require.alias("chaijs-loupe/lib/loupe.js", "jackjs-jack-util/deps/loupe/lib/loupe.js"); require.alias("chaijs-loupe/lib/getEnumerableProperties.js", "jackjs-jack-util/deps/loupe/lib/getEnumerableProperties.js"); require.alias("chaijs-loupe/lib/getName.js", "jackjs-jack-util/deps/loupe/lib/getName.js"); require.alias("chaijs-loupe/lib/getProperties.js", "jackjs-jack-util/deps/loupe/lib/getProperties.js"); require.alias("chaijs-loupe/lib/loupe.js", "jackjs-jack-util/deps/loupe/index.js"); require.alias("chaijs-loupe/lib/loupe.js", "chaijs-loupe/index.js"); require.alias("jackjs-jack-util/lib/jack-util.js", "jackjs-jack-util/index.js"); require.alias("jackjs-jack-assertions/index.js", "jackjs-jack-assertions/index.js"); require.alias("jack-chai/index.js", "jack-chai/index.js");if (typeof exports == "object") { module.exports = require("jack-chai"); } else if (typeof define == "function" && define.amd) { define(function(){ return require("jack-chai"); }); } else { this["jack-chai"] = require("jack-chai"); }})();