diff --git a/src/diff.js b/src/diff.js index 67b7f48..f83d2d9 100644 --- a/src/diff.js +++ b/src/diff.js @@ -192,13 +192,28 @@ export function stringify(input) { } export function compare(input, expect) { - if (Array.isArray(expect)) return arrays(input, expect); - if (expect instanceof RegExp) return chars(''+input, ''+expect); + if (Array.isArray(expect) && Array.isArray(input)) return arrays(input, expect); + if (expect instanceof RegExp) { + try { + return chars(''+input, ''+expect); + } catch (e) { + if (e.message !== 'Cannot convert object to primitive value') { + throw e + } + } + } - if (expect && typeof expect == 'object') { - input = stringify(sort(input, expect)); + let inputIsObject = input && typeof input === 'object' + let expectIsObject = expect && typeof expect == 'object' + if (expectIsObject && inputIsObject) { + input = sort(input, expect); + } + if (expectIsObject) { expect = stringify(expect); } + if (inputIsObject) { + input = stringify(input); + } let isA = typeof input == 'string'; let isB = typeof expect == 'string'; diff --git a/test/diff.js b/test/diff.js index cfad843..1750ad2 100644 --- a/test/diff.js +++ b/test/diff.js @@ -923,6 +923,35 @@ compare('should handle multi-line string against non-type mismatch', () => { ); }); +compare('should not fail when comparing different types', () => { + const values = [ + true, + false, + null, + undefined, + {foo: 'bar'}, + [], + new Date(), + 'str', + 1, + NaN, + Infinity, + /abc/, + function () {}, + new Promise(() => {}), + $, + ]; + for (const val1 of values) { + for (const val2 of values) { + let aType = Object.prototype.toString.call(val1) + aType = aType.substring(8, aType.length - 1) + let bType = Object.prototype.toString.call(val2) + bType = bType.substring(8, bType.length - 1) + assert.not.throws(() => $.compare(val1, val2), `${aType} is not comparable to ${bType}`) + } + } +}); + compare.run(); // ---