Skip to content

Commit 179d470

Browse files
committed
feat(matchers): Add value-in-list assertion
Adds a way to test if a value appears in a flat list. Compliments `include.members` to reverse the order of the input. Now the list appears in the assertion, as opposed to the `expect`. Closes #532
1 parent db21e48 commit 179d470

File tree

5 files changed

+92
-4
lines changed

5 files changed

+92
-4
lines changed

lib/chai/core/assertions.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,39 @@ module.exports = function (chai, _) {
15311531
);
15321532
});
15331533

1534+
/**
1535+
* ### .oneOf(list)
1536+
*
1537+
* Assert that a non-array, non-object value appears somewhere in the flat array `list`.
1538+
*
1539+
* expect('a').to.be.oneOf(['a', 'b', 'c']);
1540+
* expect(9).to.not.be.oneOf(['z']);
1541+
*
1542+
* @name oneOf
1543+
* @param {Array<*>} list
1544+
* @param {String} message _optional_
1545+
* @api public
1546+
*/
1547+
1548+
function oneOf (list, msg) {
1549+
if (msg) flag(this, 'message', msg);
1550+
var expected = flag(this, 'object');
1551+
new Assertion(list).to.be.an('array');
1552+
new Assertion(expected).to.not.be.an('array');
1553+
new Assertion(expected).to.not.be.an('object');
1554+
1555+
this.assert(
1556+
list.indexOf(expected) > -1
1557+
, 'expected #{this} to be in #{exp}'
1558+
, 'expected #{this} to not be in #{exp}'
1559+
, list
1560+
, expected
1561+
);
1562+
}
1563+
1564+
Assertion.addMethod('oneOf', oneOf);
1565+
1566+
15341567
/**
15351568
* ### .change(function)
15361569
*

lib/chai/interface/assert.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ module.exports = function (chai, util) {
11651165
assert.closeTo = function (act, exp, delta, msg) {
11661166
new Assertion(act, msg).to.be.closeTo(exp, delta);
11671167
};
1168-
1168+
11691169
/**
11701170
* ### .approximately(actual, expected, delta, [message])
11711171
*
@@ -1242,6 +1242,24 @@ module.exports = function (chai, util) {
12421242
new Assertion(superset, msg).to.include.members(subset);
12431243
}
12441244

1245+
/**
1246+
* ### .oneOf(inList, list, [message])
1247+
*
1248+
* Asserts that non-object, non-array value `inList` appears in the flat array `list`.
1249+
*
1250+
* assert.oneOf(1, [ 2, 1 ], 'Not found in list');
1251+
*
1252+
* @name oneOf
1253+
* @param {*} inList
1254+
* @param {Array<*>} list
1255+
* @param {String} message
1256+
* @api public
1257+
*/
1258+
1259+
assert.oneOf = function (inList, list, msg) {
1260+
new Assertion(inList, msg).to.be.oneOf(list);
1261+
}
1262+
12451263
/**
12461264
* ### .changes(function, object, property)
12471265
*

test/assert.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ describe('assert', function () {
713713
assert.closeTo(1.5, 1.0, true);
714714
}, "the arguments to closeTo or approximately must be numbers");
715715
});
716-
716+
717717
it('approximately', function(){
718718
assert.approximately(1.5, 1.0, 0.5);
719719
assert.approximately(10, 20, 20);
@@ -768,6 +768,31 @@ describe('assert', function () {
768768
}, 'expected [ 1, 54 ] to have the same members as [ 6, 1, 54 ]');
769769
});
770770

771+
it('oneOf', function() {
772+
assert.oneOf(1, [1, 2, 3]);
773+
774+
err(function() {
775+
assert.oneOf([1], []);
776+
}, 'expected [ 1 ] not to be an array');
777+
778+
err(function() {
779+
assert.oneOf({a: 1}, []);
780+
}, 'expected { a: 1 } not to be an object');
781+
782+
err(function() {
783+
assert.oneOf(1, 1);
784+
}, 'expected 1 to be an array');
785+
786+
err(function() {
787+
assert.oneOf(1, {a: 1});
788+
}, 'expected { a: 1 } to be an array');
789+
790+
err(function() {
791+
assert.oneOf(9, [1, 2, 3], 'Message');
792+
}, 'Message: expected 9 to be in [ 1, 2, 3 ]');
793+
794+
});
795+
771796
it('above', function() {
772797
assert.isAbove(5, 2, '5 should be above 2');
773798

test/expect.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ describe('expect', function () {
10521052
expect(1.5).to.be.closeTo(1.0, true);
10531053
}, "the arguments to closeTo or approximately must be numbers");
10541054
});
1055-
1055+
10561056
it('approximately', function(){
10571057
expect(1.5).to.be.approximately(1.0, 0.5);
10581058
expect(10).to.be.approximately(20, 20);
@@ -1079,6 +1079,11 @@ describe('expect', function () {
10791079
}, "the arguments to closeTo or approximately must be numbers");
10801080
});
10811081

1082+
it('oneOf', function() {
1083+
expect(1).to.be.oneOf([1, 2, 3]);
1084+
expect('1').to.not.be.oneOf([1, 2, 3]);
1085+
});
1086+
10821087
it('include.members', function() {
10831088
expect([1, 2, 3]).to.include.members([]);
10841089
expect([1, 2, 3]).to.include.members([3, 2]);

test/should.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,13 @@ describe('should', function() {
457457
}, "blah: expected 'foobar' to not contain 'bar'");
458458
});
459459

460+
it('oneOf()', function(){
461+
'foo'.should.be.oneOf(['foo', 'bar']);
462+
'bar'.should.be.oneOf(['foo', 'bar']);
463+
'baz'.should.not.be.oneOf(['foo', 'bar']);
464+
'baz'.should.not.be.oneOf([]);
465+
});
466+
460467
it('include()', function(){
461468
['foo', 'bar'].should.include('foo');
462469
['foo', 'bar'].should.contain('foo');
@@ -881,7 +888,7 @@ describe('should', function() {
881888
(1.5).should.be.closeTo(1.0, true);
882889
}, "the arguments to closeTo or approximately must be numbers");
883890
});
884-
891+
885892
it('approximately', function(){
886893
(1.5).should.be.approximately(1.0, 0.5);
887894

0 commit comments

Comments
 (0)