Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set helpers #isEqual, adds some test coverage #186

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 0.40.0 since we are adding a feature. I also usually add (provisional) at the right so that people know until the version is actually released.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


* 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]);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those variables should not be capitalized.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated all, including the pre-existing ones, to all be lowerCameled and more than one character

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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drop the capitalized M :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. In an act of overkill, because the jest eslinter enforces lowercase titles, I added the mocha linter to package.json. It does not; but it did catch some cases where there were arrow functions, which mocha doesn't like. I can remove or file that commit under its own PR if you prefer.

// 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