Skip to content

Commit d504573

Browse files
author
Kristján Oddsson
authored
Implement iterable assertion (#1592)
* Implement `iterator` assertion * Consider `string` to be iterable * Revert changes to `isSubsetOf` * Move iterable check out of `an()` function
1 parent 640d932 commit d504573

File tree

5 files changed

+132
-1
lines changed

5 files changed

+132
-1
lines changed

lib/chai/core/assertions.js

+32-1
Original file line numberDiff line numberDiff line change
@@ -3133,7 +3133,6 @@ function isSubsetOf(subset, superset, cmp, contains, ordered) {
31333133
* @namespace BDD
31343134
* @api public
31353135
*/
3136-
31373136
Assertion.addMethod('members', function (subset, msg) {
31383137
if (msg) flag(this, 'message', msg);
31393138
var obj = flag(this, 'object')
@@ -3170,6 +3169,38 @@ Assertion.addMethod('members', function (subset, msg) {
31703169
);
31713170
});
31723171

3172+
/**
3173+
* ### .iterable
3174+
*
3175+
* Asserts that the target is an iterable, which means that it has a iterator.
3176+
*
3177+
* expect([1, 2]).to.be.iterable;
3178+
*
3179+
* Add `.not` earlier in the chain to negate `.iterable`.
3180+
*
3181+
* expect(1).to.not.be.iterable;
3182+
* expect(true).to.not.be.iterable;
3183+
*
3184+
* A custom error message can be given as the second argument to `expect`.
3185+
*
3186+
* expect(1, 'nooo why fail??').to.be.iterable;
3187+
*
3188+
* @name iterable
3189+
* @namespace BDD
3190+
* @api public
3191+
*/
3192+
Assertion.addProperty('iterable', function(msg) {
3193+
if (msg) flag(this, 'message', msg);
3194+
var obj = flag(this, 'object');
3195+
3196+
this.assert(
3197+
obj != undefined && obj[Symbol.iterator]
3198+
, 'expected #{this} to be an iterable'
3199+
, 'expected #{this} to not be an iterable'
3200+
, obj
3201+
);
3202+
});
3203+
31733204
/**
31743205
* ### .oneOf(list[, msg])
31753206
*

lib/chai/interface/assert.js

+27
Original file line numberDiff line numberDiff line change
@@ -2376,6 +2376,33 @@ assert.oneOf = function (inList, list, msg) {
23762376
new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list);
23772377
}
23782378

2379+
/**
2380+
* ### isIterable(obj, [message])
2381+
*
2382+
* Asserts that the target is an iterable, which means that it has a iterator
2383+
* with the exception of `String.`
2384+
*
2385+
* assert.isIterable([1, 2]);
2386+
*
2387+
* @param {unknown} obj
2388+
* @param {string} [msg]
2389+
* @namespace Assert
2390+
* @api public
2391+
*/
2392+
assert.isIterable = function(obj, msg) {
2393+
if (obj == undefined || !obj[Symbol.iterator]) {
2394+
msg = msg ?
2395+
`${msg} expected ${inspect(obj)} to be an iterable` :
2396+
`expected ${inspect(obj)} to be an iterable`;
2397+
2398+
throw new AssertionError(
2399+
msg,
2400+
undefined,
2401+
assert.isIterable
2402+
);
2403+
}
2404+
}
2405+
23792406
/**
23802407
* ### .changes(function, object, property, [message])
23812408
*

test/assert.js

+27
Original file line numberDiff line numberDiff line change
@@ -2315,6 +2315,33 @@ describe('assert', function () {
23152315
}, 'blah: the argument to most must be a number');
23162316
});
23172317

2318+
it('iterable', function() {
2319+
assert.isIterable([1, 2, 3]);
2320+
assert.isIterable(new Map([[1, 'one'], [2, 'two'], [3, 'three']]));
2321+
assert.isIterable(new Set([1, 2, 3]));
2322+
assert.isIterable('hello');
2323+
2324+
err(function() {
2325+
assert.isIterable(42);
2326+
}, 'expected 42 to be an iterable');
2327+
2328+
err(function() {
2329+
assert.isIterable(undefined);
2330+
}, 'expected undefined to be an iterable');
2331+
2332+
err(function() {
2333+
assert.isIterable(null);
2334+
}, 'expected null to be an iterable');
2335+
2336+
err(function() {
2337+
assert.isIterable(true);
2338+
}, 'expected true to be an iterable');
2339+
2340+
err(function() {
2341+
assert.isIterable({ key: 'value' });
2342+
}, 'expected { key: \'value\' } to be an iterable');
2343+
});
2344+
23182345
it('change', function() {
23192346
var obj = { value: 10, str: 'foo' },
23202347
heroes = ['spiderman', 'superman'],

test/expect.js

+27
Original file line numberDiff line numberDiff line change
@@ -3569,6 +3569,33 @@ describe('expect', function () {
35693569
}, 'expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not be an ordered superset of [ { a: 1 }, { b: 2 } ]');
35703570
});
35713571

3572+
it('iterable', function() {
3573+
expect([1, 2, 3]).to.be.iterable;
3574+
expect(new Map([[1, 'one'], [2, 'two'], [3, 'three']])).to.be.iterable;
3575+
expect(new Set([1, 2, 3])).to.be.iterable;
3576+
expect('hello').to.be.iterable;
3577+
3578+
err(function() {
3579+
expect(42).to.be.iterable;
3580+
}, 'expected 42 to be an iterable');
3581+
3582+
err(function() {
3583+
expect(undefined).to.be.iterable;
3584+
}, 'expected undefined to be an iterable');
3585+
3586+
err(function() {
3587+
expect(null).to.be.iterable;
3588+
}, 'expected null to be an iterable');
3589+
3590+
err(function() {
3591+
expect(true).to.be.iterable;
3592+
}, 'expected true to be an iterable');
3593+
3594+
err(function() {
3595+
expect({ key: 'value' }).to.be.iterable;
3596+
}, 'expected { key: \'value\' } to be an iterable');
3597+
})
3598+
35723599
it('change', function() {
35733600
var obj = { value: 10, str: 'foo' },
35743601
heroes = ['spiderman', 'superman'],

test/should.js

+19
Original file line numberDiff line numberDiff line change
@@ -2937,6 +2937,25 @@ describe('should', function() {
29372937
}, 'expected [ { a: 1 }, { b: 2 }, { c: 3 } ] to not be an ordered superset of [ { a: 1 }, { b: 2 } ]');
29382938
});
29392939

2940+
it ('iterable', function() {
2941+
([1, 2, 3]).should.be.iterable;
2942+
(new Map([[1, 'one'], [2, 'two'], [3, 'three']])).should.be.iterable;
2943+
(new Set([1, 2, 3])).should.be.iterable;
2944+
('hello').should.be.iterable;
2945+
2946+
err(function() {
2947+
(42).should.be.iterable;
2948+
}, 'expected 42 to be an iterable');
2949+
2950+
err(function() {
2951+
(true).should.be.iterable;
2952+
}, 'expected true to be an iterable');
2953+
2954+
err(function() {
2955+
({ key: 'value' }).should.be.iterable;
2956+
}, 'expected { key: \'value\' } to be an iterable');
2957+
})
2958+
29402959
it('change', function() {
29412960
var obj = { value: 10, str: 'foo' },
29422961
heroes = ['spiderman', 'superman'],

0 commit comments

Comments
 (0)