chai 4.0.0 → 4.1.1

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/chai.js CHANGED
@@ -14,7 +14,7 @@ var used = [];
14
14
  * Chai version
15
15
  */
16
16
 
17
- exports.version = require('../package').version;
17
+ exports.version = '4.1.1';
18
18
 
19
19
  /*!
20
20
  * Assertion Error
@@ -95,7 +95,7 @@ exports.use(should);
95
95
  var assert = require('./chai/interface/assert');
96
96
  exports.use(assert);
97
97
 
98
- },{"../package":40,"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":33}],3:[function(require,module,exports){
98
+ },{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":22,"assertion-error":33}],3:[function(require,module,exports){
99
99
  /*!
100
100
  * chai
101
101
  * http://chaijs.com
@@ -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 page for info on the deep equality
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,65 +820,124 @@ module.exports = function (chai, _) {
810
820
  * @api public
811
821
  */
812
822
 
813
- function includeChainingBehavior () {
814
- flag(this, 'contains', true);
823
+ function SameValueZero(a, b) {
824
+ return (_.isNaN(a) && _.isNaN(b)) || a === b;
815
825
  }
816
826
 
817
- function isDeepIncluded (arr, val) {
818
- return arr.some(function (arrVal) {
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
-
826
- _.expectTypes(this, ['array', 'object', 'string'], flag(this, 'ssfi'));
827
-
833
+
828
834
  var obj = flag(this, 'object')
829
835
  , objType = _.type(obj).toLowerCase()
836
+ , flagMsg = flag(this, 'message')
837
+ , negate = flag(this, 'negate')
838
+ , ssfi = flag(this, 'ssfi')
830
839
  , isDeep = flag(this, 'deep')
831
840
  , descriptor = isDeep ? 'deep ' : '';
832
841
 
833
- // This block is for asserting a subset of properties in an object.
834
- if (objType === 'object') {
835
- var props = Object.keys(val)
836
- , negate = flag(this, 'negate')
837
- , firstErr = null
838
- , numErrs = 0;
839
-
840
- props.forEach(function (prop) {
841
- var propAssertion = new Assertion(obj);
842
- _.transferFlags(this, propAssertion, true);
843
- flag(propAssertion, 'lockSsfi', true);
844
-
845
- if (!negate || props.length === 1) {
846
- propAssertion.property(prop, val[prop]);
847
- return;
842
+ flagMsg = flagMsg ? flagMsg + ': ' : '';
843
+
844
+ var included = false;
845
+
846
+ switch (objType) {
847
+ case 'string':
848
+ included = obj.indexOf(val) !== -1;
849
+ break;
850
+
851
+ case 'weakset':
852
+ if (isDeep) {
853
+ throw new AssertionError(
854
+ flagMsg + 'unable to use .deep.include with WeakSet',
855
+ undefined,
856
+ ssfi
857
+ );
848
858
  }
849
859
 
850
- try {
851
- propAssertion.property(prop, val[prop]);
852
- } catch (err) {
853
- if (!_.checkError.compatibleConstructor(err, AssertionError)) throw err;
854
- if (firstErr === null) firstErr = err;
855
- numErrs++;
860
+ included = obj.has(val);
861
+ break;
862
+
863
+ case 'map':
864
+ var isEql = isDeep ? _.eql : SameValueZero;
865
+ obj.forEach(function (item) {
866
+ included = included || isEql(item, val);
867
+ });
868
+ break;
869
+
870
+ case 'set':
871
+ if (isDeep) {
872
+ obj.forEach(function (item) {
873
+ included = included || _.eql(item, val);
874
+ });
875
+ } else {
876
+ included = obj.has(val);
856
877
  }
857
- }, this);
878
+ break;
858
879
 
859
- // When validating .not.include with multiple properties, we only want
860
- // to throw an assertion error if all of the properties are included,
861
- // in which case we throw the first property assertion error that we
862
- // encountered.
863
- if (negate && props.length > 1 && numErrs === props.length) throw firstErr;
880
+ case 'array':
881
+ if (isDeep) {
882
+ included = obj.some(function (item) {
883
+ return _.eql(item, val);
884
+ })
885
+ } else {
886
+ included = obj.indexOf(val) !== -1;
887
+ }
888
+ break;
864
889
 
865
- return;
890
+ default:
891
+ // This block is for asserting a subset of properties in an object.
892
+ // `_.expectTypes` isn't used here because `.include` should work with
893
+ // objects with a custom `@@toStringTag`.
894
+ if (val !== Object(val)) {
895
+ throw new AssertionError(
896
+ flagMsg + 'object tested must be an array, a map, an object,'
897
+ + ' a set, a string, or a weakset, but ' + objType + ' given',
898
+ undefined,
899
+ ssfi
900
+ );
901
+ }
902
+
903
+ var props = Object.keys(val)
904
+ , firstErr = null
905
+ , numErrs = 0;
906
+
907
+ props.forEach(function (prop) {
908
+ var propAssertion = new Assertion(obj);
909
+ _.transferFlags(this, propAssertion, true);
910
+ flag(propAssertion, 'lockSsfi', true);
911
+
912
+ if (!negate || props.length === 1) {
913
+ propAssertion.property(prop, val[prop]);
914
+ return;
915
+ }
916
+
917
+ try {
918
+ propAssertion.property(prop, val[prop]);
919
+ } catch (err) {
920
+ if (!_.checkError.compatibleConstructor(err, AssertionError)) {
921
+ throw err;
922
+ }
923
+ if (firstErr === null) firstErr = err;
924
+ numErrs++;
925
+ }
926
+ }, this);
927
+
928
+ // When validating .not.include with multiple properties, we only want
929
+ // to throw an assertion error if all of the properties are included,
930
+ // in which case we throw the first property assertion error that we
931
+ // encountered.
932
+ if (negate && props.length > 1 && numErrs === props.length) {
933
+ throw firstErr;
934
+ }
935
+ return;
866
936
  }
867
937
 
868
- // Assert inclusion in an array or substring in a string.
938
+ // Assert inclusion in collection or substring in a string.
869
939
  this.assert(
870
- objType === 'string' || !isDeep ? ~obj.indexOf(val)
871
- : isDeepIncluded(obj, val)
940
+ included
872
941
  , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
873
942
  , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
874
943
  }
@@ -1385,7 +1454,7 @@ module.exports = function (chai, _) {
1385
1454
  /**
1386
1455
  * ### .above(n[, msg])
1387
1456
  *
1388
- * Asserts that the target is a number greater than the given number `n`.
1457
+ * Asserts that the target is a number or a date greater than the given number or date `n` respectively.
1389
1458
  * However, it's often best to assert that the target is equal to its expected
1390
1459
  * value.
1391
1460
  *
@@ -1430,21 +1499,29 @@ module.exports = function (chai, _) {
1430
1499
  var obj = flag(this, 'object')
1431
1500
  , doLength = flag(this, 'doLength')
1432
1501
  , flagMsg = flag(this, 'message')
1433
- , ssfi = flag(this, 'ssfi');
1502
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1503
+ , ssfi = flag(this, 'ssfi')
1504
+ , objType = _.type(obj).toLowerCase()
1505
+ , nType = _.type(n).toLowerCase()
1506
+ , shouldThrow = true;
1434
1507
 
1435
1508
  if (doLength) {
1436
1509
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1510
+ }
1511
+
1512
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1513
+ errorMessage = msgPrefix + 'the argument to above must be a date';
1514
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1515
+ errorMessage = msgPrefix + 'the argument to above must be a number';
1516
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1517
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1518
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1437
1519
  } else {
1438
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1520
+ shouldThrow = false;
1439
1521
  }
1440
1522
 
1441
- if (typeof n !== 'number') {
1442
- flagMsg = flagMsg ? flagMsg + ': ' : '';
1443
- throw new AssertionError(
1444
- flagMsg + 'the argument to above must be a number',
1445
- undefined,
1446
- ssfi
1447
- );
1523
+ if (shouldThrow) {
1524
+ throw new AssertionError(errorMessage, undefined, ssfi);
1448
1525
  }
1449
1526
 
1450
1527
  if (doLength) {
@@ -1459,8 +1536,9 @@ module.exports = function (chai, _) {
1459
1536
  } else {
1460
1537
  this.assert(
1461
1538
  obj > n
1462
- , 'expected #{this} to be above ' + n
1463
- , 'expected #{this} to be at most ' + n
1539
+ , 'expected #{this} to be above #{exp}'
1540
+ , 'expected #{this} to be at most #{exp}'
1541
+ , n
1464
1542
  );
1465
1543
  }
1466
1544
  }
@@ -1472,8 +1550,8 @@ module.exports = function (chai, _) {
1472
1550
  /**
1473
1551
  * ### .least(n[, msg])
1474
1552
  *
1475
- * Asserts that the target is a number greater than or equal to the given
1476
- * number `n`. However, it's often best to assert that the target is equal to
1553
+ * Asserts that the target is a number or a date greater than or equal to the given
1554
+ * number or date `n` respectively. However, it's often best to assert that the target is equal to
1477
1555
  * its expected value.
1478
1556
  *
1479
1557
  * expect(2).to.equal(2); // Recommended
@@ -1517,21 +1595,29 @@ module.exports = function (chai, _) {
1517
1595
  var obj = flag(this, 'object')
1518
1596
  , doLength = flag(this, 'doLength')
1519
1597
  , flagMsg = flag(this, 'message')
1520
- , ssfi = flag(this, 'ssfi');
1598
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1599
+ , ssfi = flag(this, 'ssfi')
1600
+ , objType = _.type(obj).toLowerCase()
1601
+ , nType = _.type(n).toLowerCase()
1602
+ , shouldThrow = true;
1521
1603
 
1522
1604
  if (doLength) {
1523
1605
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1606
+ }
1607
+
1608
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1609
+ errorMessage = msgPrefix + 'the argument to least must be a date';
1610
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1611
+ errorMessage = msgPrefix + 'the argument to least must be a number';
1612
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1613
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1614
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1524
1615
  } else {
1525
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1616
+ shouldThrow = false;
1526
1617
  }
1527
1618
 
1528
- if (typeof n !== 'number') {
1529
- flagMsg = flagMsg ? flagMsg + ': ' : '';
1530
- throw new AssertionError(
1531
- flagMsg + 'the argument to least must be a number',
1532
- undefined,
1533
- ssfi
1534
- );
1619
+ if (shouldThrow) {
1620
+ throw new AssertionError(errorMessage, undefined, ssfi);
1535
1621
  }
1536
1622
 
1537
1623
  if (doLength) {
@@ -1546,8 +1632,9 @@ module.exports = function (chai, _) {
1546
1632
  } else {
1547
1633
  this.assert(
1548
1634
  obj >= n
1549
- , 'expected #{this} to be at least ' + n
1550
- , 'expected #{this} to be below ' + n
1635
+ , 'expected #{this} to be at least #{exp}'
1636
+ , 'expected #{this} to be below #{exp}'
1637
+ , n
1551
1638
  );
1552
1639
  }
1553
1640
  }
@@ -1558,7 +1645,7 @@ module.exports = function (chai, _) {
1558
1645
  /**
1559
1646
  * ### .below(n[, msg])
1560
1647
  *
1561
- * Asserts that the target is a number less than the given number `n`.
1648
+ * Asserts that the target is a number or a date less than the given number or date `n` respectively.
1562
1649
  * However, it's often best to assert that the target is equal to its expected
1563
1650
  * value.
1564
1651
  *
@@ -1603,21 +1690,29 @@ module.exports = function (chai, _) {
1603
1690
  var obj = flag(this, 'object')
1604
1691
  , doLength = flag(this, 'doLength')
1605
1692
  , flagMsg = flag(this, 'message')
1606
- , ssfi = flag(this, 'ssfi');
1693
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1694
+ , ssfi = flag(this, 'ssfi')
1695
+ , objType = _.type(obj).toLowerCase()
1696
+ , nType = _.type(n).toLowerCase()
1697
+ , shouldThrow = true;
1607
1698
 
1608
1699
  if (doLength) {
1609
1700
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1701
+ }
1702
+
1703
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1704
+ errorMessage = msgPrefix + 'the argument to below must be a date';
1705
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1706
+ errorMessage = msgPrefix + 'the argument to below must be a number';
1707
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1708
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1709
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1610
1710
  } else {
1611
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1711
+ shouldThrow = false;
1612
1712
  }
1613
1713
 
1614
- if (typeof n !== 'number') {
1615
- flagMsg = flagMsg ? flagMsg + ': ' : '';
1616
- throw new AssertionError(
1617
- flagMsg + 'the argument to below must be a number',
1618
- undefined,
1619
- ssfi
1620
- );
1714
+ if (shouldThrow) {
1715
+ throw new AssertionError(errorMessage, undefined, ssfi);
1621
1716
  }
1622
1717
 
1623
1718
  if (doLength) {
@@ -1632,8 +1727,9 @@ module.exports = function (chai, _) {
1632
1727
  } else {
1633
1728
  this.assert(
1634
1729
  obj < n
1635
- , 'expected #{this} to be below ' + n
1636
- , 'expected #{this} to be at least ' + n
1730
+ , 'expected #{this} to be below #{exp}'
1731
+ , 'expected #{this} to be at least #{exp}'
1732
+ , n
1637
1733
  );
1638
1734
  }
1639
1735
  }
@@ -1645,8 +1741,8 @@ module.exports = function (chai, _) {
1645
1741
  /**
1646
1742
  * ### .most(n[, msg])
1647
1743
  *
1648
- * Asserts that the target is a number less than or equal to the given number
1649
- * `n`. However, it's often best to assert that the target is equal to its
1744
+ * Asserts that the target is a number or a date less than or equal to the given number
1745
+ * or date `n` respectively. However, it's often best to assert that the target is equal to its
1650
1746
  * expected value.
1651
1747
  *
1652
1748
  * expect(1).to.equal(1); // Recommended
@@ -1689,21 +1785,29 @@ module.exports = function (chai, _) {
1689
1785
  var obj = flag(this, 'object')
1690
1786
  , doLength = flag(this, 'doLength')
1691
1787
  , flagMsg = flag(this, 'message')
1692
- , ssfi = flag(this, 'ssfi');
1788
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1789
+ , ssfi = flag(this, 'ssfi')
1790
+ , objType = _.type(obj).toLowerCase()
1791
+ , nType = _.type(n).toLowerCase()
1792
+ , shouldThrow = true;
1693
1793
 
1694
1794
  if (doLength) {
1695
1795
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1796
+ }
1797
+
1798
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1799
+ errorMessage = msgPrefix + 'the argument to most must be a date';
1800
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1801
+ errorMessage = msgPrefix + 'the argument to most must be a number';
1802
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1803
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1804
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1696
1805
  } else {
1697
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1806
+ shouldThrow = false;
1698
1807
  }
1699
1808
 
1700
- if (typeof n !== 'number') {
1701
- flagMsg = flagMsg ? flagMsg + ': ' : '';
1702
- throw new AssertionError(
1703
- flagMsg + 'the argument to most must be a number',
1704
- undefined,
1705
- ssfi
1706
- );
1809
+ if (shouldThrow) {
1810
+ throw new AssertionError(errorMessage, undefined, ssfi);
1707
1811
  }
1708
1812
 
1709
1813
  if (doLength) {
@@ -1718,8 +1822,9 @@ module.exports = function (chai, _) {
1718
1822
  } else {
1719
1823
  this.assert(
1720
1824
  obj <= n
1721
- , 'expected #{this} to be at most ' + n
1722
- , 'expected #{this} to be above ' + n
1825
+ , 'expected #{this} to be at most #{exp}'
1826
+ , 'expected #{this} to be above #{exp}'
1827
+ , n
1723
1828
  );
1724
1829
  }
1725
1830
  }
@@ -1730,8 +1835,8 @@ module.exports = function (chai, _) {
1730
1835
  /**
1731
1836
  * ### .within(start, finish[, msg])
1732
1837
  *
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`.
1838
+ * Asserts that the target is a number or a date greater than or equal to the given
1839
+ * number or date `start`, and less than or equal to the given number or date `finish` respectively.
1735
1840
  * However, it's often best to assert that the target is equal to its expected
1736
1841
  * value.
1737
1842
  *
@@ -1773,24 +1878,35 @@ module.exports = function (chai, _) {
1773
1878
  Assertion.addMethod('within', function (start, finish, msg) {
1774
1879
  if (msg) flag(this, 'message', msg);
1775
1880
  var obj = flag(this, 'object')
1776
- , range = start + '..' + finish
1777
1881
  , doLength = flag(this, 'doLength')
1778
1882
  , flagMsg = flag(this, 'message')
1779
- , ssfi = flag(this, 'ssfi');
1883
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1884
+ , ssfi = flag(this, 'ssfi')
1885
+ , objType = _.type(obj).toLowerCase()
1886
+ , startType = _.type(start).toLowerCase()
1887
+ , finishType = _.type(finish).toLowerCase()
1888
+ , shouldThrow = true
1889
+ , range = (startType === 'date' && finishType === 'date')
1890
+ ? start.toUTCString() + '..' + finish.toUTCString()
1891
+ : start + '..' + finish;
1780
1892
 
1781
1893
  if (doLength) {
1782
1894
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1895
+ }
1896
+
1897
+ if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
1898
+ errorMessage = msgPrefix + 'the arguments to within must be dates';
1899
+ } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
1900
+ errorMessage = msgPrefix + 'the arguments to within must be numbers';
1901
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1902
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1903
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1783
1904
  } else {
1784
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1905
+ shouldThrow = false;
1785
1906
  }
1786
1907
 
1787
- if (typeof start !== 'number' || typeof finish !== 'number') {
1788
- flagMsg = flagMsg ? flagMsg + ': ' : '';
1789
- throw new AssertionError(
1790
- flagMsg + 'the arguments to within must be numbers',
1791
- undefined,
1792
- ssfi
1793
- );
1908
+ if (shouldThrow) {
1909
+ throw new AssertionError(errorMessage, undefined, ssfi);
1794
1910
  }
1795
1911
 
1796
1912
  if (doLength) {
@@ -1854,28 +1970,25 @@ module.exports = function (chai, _) {
1854
1970
  var target = flag(this, 'object')
1855
1971
  var ssfi = flag(this, 'ssfi');
1856
1972
  var flagMsg = flag(this, 'message');
1857
- var validInstanceOfTarget = constructor === Object(constructor) && (
1858
- typeof constructor === 'function' ||
1859
- (typeof Symbol !== 'undefined' &&
1860
- typeof Symbol.hasInstance !== 'undefined' &&
1861
- Symbol.hasInstance in constructor)
1862
- );
1863
1973
 
1864
- if (!validInstanceOfTarget) {
1865
- flagMsg = flagMsg ? flagMsg + ': ' : '';
1866
- var constructorType = constructor === null ? 'null' : typeof constructor;
1867
- throw new AssertionError(
1868
- flagMsg + 'The instanceof assertion needs a constructor but ' + constructorType + ' was given.',
1869
- undefined,
1870
- ssfi
1871
- );
1974
+ try {
1975
+ var isInstanceOf = target instanceof constructor;
1976
+ } catch (err) {
1977
+ if (err instanceof TypeError) {
1978
+ flagMsg = flagMsg ? flagMsg + ': ' : '';
1979
+ throw new AssertionError(
1980
+ flagMsg + 'The instanceof assertion needs a constructor but '
1981
+ + _.type(constructor) + ' was given.',
1982
+ undefined,
1983
+ ssfi
1984
+ );
1985
+ }
1986
+ throw err;
1872
1987
  }
1873
1988
 
1874
- var isInstanceOf = target instanceof constructor
1875
-
1876
1989
  var name = _.getName(constructor);
1877
1990
  if (name === null) {
1878
- name = 'an unnamed constructor';
1991
+ name = 'an unnamed constructor';
1879
1992
  }
1880
1993
 
1881
1994
  this.assert(
@@ -2005,6 +2118,7 @@ module.exports = function (chai, _) {
2005
2118
  var isNested = flag(this, 'nested')
2006
2119
  , isOwn = flag(this, 'own')
2007
2120
  , flagMsg = flag(this, 'message')
2121
+ , obj = flag(this, 'object')
2008
2122
  , ssfi = flag(this, 'ssfi');
2009
2123
 
2010
2124
  if (isNested && isOwn) {
@@ -2016,9 +2130,17 @@ module.exports = function (chai, _) {
2016
2130
  );
2017
2131
  }
2018
2132
 
2133
+ if (obj === null || obj === undefined) {
2134
+ flagMsg = flagMsg ? flagMsg + ': ' : '';
2135
+ throw new AssertionError(
2136
+ flagMsg + 'Target cannot be null or undefined.',
2137
+ undefined,
2138
+ ssfi
2139
+ );
2140
+ }
2141
+
2019
2142
  var isDeep = flag(this, 'deep')
2020
2143
  , negate = flag(this, 'negate')
2021
- , obj = flag(this, 'object')
2022
2144
  , pathInfo = isNested ? _.getPathInfo(obj, name) : null
2023
2145
  , value = isNested ? pathInfo.value : obj[name];
2024
2146
 
@@ -5645,10 +5767,10 @@ module.exports = function (chai, util) {
5645
5767
  * You can also provide a single object instead of a `keys` array and its keys
5646
5768
  * will be used as the expected set of keys.
5647
5769
  *
5648
- * assert.hasAnyKey({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
5649
- * assert.hasAnyKey({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337]);
5650
- * assert.hasAnyKey(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'thisKeyDoesNotExist']);
5651
- * assert.hasAnyKey(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'thisKeyDoesNotExist']);
5770
+ * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
5771
+ * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337});
5772
+ * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5773
+ * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']);
5652
5774
  *
5653
5775
  * @name hasAnyKeys
5654
5776
  * @param {Mixed} object
@@ -7720,8 +7842,6 @@ module.exports = function compareByInspect(a, b) {
7720
7842
  *
7721
7843
  * @param {Mixed} obj constructed Assertion
7722
7844
  * @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
7845
  * @namespace Utils
7726
7846
  * @name expectTypes
7727
7847
  * @api public
@@ -7731,8 +7851,9 @@ var AssertionError = require('assertion-error');
7731
7851
  var flag = require('./flag');
7732
7852
  var type = require('type-detect');
7733
7853
 
7734
- module.exports = function expectTypes(obj, types, ssfi) {
7854
+ module.exports = function expectTypes(obj, types) {
7735
7855
  var flagMsg = flag(obj, 'message');
7856
+ var ssfi = flag(obj, 'ssfi');
7736
7857
 
7737
7858
  flagMsg = flagMsg ? flagMsg + ': ' : '';
7738
7859
 
@@ -7740,7 +7861,7 @@ module.exports = function expectTypes(obj, types, ssfi) {
7740
7861
  types = types.map(function (t) { return t.toLowerCase(); });
7741
7862
  types.sort();
7742
7863
 
7743
- // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'
7864
+ // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
7744
7865
  var str = types.map(function (t, index) {
7745
7866
  var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
7746
7867
  var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
@@ -8257,7 +8378,7 @@ function formatValue(ctx, value, recurseTimes) {
8257
8378
  var container = document.createElementNS(ns, '_');
8258
8379
 
8259
8380
  container.appendChild(value.cloneNode(false));
8260
- html = container.innerHTML
8381
+ var html = container.innerHTML
8261
8382
  .replace('><', '>' + value.innerHTML + '<');
8262
8383
  container.innerHTML = '';
8263
8384
  return html;
@@ -10979,62 +11100,5 @@ module.exports = function typeDetect(obj) {
10979
11100
 
10980
11101
  module.exports.typeDetect = module.exports;
10981
11102
 
10982
- },{}],40:[function(require,module,exports){
10983
- module.exports={
10984
- "author": "Jake Luer <jake@alogicalparadox.com>",
10985
- "name": "chai",
10986
- "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.",
10987
- "keywords": [
10988
- "test",
10989
- "assertion",
10990
- "assert",
10991
- "testing",
10992
- "chai"
10993
- ],
10994
- "homepage": "http://chaijs.com",
10995
- "license": "MIT",
10996
- "contributors": [
10997
- "Jake Luer <jake@alogicalparadox.com>",
10998
- "Domenic Denicola <domenic@domenicdenicola.com> (http://domenicdenicola.com)",
10999
- "Veselin Todorov <hi@vesln.com>",
11000
- "John Firebaugh <john.firebaugh@gmail.com>"
11001
- ],
11002
- "version": "4.0.0",
11003
- "repository": {
11004
- "type": "git",
11005
- "url": "https://github.com/chaijs/chai"
11006
- },
11007
- "bugs": {
11008
- "url": "https://github.com/chaijs/chai/issues"
11009
- },
11010
- "main": "./index",
11011
- "browser": "./chai.js",
11012
- "scripts": {
11013
- "test": "make test"
11014
- },
11015
- "engines": {
11016
- "node": ">=4"
11017
- },
11018
- "dependencies": {
11019
- "assertion-error": "^1.0.1",
11020
- "check-error": "^1.0.1",
11021
- "deep-eql": "^2.0.1",
11022
- "get-func-name": "^2.0.0",
11023
- "pathval": "^1.0.0",
11024
- "type-detect": "^4.0.0"
11025
- },
11026
- "devDependencies": {
11027
- "browserify": "^13.0.1",
11028
- "bump-cli": "^1.1.3",
11029
- "istanbul": "^0.4.3",
11030
- "karma": "^1.0.0",
11031
- "karma-firefox-launcher": "^1.0.0",
11032
- "karma-mocha": "^1.0.1",
11033
- "karma-phantomjs-launcher": "^1.0.0",
11034
- "karma-sauce-launcher": "^1.0.0",
11035
- "mocha": "^3.0.0"
11036
- }
11037
- }
11038
-
11039
11103
  },{}]},{},[1])(1)
11040
11104
  });