Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ var $setDelete = callBound('Set.prototype.delete', true);
var $setHas = callBound('Set.prototype.has', true);
var $setSize = callBound('Set.prototype.size', true);

// the primitive that a boxed primitive wraps, read without calling a `valueOf` that the object may override
function unbox(boxed, kind) {
return callBound(kind + '.prototype.valueOf')(boxed);
}

// taken from https://github.com/browserify/commonjs-assert/blob/bba838e9ba9e28edf3127ce6974624208502f6bc/internal/util/comparisons.js#L401-L414
function setHasEqualElement(set, val1, opts, channel) {
var i = getIterator(set);
Expand Down Expand Up @@ -130,6 +135,8 @@ function internalDeepEqual(actual, expected, options, channel) {
if (actualBoxed !== expectedBoxed) {
return false;
}
// two boxed primitives of the same kind are equal only if the primitives they wrap are the same
if (actualBoxed && !is(unbox(actual, actualBoxed), unbox(expected, actualBoxed))) { return false; }

// 7.3. Other pairs that do not both pass typeof value == 'object', equivalence is determined by ==.
if (!actual || !expected || (typeof actual !== 'object' && typeof expected !== 'object')) {
Expand Down
16 changes: 16 additions & 0 deletions test/cmp.js
Original file line number Diff line number Diff line change
Expand Up @@ -1042,15 +1042,31 @@ test('boxed primitives', function (t) {
t.deepEqualTest(Object(''), '', 'boxed and primitive `""`', false, false);
t.deepEqualTest(Object('str'), 'str', 'boxed and primitive `"str"`', false, false);

t.deepEqualTest(Object(3), Object(3), 'two boxed `3`s', true, true);
t.deepEqualTest(Object(3), Object(4), 'boxed `3` and boxed `4`', false, false);
t.deepEqualTest(Object(NaN), Object(NaN), 'two boxed `NaN`s', true, true);
t.deepEqualTest(Object(0), Object(-0), 'boxed `0` and boxed `-0`', false, false);
t.deepEqualTest(Object(true), Object(true), 'two boxed `true`s', true, true);
t.deepEqualTest(Object(true), Object(false), 'boxed `true` and boxed `false`', false, false);
t.deepEqualTest(Object('str'), Object('str'), 'two boxed `"str"`s', true, true);
t.deepEqualTest(Object('str'), Object('other'), 'boxed `"str"` and boxed `"other"`', false, false);
t.deepEqualTest([Object(3)], [Object(4)], 'boxed numbers that differ, in arrays', false, false);
t.deepEqualTest({ a: Object(3) }, { a: Object(4) }, 'boxed numbers that differ, in objects', false, false);
t.deepEqualTest({ a: Object(3) }, { a: Object(3) }, 'boxed numbers that match, in objects', true, true);

t.test('symbol', { skip: !hasSymbols }, function (st) {
var s = Symbol('');
st.deepEqualTest(Object(s), s, 'boxed and primitive `Symbol()`', false, false);
st.deepEqualTest(Object(s), Object(s), 'two boxes of the same `Symbol()`', true, true);
st.deepEqualTest(Object(s), Object(Symbol('')), 'boxes of two different symbols', false, false);
st.end();
});

t.test('bigint', { skip: typeof BigInt !== 'function' }, function (st) {
var hhgtg = BigInt(42);
st.deepEqualTest(Object(hhgtg), hhgtg, 'boxed and primitive `BigInt(42)`', false, false);
st.deepEqualTest(Object(hhgtg), Object(BigInt(42)), 'two boxed `BigInt(42)`s', true, true);
st.deepEqualTest(Object(hhgtg), Object(BigInt(43)), 'boxed `BigInt(42)` and boxed `BigInt(43)`', false, false);
st.end();
});

Expand Down
Loading