diff --git a/.eslintrc b/.eslintrc index 459b3d4..c137b67 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,9 +5,9 @@ "complexity": 0, "func-style": [2, 'declaration'], "indent": [2, 4], - "max-lines-per-function": [2, 120], + "max-lines-per-function": [2, 130], "max-params": [2, 4], - "max-statements": [2, 80], + "max-statements": [2, 90], "max-statements-per-line": [2, { "max": 2 }], "no-magic-numbers": 0, "no-param-reassign": 1, @@ -15,6 +15,8 @@ }, "globals": { "BigInt": false, + "WeakSet": false, + "WeakMap": false, }, "overrides": [ { diff --git a/.nycrc b/.nycrc index b65425a..7b95a1e 100644 --- a/.nycrc +++ b/.nycrc @@ -4,10 +4,10 @@ "instrumentation": false, "sourceMap": false, "reporter": ["html", "text-summary"], - "lines": 94, - "statements": 94, + "lines": 93, + "statements": 93, "functions": 96, - "branches": 90, + "branches": 89, "exclude": [ "coverage", "example", diff --git a/index.js b/index.js index 0cac810..1394e53 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,10 @@ var hasSet = typeof Set === 'function' && Set.prototype; var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null; var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null; var setForEach = hasSet && Set.prototype.forEach; +var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype; +var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null; +var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype; +var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null; var booleanValueOf = Boolean.prototype.valueOf; var objectToString = Object.prototype.toString; var match = String.prototype.match; @@ -113,6 +117,12 @@ module.exports = function inspect_(obj, options, depth, seen) { }); return collectionOf('Set', setSize.call(obj), setParts); } + if (isWeakMap(obj)) { + return weakCollectionOf('WeakMap'); + } + if (isWeakSet(obj)) { + return weakCollectionOf('WeakSet'); + } if (isNumber(obj)) { return markBoxed(inspect(Number(obj))); } @@ -192,6 +202,22 @@ function isMap(x) { return false; } +function isWeakMap(x) { + if (!weakMapHas || !x || typeof x !== 'object') { + return false; + } + try { + weakMapHas.call(x, weakMapHas); + try { + weakSetHas.call(x, weakSetHas); + } catch (s) { + return true; + } + return x instanceof WeakMap; // core-js workaround, pre-v2.5.0 + } catch (e) {} + return false; +} + function isSet(x) { if (!setSize || !x || typeof x !== 'object') { return false; @@ -208,6 +234,22 @@ function isSet(x) { return false; } +function isWeakSet(x) { + if (!weakSetHas || !x || typeof x !== 'object') { + return false; + } + try { + weakSetHas.call(x, weakSetHas); + try { + weakMapHas.call(x, weakMapHas); + } catch (s) { + return true; + } + return x instanceof WeakSet; // core-js workaround, pre-v2.5.0 + } catch (e) {} + return false; +} + function isElement(x) { if (!x || typeof x !== 'object') { return false; } if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) { @@ -235,6 +277,10 @@ function markBoxed(str) { return 'Object(' + str + ')'; } +function weakCollectionOf(type) { + return type + ' { ? }'; +} + function collectionOf(type, size, entries) { return type + ' (' + size + ') {' + entries.join(', ') + '}'; } diff --git a/test/values.js b/test/values.js index 02b0f5b..20709d5 100644 --- a/test/values.js +++ b/test/values.js @@ -87,6 +87,16 @@ test('Map', { skip: typeof Map !== 'function' }, function (t) { t.end(); }); +test('WeakMap', { skip: typeof WeakMap !== 'function' }, function (t) { + var map = new WeakMap(); + map.set({ a: 1 }, ['b']); + var expectedString = 'WeakMap { ? }'; + t.equal(inspect(map), expectedString, 'new WeakMap([[{ a: 1 }, ["b"]]]) should not show size or contents'); + t.equal(inspect(new WeakMap()), 'WeakMap { ? }', 'empty WeakMap should not show as empty'); + + t.end(); +}); + test('Set', { skip: typeof Set !== 'function' }, function (t) { var set = new Set(); set.add({ a: 1 }); @@ -103,6 +113,16 @@ test('Set', { skip: typeof Set !== 'function' }, function (t) { t.end(); }); +test('WeakSet', { skip: typeof WeakSet !== 'function' }, function (t) { + var map = new WeakSet(); + map.add({ a: 1 }); + var expectedString = 'WeakSet { ? }'; + t.equal(inspect(map), expectedString, 'new WeakSet([{ a: 1 }]) should not show size or contents'); + t.equal(inspect(new WeakSet()), 'WeakSet { ? }', 'empty WeakSet should not show as empty'); + + t.end(); +}); + test('Strings', function (t) { var str = 'abc';