From bf8e03a22da8f584df54f07264f96eaedc0418fb Mon Sep 17 00:00:00 2001 From: David Bushong Date: Mon, 17 Jul 2017 16:58:35 -0700 Subject: [PATCH] fix: don't try to require('diff') for browsers the sourcemaps crash some front-end transpilers :-( --- lib/assertive.js | 12 +++--------- lib/assertive.js.map | 2 +- lib/diff-stub.js | 39 +++++++++++++++++++++++++++++++++++++++ lib/diff-stub.js.map | 1 + package.json | 3 +++ src/assertive.js | 11 +++-------- src/diff-stub.js | 39 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 lib/diff-stub.js create mode 100644 lib/diff-stub.js.map create mode 100644 src/diff-stub.js diff --git a/lib/assertive.js b/lib/assertive.js index 912660f..589758c 100644 --- a/lib/assertive.js +++ b/lib/assertive.js @@ -75,12 +75,8 @@ var assert = void 0; // eslint-disable-next-line global-require var _ = global._ || require('lodash'); -// we can make this optional for browser use -var jsDiff = void 0; -// eslint-disable-next-line global-require -try { - jsDiff = require('diff'); -} catch (err) {/* */} +// may be stubbed out for browsers +var jsDiff = require('diff'); var toString = Object.prototype.toString; @@ -323,7 +319,7 @@ var assertSync = { var message = void 0; if (wrongLooks === rightLooks) { message = 'deepEqual ' + green(rightLooks) + ' failed on something that\n' + 'serializes to the same result (likely some function)'; - } else if (jsDiff) { + } else { var values = jsDiff.diffJson(actual, expected).map(function (entry) { var value = entry.value; var prefix = ' '; @@ -333,8 +329,6 @@ var assertSync = { return value; }); message = 'Actual: ' + red('-') + ' Expected: ' + green('+') + '\n' + values.join('\n'); - } else { - message = 'Expected: ' + green(rightLooks) + '\n Actually: ' + ('' + red(wrongLooks)); } throw error(message, explanation); diff --git a/lib/assertive.js.map b/lib/assertive.js.map index e7f04f4..c20a404 100644 --- a/lib/assertive.js.map +++ b/lib/assertive.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/assertive.js"],"names":["global","Function","assert","_","require","jsDiff","err","toString","Object","prototype","green","x","red","clear","process","isTTY","error","message","explanation","Error","nameNegative","name","charAt","toUpperCase","slice","asRegExp","re","flags","multiline","ignoreCase","source","stringifyReplacer","key","val","isRegExp","isObject","isArray","toPairs","sortBy","fromPairs","value","stringify","isNaN","json","JSON","className","constructor","test","stack","e","handleArgs","self","count","args","help","negated","isString","argc","length","max","indexOf","n","wantedArgCount","isNumber","join","pop","actualArgs","call","functionSource","wantedArgNames","match","wanted","actual","type","TypeError","abbreviate","threshold","str","desc","getNameOfType","isFunction","types","implodeNicely","list","conjunction","first","last","isType","typeName","isDate","getTypeName","find","partial","assertSync","truthy","bool","arguments","expect","equal","expected","deepEqual","isEqual","wrongLooks","rightLooks","values","diffJson","map","entry","prefix","added","removed","replace","include","needle","haystack","what","problem","contained","includes","s","regexp","string","oops","called","matched","throws","fn","undefined","hasType","expectedType","stringType","badArg","suggestions","typeMatches","toBeOrNotToBe","positiveAssertions","forEach","_oneTest","apply","isPromiseAlike","p","then","resolves","testee","identity","catch","rejects","module","exports"],"mappings":"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","file":"assertive.js","sourcesContent":["/*\n * Copyright (c) 2013, Groupon, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * Redistributions of source code must retain the above copyright notice,\n * this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of GROUPON nor the names of its contributors may be\n * used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n * IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\nCopyright (c) 2013, Groupon, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nNeither the name of GROUPON nor the names of its contributors may be\nused to endorse or promote products derived from this software without\nspecific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n// eat _ off the global scope, or require it ourselves if missing\n// eslint-disable-next-line no-new-func\nconst global = Function('return this')();\nlet assert;\n\n// eslint-disable-next-line global-require\nconst _ = global._ || require('lodash');\n\n// we can make this optional for browser use\nlet jsDiff;\n// eslint-disable-next-line global-require\ntry { jsDiff = require('diff'); } catch (err) { /* */ }\n\nconst toString = Object.prototype.toString;\n\nlet green = x => `\\x1B[32m${x}\\x1B[39m`;\nlet red = x => `\\x1B[31m${x}\\x1B[39m`;\nlet clear = '\\x1b[39;49;00m';\n\nif (global.process && process.isTTY && process.isTTY()) {\n red = x => `${x}`;\n green = red;\n clear = '';\n}\n\nfunction error(message, explanation) {\n if (explanation != null) {\n message = `Assertion failed: ${explanation}\\n${clear}${message}`;\n }\n return new Error(message);\n}\n\nfunction nameNegative(name) {\n if (name === 'truthy') { return 'falsey'; }\n if (name === 'resolves') { return 'rejects'; }\n return `not${name.charAt().toUpperCase()}${name.slice(1)}`;\n}\n\nfunction asRegExp(re) {\n let flags = '';\n if (re.global) flags += 'g';\n if (re.multiline) flags += 'm';\n if (re.ignoreCase) flags += 'i';\n return `/${re.source}/${flags}`;\n}\n\nfunction stringifyReplacer(key, val) {\n if (typeof val === 'function') return toString(val);\n if (_.isRegExp(val)) return asRegExp(val);\n if (_.isObject(val) && !_.isArray(val)) {\n return _(val).toPairs().sortBy(0).fromPairs()\n .value();\n }\n return val;\n}\n\nfunction stringify(x) {\n if (x == null) return `${x}`;\n if (_.isNaN(x)) return 'NaN';\n if (_.isRegExp(x)) return asRegExp(x);\n if (typeof x === 'symbol') return x.toString();\n const json = JSON.stringify(x, stringifyReplacer, 2);\n const className = x && x.constructor && x.constructor.name;\n if (typeof x !== 'object' || className === 'Object' || className === 'Array') {\n return json;\n }\n\n if (x instanceof Error || /Error/.test(className)) {\n if (json === '{}') { return x.stack; }\n return `${x.stack}\\nwith error metadata:\\n${json}`;\n }\n if (x.toString === toString) { return className; }\n try {\n return `${className}[${x}]`;\n } catch (e) {\n return className;\n }\n}\n\n// assert that the function got `count` args (if an integer), one of the number\n// of args (if an array of legal counts), and if it was an array and the count\n// was equal to the last option (fully populated), that the first arg is a String\n// (that test's semantic explanation)\nfunction handleArgs(self, count, args, name, help) {\n let negated = false;\n if (_.isString(self)) {\n negated = true;\n name = nameNegative(name);\n }\n\n const argc = args.length;\n if (argc === count) return [name, negated];\n\n let max = '';\n if (_.isArray(count) && count.indexOf(argc) !== -1) {\n const n = count[count.length - 1];\n if ((argc !== n) || _.isString(args[0])) return [name, negated];\n max = `,\\nand when called with ${n} args, the first arg must be a docstring`;\n }\n\n let wantedArgCount;\n if (_.isNumber(count)) {\n wantedArgCount = `${count} argument`;\n } else {\n wantedArgCount = count.slice(0, -1).join(', ');\n count = count.pop();\n wantedArgCount = `${wantedArgCount} or ${count} argument`;\n }\n if (count !== 1) wantedArgCount += 's';\n\n const actualArgs = stringify([].slice.call(args)).slice(1, -1);\n\n const functionSource = Function.prototype.toString.call(assert[name]);\n let wantedArgNames = functionSource.match(/^function\\s*[^(]*\\s*\\(([^)]*)/)[1];\n if (max) { wantedArgNames = `explanation, ${wantedArgNames}`; }\n\n const wanted = `${name}(${wantedArgNames})`;\n const actual = `${name}(${actualArgs})`;\n const message = `${green(wanted)} needs ${wantedArgCount + max}\nyour usage: ${red(actual)}`;\n\n if (typeof help === 'function') { help = help(); }\n throw error(message, help);\n}\n\nfunction type(x) {\n if (_.isString(x)) return 'String';\n if (_.isNumber(x)) return 'Number';\n if (_.isRegExp(x)) return 'RegExp';\n if (_.isArray(x)) return 'Array';\n throw new TypeError(`unsupported type: ${x}`);\n}\n\nfunction abbreviate(name, value, threshold) {\n const str = stringify(value);\n if (str.length <= (threshold || 1024)) return str;\n let desc = `length: ${value.length}`;\n if (_.isArray(value)) desc += `; ${str.length} JSON encoded`;\n if (name) name += ' ';\n return `${name}${type(value)}[${desc}]`;\n}\n\n// translates any argument we were meant to interpret as a type, into its name\nfunction getNameOfType(x) {\n switch (false) {\n case !(x == null): return `${x}`; // null / undefined\n case !_.isString(x): return x;\n case !_.isFunction(x): return x.name;\n case !_.isNaN(x): return 'NaN';\n default: return x;\n }\n}\n\n// listing the most specific types first lets us iterate in order and verify that\n// the expected type was the first match\nconst types = [\n 'null',\n 'Date',\n 'Array',\n 'String',\n 'RegExp',\n 'Boolean',\n 'Function',\n 'Object',\n 'NaN',\n 'Number',\n 'undefined',\n];\n\nfunction implodeNicely(list, conjunction) {\n const first = list.slice(0, -1).join(', ');\n const last = list[list.length - 1];\n return `${first} ${conjunction || 'and'} ${last}`;\n}\n\nfunction isType(value, typeName) {\n if (typeName === 'Date') return _.isDate(value) && !_.isNaN(+value);\n return _[`is${typeName[0].toUpperCase()}${typeName.slice(1)}`](value);\n}\n\n// gets the name of the type that value is an incarnation of\nfunction getTypeName(value) {\n return _.find(types, _.partial(isType, value));\n}\n\n/* eslint-disable prefer-rest-params */\nconst assertSync = {\n truthy(bool) {\n const args = handleArgs(this, [1, 2], arguments, 'truthy');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n bool = arguments[1];\n }\n if ((!bool && !negated) || (bool && negated)) {\n throw error(`Expected ${red(stringify(bool))} to be ${name}`, explanation);\n }\n },\n\n expect(bool) {\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n bool = arguments[1];\n }\n if (explanation) return assertSync.equal(explanation, true, bool);\n return assertSync.equal(true, bool);\n },\n\n equal(expected, actual) {\n let explanation;\n const negated = handleArgs(this, [2, 3], arguments, 'equal')[1];\n if (arguments.length === 3) {\n explanation = arguments[0];\n expected = arguments[1];\n actual = arguments[2];\n }\n if (negated) {\n if (expected === actual) {\n throw error(`notEqual assertion expected ${red(stringify(actual))}` +\n ' to be exactly anything else', explanation);\n }\n } else if (expected !== actual) {\n throw error(`Expected: ${green(stringify(expected))}\\nActually: ` +\n `${red(stringify(actual))}`, explanation);\n }\n },\n\n deepEqual(expected, actual) {\n let explanation;\n const negated = handleArgs(this, [2, 3], arguments, 'deepEqual')[1];\n if (arguments.length === 3) {\n explanation = arguments[0];\n expected = arguments[1];\n actual = arguments[2];\n }\n const isEqual = _.isEqual(expected, actual);\n if ((isEqual && !negated) || (!isEqual && negated)) return;\n\n const wrongLooks = stringify(actual);\n if (negated) {\n throw error(`notDeepEqual assertion expected exactly anything else but\n${red(wrongLooks)}`, explanation);\n }\n\n const rightLooks = stringify(expected);\n let message;\n if (wrongLooks === rightLooks) {\n message = `deepEqual ${green(rightLooks)} failed on something that\\n` +\n 'serializes to the same result (likely some function)';\n } else if (jsDiff) {\n const values = jsDiff.diffJson(actual, expected).map((entry) => {\n let value = entry.value;\n let prefix = ' ';\n if (entry.added) prefix = '+ ';\n else if (entry.removed) prefix = '- ';\n value = value.replace(/^/gm, prefix).replace(/\\n..$/, '');\n if (entry.added) value = green(value);\n else if (entry.removed) value = red(value);\n return value;\n });\n message =\n `Actual: ${red('-')} Expected: ${green('+')}\\n${values.join('\\n')}`;\n } else {\n message = `Expected: ${green(rightLooks)}\\n Actually: ` +\n `${red(wrongLooks)}`;\n }\n\n throw error(message, explanation);\n },\n\n include(needle, haystack) {\n const args = handleArgs(this, [2, 3], arguments, 'include');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 3) {\n explanation = arguments[0];\n needle = arguments[1];\n haystack = arguments[2];\n }\n if (_.isString(haystack)) {\n if (needle === '') {\n const what = negated ? 'always-failing test' : 'no-op test';\n throw error(`${what} detected: all strings contain the empty string!`);\n }\n if (!_.isString(needle) && !_.isNumber(needle) && !_.isRegExp(needle)) {\n const problem = 'needs a RegExp/String/Number needle for a String haystack';\n throw new TypeError(\n `${name} ${problem}; you used:\\n` +\n `${name} ${green(stringify(haystack))}, ${red(stringify(needle))}`\n );\n }\n } else if (!_.isArray(haystack)) {\n needle = stringify(needle);\n throw new TypeError(`${name} takes a String or Array haystack; you used:\n${name} ${red(stringify(haystack))}, ${needle}`\n );\n }\n\n let contained;\n if (_.isString(haystack)) {\n if (_.isRegExp(needle)) {\n contained = haystack.match(needle);\n } else {\n contained = haystack.indexOf(needle) !== -1;\n }\n } else {\n contained = _.includes(haystack, needle);\n }\n\n if (negated) {\n if (contained) {\n // eslint-disable-next-line prefer-template\n let message = 'notInclude expected needle not to be found in ' +\n `haystack\\n- needle: ${stringify(needle)}\\n haystack: ` +\n abbreviate('', haystack);\n if (_.isString(haystack) && _.isRegExp(needle)) {\n message += ', but found:\\n';\n if (needle.global) {\n message += contained.map(s => `* ${red(stringify(s))}`).join('\\n');\n } else {\n message += `* ${red(stringify(contained[0]))}`;\n }\n }\n throw error(message, explanation);\n }\n } else if (!contained) {\n throw error(`${name} expected needle to be found in haystack\\n` +\n `- needle: ${stringify(needle)}\\n` +\n `haystack: ${abbreviate('', haystack)}`, explanation);\n }\n },\n\n match(regexp, string) {\n const args = handleArgs(this, [2, 3], arguments, 'match');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 3) {\n explanation = arguments[0];\n regexp = arguments[1];\n string = arguments[2];\n }\n\n const re = _.isRegExp(regexp);\n if (!re || !_.isString(string)) {\n string = abbreviate('string', string);\n const oops = re ? 'string arg is not a String'\n : 'regexp arg is not a RegExp';\n const called = `${name} ${stringify(regexp)}, ${red(string)}`;\n throw new TypeError(`${name}: ${oops}; you used:\\n${called}`);\n }\n\n const matched = regexp.test(string);\n if (negated) {\n if (!matched) return;\n let message = `Expected: ${stringify(regexp)}\\nnot to match: ` +\n `${red(abbreviate('string', string))}`;\n if (regexp.global) {\n const count = string.match(regexp).length;\n message += `\\nMatches: ${red(count)}`;\n }\n throw error(message, explanation);\n }\n if (!matched) {\n throw error(`Expected: ${stringify(regexp)}\\nto match: ` +\n `${red(abbreviate('string', string))}`, explanation);\n }\n },\n\n throws(fn) {\n const args = handleArgs(this, [1, 2], arguments, 'throws');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n fn = arguments[1];\n }\n if (typeof explanation === 'function') {\n fn = explanation;\n explanation = undefined;\n }\n if (typeof fn !== 'function') {\n throw error(`${name} expects ${green('a function')} but got ${red(fn)}`);\n }\n\n try {\n fn();\n } catch (err) {\n if (negated) {\n throw error(`Threw an exception despite ${name} assertion:\\n` +\n `${err.message}`, explanation);\n }\n return err;\n }\n\n if (negated) return undefined;\n throw error(\"Didn't throw an exception as expected to\", explanation);\n },\n\n hasType(expectedType, value) {\n const args = handleArgs(this, [2, 3], arguments, 'hasType');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 3) {\n explanation = arguments[0];\n expectedType = arguments[1];\n value = arguments[2];\n }\n\n const stringType = getNameOfType(expectedType);\n if (types.indexOf(stringType) === -1) {\n const badArg = stringify(expectedType);\n const suggestions = implodeNicely(types, 'or');\n throw new TypeError(\n `${name}: unknown expectedType ${badArg}; you used:\\n${name} ` +\n `${red(badArg)}, ${stringify(value)}\\nDid you mean ${suggestions}?`\n );\n }\n\n const typeMatches = stringType === getTypeName(value);\n if ((!typeMatches && !negated) || (typeMatches && negated)) {\n value = red(stringify(value));\n const toBeOrNotToBe = `${negated ? 'not ' : ''}to be`;\n const message =\n `Expected value ${value} ${toBeOrNotToBe} of type ${stringType}`;\n throw error(message, explanation);\n }\n },\n};\n\n// produce negatived versions of all the common assertion functions\nconst positiveAssertions = [\n 'truthy',\n 'equal',\n 'deepEqual',\n 'include',\n 'match',\n 'throws',\n 'hasType',\n];\npositiveAssertions.forEach((name) => {\n assertSync[nameNegative(name)] = function _oneTest() {\n return assertSync[name].apply('!', arguments);\n };\n});\n\n// borrowed from Q\nfunction isPromiseAlike(p) {\n return p === Object(p) && (typeof p.then === 'function');\n}\n\n// promise-specific tests\nassert = {\n resolves(testee) {\n const name = handleArgs(this, [1, 2], arguments, 'resolves')[0];\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n testee = arguments[1];\n }\n\n if (!isPromiseAlike(testee)) {\n throw error(\n `${name} expects ${green('a promise')} but got ${red(stringify(testee))}`\n );\n }\n\n if (name === 'rejects') {\n return testee.then(\n (() => { throw error(\"Promise wasn't rejected as expected to\", explanation); }),\n _.identity\n );\n }\n return testee.catch((err) => {\n throw error('Promise was rejected despite resolves assertion:\\n' +\n `${(err && err.message) || err}`, explanation);\n });\n },\n\n rejects() { return assert.resolves.apply('!', arguments); },\n};\n\n// union of promise-specific and promise-aware wrapped synchronous tests\n_.forEach(assertSync || {}, (fn, name) => {\n assert[name] = function _oneTest() {\n if (arguments.length === 0) return fn();\n const args = [].slice.call(arguments);\n const testee = args.pop();\n if (isPromiseAlike(testee)) {\n return testee.then(val => fn(...args, val));\n }\n return fn(...args, testee);\n };\n});\n\n\n// export as a module to node - or to the global scope, if not\nif (typeof module !== 'undefined' && module && module.exports) {\n module.exports = assert;\n} else {\n global.assert = assert;\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/assertive.js"],"names":["global","Function","assert","_","require","jsDiff","toString","Object","prototype","green","x","red","clear","process","isTTY","error","message","explanation","Error","nameNegative","name","charAt","toUpperCase","slice","asRegExp","re","flags","multiline","ignoreCase","source","stringifyReplacer","key","val","isRegExp","isObject","isArray","toPairs","sortBy","fromPairs","value","stringify","isNaN","json","JSON","className","constructor","test","stack","e","handleArgs","self","count","args","help","negated","isString","argc","length","max","indexOf","n","wantedArgCount","isNumber","join","pop","actualArgs","call","functionSource","wantedArgNames","match","wanted","actual","type","TypeError","abbreviate","threshold","str","desc","getNameOfType","isFunction","types","implodeNicely","list","conjunction","first","last","isType","typeName","isDate","getTypeName","find","partial","assertSync","truthy","bool","arguments","expect","equal","expected","deepEqual","isEqual","wrongLooks","rightLooks","values","diffJson","map","entry","prefix","added","removed","replace","include","needle","haystack","what","problem","contained","includes","s","regexp","string","oops","called","matched","throws","fn","undefined","err","hasType","expectedType","stringType","badArg","suggestions","typeMatches","toBeOrNotToBe","positiveAssertions","forEach","_oneTest","apply","isPromiseAlike","p","then","resolves","testee","identity","catch","rejects","module","exports"],"mappings":"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","file":"assertive.js","sourcesContent":["/*\n * Copyright (c) 2013, Groupon, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * Redistributions of source code must retain the above copyright notice,\n * this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of GROUPON nor the names of its contributors may be\n * used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n * IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/*\nCopyright (c) 2013, Groupon, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\nNeither the name of GROUPON nor the names of its contributors may be\nused to endorse or promote products derived from this software without\nspecific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n// eat _ off the global scope, or require it ourselves if missing\n// eslint-disable-next-line no-new-func\nconst global = Function('return this')();\nlet assert;\n\n// eslint-disable-next-line global-require\nconst _ = global._ || require('lodash');\n\n// may be stubbed out for browsers\nconst jsDiff = require('diff');\n\nconst toString = Object.prototype.toString;\n\nlet green = x => `\\x1B[32m${x}\\x1B[39m`;\nlet red = x => `\\x1B[31m${x}\\x1B[39m`;\nlet clear = '\\x1b[39;49;00m';\n\nif (global.process && process.isTTY && process.isTTY()) {\n red = x => `${x}`;\n green = red;\n clear = '';\n}\n\nfunction error(message, explanation) {\n if (explanation != null) {\n message = `Assertion failed: ${explanation}\\n${clear}${message}`;\n }\n return new Error(message);\n}\n\nfunction nameNegative(name) {\n if (name === 'truthy') { return 'falsey'; }\n if (name === 'resolves') { return 'rejects'; }\n return `not${name.charAt().toUpperCase()}${name.slice(1)}`;\n}\n\nfunction asRegExp(re) {\n let flags = '';\n if (re.global) flags += 'g';\n if (re.multiline) flags += 'm';\n if (re.ignoreCase) flags += 'i';\n return `/${re.source}/${flags}`;\n}\n\nfunction stringifyReplacer(key, val) {\n if (typeof val === 'function') return toString(val);\n if (_.isRegExp(val)) return asRegExp(val);\n if (_.isObject(val) && !_.isArray(val)) {\n return _(val).toPairs().sortBy(0).fromPairs()\n .value();\n }\n return val;\n}\n\nfunction stringify(x) {\n if (x == null) return `${x}`;\n if (_.isNaN(x)) return 'NaN';\n if (_.isRegExp(x)) return asRegExp(x);\n if (typeof x === 'symbol') return x.toString();\n const json = JSON.stringify(x, stringifyReplacer, 2);\n const className = x && x.constructor && x.constructor.name;\n if (typeof x !== 'object' || className === 'Object' || className === 'Array') {\n return json;\n }\n\n if (x instanceof Error || /Error/.test(className)) {\n if (json === '{}') { return x.stack; }\n return `${x.stack}\\nwith error metadata:\\n${json}`;\n }\n if (x.toString === toString) { return className; }\n try {\n return `${className}[${x}]`;\n } catch (e) {\n return className;\n }\n}\n\n// assert that the function got `count` args (if an integer), one of the number\n// of args (if an array of legal counts), and if it was an array and the count\n// was equal to the last option (fully populated), that the first arg is a String\n// (that test's semantic explanation)\nfunction handleArgs(self, count, args, name, help) {\n let negated = false;\n if (_.isString(self)) {\n negated = true;\n name = nameNegative(name);\n }\n\n const argc = args.length;\n if (argc === count) return [name, negated];\n\n let max = '';\n if (_.isArray(count) && count.indexOf(argc) !== -1) {\n const n = count[count.length - 1];\n if ((argc !== n) || _.isString(args[0])) return [name, negated];\n max = `,\\nand when called with ${n} args, the first arg must be a docstring`;\n }\n\n let wantedArgCount;\n if (_.isNumber(count)) {\n wantedArgCount = `${count} argument`;\n } else {\n wantedArgCount = count.slice(0, -1).join(', ');\n count = count.pop();\n wantedArgCount = `${wantedArgCount} or ${count} argument`;\n }\n if (count !== 1) wantedArgCount += 's';\n\n const actualArgs = stringify([].slice.call(args)).slice(1, -1);\n\n const functionSource = Function.prototype.toString.call(assert[name]);\n let wantedArgNames = functionSource.match(/^function\\s*[^(]*\\s*\\(([^)]*)/)[1];\n if (max) { wantedArgNames = `explanation, ${wantedArgNames}`; }\n\n const wanted = `${name}(${wantedArgNames})`;\n const actual = `${name}(${actualArgs})`;\n const message = `${green(wanted)} needs ${wantedArgCount + max}\nyour usage: ${red(actual)}`;\n\n if (typeof help === 'function') { help = help(); }\n throw error(message, help);\n}\n\nfunction type(x) {\n if (_.isString(x)) return 'String';\n if (_.isNumber(x)) return 'Number';\n if (_.isRegExp(x)) return 'RegExp';\n if (_.isArray(x)) return 'Array';\n throw new TypeError(`unsupported type: ${x}`);\n}\n\nfunction abbreviate(name, value, threshold) {\n const str = stringify(value);\n if (str.length <= (threshold || 1024)) return str;\n let desc = `length: ${value.length}`;\n if (_.isArray(value)) desc += `; ${str.length} JSON encoded`;\n if (name) name += ' ';\n return `${name}${type(value)}[${desc}]`;\n}\n\n// translates any argument we were meant to interpret as a type, into its name\nfunction getNameOfType(x) {\n switch (false) {\n case !(x == null): return `${x}`; // null / undefined\n case !_.isString(x): return x;\n case !_.isFunction(x): return x.name;\n case !_.isNaN(x): return 'NaN';\n default: return x;\n }\n}\n\n// listing the most specific types first lets us iterate in order and verify that\n// the expected type was the first match\nconst types = [\n 'null',\n 'Date',\n 'Array',\n 'String',\n 'RegExp',\n 'Boolean',\n 'Function',\n 'Object',\n 'NaN',\n 'Number',\n 'undefined',\n];\n\nfunction implodeNicely(list, conjunction) {\n const first = list.slice(0, -1).join(', ');\n const last = list[list.length - 1];\n return `${first} ${conjunction || 'and'} ${last}`;\n}\n\nfunction isType(value, typeName) {\n if (typeName === 'Date') return _.isDate(value) && !_.isNaN(+value);\n return _[`is${typeName[0].toUpperCase()}${typeName.slice(1)}`](value);\n}\n\n// gets the name of the type that value is an incarnation of\nfunction getTypeName(value) {\n return _.find(types, _.partial(isType, value));\n}\n\n/* eslint-disable prefer-rest-params */\nconst assertSync = {\n truthy(bool) {\n const args = handleArgs(this, [1, 2], arguments, 'truthy');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n bool = arguments[1];\n }\n if ((!bool && !negated) || (bool && negated)) {\n throw error(`Expected ${red(stringify(bool))} to be ${name}`, explanation);\n }\n },\n\n expect(bool) {\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n bool = arguments[1];\n }\n if (explanation) return assertSync.equal(explanation, true, bool);\n return assertSync.equal(true, bool);\n },\n\n equal(expected, actual) {\n let explanation;\n const negated = handleArgs(this, [2, 3], arguments, 'equal')[1];\n if (arguments.length === 3) {\n explanation = arguments[0];\n expected = arguments[1];\n actual = arguments[2];\n }\n if (negated) {\n if (expected === actual) {\n throw error(`notEqual assertion expected ${red(stringify(actual))}` +\n ' to be exactly anything else', explanation);\n }\n } else if (expected !== actual) {\n throw error(`Expected: ${green(stringify(expected))}\\nActually: ` +\n `${red(stringify(actual))}`, explanation);\n }\n },\n\n deepEqual(expected, actual) {\n let explanation;\n const negated = handleArgs(this, [2, 3], arguments, 'deepEqual')[1];\n if (arguments.length === 3) {\n explanation = arguments[0];\n expected = arguments[1];\n actual = arguments[2];\n }\n const isEqual = _.isEqual(expected, actual);\n if ((isEqual && !negated) || (!isEqual && negated)) return;\n\n const wrongLooks = stringify(actual);\n if (negated) {\n throw error(`notDeepEqual assertion expected exactly anything else but\n${red(wrongLooks)}`, explanation);\n }\n\n const rightLooks = stringify(expected);\n let message;\n if (wrongLooks === rightLooks) {\n message = `deepEqual ${green(rightLooks)} failed on something that\\n` +\n 'serializes to the same result (likely some function)';\n } else {\n const values = jsDiff.diffJson(actual, expected).map((entry) => {\n let value = entry.value;\n let prefix = ' ';\n if (entry.added) prefix = '+ ';\n else if (entry.removed) prefix = '- ';\n value = value.replace(/^/gm, prefix).replace(/\\n..$/, '');\n if (entry.added) value = green(value);\n else if (entry.removed) value = red(value);\n return value;\n });\n message =\n `Actual: ${red('-')} Expected: ${green('+')}\\n${values.join('\\n')}`;\n }\n\n throw error(message, explanation);\n },\n\n include(needle, haystack) {\n const args = handleArgs(this, [2, 3], arguments, 'include');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 3) {\n explanation = arguments[0];\n needle = arguments[1];\n haystack = arguments[2];\n }\n if (_.isString(haystack)) {\n if (needle === '') {\n const what = negated ? 'always-failing test' : 'no-op test';\n throw error(`${what} detected: all strings contain the empty string!`);\n }\n if (!_.isString(needle) && !_.isNumber(needle) && !_.isRegExp(needle)) {\n const problem = 'needs a RegExp/String/Number needle for a String haystack';\n throw new TypeError(\n `${name} ${problem}; you used:\\n` +\n `${name} ${green(stringify(haystack))}, ${red(stringify(needle))}`\n );\n }\n } else if (!_.isArray(haystack)) {\n needle = stringify(needle);\n throw new TypeError(`${name} takes a String or Array haystack; you used:\n${name} ${red(stringify(haystack))}, ${needle}`\n );\n }\n\n let contained;\n if (_.isString(haystack)) {\n if (_.isRegExp(needle)) {\n contained = haystack.match(needle);\n } else {\n contained = haystack.indexOf(needle) !== -1;\n }\n } else {\n contained = _.includes(haystack, needle);\n }\n\n if (negated) {\n if (contained) {\n // eslint-disable-next-line prefer-template\n let message = 'notInclude expected needle not to be found in ' +\n `haystack\\n- needle: ${stringify(needle)}\\n haystack: ` +\n abbreviate('', haystack);\n if (_.isString(haystack) && _.isRegExp(needle)) {\n message += ', but found:\\n';\n if (needle.global) {\n message += contained.map(s => `* ${red(stringify(s))}`).join('\\n');\n } else {\n message += `* ${red(stringify(contained[0]))}`;\n }\n }\n throw error(message, explanation);\n }\n } else if (!contained) {\n throw error(`${name} expected needle to be found in haystack\\n` +\n `- needle: ${stringify(needle)}\\n` +\n `haystack: ${abbreviate('', haystack)}`, explanation);\n }\n },\n\n match(regexp, string) {\n const args = handleArgs(this, [2, 3], arguments, 'match');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 3) {\n explanation = arguments[0];\n regexp = arguments[1];\n string = arguments[2];\n }\n\n const re = _.isRegExp(regexp);\n if (!re || !_.isString(string)) {\n string = abbreviate('string', string);\n const oops = re ? 'string arg is not a String'\n : 'regexp arg is not a RegExp';\n const called = `${name} ${stringify(regexp)}, ${red(string)}`;\n throw new TypeError(`${name}: ${oops}; you used:\\n${called}`);\n }\n\n const matched = regexp.test(string);\n if (negated) {\n if (!matched) return;\n let message = `Expected: ${stringify(regexp)}\\nnot to match: ` +\n `${red(abbreviate('string', string))}`;\n if (regexp.global) {\n const count = string.match(regexp).length;\n message += `\\nMatches: ${red(count)}`;\n }\n throw error(message, explanation);\n }\n if (!matched) {\n throw error(`Expected: ${stringify(regexp)}\\nto match: ` +\n `${red(abbreviate('string', string))}`, explanation);\n }\n },\n\n throws(fn) {\n const args = handleArgs(this, [1, 2], arguments, 'throws');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n fn = arguments[1];\n }\n if (typeof explanation === 'function') {\n fn = explanation;\n explanation = undefined;\n }\n if (typeof fn !== 'function') {\n throw error(`${name} expects ${green('a function')} but got ${red(fn)}`);\n }\n\n try {\n fn();\n } catch (err) {\n if (negated) {\n throw error(`Threw an exception despite ${name} assertion:\\n` +\n `${err.message}`, explanation);\n }\n return err;\n }\n\n if (negated) return undefined;\n throw error(\"Didn't throw an exception as expected to\", explanation);\n },\n\n hasType(expectedType, value) {\n const args = handleArgs(this, [2, 3], arguments, 'hasType');\n const name = args[0];\n const negated = args[1];\n let explanation;\n if (arguments.length === 3) {\n explanation = arguments[0];\n expectedType = arguments[1];\n value = arguments[2];\n }\n\n const stringType = getNameOfType(expectedType);\n if (types.indexOf(stringType) === -1) {\n const badArg = stringify(expectedType);\n const suggestions = implodeNicely(types, 'or');\n throw new TypeError(\n `${name}: unknown expectedType ${badArg}; you used:\\n${name} ` +\n `${red(badArg)}, ${stringify(value)}\\nDid you mean ${suggestions}?`\n );\n }\n\n const typeMatches = stringType === getTypeName(value);\n if ((!typeMatches && !negated) || (typeMatches && negated)) {\n value = red(stringify(value));\n const toBeOrNotToBe = `${negated ? 'not ' : ''}to be`;\n const message =\n `Expected value ${value} ${toBeOrNotToBe} of type ${stringType}`;\n throw error(message, explanation);\n }\n },\n};\n\n// produce negatived versions of all the common assertion functions\nconst positiveAssertions = [\n 'truthy',\n 'equal',\n 'deepEqual',\n 'include',\n 'match',\n 'throws',\n 'hasType',\n];\npositiveAssertions.forEach((name) => {\n assertSync[nameNegative(name)] = function _oneTest() {\n return assertSync[name].apply('!', arguments);\n };\n});\n\n// borrowed from Q\nfunction isPromiseAlike(p) {\n return p === Object(p) && (typeof p.then === 'function');\n}\n\n// promise-specific tests\nassert = {\n resolves(testee) {\n const name = handleArgs(this, [1, 2], arguments, 'resolves')[0];\n let explanation;\n if (arguments.length === 2) {\n explanation = arguments[0];\n testee = arguments[1];\n }\n\n if (!isPromiseAlike(testee)) {\n throw error(\n `${name} expects ${green('a promise')} but got ${red(stringify(testee))}`\n );\n }\n\n if (name === 'rejects') {\n return testee.then(\n (() => { throw error(\"Promise wasn't rejected as expected to\", explanation); }),\n _.identity\n );\n }\n return testee.catch((err) => {\n throw error('Promise was rejected despite resolves assertion:\\n' +\n `${(err && err.message) || err}`, explanation);\n });\n },\n\n rejects() { return assert.resolves.apply('!', arguments); },\n};\n\n// union of promise-specific and promise-aware wrapped synchronous tests\n_.forEach(assertSync || {}, (fn, name) => {\n assert[name] = function _oneTest() {\n if (arguments.length === 0) return fn();\n const args = [].slice.call(arguments);\n const testee = args.pop();\n if (isPromiseAlike(testee)) {\n return testee.then(val => fn(...args, val));\n }\n return fn(...args, testee);\n };\n});\n\n\n// export as a module to node - or to the global scope, if not\nif (typeof module !== 'undefined' && module && module.exports) {\n module.exports = assert;\n} else {\n global.assert = assert;\n}\n"]} \ No newline at end of file diff --git a/lib/diff-stub.js b/lib/diff-stub.js new file mode 100644 index 0000000..32758a9 --- /dev/null +++ b/lib/diff-stub.js @@ -0,0 +1,39 @@ +"use strict"; + +/* + * Copyright (c) 2013, Groupon, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of GROUPON nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// can't require('diff') properly with browserify, so just fall back on this +function diffJson(a, b) { + return [{ removed: true, value: JSON.stringify(a, null, 2) }, { added: true, value: JSON.stringify(b, null, 2) }]; +} +exports.diffJson = diffJson; +//# sourceMappingURL=diff-stub.js.map \ No newline at end of file diff --git a/lib/diff-stub.js.map b/lib/diff-stub.js.map new file mode 100644 index 0000000..1357400 --- /dev/null +++ b/lib/diff-stub.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/diff-stub.js"],"names":["diffJson","a","b","removed","value","JSON","stringify","added","exports"],"mappings":";;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA;AACA,SAASA,QAAT,CAAkBC,CAAlB,EAAqBC,CAArB,EAAwB;AACtB,SAAO,CACL,EAAEC,SAAS,IAAX,EAAiBC,OAAOC,KAAKC,SAAL,CAAeL,CAAf,EAAkB,IAAlB,EAAwB,CAAxB,CAAxB,EADK,EAEL,EAAEM,OAAO,IAAT,EAAeH,OAAOC,KAAKC,SAAL,CAAeJ,CAAf,EAAkB,IAAlB,EAAwB,CAAxB,CAAtB,EAFK,CAAP;AAID;AACDM,QAAQR,QAAR,GAAmBA,QAAnB","file":"diff-stub.js","sourcesContent":["/*\n * Copyright (c) 2013, Groupon, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * Redistributions of source code must retain the above copyright notice,\n * this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of GROUPON nor the names of its contributors may be\n * used to endorse or promote products derived from this software without\n * specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n * IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n// can't require('diff') properly with browserify, so just fall back on this\nfunction diffJson(a, b) {\n return [\n { removed: true, value: JSON.stringify(a, null, 2) },\n { added: true, value: JSON.stringify(b, null, 2) },\n ];\n}\nexports.diffJson = diffJson;\n"]} \ No newline at end of file diff --git a/package.json b/package.json index 436bd67..9a7b67c 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ ] } }, + "browser": { + "diff": "./lib/diff-stub.js" + }, "dependencies": { "diff": "^3.3.0", "lodash": "^4.6.1" diff --git a/src/assertive.js b/src/assertive.js index 0900acc..60fc583 100644 --- a/src/assertive.js +++ b/src/assertive.js @@ -69,10 +69,8 @@ let assert; // eslint-disable-next-line global-require const _ = global._ || require('lodash'); -// we can make this optional for browser use -let jsDiff; -// eslint-disable-next-line global-require -try { jsDiff = require('diff'); } catch (err) { /* */ } +// may be stubbed out for browsers +const jsDiff = require('diff'); const toString = Object.prototype.toString; @@ -313,7 +311,7 @@ ${red(wrongLooks)}`, explanation); if (wrongLooks === rightLooks) { message = `deepEqual ${green(rightLooks)} failed on something that\n` + 'serializes to the same result (likely some function)'; - } else if (jsDiff) { + } else { const values = jsDiff.diffJson(actual, expected).map((entry) => { let value = entry.value; let prefix = ' '; @@ -326,9 +324,6 @@ ${red(wrongLooks)}`, explanation); }); message = `Actual: ${red('-')} Expected: ${green('+')}\n${values.join('\n')}`; - } else { - message = `Expected: ${green(rightLooks)}\n Actually: ` + - `${red(wrongLooks)}`; } throw error(message, explanation); diff --git a/src/diff-stub.js b/src/diff-stub.js new file mode 100644 index 0000000..689e05c --- /dev/null +++ b/src/diff-stub.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, Groupon, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of GROUPON nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// can't require('diff') properly with browserify, so just fall back on this +function diffJson(a, b) { + return [ + { removed: true, value: JSON.stringify(a, null, 2) }, + { added: true, value: JSON.stringify(b, null, 2) }, + ]; +} +exports.diffJson = diffJson;