Skip to content

Commit

Permalink
.lengthOf for Maps and Sets
Browse files Browse the repository at this point in the history
  • Loading branch information
asbish committed Jan 25, 2018
1 parent e354bee commit bbdc3e1
Show file tree
Hide file tree
Showing 4 changed files with 620 additions and 36 deletions.
124 changes: 88 additions & 36 deletions lib/chai/core/assertions.js
Expand Up @@ -1147,7 +1147,7 @@ module.exports = function (chai, _) {
, errorMessage
, shouldThrow = true;

if (doLength) {
if (doLength && objType !== 'map' && objType !== 'set') {
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
}

Expand All @@ -1167,13 +1167,20 @@ module.exports = function (chai, _) {
}

if (doLength) {
var len = obj.length;
var descriptor = 'length'
, itemsCount;
if (objType === 'map' || objType === 'set') {
descriptor = 'size';
itemsCount = obj.size;
} else {
itemsCount = obj.length;
}
this.assert(
len > n
, 'expected #{this} to have a length above #{exp} but got #{act}'
, 'expected #{this} to not have a length above #{exp}'
itemsCount > n
, 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
, 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
, n
, len
, itemsCount
);
} else {
this.assert(
Expand Down Expand Up @@ -1244,7 +1251,7 @@ module.exports = function (chai, _) {
, errorMessage
, shouldThrow = true;

if (doLength) {
if (doLength && objType !== 'map' && objType !== 'set') {
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
}

Expand All @@ -1264,13 +1271,20 @@ module.exports = function (chai, _) {
}

if (doLength) {
var len = obj.length;
var descriptor = 'length'
, itemsCount;
if (objType === 'map' || objType === 'set') {
descriptor = 'size';
itemsCount = obj.size;
} else {
itemsCount = obj.length;
}
this.assert(
len >= n
, 'expected #{this} to have a length at least #{exp} but got #{act}'
, 'expected #{this} to have a length below #{exp}'
itemsCount >= n
, 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
, 'expected #{this} to have a ' + descriptor + ' below #{exp}'
, n
, len
, itemsCount
);
} else {
this.assert(
Expand Down Expand Up @@ -1340,7 +1354,7 @@ module.exports = function (chai, _) {
, errorMessage
, shouldThrow = true;

if (doLength) {
if (doLength && objType !== 'map' && objType !== 'set') {
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
}

Expand All @@ -1360,13 +1374,20 @@ module.exports = function (chai, _) {
}

if (doLength) {
var len = obj.length;
var descriptor = 'length'
, itemsCount;
if (objType === 'map' || objType === 'set') {
descriptor = 'size';
itemsCount = obj.size;
} else {
itemsCount = obj.length;
}
this.assert(
len < n
, 'expected #{this} to have a length below #{exp} but got #{act}'
, 'expected #{this} to not have a length below #{exp}'
itemsCount < n
, 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
, 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
, n
, len
, itemsCount
);
} else {
this.assert(
Expand Down Expand Up @@ -1436,7 +1457,7 @@ module.exports = function (chai, _) {
, errorMessage
, shouldThrow = true;

if (doLength) {
if (doLength && objType !== 'map' && objType !== 'set') {
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
}

Expand All @@ -1456,13 +1477,20 @@ module.exports = function (chai, _) {
}

if (doLength) {
var len = obj.length;
var descriptor = 'length'
, itemsCount;
if (objType === 'map' || objType === 'set') {
descriptor = 'size';
itemsCount = obj.size;
} else {
itemsCount = obj.length;
}
this.assert(
len <= n
, 'expected #{this} to have a length at most #{exp} but got #{act}'
, 'expected #{this} to have a length above #{exp}'
itemsCount <= n
, 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
, 'expected #{this} to have a ' + descriptor + ' above #{exp}'
, n
, len
, itemsCount
);
} else {
this.assert(
Expand Down Expand Up @@ -1536,7 +1564,7 @@ module.exports = function (chai, _) {
? start.toUTCString() + '..' + finish.toUTCString()
: start + '..' + finish;

if (doLength) {
if (doLength && objType !== 'map' && objType !== 'set') {
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
}

Expand All @@ -1556,11 +1584,18 @@ module.exports = function (chai, _) {
}

if (doLength) {
var len = obj.length;
var descriptor = 'length'
, itemsCount;
if (objType === 'map' || objType === 'set') {
descriptor = 'size';
itemsCount = obj.size;
} else {
itemsCount = obj.length;
}
this.assert(
len >= start && len <= finish
, 'expected #{this} to have a length within ' + range
, 'expected #{this} to not have a length within ' + range
itemsCount >= start && itemsCount <= finish
, 'expected #{this} to have a ' + descriptor + ' within ' + range
, 'expected #{this} to not have a ' + descriptor + ' within ' + range
);
} else {
this.assert(
Expand Down Expand Up @@ -2013,6 +2048,11 @@ module.exports = function (chai, _) {
* expect([1, 2, 3]).to.have.lengthOf(3);
* expect('foo').to.have.lengthOf(3);
*
* When the target is a map or set, asserts that the target's `size` property.
*
* expect(new Set([1, 2])).to.hove.lengthOf(2);
* expect(new Map([['a', 1], ['b', 2]])).to.hove.lengthOf(2);
*
* Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often
* best to assert that the target's `length` property is equal to its expected
* value, rather than not equal to one of many unexpected values.
Expand Down Expand Up @@ -2067,17 +2107,29 @@ module.exports = function (chai, _) {
function assertLength (n, msg) {
if (msg) flag(this, 'message', msg);
var obj = flag(this, 'object')
, objType = _.type(obj).toLowerCase()
, flagMsg = flag(this, 'message')
, ssfi = flag(this, 'ssfi');
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
var len = obj.length;
, ssfi = flag(this, 'ssfi')
, descriptor = 'length'
, itemsCount;

switch (objType) {
case 'map':
case 'set':
descriptor = 'size';
itemsCount = obj.size;
break;
default:
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
itemsCount = obj.length;
}

this.assert(
len == n
, 'expected #{this} to have a length of #{exp} but got #{act}'
, 'expected #{this} to not have a length of #{act}'
itemsCount == n
, 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
, 'expected #{this} to not have a ' + descriptor + ' of #{act}'
, n
, len
, itemsCount
);
}

Expand Down
28 changes: 28 additions & 0 deletions test/assert.js
Expand Up @@ -1388,6 +1388,34 @@ describe('assert', function () {
err(function () {
assert.lengthOf(1, 5);
}, "expected 1 to have property \'length\'");

if (typeof Map === 'function') {
assert.lengthOf(new Map, 0);

var map = new Map;
map.set('a', 1);
map.set('b', 2);

assert.lengthOf(map, 2);

err(function(){
assert.lengthOf(map, 3, 'blah');
}, "blah: expected {} to have a size of 3 but got 2");
}

if (typeof Set === 'function') {
assert.lengthOf(new Set, 0);

var set = new Set;
set.add(1);
set.add(2);

assert.lengthOf(set, 2);

err(function(){
assert.lengthOf(set, 3, 'blah');
}, "blah: expected {} to have a size of 3 but got 2");
}
});

it('match', function () {
Expand Down

0 comments on commit bbdc3e1

Please sign in to comment.