Skip to content

Commit

Permalink
[Refactor] use es-get-iterator internally
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Nov 28, 2019
1 parent d9d9198 commit 09dac2f
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 88 deletions.
2 changes: 2 additions & 0 deletions getCollectionsForEach.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

// TODO: delete in next semver-major

module.exports = function getCollectionsforEach() {
var mapForEach = (function () {
if (typeof Map !== 'function') { return null; }
Expand Down
2 changes: 2 additions & 0 deletions getSymbolIterator.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

// TODO: delete in next semver-major

var isSymbol = require('is-symbol');

module.exports = function getSymbolIterator() {
Expand Down
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"pretest": "npm run --silent lint",
"test": "npm run --silent tests-only",
"posttest": "npx aud",
"tests-only": "npm run --silent test:native && npm run --silent test:why && npm run --silent test:shimmed && npm run --silent test:corejs",
"tests-only": "npm run test:native && npm run test:why && npm run test:shimmed && npm run test:corejs",
"test:native": "node test/native",
"test:why": "node test/why",
"test:shimmed": "node test/shimmed",
Expand All @@ -40,6 +40,8 @@
"equality"
],
"dependencies": {
"es-get-iterator": "^1.0.1",
"functions-have-names": "^1.2.0",
"has": "^1.0.3",
"is-arrow-function": "^2.0.3",
"is-bigint": "^1.0.0",
Expand All @@ -51,7 +53,11 @@
"is-regex": "^1.0.4",
"is-string": "^1.0.4",
"is-symbol": "^1.0.3",
"object.entries": "^1.1.0"
"isarray": "^2.0.5",
"object-inspect": "^1.7.0",
"object.entries": "^1.1.0",
"which-boxed-primitive": "^1.0.1",
"which-collection": "^1.0.0"
},
"devDependencies": {
"@ljharb/eslint-config": "^15.0.2",
Expand All @@ -61,7 +67,6 @@
"es6-shim": "^0.35.5",
"eslint": "^6.7.1",
"foreach": "^2.0.5",
"functions-have-names": "^1.2.0",
"has-bigints": "^1.0.0",
"has-symbols": "^1.0.1",
"make-arrow-function": "^1.1.0",
Expand Down
32 changes: 11 additions & 21 deletions test/why.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,22 +499,22 @@ test('iterables', function (t) {
);
mt.equal(
isEqualWhy(a, c),
'second argument finished iterating before first',
'second Map argument finished iterating before first Map',
'unequal Maps (a, c) are not equal'
);
mt.equal(
isEqualWhy(b, c),
'second argument finished iterating before first',
'second Map argument finished iterating before first Map',
'unequal Maps (b, c) are not equal'
);
mt.equal(
isEqualWhy(c, a),
'first argument finished iterating before second',
'first Map argument finished iterating before second Map',
'unequal Maps (c, a) are not equal'
);
mt.equal(
isEqualWhy(c, b),
'first argument finished iterating before second',
'first Map argument finished iterating before second Map',
'unequal Maps (c, b) are not equal'
);

Expand All @@ -535,30 +535,22 @@ test('iterables', function (t) {
st.equal('', isEqualWhy(b, a), 'equal Set (b, a) are equal');
st.equal(
isEqualWhy(a, c),
symbolIterator
? 'second argument finished iterating before first'
: 'Collection entries differ: arrays have different length: 2 !== 1',
'second Set argument finished iterating before first Set',
'unequal Set (a, c) are not equal'
);
st.equal(
isEqualWhy(b, c),
symbolIterator
? 'second argument finished iterating before first'
: 'Collection entries differ: arrays have different length: 2 !== 1',
'second Set argument finished iterating before first Set',
'unequal Set (b, c) are not equal'
);
st.equal(
isEqualWhy(c, a),
symbolIterator
? 'first argument finished iterating before second'
: 'Collection entries differ: arrays have different length: 1 !== 2',
'first Set argument finished iterating before second Set',
'unequal Set (c, a) are not equal'
);
st.equal(
isEqualWhy(c, b),
symbolIterator
? 'first argument finished iterating before second'
: 'Collection entries differ: arrays have different length: 1 !== 2',
'first Set argument finished iterating before second Set',
'unequal Set (b, c) are not equal'
);

Expand All @@ -581,9 +573,7 @@ test('iterables', function (t) {
}
st.equal(
isEqualWhy(ab, ac),
symbolIterator
? 'iteration results are not equal: value at key "value" differs: string values are different: "b" !== "c"'
: 'Collection entries differ: string values are different: "b" !== "c"',
'iteration results are not equal: value at key "value" differs: string values are different: "b" !== "c"',
'Sets initially populated with different strings are not equal'
);
sst.end();
Expand Down Expand Up @@ -638,12 +628,12 @@ test('iterables', function (t) {

it.equal(
isEqualWhy(c, d),
'first argument finished iterating before second',
'first object argument finished iterating before second object',
'iterable c / iterable d are not equal'
);
it.equal(
isEqualWhy(d, c),
'second argument finished iterating before first',
'second object argument finished iterating before first object',
'iterable d / iterable c are not equal'
);

Expand Down
91 changes: 27 additions & 64 deletions why.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var ObjectPrototype = Object.prototype;
var toStr = ObjectPrototype.toString;
var booleanValue = Boolean.prototype.valueOf;
var has = require('has');
var isArray = require('isarray');
var isArrowFunction = require('is-arrow-function');
var isBoolean = require('is-boolean-object');
var isDate = require('is-date-object');
Expand All @@ -14,19 +15,20 @@ var isString = require('is-string');
var isSymbol = require('is-symbol');
var isCallable = require('is-callable');
var isBigInt = require('is-bigint');
var getIterator = require('es-get-iterator');
var whichCollection = require('which-collection');
var whichBoxedPrimitive = require('which-boxed-primitive');

var objectType = function (v) { return whichCollection(v) || whichBoxedPrimitive(v) || typeof v; };

var isProto = Object.prototype.isPrototypeOf;

var namedFoo = function foo() {};
var functionsHaveNames = namedFoo.name === 'foo';
var functionsHaveNames = require('functions-have-names')();

var symbolValue = typeof Symbol === 'function' ? Symbol.prototype.valueOf : null;
var symbolIterator = require('./getSymbolIterator')();

var bigIntValue = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;

var collectionsForEach = require('./getCollectionsForEach')();

var getPrototypeOf = Object.getPrototypeOf;
if (!getPrototypeOf) {
/* eslint-disable no-proto */
Expand Down Expand Up @@ -54,33 +56,11 @@ if (!getPrototypeOf) {
/* eslint-enable no-proto */
}

var isArray = Array.isArray || function (value) {
return toStr.call(value) === '[object Array]';
};

var normalizeFnWhitespace = function normalizeWhitespace(fnStr) {
// this is needed in IE 9, at least, which has inconsistencies here.
return fnStr.replace(/^function ?\(/, 'function (').replace('){', ') {');
};

var tryMapSetEntries = function tryCollectionEntries(collection) {
var foundEntries = [];
try {
collectionsForEach.Map.call(collection, function (key, value) {
foundEntries.push([key, value]);
});
} catch (notMap) {
try {
collectionsForEach.Set.call(collection, function (value) {
foundEntries.push([value]);
});
} catch (notSet) {
return false;
}
}
return foundEntries;
};

module.exports = function whyNotEqual(value, other) {
if (value === other) { return ''; }
if (value == null || other == null) {
Expand Down Expand Up @@ -238,44 +218,27 @@ module.exports = function whyNotEqual(value, other) {
if (isProto.call(other, value)) { return 'second argument is the [[Prototype]] of the first'; }
if (getPrototypeOf(value) !== getPrototypeOf(other)) { return 'arguments have a different [[Prototype]]'; }

if (symbolIterator) {
var valueIteratorFn = value[symbolIterator];
var valueIsIterable = isCallable(valueIteratorFn);
var otherIteratorFn = other[symbolIterator];
var otherIsIterable = isCallable(otherIteratorFn);
if (valueIsIterable !== otherIsIterable) {
if (valueIsIterable) { return 'first argument is iterable; second is not'; }
return 'second argument is iterable; first is not';
}
if (valueIsIterable && otherIsIterable) {
var valueIterator = valueIteratorFn.call(value);
var otherIterator = otherIteratorFn.call(other);
var valueNext, otherNext, nextWhy;
do {
valueNext = valueIterator.next();
otherNext = otherIterator.next();
if (!valueNext.done && !otherNext.done) {
nextWhy = whyNotEqual(valueNext, otherNext);
if (nextWhy !== '') {
return 'iteration results are not equal: ' + nextWhy;
}
var valueIterator = getIterator(value);
var otherIterator = getIterator(other);
if (!!valueIterator !== !!otherIterator) {
if (valueIterator) { return 'first argument is iterable; second is not'; }
return 'second argument is iterable; first is not';
}
if (valueIterator && otherIterator) { // both should be truthy or falsy at this point
var valueNext, otherNext, nextWhy;
do {
valueNext = valueIterator.next();
otherNext = otherIterator.next();
if (!valueNext.done && !otherNext.done) {
nextWhy = whyNotEqual(valueNext, otherNext);
if (nextWhy !== '') {
return 'iteration results are not equal: ' + nextWhy;
}
} while (!valueNext.done && !otherNext.done);
if (valueNext.done && !otherNext.done) { return 'first argument finished iterating before second'; }
if (!valueNext.done && otherNext.done) { return 'second argument finished iterating before first'; }
return '';
}
} else if (collectionsForEach.Map || collectionsForEach.Set) {
var valueEntries = tryMapSetEntries(value);
var otherEntries = tryMapSetEntries(other);
var valueEntriesIsArray = isArray(valueEntries);
var otherEntriesIsArray = isArray(otherEntries);
if (valueEntriesIsArray && !otherEntriesIsArray) { return 'first argument has Collection entries, second does not'; }
if (!valueEntriesIsArray && otherEntriesIsArray) { return 'second argument has Collection entries, first does not'; }
if (valueEntriesIsArray && otherEntriesIsArray) {
var entriesWhy = whyNotEqual(valueEntries, otherEntries);
return entriesWhy === '' ? '' : 'Collection entries differ: ' + entriesWhy;
}
}
} while (!valueNext.done && !otherNext.done);
if (valueNext.done && !otherNext.done) { return 'first ' + objectType(value) + ' argument finished iterating before second ' + objectType(other); }
if (!valueNext.done && otherNext.done) { return 'second ' + objectType(other) + ' argument finished iterating before first ' + objectType(value); }
return '';
}

var key, valueKeyIsRecursive, otherKeyIsRecursive, keyWhy;
Expand Down

0 comments on commit 09dac2f

Please sign in to comment.