Skip to content

Commit

Permalink
Merge pull request #153 from NickHeiner/array-assertions
Browse files Browse the repository at this point in the history
Adding members and memberEquals assertions
  • Loading branch information
logicalparadox committed Apr 29, 2013
2 parents 039d8c6 + 244fa51 commit 387ee31
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 1 deletion.
98 changes: 97 additions & 1 deletion lib/chai/core/assertions.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module.exports = function (chai, _) {
[ 'to', 'be', 'been'
, 'is', 'and', 'have'
, 'with', 'that', 'at'
, 'of' ].forEach(function (chain) {
, 'of', 'same'].forEach(function (chain) {
Assertion.addProperty(chain, function () {
return this;
});
Expand Down Expand Up @@ -80,6 +80,18 @@ module.exports = function (chai, _) {
flag(this, 'deep', true);
});

/**
* ### .same
*
* Sets the `same` flag, later used by the `members` assertion.
*
* expect([1, 2, 3]).to.have.same.members([3, 2, 1])
*/

Assertion.addProperty('same', function () {
flag(this, 'same', true);
});

/**
* ### .a(type)
*
Expand Down Expand Up @@ -1217,4 +1229,88 @@ module.exports = function (chai, _) {
);
});

function isSubsetOf(subset, superset) {
return subset.every(function(elem) {
return superset.indexOf(elem) !== -1;
})
}

/**
* ### .members
*
* Asserts that the target is a superset of `set`,
* or that the target and `set` have the same members.
*
* expect([1, 2, 3]).to.include.members([3, 2]);
* expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
*
* expect([4, 2]).to.have.same.members([2, 4]);
* expect([5, 2]).to.not.have.same.members([5, 2, 1]);
*
* @name members
* @param {Array} set
* @param {String} message _optional_
* @api public
*/

Assertion.addMethod('members', function (subset, msg) {
if (msg) flag(this, 'message', msg);
var obj = flag(this, 'object');

new Assertion(obj).to.be.an('array');
new Assertion(subset).to.be.an('array');

if (flag(this, 'contains')) {
return this.assert(
isSubsetOf(subset, obj)
, 'expected #{this} to be a superset of #{act}'
, 'expected #{this} to not be a superset of #{act}'
, obj
, subset
);
}

this.assert(
isSubsetOf(obj, subset) && isSubsetOf(subset, obj)
, 'expected #{this} to have the same members as #{act}'
, 'expected #{this} to not have the same members as #{act}'
, obj
, subset
);



});


/**
* ### .memberEquals
*
* Asserts that the target and `items` have the same set of members.
*
* expect([1, 2, 3]).to.be.memberEquals([3, 2, 1])
* expect([1, 2, 3]).to.not.be.memberEquals([6, 1, 2, 3])
*
* @name memberEquals
* @param {Array} items
* @param {String} message _optional_
* @api public
*/
//
// Assertion.addMethod('memberEquals', function (items, msg) {
// if (msg) flag(this, 'message', msg);
// var obj = flag(this, 'object');
//
// new Assertion(obj).to.be.an('array');
// new Assertion(items).to.be.an('array');
//
// this.assert(
// isSubsetOf(obj, items) && isSubsetOf(items, obj)
// , 'expected #{this} to have the same members as #{act}'
// , 'expected #{this} to not have the same members as #{act}'
// , obj
// , items
// );
// });

};
8 changes: 8 additions & 0 deletions lib/chai/interface/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,14 @@ module.exports = function (chai, util) {
new Assertion(act, msg).to.be.closeTo(exp, delta);
};

assert.includeMembers = function (superset, subset, msg) {
new Assertion(superset, msg).to.include.members(subset);
}

assert.sameMembers = function (set1, set2, msg) {
new Assertion(set1, msg).to.have.same.members(set2);
}

/*!
* Undocumented / untested
*/
Expand Down
29 changes: 29 additions & 0 deletions test/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,4 +533,33 @@ suite('assert', function () {
assert.closeTo(-10, 20, 29);
}, "expected -10 to be close to 20 +/- 29");
});

test('members', function() {
assert.includeMembers([1, 2, 3], [2, 3]);
assert.includeMembers([1, 2, 3], []);
assert.includeMembers([1, 2, 3], [3]);

err(function() {
assert.includeMembers([5, 6], [7, 8]);
}, 'expected [ 5, 6 ] to be a superset of [ 7, 8 ]');

err(function() {
assert.includeMembers([5, 6], [5, 6, 0]);
}, 'expected [ 5, 6 ] to be a superset of [ 5, 6, 0 ]');
});

test('memberEquals', function() {
assert.sameMembers([], []);
assert.sameMembers([1, 2, 3], [3, 2, 1]);
assert.sameMembers([4, 2], [4, 2]);

err(function() {
assert.sameMembers([], [1, 2]);
}, 'expected [] to have the same members as [ 1, 2 ]');

err(function() {
assert.sameMembers([1, 54], [6, 1, 54]);
}, 'expected [ 1, 54 ] to have the same members as [ 6, 1, 54 ]');
});

});
29 changes: 29 additions & 0 deletions test/expect.js
Original file line number Diff line number Diff line change
Expand Up @@ -718,4 +718,33 @@ suite('expect', function () {
expect(-10).to.be.closeTo(20, 29, 'blah');
}, "blah: expected -10 to be close to 20 +/- 29");
});

test('include.members', function() {
expect([1, 2, 3]).to.include.members([]);

expect([1, 2, 3]).to.include.members([3, 2]);

expect([1, 2, 3]).to.not.include.members([8, 4]);

expect([1, 2, 3]).to.not.include.members([1, 2, 3, 4]);
});

test('same.members', function() {
expect([5, 4]).to.have.same.members([4, 5]);
expect([5, 4]).to.have.same.members([5, 4]);

expect([5, 4]).to.not.have.same.members([]);
expect([5, 4]).to.not.have.same.members([6, 3]);
expect([5, 4]).to.not.have.same.members([5, 4, 2]);
});

test('members', function() {
expect([5, 4]).members([4, 5]);
expect([5, 4]).members([5, 4]);

expect([5, 4]).not.members([]);
expect([5, 4]).not.members([6, 3]);
expect([5, 4]).not.members([5, 4, 2]);
})

});
39 changes: 39 additions & 0 deletions test/should.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,4 +670,43 @@ suite('should', function() {
(2).should.be.closeTo(1.0, 0.5, 'blah');
}, "blah: expected 2 to be close to 1 +/- 0.5");
});

test('include.members', function() {
[1, 2, 3].should.include.members([3]);
[1, 2, 3].should.include.members([]);
[1, 2, 3].should.include.members([2, 1]);

[1, 2, 3].should.not.include.members([999]);
[].should.not.include.members([23]);

err(function() {
[].should.include.members([43]);
}, 'expected [] to be a superset of [ 43 ]');

err(function() {
[5, 2, 1].should.not.include.members([2]);
}, 'expected [ 5, 2, 1 ] to not be a superset of [ 2 ]');

err(function() {
'foo'.should.include.members([12]);
}, "expected 'foo' to be an array");

err(function() {
[1, 2, 3].should.include.members('o');
}, "expected 'o' to be an array");
});

test('memberEquals', function() {
[1, 2, 3].should.have.same.members([3, 2, 1]);
[5, 4].should.have.same.members([5, 4]);
[].should.have.same.members([]);

err(function() {
[1, 2, 3].should.have.same.members([]);
}, 'expected [ 1, 2, 3 ] to have the same members as []');

err(function() {
[1, 2, 3].should.have.same.members(4);
}, 'expected 4 to be an array');
});
});

0 comments on commit 387ee31

Please sign in to comment.