chai 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODEOWNERS +1 -0
- package/chai.js +200 -84
- package/lib/chai/core/assertions.js +195 -78
- package/lib/chai/utils/expectTypes.js +3 -4
- package/lib/chai/utils/inspect.js +1 -1
- package/lib/chai.js +1 -1
- package/package.json +2 -2
package/CODEOWNERS
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @chaijs/chai
|
package/chai.js
CHANGED
|
@@ -14,7 +14,7 @@ var used = [];
|
|
|
14
14
|
* Chai version
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
exports.version = '4.0
|
|
17
|
+
exports.version = '4.1.0';
|
|
18
18
|
|
|
19
19
|
/*!
|
|
20
20
|
* Assertion Error
|
|
@@ -691,6 +691,16 @@ module.exports = function (chai, _) {
|
|
|
691
691
|
*
|
|
692
692
|
* expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
|
|
693
693
|
*
|
|
694
|
+
* When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
|
|
695
|
+
* member of the target. SameValueZero equality algorithm is used.
|
|
696
|
+
*
|
|
697
|
+
* expect(new Set([1, 2])).to.include(2);
|
|
698
|
+
*
|
|
699
|
+
* When the target is a Map, `.include` asserts that the given `val` is one of
|
|
700
|
+
* the values of the target. SameValueZero equality algorithm is used.
|
|
701
|
+
*
|
|
702
|
+
* expect(new Map([['a', 1], ['b', 2]])).to.include(2);
|
|
703
|
+
*
|
|
694
704
|
* Because `.include` does different things based on the target's type, it's
|
|
695
705
|
* important to check the target's type before using `.include`. See the `.a`
|
|
696
706
|
* doc for info on testing a target's type.
|
|
@@ -699,8 +709,8 @@ module.exports = function (chai, _) {
|
|
|
699
709
|
*
|
|
700
710
|
* By default, strict (`===`) equality is used to compare array members and
|
|
701
711
|
* object properties. Add `.deep` earlier in the chain to use deep equality
|
|
702
|
-
* instead. See the `deep-eql` project
|
|
703
|
-
* algorithm: https://github.com/chaijs/deep-eql.
|
|
712
|
+
* instead (WeakSet targets are not supported). See the `deep-eql` project
|
|
713
|
+
* page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
|
|
704
714
|
*
|
|
705
715
|
* // Target array deeply (but not strictly) includes `{a: 1}`
|
|
706
716
|
* expect([{a: 1}]).to.deep.include({a: 1});
|
|
@@ -810,25 +820,24 @@ module.exports = function (chai, _) {
|
|
|
810
820
|
* @api public
|
|
811
821
|
*/
|
|
812
822
|
|
|
813
|
-
function
|
|
814
|
-
|
|
823
|
+
function SameValueZero(a, b) {
|
|
824
|
+
return (_.isNaN(a) && _.isNaN(b)) || a === b;
|
|
815
825
|
}
|
|
816
826
|
|
|
817
|
-
function
|
|
818
|
-
|
|
819
|
-
return _.eql(arrVal, val);
|
|
820
|
-
});
|
|
827
|
+
function includeChainingBehavior () {
|
|
828
|
+
flag(this, 'contains', true);
|
|
821
829
|
}
|
|
822
830
|
|
|
823
831
|
function include (val, msg) {
|
|
824
832
|
if (msg) flag(this, 'message', msg);
|
|
825
833
|
|
|
826
|
-
_.expectTypes(this, [
|
|
834
|
+
_.expectTypes(this, [
|
|
835
|
+
'array', 'object', 'string',
|
|
836
|
+
'map', 'set', 'weakset',
|
|
837
|
+
]);
|
|
827
838
|
|
|
828
839
|
var obj = flag(this, 'object')
|
|
829
|
-
, objType = _.type(obj).toLowerCase()
|
|
830
|
-
, isDeep = flag(this, 'deep')
|
|
831
|
-
, descriptor = isDeep ? 'deep ' : '';
|
|
840
|
+
, objType = _.type(obj).toLowerCase();
|
|
832
841
|
|
|
833
842
|
// This block is for asserting a subset of properties in an object.
|
|
834
843
|
if (objType === 'object') {
|
|
@@ -865,10 +874,62 @@ module.exports = function (chai, _) {
|
|
|
865
874
|
return;
|
|
866
875
|
}
|
|
867
876
|
|
|
868
|
-
|
|
877
|
+
var isDeep = flag(this, 'deep')
|
|
878
|
+
, descriptor = isDeep ? 'deep ' : ''
|
|
879
|
+
, included = false;
|
|
880
|
+
|
|
881
|
+
switch (objType) {
|
|
882
|
+
case 'string':
|
|
883
|
+
included = obj.indexOf(val) !== -1;
|
|
884
|
+
break;
|
|
885
|
+
|
|
886
|
+
case 'weakset':
|
|
887
|
+
if (isDeep) {
|
|
888
|
+
var flagMsg = flag(this, 'message')
|
|
889
|
+
, ssfi = flag(this, 'ssfi');
|
|
890
|
+
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
891
|
+
|
|
892
|
+
throw new AssertionError(
|
|
893
|
+
flagMsg + 'unable to use .deep.include with WeakSet',
|
|
894
|
+
undefined,
|
|
895
|
+
ssfi
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
included = obj.has(val);
|
|
900
|
+
break;
|
|
901
|
+
|
|
902
|
+
case 'map':
|
|
903
|
+
var isEql = isDeep ? _.eql : SameValueZero;
|
|
904
|
+
obj.forEach(function (item) {
|
|
905
|
+
included = included || isEql(item, val);
|
|
906
|
+
});
|
|
907
|
+
break;
|
|
908
|
+
|
|
909
|
+
case 'set':
|
|
910
|
+
if (isDeep) {
|
|
911
|
+
obj.forEach(function (item) {
|
|
912
|
+
included = included || _.eql(item, val);
|
|
913
|
+
});
|
|
914
|
+
} else {
|
|
915
|
+
included = obj.has(val);
|
|
916
|
+
}
|
|
917
|
+
break;
|
|
918
|
+
|
|
919
|
+
case 'array':
|
|
920
|
+
if (isDeep) {
|
|
921
|
+
included = obj.some(function (item) {
|
|
922
|
+
return _.eql(item, val);
|
|
923
|
+
})
|
|
924
|
+
} else {
|
|
925
|
+
included = obj.indexOf(val) !== -1;
|
|
926
|
+
}
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
// Assert inclusion in collection or substring in a string.
|
|
869
931
|
this.assert(
|
|
870
|
-
|
|
871
|
-
: isDeepIncluded(obj, val)
|
|
932
|
+
included
|
|
872
933
|
, 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
|
|
873
934
|
, 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
|
|
874
935
|
}
|
|
@@ -1385,7 +1446,7 @@ module.exports = function (chai, _) {
|
|
|
1385
1446
|
/**
|
|
1386
1447
|
* ### .above(n[, msg])
|
|
1387
1448
|
*
|
|
1388
|
-
* Asserts that the target is a number greater than the given number `n
|
|
1449
|
+
* Asserts that the target is a number or a date greater than the given number or date `n` respectively.
|
|
1389
1450
|
* However, it's often best to assert that the target is equal to its expected
|
|
1390
1451
|
* value.
|
|
1391
1452
|
*
|
|
@@ -1430,21 +1491,29 @@ module.exports = function (chai, _) {
|
|
|
1430
1491
|
var obj = flag(this, 'object')
|
|
1431
1492
|
, doLength = flag(this, 'doLength')
|
|
1432
1493
|
, flagMsg = flag(this, 'message')
|
|
1433
|
-
,
|
|
1494
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1495
|
+
, ssfi = flag(this, 'ssfi')
|
|
1496
|
+
, objType = _.type(obj).toLowerCase()
|
|
1497
|
+
, nType = _.type(n).toLowerCase()
|
|
1498
|
+
, shouldThrow = true;
|
|
1434
1499
|
|
|
1435
1500
|
if (doLength) {
|
|
1436
1501
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1505
|
+
errorMessage = msgPrefix + 'the argument to above must be a date';
|
|
1506
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1507
|
+
errorMessage = msgPrefix + 'the argument to above must be a number';
|
|
1508
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1509
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1510
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1437
1511
|
} else {
|
|
1438
|
-
|
|
1512
|
+
shouldThrow = false;
|
|
1439
1513
|
}
|
|
1440
1514
|
|
|
1441
|
-
if (
|
|
1442
|
-
|
|
1443
|
-
throw new AssertionError(
|
|
1444
|
-
flagMsg + 'the argument to above must be a number',
|
|
1445
|
-
undefined,
|
|
1446
|
-
ssfi
|
|
1447
|
-
);
|
|
1515
|
+
if (shouldThrow) {
|
|
1516
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1448
1517
|
}
|
|
1449
1518
|
|
|
1450
1519
|
if (doLength) {
|
|
@@ -1459,8 +1528,9 @@ module.exports = function (chai, _) {
|
|
|
1459
1528
|
} else {
|
|
1460
1529
|
this.assert(
|
|
1461
1530
|
obj > n
|
|
1462
|
-
, 'expected #{this} to be above '
|
|
1463
|
-
, 'expected #{this} to be at most '
|
|
1531
|
+
, 'expected #{this} to be above #{exp}'
|
|
1532
|
+
, 'expected #{this} to be at most #{exp}'
|
|
1533
|
+
, n
|
|
1464
1534
|
);
|
|
1465
1535
|
}
|
|
1466
1536
|
}
|
|
@@ -1472,8 +1542,8 @@ module.exports = function (chai, _) {
|
|
|
1472
1542
|
/**
|
|
1473
1543
|
* ### .least(n[, msg])
|
|
1474
1544
|
*
|
|
1475
|
-
* Asserts that the target is a number greater than or equal to the given
|
|
1476
|
-
* number `n
|
|
1545
|
+
* Asserts that the target is a number or a date greater than or equal to the given
|
|
1546
|
+
* number or date `n` respectively. However, it's often best to assert that the target is equal to
|
|
1477
1547
|
* its expected value.
|
|
1478
1548
|
*
|
|
1479
1549
|
* expect(2).to.equal(2); // Recommended
|
|
@@ -1517,21 +1587,29 @@ module.exports = function (chai, _) {
|
|
|
1517
1587
|
var obj = flag(this, 'object')
|
|
1518
1588
|
, doLength = flag(this, 'doLength')
|
|
1519
1589
|
, flagMsg = flag(this, 'message')
|
|
1520
|
-
,
|
|
1590
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1591
|
+
, ssfi = flag(this, 'ssfi')
|
|
1592
|
+
, objType = _.type(obj).toLowerCase()
|
|
1593
|
+
, nType = _.type(n).toLowerCase()
|
|
1594
|
+
, shouldThrow = true;
|
|
1521
1595
|
|
|
1522
1596
|
if (doLength) {
|
|
1523
1597
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1601
|
+
errorMessage = msgPrefix + 'the argument to least must be a date';
|
|
1602
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1603
|
+
errorMessage = msgPrefix + 'the argument to least must be a number';
|
|
1604
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1605
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1606
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1524
1607
|
} else {
|
|
1525
|
-
|
|
1608
|
+
shouldThrow = false;
|
|
1526
1609
|
}
|
|
1527
1610
|
|
|
1528
|
-
if (
|
|
1529
|
-
|
|
1530
|
-
throw new AssertionError(
|
|
1531
|
-
flagMsg + 'the argument to least must be a number',
|
|
1532
|
-
undefined,
|
|
1533
|
-
ssfi
|
|
1534
|
-
);
|
|
1611
|
+
if (shouldThrow) {
|
|
1612
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1535
1613
|
}
|
|
1536
1614
|
|
|
1537
1615
|
if (doLength) {
|
|
@@ -1546,8 +1624,9 @@ module.exports = function (chai, _) {
|
|
|
1546
1624
|
} else {
|
|
1547
1625
|
this.assert(
|
|
1548
1626
|
obj >= n
|
|
1549
|
-
, 'expected #{this} to be at least '
|
|
1550
|
-
, 'expected #{this} to be below '
|
|
1627
|
+
, 'expected #{this} to be at least #{exp}'
|
|
1628
|
+
, 'expected #{this} to be below #{exp}'
|
|
1629
|
+
, n
|
|
1551
1630
|
);
|
|
1552
1631
|
}
|
|
1553
1632
|
}
|
|
@@ -1558,7 +1637,7 @@ module.exports = function (chai, _) {
|
|
|
1558
1637
|
/**
|
|
1559
1638
|
* ### .below(n[, msg])
|
|
1560
1639
|
*
|
|
1561
|
-
* Asserts that the target is a number less than the given number `n
|
|
1640
|
+
* Asserts that the target is a number or a date less than the given number or date `n` respectively.
|
|
1562
1641
|
* However, it's often best to assert that the target is equal to its expected
|
|
1563
1642
|
* value.
|
|
1564
1643
|
*
|
|
@@ -1603,21 +1682,29 @@ module.exports = function (chai, _) {
|
|
|
1603
1682
|
var obj = flag(this, 'object')
|
|
1604
1683
|
, doLength = flag(this, 'doLength')
|
|
1605
1684
|
, flagMsg = flag(this, 'message')
|
|
1606
|
-
,
|
|
1685
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1686
|
+
, ssfi = flag(this, 'ssfi')
|
|
1687
|
+
, objType = _.type(obj).toLowerCase()
|
|
1688
|
+
, nType = _.type(n).toLowerCase()
|
|
1689
|
+
, shouldThrow = true;
|
|
1607
1690
|
|
|
1608
1691
|
if (doLength) {
|
|
1609
1692
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1696
|
+
errorMessage = msgPrefix + 'the argument to below must be a date';
|
|
1697
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1698
|
+
errorMessage = msgPrefix + 'the argument to below must be a number';
|
|
1699
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1700
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1701
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1610
1702
|
} else {
|
|
1611
|
-
|
|
1703
|
+
shouldThrow = false;
|
|
1612
1704
|
}
|
|
1613
1705
|
|
|
1614
|
-
if (
|
|
1615
|
-
|
|
1616
|
-
throw new AssertionError(
|
|
1617
|
-
flagMsg + 'the argument to below must be a number',
|
|
1618
|
-
undefined,
|
|
1619
|
-
ssfi
|
|
1620
|
-
);
|
|
1706
|
+
if (shouldThrow) {
|
|
1707
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1621
1708
|
}
|
|
1622
1709
|
|
|
1623
1710
|
if (doLength) {
|
|
@@ -1632,8 +1719,9 @@ module.exports = function (chai, _) {
|
|
|
1632
1719
|
} else {
|
|
1633
1720
|
this.assert(
|
|
1634
1721
|
obj < n
|
|
1635
|
-
, 'expected #{this} to be below '
|
|
1636
|
-
, 'expected #{this} to be at least '
|
|
1722
|
+
, 'expected #{this} to be below #{exp}'
|
|
1723
|
+
, 'expected #{this} to be at least #{exp}'
|
|
1724
|
+
, n
|
|
1637
1725
|
);
|
|
1638
1726
|
}
|
|
1639
1727
|
}
|
|
@@ -1645,8 +1733,8 @@ module.exports = function (chai, _) {
|
|
|
1645
1733
|
/**
|
|
1646
1734
|
* ### .most(n[, msg])
|
|
1647
1735
|
*
|
|
1648
|
-
* Asserts that the target is a number less than or equal to the given number
|
|
1649
|
-
* `n
|
|
1736
|
+
* Asserts that the target is a number or a date less than or equal to the given number
|
|
1737
|
+
* or date `n` respectively. However, it's often best to assert that the target is equal to its
|
|
1650
1738
|
* expected value.
|
|
1651
1739
|
*
|
|
1652
1740
|
* expect(1).to.equal(1); // Recommended
|
|
@@ -1689,21 +1777,29 @@ module.exports = function (chai, _) {
|
|
|
1689
1777
|
var obj = flag(this, 'object')
|
|
1690
1778
|
, doLength = flag(this, 'doLength')
|
|
1691
1779
|
, flagMsg = flag(this, 'message')
|
|
1692
|
-
,
|
|
1780
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1781
|
+
, ssfi = flag(this, 'ssfi')
|
|
1782
|
+
, objType = _.type(obj).toLowerCase()
|
|
1783
|
+
, nType = _.type(n).toLowerCase()
|
|
1784
|
+
, shouldThrow = true;
|
|
1693
1785
|
|
|
1694
1786
|
if (doLength) {
|
|
1695
1787
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1791
|
+
errorMessage = msgPrefix + 'the argument to most must be a date';
|
|
1792
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1793
|
+
errorMessage = msgPrefix + 'the argument to most must be a number';
|
|
1794
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1795
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1796
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1696
1797
|
} else {
|
|
1697
|
-
|
|
1798
|
+
shouldThrow = false;
|
|
1698
1799
|
}
|
|
1699
1800
|
|
|
1700
|
-
if (
|
|
1701
|
-
|
|
1702
|
-
throw new AssertionError(
|
|
1703
|
-
flagMsg + 'the argument to most must be a number',
|
|
1704
|
-
undefined,
|
|
1705
|
-
ssfi
|
|
1706
|
-
);
|
|
1801
|
+
if (shouldThrow) {
|
|
1802
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1707
1803
|
}
|
|
1708
1804
|
|
|
1709
1805
|
if (doLength) {
|
|
@@ -1718,8 +1814,9 @@ module.exports = function (chai, _) {
|
|
|
1718
1814
|
} else {
|
|
1719
1815
|
this.assert(
|
|
1720
1816
|
obj <= n
|
|
1721
|
-
, 'expected #{this} to be at most '
|
|
1722
|
-
, 'expected #{this} to be above '
|
|
1817
|
+
, 'expected #{this} to be at most #{exp}'
|
|
1818
|
+
, 'expected #{this} to be above #{exp}'
|
|
1819
|
+
, n
|
|
1723
1820
|
);
|
|
1724
1821
|
}
|
|
1725
1822
|
}
|
|
@@ -1730,8 +1827,8 @@ module.exports = function (chai, _) {
|
|
|
1730
1827
|
/**
|
|
1731
1828
|
* ### .within(start, finish[, msg])
|
|
1732
1829
|
*
|
|
1733
|
-
* Asserts that the target is a number greater than or equal to the given
|
|
1734
|
-
* number `start`, and less than or equal to the given number `finish
|
|
1830
|
+
* Asserts that the target is a number or a date greater than or equal to the given
|
|
1831
|
+
* number or date `start`, and less than or equal to the given number or date `finish` respectively.
|
|
1735
1832
|
* However, it's often best to assert that the target is equal to its expected
|
|
1736
1833
|
* value.
|
|
1737
1834
|
*
|
|
@@ -1773,24 +1870,35 @@ module.exports = function (chai, _) {
|
|
|
1773
1870
|
Assertion.addMethod('within', function (start, finish, msg) {
|
|
1774
1871
|
if (msg) flag(this, 'message', msg);
|
|
1775
1872
|
var obj = flag(this, 'object')
|
|
1776
|
-
, range = start + '..' + finish
|
|
1777
1873
|
, doLength = flag(this, 'doLength')
|
|
1778
1874
|
, flagMsg = flag(this, 'message')
|
|
1779
|
-
,
|
|
1875
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1876
|
+
, ssfi = flag(this, 'ssfi')
|
|
1877
|
+
, objType = _.type(obj).toLowerCase()
|
|
1878
|
+
, startType = _.type(start).toLowerCase()
|
|
1879
|
+
, finishType = _.type(finish).toLowerCase()
|
|
1880
|
+
, shouldThrow = true
|
|
1881
|
+
, range = (startType === 'date' && finishType === 'date')
|
|
1882
|
+
? start.toUTCString() + '..' + finish.toUTCString()
|
|
1883
|
+
: start + '..' + finish;
|
|
1780
1884
|
|
|
1781
1885
|
if (doLength) {
|
|
1782
1886
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
|
|
1890
|
+
errorMessage = msgPrefix + 'the arguments to within must be dates';
|
|
1891
|
+
} else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
|
|
1892
|
+
errorMessage = msgPrefix + 'the arguments to within must be numbers';
|
|
1893
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1894
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1895
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1783
1896
|
} else {
|
|
1784
|
-
|
|
1897
|
+
shouldThrow = false;
|
|
1785
1898
|
}
|
|
1786
1899
|
|
|
1787
|
-
if (
|
|
1788
|
-
|
|
1789
|
-
throw new AssertionError(
|
|
1790
|
-
flagMsg + 'the arguments to within must be numbers',
|
|
1791
|
-
undefined,
|
|
1792
|
-
ssfi
|
|
1793
|
-
);
|
|
1900
|
+
if (shouldThrow) {
|
|
1901
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1794
1902
|
}
|
|
1795
1903
|
|
|
1796
1904
|
if (doLength) {
|
|
@@ -2005,6 +2113,7 @@ module.exports = function (chai, _) {
|
|
|
2005
2113
|
var isNested = flag(this, 'nested')
|
|
2006
2114
|
, isOwn = flag(this, 'own')
|
|
2007
2115
|
, flagMsg = flag(this, 'message')
|
|
2116
|
+
, obj = flag(this, 'object')
|
|
2008
2117
|
, ssfi = flag(this, 'ssfi');
|
|
2009
2118
|
|
|
2010
2119
|
if (isNested && isOwn) {
|
|
@@ -2016,9 +2125,17 @@ module.exports = function (chai, _) {
|
|
|
2016
2125
|
);
|
|
2017
2126
|
}
|
|
2018
2127
|
|
|
2128
|
+
if (obj === null || obj === undefined) {
|
|
2129
|
+
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
2130
|
+
throw new AssertionError(
|
|
2131
|
+
flagMsg + 'Target cannot be null or undefined.',
|
|
2132
|
+
undefined,
|
|
2133
|
+
ssfi
|
|
2134
|
+
);
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2019
2137
|
var isDeep = flag(this, 'deep')
|
|
2020
2138
|
, negate = flag(this, 'negate')
|
|
2021
|
-
, obj = flag(this, 'object')
|
|
2022
2139
|
, pathInfo = isNested ? _.getPathInfo(obj, name) : null
|
|
2023
2140
|
, value = isNested ? pathInfo.value : obj[name];
|
|
2024
2141
|
|
|
@@ -7720,8 +7837,6 @@ module.exports = function compareByInspect(a, b) {
|
|
|
7720
7837
|
*
|
|
7721
7838
|
* @param {Mixed} obj constructed Assertion
|
|
7722
7839
|
* @param {Array} type A list of allowed types for this assertion
|
|
7723
|
-
* @param {Function} ssfi starting point for removing implementation frames from
|
|
7724
|
-
* stack trace of AssertionError
|
|
7725
7840
|
* @namespace Utils
|
|
7726
7841
|
* @name expectTypes
|
|
7727
7842
|
* @api public
|
|
@@ -7731,8 +7846,9 @@ var AssertionError = require('assertion-error');
|
|
|
7731
7846
|
var flag = require('./flag');
|
|
7732
7847
|
var type = require('type-detect');
|
|
7733
7848
|
|
|
7734
|
-
module.exports = function expectTypes(obj, types
|
|
7849
|
+
module.exports = function expectTypes(obj, types) {
|
|
7735
7850
|
var flagMsg = flag(obj, 'message');
|
|
7851
|
+
var ssfi = flag(obj, 'ssfi');
|
|
7736
7852
|
|
|
7737
7853
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
7738
7854
|
|
|
@@ -7740,7 +7856,7 @@ module.exports = function expectTypes(obj, types, ssfi) {
|
|
|
7740
7856
|
types = types.map(function (t) { return t.toLowerCase(); });
|
|
7741
7857
|
types.sort();
|
|
7742
7858
|
|
|
7743
|
-
// Transforms ['lorem', 'ipsum'] into 'a
|
|
7859
|
+
// Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
|
|
7744
7860
|
var str = types.map(function (t, index) {
|
|
7745
7861
|
var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
|
|
7746
7862
|
var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
|
|
@@ -8257,7 +8373,7 @@ function formatValue(ctx, value, recurseTimes) {
|
|
|
8257
8373
|
var container = document.createElementNS(ns, '_');
|
|
8258
8374
|
|
|
8259
8375
|
container.appendChild(value.cloneNode(false));
|
|
8260
|
-
html = container.innerHTML
|
|
8376
|
+
var html = container.innerHTML
|
|
8261
8377
|
.replace('><', '>' + value.innerHTML + '<');
|
|
8262
8378
|
container.innerHTML = '';
|
|
8263
8379
|
return html;
|
|
@@ -330,6 +330,16 @@ module.exports = function (chai, _) {
|
|
|
330
330
|
*
|
|
331
331
|
* expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
|
|
332
332
|
*
|
|
333
|
+
* When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
|
|
334
|
+
* member of the target. SameValueZero equality algorithm is used.
|
|
335
|
+
*
|
|
336
|
+
* expect(new Set([1, 2])).to.include(2);
|
|
337
|
+
*
|
|
338
|
+
* When the target is a Map, `.include` asserts that the given `val` is one of
|
|
339
|
+
* the values of the target. SameValueZero equality algorithm is used.
|
|
340
|
+
*
|
|
341
|
+
* expect(new Map([['a', 1], ['b', 2]])).to.include(2);
|
|
342
|
+
*
|
|
333
343
|
* Because `.include` does different things based on the target's type, it's
|
|
334
344
|
* important to check the target's type before using `.include`. See the `.a`
|
|
335
345
|
* doc for info on testing a target's type.
|
|
@@ -338,8 +348,8 @@ module.exports = function (chai, _) {
|
|
|
338
348
|
*
|
|
339
349
|
* By default, strict (`===`) equality is used to compare array members and
|
|
340
350
|
* object properties. Add `.deep` earlier in the chain to use deep equality
|
|
341
|
-
* instead. See the `deep-eql` project
|
|
342
|
-
* algorithm: https://github.com/chaijs/deep-eql.
|
|
351
|
+
* instead (WeakSet targets are not supported). See the `deep-eql` project
|
|
352
|
+
* page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
|
|
343
353
|
*
|
|
344
354
|
* // Target array deeply (but not strictly) includes `{a: 1}`
|
|
345
355
|
* expect([{a: 1}]).to.deep.include({a: 1});
|
|
@@ -449,25 +459,24 @@ module.exports = function (chai, _) {
|
|
|
449
459
|
* @api public
|
|
450
460
|
*/
|
|
451
461
|
|
|
452
|
-
function
|
|
453
|
-
|
|
462
|
+
function SameValueZero(a, b) {
|
|
463
|
+
return (_.isNaN(a) && _.isNaN(b)) || a === b;
|
|
454
464
|
}
|
|
455
465
|
|
|
456
|
-
function
|
|
457
|
-
|
|
458
|
-
return _.eql(arrVal, val);
|
|
459
|
-
});
|
|
466
|
+
function includeChainingBehavior () {
|
|
467
|
+
flag(this, 'contains', true);
|
|
460
468
|
}
|
|
461
469
|
|
|
462
470
|
function include (val, msg) {
|
|
463
471
|
if (msg) flag(this, 'message', msg);
|
|
464
472
|
|
|
465
|
-
_.expectTypes(this, [
|
|
473
|
+
_.expectTypes(this, [
|
|
474
|
+
'array', 'object', 'string',
|
|
475
|
+
'map', 'set', 'weakset',
|
|
476
|
+
]);
|
|
466
477
|
|
|
467
478
|
var obj = flag(this, 'object')
|
|
468
|
-
, objType = _.type(obj).toLowerCase()
|
|
469
|
-
, isDeep = flag(this, 'deep')
|
|
470
|
-
, descriptor = isDeep ? 'deep ' : '';
|
|
479
|
+
, objType = _.type(obj).toLowerCase();
|
|
471
480
|
|
|
472
481
|
// This block is for asserting a subset of properties in an object.
|
|
473
482
|
if (objType === 'object') {
|
|
@@ -504,10 +513,62 @@ module.exports = function (chai, _) {
|
|
|
504
513
|
return;
|
|
505
514
|
}
|
|
506
515
|
|
|
507
|
-
|
|
516
|
+
var isDeep = flag(this, 'deep')
|
|
517
|
+
, descriptor = isDeep ? 'deep ' : ''
|
|
518
|
+
, included = false;
|
|
519
|
+
|
|
520
|
+
switch (objType) {
|
|
521
|
+
case 'string':
|
|
522
|
+
included = obj.indexOf(val) !== -1;
|
|
523
|
+
break;
|
|
524
|
+
|
|
525
|
+
case 'weakset':
|
|
526
|
+
if (isDeep) {
|
|
527
|
+
var flagMsg = flag(this, 'message')
|
|
528
|
+
, ssfi = flag(this, 'ssfi');
|
|
529
|
+
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
530
|
+
|
|
531
|
+
throw new AssertionError(
|
|
532
|
+
flagMsg + 'unable to use .deep.include with WeakSet',
|
|
533
|
+
undefined,
|
|
534
|
+
ssfi
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
included = obj.has(val);
|
|
539
|
+
break;
|
|
540
|
+
|
|
541
|
+
case 'map':
|
|
542
|
+
var isEql = isDeep ? _.eql : SameValueZero;
|
|
543
|
+
obj.forEach(function (item) {
|
|
544
|
+
included = included || isEql(item, val);
|
|
545
|
+
});
|
|
546
|
+
break;
|
|
547
|
+
|
|
548
|
+
case 'set':
|
|
549
|
+
if (isDeep) {
|
|
550
|
+
obj.forEach(function (item) {
|
|
551
|
+
included = included || _.eql(item, val);
|
|
552
|
+
});
|
|
553
|
+
} else {
|
|
554
|
+
included = obj.has(val);
|
|
555
|
+
}
|
|
556
|
+
break;
|
|
557
|
+
|
|
558
|
+
case 'array':
|
|
559
|
+
if (isDeep) {
|
|
560
|
+
included = obj.some(function (item) {
|
|
561
|
+
return _.eql(item, val);
|
|
562
|
+
})
|
|
563
|
+
} else {
|
|
564
|
+
included = obj.indexOf(val) !== -1;
|
|
565
|
+
}
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Assert inclusion in collection or substring in a string.
|
|
508
570
|
this.assert(
|
|
509
|
-
|
|
510
|
-
: isDeepIncluded(obj, val)
|
|
571
|
+
included
|
|
511
572
|
, 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
|
|
512
573
|
, 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
|
|
513
574
|
}
|
|
@@ -1024,7 +1085,7 @@ module.exports = function (chai, _) {
|
|
|
1024
1085
|
/**
|
|
1025
1086
|
* ### .above(n[, msg])
|
|
1026
1087
|
*
|
|
1027
|
-
* Asserts that the target is a number greater than the given number `n
|
|
1088
|
+
* Asserts that the target is a number or a date greater than the given number or date `n` respectively.
|
|
1028
1089
|
* However, it's often best to assert that the target is equal to its expected
|
|
1029
1090
|
* value.
|
|
1030
1091
|
*
|
|
@@ -1069,21 +1130,29 @@ module.exports = function (chai, _) {
|
|
|
1069
1130
|
var obj = flag(this, 'object')
|
|
1070
1131
|
, doLength = flag(this, 'doLength')
|
|
1071
1132
|
, flagMsg = flag(this, 'message')
|
|
1072
|
-
,
|
|
1133
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1134
|
+
, ssfi = flag(this, 'ssfi')
|
|
1135
|
+
, objType = _.type(obj).toLowerCase()
|
|
1136
|
+
, nType = _.type(n).toLowerCase()
|
|
1137
|
+
, shouldThrow = true;
|
|
1073
1138
|
|
|
1074
1139
|
if (doLength) {
|
|
1075
1140
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1144
|
+
errorMessage = msgPrefix + 'the argument to above must be a date';
|
|
1145
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1146
|
+
errorMessage = msgPrefix + 'the argument to above must be a number';
|
|
1147
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1148
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1149
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1076
1150
|
} else {
|
|
1077
|
-
|
|
1151
|
+
shouldThrow = false;
|
|
1078
1152
|
}
|
|
1079
1153
|
|
|
1080
|
-
if (
|
|
1081
|
-
|
|
1082
|
-
throw new AssertionError(
|
|
1083
|
-
flagMsg + 'the argument to above must be a number',
|
|
1084
|
-
undefined,
|
|
1085
|
-
ssfi
|
|
1086
|
-
);
|
|
1154
|
+
if (shouldThrow) {
|
|
1155
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1087
1156
|
}
|
|
1088
1157
|
|
|
1089
1158
|
if (doLength) {
|
|
@@ -1098,8 +1167,9 @@ module.exports = function (chai, _) {
|
|
|
1098
1167
|
} else {
|
|
1099
1168
|
this.assert(
|
|
1100
1169
|
obj > n
|
|
1101
|
-
, 'expected #{this} to be above '
|
|
1102
|
-
, 'expected #{this} to be at most '
|
|
1170
|
+
, 'expected #{this} to be above #{exp}'
|
|
1171
|
+
, 'expected #{this} to be at most #{exp}'
|
|
1172
|
+
, n
|
|
1103
1173
|
);
|
|
1104
1174
|
}
|
|
1105
1175
|
}
|
|
@@ -1111,8 +1181,8 @@ module.exports = function (chai, _) {
|
|
|
1111
1181
|
/**
|
|
1112
1182
|
* ### .least(n[, msg])
|
|
1113
1183
|
*
|
|
1114
|
-
* Asserts that the target is a number greater than or equal to the given
|
|
1115
|
-
* number `n
|
|
1184
|
+
* Asserts that the target is a number or a date greater than or equal to the given
|
|
1185
|
+
* number or date `n` respectively. However, it's often best to assert that the target is equal to
|
|
1116
1186
|
* its expected value.
|
|
1117
1187
|
*
|
|
1118
1188
|
* expect(2).to.equal(2); // Recommended
|
|
@@ -1156,21 +1226,29 @@ module.exports = function (chai, _) {
|
|
|
1156
1226
|
var obj = flag(this, 'object')
|
|
1157
1227
|
, doLength = flag(this, 'doLength')
|
|
1158
1228
|
, flagMsg = flag(this, 'message')
|
|
1159
|
-
,
|
|
1229
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1230
|
+
, ssfi = flag(this, 'ssfi')
|
|
1231
|
+
, objType = _.type(obj).toLowerCase()
|
|
1232
|
+
, nType = _.type(n).toLowerCase()
|
|
1233
|
+
, shouldThrow = true;
|
|
1160
1234
|
|
|
1161
1235
|
if (doLength) {
|
|
1162
1236
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1240
|
+
errorMessage = msgPrefix + 'the argument to least must be a date';
|
|
1241
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1242
|
+
errorMessage = msgPrefix + 'the argument to least must be a number';
|
|
1243
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1244
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1245
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1163
1246
|
} else {
|
|
1164
|
-
|
|
1247
|
+
shouldThrow = false;
|
|
1165
1248
|
}
|
|
1166
1249
|
|
|
1167
|
-
if (
|
|
1168
|
-
|
|
1169
|
-
throw new AssertionError(
|
|
1170
|
-
flagMsg + 'the argument to least must be a number',
|
|
1171
|
-
undefined,
|
|
1172
|
-
ssfi
|
|
1173
|
-
);
|
|
1250
|
+
if (shouldThrow) {
|
|
1251
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1174
1252
|
}
|
|
1175
1253
|
|
|
1176
1254
|
if (doLength) {
|
|
@@ -1185,8 +1263,9 @@ module.exports = function (chai, _) {
|
|
|
1185
1263
|
} else {
|
|
1186
1264
|
this.assert(
|
|
1187
1265
|
obj >= n
|
|
1188
|
-
, 'expected #{this} to be at least '
|
|
1189
|
-
, 'expected #{this} to be below '
|
|
1266
|
+
, 'expected #{this} to be at least #{exp}'
|
|
1267
|
+
, 'expected #{this} to be below #{exp}'
|
|
1268
|
+
, n
|
|
1190
1269
|
);
|
|
1191
1270
|
}
|
|
1192
1271
|
}
|
|
@@ -1197,7 +1276,7 @@ module.exports = function (chai, _) {
|
|
|
1197
1276
|
/**
|
|
1198
1277
|
* ### .below(n[, msg])
|
|
1199
1278
|
*
|
|
1200
|
-
* Asserts that the target is a number less than the given number `n
|
|
1279
|
+
* Asserts that the target is a number or a date less than the given number or date `n` respectively.
|
|
1201
1280
|
* However, it's often best to assert that the target is equal to its expected
|
|
1202
1281
|
* value.
|
|
1203
1282
|
*
|
|
@@ -1242,21 +1321,29 @@ module.exports = function (chai, _) {
|
|
|
1242
1321
|
var obj = flag(this, 'object')
|
|
1243
1322
|
, doLength = flag(this, 'doLength')
|
|
1244
1323
|
, flagMsg = flag(this, 'message')
|
|
1245
|
-
,
|
|
1324
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1325
|
+
, ssfi = flag(this, 'ssfi')
|
|
1326
|
+
, objType = _.type(obj).toLowerCase()
|
|
1327
|
+
, nType = _.type(n).toLowerCase()
|
|
1328
|
+
, shouldThrow = true;
|
|
1246
1329
|
|
|
1247
1330
|
if (doLength) {
|
|
1248
1331
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1335
|
+
errorMessage = msgPrefix + 'the argument to below must be a date';
|
|
1336
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1337
|
+
errorMessage = msgPrefix + 'the argument to below must be a number';
|
|
1338
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1339
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1340
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1249
1341
|
} else {
|
|
1250
|
-
|
|
1342
|
+
shouldThrow = false;
|
|
1251
1343
|
}
|
|
1252
1344
|
|
|
1253
|
-
if (
|
|
1254
|
-
|
|
1255
|
-
throw new AssertionError(
|
|
1256
|
-
flagMsg + 'the argument to below must be a number',
|
|
1257
|
-
undefined,
|
|
1258
|
-
ssfi
|
|
1259
|
-
);
|
|
1345
|
+
if (shouldThrow) {
|
|
1346
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1260
1347
|
}
|
|
1261
1348
|
|
|
1262
1349
|
if (doLength) {
|
|
@@ -1271,8 +1358,9 @@ module.exports = function (chai, _) {
|
|
|
1271
1358
|
} else {
|
|
1272
1359
|
this.assert(
|
|
1273
1360
|
obj < n
|
|
1274
|
-
, 'expected #{this} to be below '
|
|
1275
|
-
, 'expected #{this} to be at least '
|
|
1361
|
+
, 'expected #{this} to be below #{exp}'
|
|
1362
|
+
, 'expected #{this} to be at least #{exp}'
|
|
1363
|
+
, n
|
|
1276
1364
|
);
|
|
1277
1365
|
}
|
|
1278
1366
|
}
|
|
@@ -1284,8 +1372,8 @@ module.exports = function (chai, _) {
|
|
|
1284
1372
|
/**
|
|
1285
1373
|
* ### .most(n[, msg])
|
|
1286
1374
|
*
|
|
1287
|
-
* Asserts that the target is a number less than or equal to the given number
|
|
1288
|
-
* `n
|
|
1375
|
+
* Asserts that the target is a number or a date less than or equal to the given number
|
|
1376
|
+
* or date `n` respectively. However, it's often best to assert that the target is equal to its
|
|
1289
1377
|
* expected value.
|
|
1290
1378
|
*
|
|
1291
1379
|
* expect(1).to.equal(1); // Recommended
|
|
@@ -1328,21 +1416,29 @@ module.exports = function (chai, _) {
|
|
|
1328
1416
|
var obj = flag(this, 'object')
|
|
1329
1417
|
, doLength = flag(this, 'doLength')
|
|
1330
1418
|
, flagMsg = flag(this, 'message')
|
|
1331
|
-
,
|
|
1419
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1420
|
+
, ssfi = flag(this, 'ssfi')
|
|
1421
|
+
, objType = _.type(obj).toLowerCase()
|
|
1422
|
+
, nType = _.type(n).toLowerCase()
|
|
1423
|
+
, shouldThrow = true;
|
|
1332
1424
|
|
|
1333
1425
|
if (doLength) {
|
|
1334
1426
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
if (!doLength && (objType === 'date' && nType !== 'date')) {
|
|
1430
|
+
errorMessage = msgPrefix + 'the argument to most must be a date';
|
|
1431
|
+
} else if (nType !== 'number' && (doLength || objType === 'number')) {
|
|
1432
|
+
errorMessage = msgPrefix + 'the argument to most must be a number';
|
|
1433
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1434
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1435
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1335
1436
|
} else {
|
|
1336
|
-
|
|
1437
|
+
shouldThrow = false;
|
|
1337
1438
|
}
|
|
1338
1439
|
|
|
1339
|
-
if (
|
|
1340
|
-
|
|
1341
|
-
throw new AssertionError(
|
|
1342
|
-
flagMsg + 'the argument to most must be a number',
|
|
1343
|
-
undefined,
|
|
1344
|
-
ssfi
|
|
1345
|
-
);
|
|
1440
|
+
if (shouldThrow) {
|
|
1441
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1346
1442
|
}
|
|
1347
1443
|
|
|
1348
1444
|
if (doLength) {
|
|
@@ -1357,8 +1453,9 @@ module.exports = function (chai, _) {
|
|
|
1357
1453
|
} else {
|
|
1358
1454
|
this.assert(
|
|
1359
1455
|
obj <= n
|
|
1360
|
-
, 'expected #{this} to be at most '
|
|
1361
|
-
, 'expected #{this} to be above '
|
|
1456
|
+
, 'expected #{this} to be at most #{exp}'
|
|
1457
|
+
, 'expected #{this} to be above #{exp}'
|
|
1458
|
+
, n
|
|
1362
1459
|
);
|
|
1363
1460
|
}
|
|
1364
1461
|
}
|
|
@@ -1369,8 +1466,8 @@ module.exports = function (chai, _) {
|
|
|
1369
1466
|
/**
|
|
1370
1467
|
* ### .within(start, finish[, msg])
|
|
1371
1468
|
*
|
|
1372
|
-
* Asserts that the target is a number greater than or equal to the given
|
|
1373
|
-
* number `start`, and less than or equal to the given number `finish
|
|
1469
|
+
* Asserts that the target is a number or a date greater than or equal to the given
|
|
1470
|
+
* number or date `start`, and less than or equal to the given number or date `finish` respectively.
|
|
1374
1471
|
* However, it's often best to assert that the target is equal to its expected
|
|
1375
1472
|
* value.
|
|
1376
1473
|
*
|
|
@@ -1412,24 +1509,35 @@ module.exports = function (chai, _) {
|
|
|
1412
1509
|
Assertion.addMethod('within', function (start, finish, msg) {
|
|
1413
1510
|
if (msg) flag(this, 'message', msg);
|
|
1414
1511
|
var obj = flag(this, 'object')
|
|
1415
|
-
, range = start + '..' + finish
|
|
1416
1512
|
, doLength = flag(this, 'doLength')
|
|
1417
1513
|
, flagMsg = flag(this, 'message')
|
|
1418
|
-
,
|
|
1514
|
+
, msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
|
|
1515
|
+
, ssfi = flag(this, 'ssfi')
|
|
1516
|
+
, objType = _.type(obj).toLowerCase()
|
|
1517
|
+
, startType = _.type(start).toLowerCase()
|
|
1518
|
+
, finishType = _.type(finish).toLowerCase()
|
|
1519
|
+
, shouldThrow = true
|
|
1520
|
+
, range = (startType === 'date' && finishType === 'date')
|
|
1521
|
+
? start.toUTCString() + '..' + finish.toUTCString()
|
|
1522
|
+
: start + '..' + finish;
|
|
1419
1523
|
|
|
1420
1524
|
if (doLength) {
|
|
1421
1525
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
|
|
1529
|
+
errorMessage = msgPrefix + 'the arguments to within must be dates';
|
|
1530
|
+
} else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
|
|
1531
|
+
errorMessage = msgPrefix + 'the arguments to within must be numbers';
|
|
1532
|
+
} else if (!doLength && (objType !== 'date' && objType !== 'number')) {
|
|
1533
|
+
var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
|
|
1534
|
+
errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
|
|
1422
1535
|
} else {
|
|
1423
|
-
|
|
1536
|
+
shouldThrow = false;
|
|
1424
1537
|
}
|
|
1425
1538
|
|
|
1426
|
-
if (
|
|
1427
|
-
|
|
1428
|
-
throw new AssertionError(
|
|
1429
|
-
flagMsg + 'the arguments to within must be numbers',
|
|
1430
|
-
undefined,
|
|
1431
|
-
ssfi
|
|
1432
|
-
);
|
|
1539
|
+
if (shouldThrow) {
|
|
1540
|
+
throw new AssertionError(errorMessage, undefined, ssfi);
|
|
1433
1541
|
}
|
|
1434
1542
|
|
|
1435
1543
|
if (doLength) {
|
|
@@ -1644,6 +1752,7 @@ module.exports = function (chai, _) {
|
|
|
1644
1752
|
var isNested = flag(this, 'nested')
|
|
1645
1753
|
, isOwn = flag(this, 'own')
|
|
1646
1754
|
, flagMsg = flag(this, 'message')
|
|
1755
|
+
, obj = flag(this, 'object')
|
|
1647
1756
|
, ssfi = flag(this, 'ssfi');
|
|
1648
1757
|
|
|
1649
1758
|
if (isNested && isOwn) {
|
|
@@ -1655,9 +1764,17 @@ module.exports = function (chai, _) {
|
|
|
1655
1764
|
);
|
|
1656
1765
|
}
|
|
1657
1766
|
|
|
1767
|
+
if (obj === null || obj === undefined) {
|
|
1768
|
+
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
1769
|
+
throw new AssertionError(
|
|
1770
|
+
flagMsg + 'Target cannot be null or undefined.',
|
|
1771
|
+
undefined,
|
|
1772
|
+
ssfi
|
|
1773
|
+
);
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1658
1776
|
var isDeep = flag(this, 'deep')
|
|
1659
1777
|
, negate = flag(this, 'negate')
|
|
1660
|
-
, obj = flag(this, 'object')
|
|
1661
1778
|
, pathInfo = isNested ? _.getPathInfo(obj, name) : null
|
|
1662
1779
|
, value = isNested ? pathInfo.value : obj[name];
|
|
1663
1780
|
|
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @param {Mixed} obj constructed Assertion
|
|
15
15
|
* @param {Array} type A list of allowed types for this assertion
|
|
16
|
-
* @param {Function} ssfi starting point for removing implementation frames from
|
|
17
|
-
* stack trace of AssertionError
|
|
18
16
|
* @namespace Utils
|
|
19
17
|
* @name expectTypes
|
|
20
18
|
* @api public
|
|
@@ -24,8 +22,9 @@ var AssertionError = require('assertion-error');
|
|
|
24
22
|
var flag = require('./flag');
|
|
25
23
|
var type = require('type-detect');
|
|
26
24
|
|
|
27
|
-
module.exports = function expectTypes(obj, types
|
|
25
|
+
module.exports = function expectTypes(obj, types) {
|
|
28
26
|
var flagMsg = flag(obj, 'message');
|
|
27
|
+
var ssfi = flag(obj, 'ssfi');
|
|
29
28
|
|
|
30
29
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
31
30
|
|
|
@@ -33,7 +32,7 @@ module.exports = function expectTypes(obj, types, ssfi) {
|
|
|
33
32
|
types = types.map(function (t) { return t.toLowerCase(); });
|
|
34
33
|
types.sort();
|
|
35
34
|
|
|
36
|
-
// Transforms ['lorem', 'ipsum'] into 'a
|
|
35
|
+
// Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
|
|
37
36
|
var str = types.map(function (t, index) {
|
|
38
37
|
var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
|
|
39
38
|
var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
|
|
@@ -86,7 +86,7 @@ function formatValue(ctx, value, recurseTimes) {
|
|
|
86
86
|
var container = document.createElementNS(ns, '_');
|
|
87
87
|
|
|
88
88
|
container.appendChild(value.cloneNode(false));
|
|
89
|
-
html = container.innerHTML
|
|
89
|
+
var html = container.innerHTML
|
|
90
90
|
.replace('><', '>' + value.innerHTML + '<');
|
|
91
91
|
container.innerHTML = '';
|
|
92
92
|
return html;
|
package/lib/chai.js
CHANGED
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"Veselin Todorov <hi@vesln.com>",
|
|
18
18
|
"John Firebaugh <john.firebaugh@gmail.com>"
|
|
19
19
|
],
|
|
20
|
-
"version": "4.0
|
|
20
|
+
"version": "4.1.0",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
23
|
"url": "https://github.com/chaijs/chai"
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"type-detect": "^4.0.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"browserify": "^
|
|
44
|
+
"browserify": "^14.4.0",
|
|
45
45
|
"bump-cli": "^1.1.3",
|
|
46
46
|
"istanbul": "^0.4.3",
|
|
47
47
|
"karma": "^1.0.0",
|