Skip to content

Commit

Permalink
feat: #isEqual set helpers (wip); test coverage; alternate intersecti…
Browse files Browse the repository at this point in the history
…on impl
  • Loading branch information
mrflip committed Aug 5, 2022
1 parent 432b4da commit 44b77af
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.39.3

* Adding `#isEqual` to Set helpers.

## 0.39.2

* Fixing typings of low-level structure consuming methods (@jerome-benoit).
Expand Down
27 changes: 27 additions & 0 deletions set.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,33 @@ exports.isSubset = function(A, B) {
return true;
};


/**
* Function returning whether A equals B (same size and B has all elements of A)
*
* @param {Set} A - First set.
* @param {Set} B - Second set.
* @return {boolean}
*/
exports.isEqual = function(A, B) {
var iterator = A.values(),
step;

// Shortcuts
if (A === B)
return true;

if (A.size !== B.size)
return false;

while ((step = iterator.next(), !step.done)) {
if (!B.has(step.value))
return false;
}

return true;
};

/**
* Function returning whether A is a superset of B.
*
Expand Down
190 changes: 172 additions & 18 deletions test/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,93 @@ describe('Set functions', function() {
describe('#.intersection', function() {

it('should properly compute the intersection of two sets.', function() {
var A = new Set([1, 2, 3]),
B = new Set([2, 3, 4]);
var Exemplar = new Set([2, 3, 1]);
var Equiv = new Set([1, 2, 3]);
var Missing1 = new Set([2, 3]);
var Extra45 = new Set([1, 2, 3, 4, 5]);
var Disjoint = new Set([7, 8, 9]);
var Empty = new Set([])
//
var WithItself = functions.intersection(Exemplar, Exemplar);
assert.deepStrictEqual(Array.from(WithItself), [2, 3, 1]);
var WithEquiv = functions.intersection(Exemplar, Equiv);
assert.deepStrictEqual(Array.from(WithEquiv), [2, 3, 1]);
var WithSubset = functions.intersection(Exemplar, Missing1);
assert.deepStrictEqual(Array.from(WithSubset), [2, 3]);
var WithExtras = functions.intersection(Exemplar, Extra45);
assert.deepStrictEqual(Array.from(WithExtras), [2, 3, 1]);
var WithDisjoint = functions.intersection(Exemplar, Disjoint);
assert.deepStrictEqual(Array.from(WithDisjoint), []);
var WithEmpty = functions.intersection(Exemplar, Empty);
assert.deepStrictEqual(Array.from(WithEmpty), []);
});

var I = functions.intersection(A, B);
it('Makes no guarantees for element ordering.', function() {
// To be clear: it *currently* preserves the order of the earliest of
// sets with the smallest size, but do not depend on this behavior.
//
var Exemplar = new Set([2, 3, 99, 1, 10]);
var Equiv = new Set([1, 2, 3, 10, 99]);
var SubsetA = new Set([99, 3, 2]);
var SubsetB = new Set([3, 99, 2]);
//
var R1 = functions.intersection(Exemplar, Equiv);
assert.deepStrictEqual(Array.from(R1), [2, 3, 99, 1, 10]);
//
var R2 = functions.intersection(Equiv, Exemplar);
assert.deepStrictEqual(Array.from(R2), [1, 2, 3, 10, 99]);
//
var R3 = functions.intersection(Exemplar, Equiv, SubsetA);
assert.deepStrictEqual(Array.from(R3), [99, 3, 2]);
//
var R4 = functions.intersection(Exemplar, SubsetB, Equiv, SubsetA);
assert.deepStrictEqual(Array.from(R4), [3, 99, 2]);
});

assert.deepStrictEqual(Array.from(I), [2, 3]);
it('compares identity, not equivalence.', function() {
var arrE1 = []
var arrE2 = []
var arrN1 = [1]
var arrN2 = [1]
var Exemplar = new Set([1, 2, 3, 'same', arrE1, arrN1]);
var NoneIdentical = new Set([2, 3, 'same', arrE2, arrN2]);
var SomeIdentical = new Set([arrN2, 2, 3, 'same', arrE1]);
//
var WithNoneI = functions.intersection(Exemplar, NoneIdentical);
assert.deepStrictEqual(Array.from(WithNoneI), [2, 3, 'same']);
var WithSomeI = functions.intersection(Exemplar, SomeIdentical);
assert.deepStrictEqual(Array.from(WithSomeI), [2, 3, 'same', arrE1]);
});

it('should be variadic.', function() {
var A = new Set([1, 2, 3, 4]),
B = new Set([2, 3, 4]),
C = new Set([1, 4]),
D = new Set([4, 5, 6]);
it('returns a new set, modifying none', function() {
var Exemplar = new Set([1, 2, 3]);
var Missing1 = new Set([2, 3]);
var Extra45 = new Set([1, 2, 3, 4, 5]);
var Disjoint = new Set([7, 8, 9]);
//
functions.intersection(Exemplar, Missing1, Extra45, Disjoint);
//
assert.deepStrictEqual(Array.from(Exemplar), [1, 2, 3]);
assert.deepStrictEqual(Array.from(Missing1), [2, 3]);
assert.deepStrictEqual(Array.from(Extra45), [1, 2, 3, 4, 5]);
assert.deepStrictEqual(Array.from(Disjoint), [7, 8, 9]);
});

it('should be variadic (work with multiple sets).', function() {
var Exemplar = new Set([1, 2, 3]);
var Equiv = new Set([1, 2, 3]);
var Missing1 = new Set([2, 3]);
var Extra45 = new Set([1, 2, 3, 4, 5]);
var Disjoint = new Set([7, 8, 9]);
var Empty = new Set([])

var I = functions.intersection(A, B, C, D);
var I1 = functions.intersection(Exemplar, Missing1, Extra45);

assert.deepStrictEqual(Array.from(I), [4]);
assert.deepStrictEqual(Array.from(I1), [2, 3]);

var I2 = functions.intersection(Exemplar, Missing1, Extra45, Disjoint);

assert.deepStrictEqual(Array.from(I2), []);
});
});

Expand Down Expand Up @@ -82,21 +152,52 @@ describe('Set functions', function() {
it('should properly return if the first set is a subset of the second.', function() {
var A = new Set([1, 2]),
B = new Set([1, 2, 3]),
C = new Set([2, 4]);
C = new Set([2, 4]),
Empty = new Set([]);

assert.strictEqual(functions.isSubset(A, B), true);
assert.strictEqual(functions.isSubset(C, B), false);
assert.strictEqual(functions.isSubset(Empty, B), true);
assert.strictEqual(functions.isSubset(B, Empty), false);
assert.strictEqual(functions.isSubset(Empty, Empty), true);
});
});

describe('#.isEqual', function() {
it('should properly return if the first set is equal to the second set.', function() {
var Exemplar = new Set([1, 2, 3]),
SameObj = Exemplar,
YepEqualsTo = new Set([1, 2, 3]),
MoreEls = new Set([1, 2, 3, 4]),
FewerEls = new Set([1]),
DifferentEls = new Set([1, 2, 4]),
Empty = new Set([]);

assert.strictEqual(functions.isEqual(Exemplar, Exemplar), true);
assert.strictEqual(functions.isEqual(SameObj, Exemplar), true);
assert.strictEqual(functions.isEqual(YepEqualsTo, Exemplar), true);
assert.strictEqual(functions.isEqual(Empty, Empty), true);
//
assert.strictEqual(functions.isEqual(MoreEls, Exemplar), false);
assert.strictEqual(functions.isEqual(FewerEls, Exemplar), false);
assert.strictEqual(functions.isEqual(DifferentEls, Exemplar), false);
assert.strictEqual(functions.isEqual(Empty, Exemplar), false);
assert.strictEqual(functions.isEqual(Exemplar, Empty), false);
});
});

describe('#.isSuperset', function() {
it('should properly return if the first set is a subset of the second.', function() {
it('should properly return if the first set is a superset of the second.', function() {
var A = new Set([1, 2]),
B = new Set([1, 2, 3]),
C = new Set([2, 4]);
C = new Set([2, 4]),
Empty = new Set([]);

assert.strictEqual(functions.isSuperset(B, A), true);
assert.strictEqual(functions.isSuperset(B, C), false);
assert.strictEqual(functions.isSuperset(B, Empty), true);
assert.strictEqual(functions.isSuperset(Empty, B), false);
assert.strictEqual(functions.isSuperset(Empty, Empty), true);
});
});

Expand All @@ -107,6 +208,10 @@ describe('Set functions', function() {
functions.add(A, new Set([2, 3]));

assert.deepStrictEqual(Array.from(A), [1, 2, 3]);

functions.add(A, new Set());

assert.deepStrictEqual(Array.from(A), [1, 2, 3]);
});
});

Expand All @@ -117,16 +222,65 @@ describe('Set functions', function() {
functions.subtract(A, new Set([2, 3]));

assert.deepStrictEqual(Array.from(A), [1]);

functions.subtract(A, new Set());

assert.deepStrictEqual(Array.from(A), [1]);
});

it('should properly subtract sets from an empty set.', function() {
var Empty = new Set([]);

functions.subtract(Empty, new Set([2, 3]));

assert.deepStrictEqual(Array.from(Empty), []);

functions.subtract(Empty, new Set());

assert.deepStrictEqual(Array.from(Empty), []);
});
});

describe('#.intersect', function() {
it('should properly intersect the second set to the first.', function() {
var A = new Set([1, 2]);
var Equiv = new Set([1, 2, 3]);
var Missing1 = new Set([2, 3]);
var Disjoint = new Set([7, 8, 9]);
var Empty = new Set([])

it('should properly intersect overlapping sets.', function() {
var Exemplar = new Set([1, 2, 3]);
functions.intersect(Exemplar, Missing1)

assert.deepStrictEqual(Array.from(Exemplar), [2, 3]);
assert.deepStrictEqual(Array.from(Missing1), [2, 3]);
});

it('should properly intersect equivalent sets.', function() {
var Exemplar = new Set([1, 2, 3]);
functions.intersect(Exemplar, Exemplar)

assert.deepStrictEqual(Array.from(Exemplar), [1, 2, 3]);

functions.intersect(Exemplar, Equiv)

assert.deepStrictEqual(Array.from(Exemplar), [1, 2, 3]);
assert.deepStrictEqual(Array.from(Equiv), [1, 2, 3]);
});

it('should properly intersect disjoint sets.', function() {
var Exemplar = new Set([1, 2, 3]);

functions.intersect(Exemplar, Disjoint);

assert.deepStrictEqual(Array.from(Exemplar), []);
assert.deepStrictEqual(Array.from(Disjoint), [7, 8, 9]);

Exemplar = new Set([1, 2, 3]);

functions.intersect(A, new Set([2, 3]));
functions.intersect(Exemplar, Empty);

assert.deepStrictEqual(Array.from(A), [2]);
assert.deepStrictEqual(Array.from(Exemplar), []);
assert.deepStrictEqual(Array.from(Empty), []);
});
});

Expand Down

0 comments on commit 44b77af

Please sign in to comment.