chai 4.0.2 → 4.2.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/chai.js CHANGED
@@ -1,4 +1,4 @@
1
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  module.exports = require('./lib/chai');
3
3
 
4
4
  },{"./lib/chai":2}],2:[function(require,module,exports){
@@ -14,7 +14,7 @@ var used = [];
14
14
  * Chai version
15
15
  */
16
16
 
17
- exports.version = '4.0.2';
17
+ exports.version = '4.2.0';
18
18
 
19
19
  /*!
20
20
  * Assertion Error
@@ -355,7 +355,7 @@ module.exports = {
355
355
  * @api public
356
356
  */
357
357
 
358
- proxyExcludedKeys: ['then', 'inspect', 'toJSON']
358
+ proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON']
359
359
  };
360
360
 
361
361
  },{}],5:[function(require,module,exports){
@@ -394,16 +394,17 @@ module.exports = function (chai, _) {
394
394
  * - same
395
395
  * - but
396
396
  * - does
397
+ * - still
397
398
  *
398
399
  * @name language chains
399
400
  * @namespace BDD
400
401
  * @api public
401
402
  */
402
403
 
403
- [ 'to', 'be', 'been'
404
- , 'is', 'and', 'has', 'have'
405
- , 'with', 'that', 'which', 'at'
406
- , 'of', 'same', 'but', 'does' ].forEach(function (chain) {
404
+ [ 'to', 'be', 'been', 'is'
405
+ , 'and', 'has', 'have', 'with'
406
+ , 'that', 'which', 'at', 'of'
407
+ , 'same', 'but', 'does', 'still' ].forEach(function (chain) {
407
408
  Assertion.addProperty(chain);
408
409
  });
409
410
 
@@ -510,7 +511,8 @@ module.exports = function (chai, _) {
510
511
  * Object.prototype.b = 2;
511
512
  *
512
513
  * expect({a: 1}).to.have.own.property('a');
513
- * expect({a: 1}).to.have.property('b').but.not.own.property('b');
514
+ * expect({a: 1}).to.have.property('b');
515
+ * expect({a: 1}).to.not.have.own.property('b');
514
516
  *
515
517
  * expect({a: 1}).to.own.include({a: 1});
516
518
  * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2});
@@ -571,7 +573,6 @@ module.exports = function (chai, _) {
571
573
  flag(this, 'all', false);
572
574
  });
573
575
 
574
-
575
576
  /**
576
577
  * ### .all
577
578
  *
@@ -643,7 +644,7 @@ module.exports = function (chai, _) {
643
644
  * expect(1, 'nooo why fail??').to.be.a('string');
644
645
  *
645
646
  * `.a` can also be used as a language chain to improve the readability of
646
- * your assertions.
647
+ * your assertions.
647
648
  *
648
649
  * expect({b: 2}).to.have.a.property('b');
649
650
  *
@@ -691,6 +692,16 @@ module.exports = function (chai, _) {
691
692
  *
692
693
  * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2});
693
694
  *
695
+ * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a
696
+ * member of the target. SameValueZero equality algorithm is used.
697
+ *
698
+ * expect(new Set([1, 2])).to.include(2);
699
+ *
700
+ * When the target is a Map, `.include` asserts that the given `val` is one of
701
+ * the values of the target. SameValueZero equality algorithm is used.
702
+ *
703
+ * expect(new Map([['a', 1], ['b', 2]])).to.include(2);
704
+ *
694
705
  * Because `.include` does different things based on the target's type, it's
695
706
  * important to check the target's type before using `.include`. See the `.a`
696
707
  * doc for info on testing a target's type.
@@ -699,8 +710,8 @@ module.exports = function (chai, _) {
699
710
  *
700
711
  * By default, strict (`===`) equality is used to compare array members and
701
712
  * 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.
713
+ * instead (WeakSet targets are not supported). See the `deep-eql` project
714
+ * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql.
704
715
  *
705
716
  * // Target array deeply (but not strictly) includes `{a: 1}`
706
717
  * expect([{a: 1}]).to.deep.include({a: 1});
@@ -747,7 +758,7 @@ module.exports = function (chai, _) {
747
758
  *
748
759
  * expect('foobar').to.not.include('taco');
749
760
  * expect([1, 2, 3]).to.not.include(4);
750
- *
761
+ *
751
762
  * However, it's dangerous to negate `.include` when the target is an object.
752
763
  * The problem is that it creates uncertain expectations by asserting that the
753
764
  * target object doesn't have all of `val`'s key/value pairs but may or may
@@ -810,65 +821,124 @@ module.exports = function (chai, _) {
810
821
  * @api public
811
822
  */
812
823
 
813
- function includeChainingBehavior () {
814
- flag(this, 'contains', true);
824
+ function SameValueZero(a, b) {
825
+ return (_.isNaN(a) && _.isNaN(b)) || a === b;
815
826
  }
816
827
 
817
- function isDeepIncluded (arr, val) {
818
- return arr.some(function (arrVal) {
819
- return _.eql(arrVal, val);
820
- });
828
+ function includeChainingBehavior () {
829
+ flag(this, 'contains', true);
821
830
  }
822
831
 
823
832
  function include (val, msg) {
824
833
  if (msg) flag(this, 'message', msg);
825
834
 
826
- _.expectTypes(this, ['array', 'object', 'string'], flag(this, 'ssfi'));
827
-
828
835
  var obj = flag(this, 'object')
829
836
  , objType = _.type(obj).toLowerCase()
837
+ , flagMsg = flag(this, 'message')
838
+ , negate = flag(this, 'negate')
839
+ , ssfi = flag(this, 'ssfi')
830
840
  , isDeep = flag(this, 'deep')
831
841
  , descriptor = isDeep ? 'deep ' : '';
832
842
 
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;
843
+ flagMsg = flagMsg ? flagMsg + ': ' : '';
844
+
845
+ var included = false;
846
+
847
+ switch (objType) {
848
+ case 'string':
849
+ included = obj.indexOf(val) !== -1;
850
+ break;
851
+
852
+ case 'weakset':
853
+ if (isDeep) {
854
+ throw new AssertionError(
855
+ flagMsg + 'unable to use .deep.include with WeakSet',
856
+ undefined,
857
+ ssfi
858
+ );
859
+ }
860
+
861
+ included = obj.has(val);
862
+ break;
863
+
864
+ case 'map':
865
+ var isEql = isDeep ? _.eql : SameValueZero;
866
+ obj.forEach(function (item) {
867
+ included = included || isEql(item, val);
868
+ });
869
+ break;
870
+
871
+ case 'set':
872
+ if (isDeep) {
873
+ obj.forEach(function (item) {
874
+ included = included || _.eql(item, val);
875
+ });
876
+ } else {
877
+ included = obj.has(val);
878
+ }
879
+ break;
880
+
881
+ case 'array':
882
+ if (isDeep) {
883
+ included = obj.some(function (item) {
884
+ return _.eql(item, val);
885
+ })
886
+ } else {
887
+ included = obj.indexOf(val) !== -1;
848
888
  }
889
+ break;
849
890
 
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++;
891
+ default:
892
+ // This block is for asserting a subset of properties in an object.
893
+ // `_.expectTypes` isn't used here because `.include` should work with
894
+ // objects with a custom `@@toStringTag`.
895
+ if (val !== Object(val)) {
896
+ throw new AssertionError(
897
+ flagMsg + 'object tested must be an array, a map, an object,'
898
+ + ' a set, a string, or a weakset, but ' + objType + ' given',
899
+ undefined,
900
+ ssfi
901
+ );
856
902
  }
857
- }, this);
858
903
 
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;
904
+ var props = Object.keys(val)
905
+ , firstErr = null
906
+ , numErrs = 0;
907
+
908
+ props.forEach(function (prop) {
909
+ var propAssertion = new Assertion(obj);
910
+ _.transferFlags(this, propAssertion, true);
911
+ flag(propAssertion, 'lockSsfi', true);
912
+
913
+ if (!negate || props.length === 1) {
914
+ propAssertion.property(prop, val[prop]);
915
+ return;
916
+ }
864
917
 
865
- return;
918
+ try {
919
+ propAssertion.property(prop, val[prop]);
920
+ } catch (err) {
921
+ if (!_.checkError.compatibleConstructor(err, AssertionError)) {
922
+ throw err;
923
+ }
924
+ if (firstErr === null) firstErr = err;
925
+ numErrs++;
926
+ }
927
+ }, this);
928
+
929
+ // When validating .not.include with multiple properties, we only want
930
+ // to throw an assertion error if all of the properties are included,
931
+ // in which case we throw the first property assertion error that we
932
+ // encountered.
933
+ if (negate && props.length > 1 && numErrs === props.length) {
934
+ throw firstErr;
935
+ }
936
+ return;
866
937
  }
867
938
 
868
- // Assert inclusion in an array or substring in a string.
939
+ // Assert inclusion in collection or substring in a string.
869
940
  this.assert(
870
- objType === 'string' || !isDeep ? ~obj.indexOf(val)
871
- : isDeepIncluded(obj, val)
941
+ included
872
942
  , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
873
943
  , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
874
944
  }
@@ -881,9 +951,9 @@ module.exports = function (chai, _) {
881
951
  /**
882
952
  * ### .ok
883
953
  *
884
- * Asserts that the target is loosely (`==`) equal to `true`. However, it's
885
- * often best to assert that the target is strictly (`===`) or deeply equal to
886
- * its expected value.
954
+ * Asserts that the target is a truthy value (considered `true` in boolean context).
955
+ * However, it's often best to assert that the target is strictly (`===`) or
956
+ * deeply equal to its expected value.
887
957
  *
888
958
  * expect(1).to.equal(1); // Recommended
889
959
  * expect(1).to.be.ok; // Not recommended
@@ -1267,7 +1337,7 @@ module.exports = function (chai, _) {
1267
1337
  *
1268
1338
  * expect(1).to.equal(1);
1269
1339
  * expect('foo').to.equal('foo');
1270
- *
1340
+ *
1271
1341
  * Add `.deep` earlier in the chain to use deep equality instead. See the
1272
1342
  * `deep-eql` project page for info on the deep equality algorithm:
1273
1343
  * https://github.com/chaijs/deep-eql.
@@ -1309,7 +1379,10 @@ module.exports = function (chai, _) {
1309
1379
  if (msg) flag(this, 'message', msg);
1310
1380
  var obj = flag(this, 'object');
1311
1381
  if (flag(this, 'deep')) {
1312
- return this.eql(val);
1382
+ var prevLockSsfi = flag(this, 'lockSsfi');
1383
+ flag(this, 'lockSsfi', true);
1384
+ this.eql(val);
1385
+ flag(this, 'lockSsfi', prevLockSsfi);
1313
1386
  } else {
1314
1387
  this.assert(
1315
1388
  val === obj
@@ -1385,15 +1458,15 @@ module.exports = function (chai, _) {
1385
1458
  /**
1386
1459
  * ### .above(n[, msg])
1387
1460
  *
1388
- * Asserts that the target is a number greater than the given number `n`.
1461
+ * Asserts that the target is a number or a date greater than the given number or date `n` respectively.
1389
1462
  * However, it's often best to assert that the target is equal to its expected
1390
1463
  * value.
1391
1464
  *
1392
1465
  * expect(2).to.equal(2); // Recommended
1393
1466
  * expect(2).to.be.above(1); // Not recommended
1394
1467
  *
1395
- * Add `.lengthOf` earlier in the chain to assert that the value of the
1396
- * target's `length` property is greater than the given number `n`.
1468
+ * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1469
+ * or `size` is greater than the given number `n`.
1397
1470
  *
1398
1471
  * expect('foo').to.have.lengthOf(3); // Recommended
1399
1472
  * expect('foo').to.have.lengthOf.above(2); // Not recommended
@@ -1430,37 +1503,54 @@ module.exports = function (chai, _) {
1430
1503
  var obj = flag(this, 'object')
1431
1504
  , doLength = flag(this, 'doLength')
1432
1505
  , flagMsg = flag(this, 'message')
1433
- , ssfi = flag(this, 'ssfi');
1506
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1507
+ , ssfi = flag(this, 'ssfi')
1508
+ , objType = _.type(obj).toLowerCase()
1509
+ , nType = _.type(n).toLowerCase()
1510
+ , errorMessage
1511
+ , shouldThrow = true;
1434
1512
 
1435
- if (doLength) {
1513
+ if (doLength && objType !== 'map' && objType !== 'set') {
1436
1514
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1515
+ }
1516
+
1517
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1518
+ errorMessage = msgPrefix + 'the argument to above must be a date';
1519
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1520
+ errorMessage = msgPrefix + 'the argument to above must be a number';
1521
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1522
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1523
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1437
1524
  } else {
1438
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1525
+ shouldThrow = false;
1439
1526
  }
1440
1527
 
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
- );
1528
+ if (shouldThrow) {
1529
+ throw new AssertionError(errorMessage, undefined, ssfi);
1448
1530
  }
1449
1531
 
1450
1532
  if (doLength) {
1451
- var len = obj.length;
1533
+ var descriptor = 'length'
1534
+ , itemsCount;
1535
+ if (objType === 'map' || objType === 'set') {
1536
+ descriptor = 'size';
1537
+ itemsCount = obj.size;
1538
+ } else {
1539
+ itemsCount = obj.length;
1540
+ }
1452
1541
  this.assert(
1453
- len > n
1454
- , 'expected #{this} to have a length above #{exp} but got #{act}'
1455
- , 'expected #{this} to not have a length above #{exp}'
1542
+ itemsCount > n
1543
+ , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
1544
+ , 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
1456
1545
  , n
1457
- , len
1546
+ , itemsCount
1458
1547
  );
1459
1548
  } else {
1460
1549
  this.assert(
1461
1550
  obj > n
1462
- , 'expected #{this} to be above ' + n
1463
- , 'expected #{this} to be at most ' + n
1551
+ , 'expected #{this} to be above #{exp}'
1552
+ , 'expected #{this} to be at most #{exp}'
1553
+ , n
1464
1554
  );
1465
1555
  }
1466
1556
  }
@@ -1472,17 +1562,16 @@ module.exports = function (chai, _) {
1472
1562
  /**
1473
1563
  * ### .least(n[, msg])
1474
1564
  *
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
1565
+ * Asserts that the target is a number or a date greater than or equal to the given
1566
+ * number or date `n` respectively. However, it's often best to assert that the target is equal to
1477
1567
  * its expected value.
1478
1568
  *
1479
1569
  * expect(2).to.equal(2); // Recommended
1480
1570
  * expect(2).to.be.at.least(1); // Not recommended
1481
1571
  * expect(2).to.be.at.least(2); // Not recommended
1482
1572
  *
1483
- * Add `.lengthOf` earlier in the chain to assert that the value of the
1484
- * target's `length` property is greater than or equal to the given number
1485
- * `n`.
1573
+ * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1574
+ * or `size` is greater than or equal to the given number `n`.
1486
1575
  *
1487
1576
  * expect('foo').to.have.lengthOf(3); // Recommended
1488
1577
  * expect('foo').to.have.lengthOf.at.least(2); // Not recommended
@@ -1517,37 +1606,54 @@ module.exports = function (chai, _) {
1517
1606
  var obj = flag(this, 'object')
1518
1607
  , doLength = flag(this, 'doLength')
1519
1608
  , flagMsg = flag(this, 'message')
1520
- , ssfi = flag(this, 'ssfi');
1609
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1610
+ , ssfi = flag(this, 'ssfi')
1611
+ , objType = _.type(obj).toLowerCase()
1612
+ , nType = _.type(n).toLowerCase()
1613
+ , errorMessage
1614
+ , shouldThrow = true;
1521
1615
 
1522
- if (doLength) {
1616
+ if (doLength && objType !== 'map' && objType !== 'set') {
1523
1617
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1618
+ }
1619
+
1620
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1621
+ errorMessage = msgPrefix + 'the argument to least must be a date';
1622
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1623
+ errorMessage = msgPrefix + 'the argument to least must be a number';
1624
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1625
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1626
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1524
1627
  } else {
1525
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1628
+ shouldThrow = false;
1526
1629
  }
1527
1630
 
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
- );
1631
+ if (shouldThrow) {
1632
+ throw new AssertionError(errorMessage, undefined, ssfi);
1535
1633
  }
1536
1634
 
1537
1635
  if (doLength) {
1538
- var len = obj.length;
1636
+ var descriptor = 'length'
1637
+ , itemsCount;
1638
+ if (objType === 'map' || objType === 'set') {
1639
+ descriptor = 'size';
1640
+ itemsCount = obj.size;
1641
+ } else {
1642
+ itemsCount = obj.length;
1643
+ }
1539
1644
  this.assert(
1540
- len >= n
1541
- , 'expected #{this} to have a length at least #{exp} but got #{act}'
1542
- , 'expected #{this} to have a length below #{exp}'
1645
+ itemsCount >= n
1646
+ , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
1647
+ , 'expected #{this} to have a ' + descriptor + ' below #{exp}'
1543
1648
  , n
1544
- , len
1649
+ , itemsCount
1545
1650
  );
1546
1651
  } else {
1547
1652
  this.assert(
1548
1653
  obj >= n
1549
- , 'expected #{this} to be at least ' + n
1550
- , 'expected #{this} to be below ' + n
1654
+ , 'expected #{this} to be at least #{exp}'
1655
+ , 'expected #{this} to be below #{exp}'
1656
+ , n
1551
1657
  );
1552
1658
  }
1553
1659
  }
@@ -1558,15 +1664,15 @@ module.exports = function (chai, _) {
1558
1664
  /**
1559
1665
  * ### .below(n[, msg])
1560
1666
  *
1561
- * Asserts that the target is a number less than the given number `n`.
1667
+ * Asserts that the target is a number or a date less than the given number or date `n` respectively.
1562
1668
  * However, it's often best to assert that the target is equal to its expected
1563
1669
  * value.
1564
1670
  *
1565
1671
  * expect(1).to.equal(1); // Recommended
1566
1672
  * expect(1).to.be.below(2); // Not recommended
1567
1673
  *
1568
- * Add `.lengthOf` earlier in the chain to assert that the value of the
1569
- * target's `length` property is less than the given number `n`.
1674
+ * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1675
+ * or `size` is less than the given number `n`.
1570
1676
  *
1571
1677
  * expect('foo').to.have.lengthOf(3); // Recommended
1572
1678
  * expect('foo').to.have.lengthOf.below(4); // Not recommended
@@ -1603,37 +1709,54 @@ module.exports = function (chai, _) {
1603
1709
  var obj = flag(this, 'object')
1604
1710
  , doLength = flag(this, 'doLength')
1605
1711
  , flagMsg = flag(this, 'message')
1606
- , ssfi = flag(this, 'ssfi');
1712
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1713
+ , ssfi = flag(this, 'ssfi')
1714
+ , objType = _.type(obj).toLowerCase()
1715
+ , nType = _.type(n).toLowerCase()
1716
+ , errorMessage
1717
+ , shouldThrow = true;
1607
1718
 
1608
- if (doLength) {
1719
+ if (doLength && objType !== 'map' && objType !== 'set') {
1609
1720
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1721
+ }
1722
+
1723
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1724
+ errorMessage = msgPrefix + 'the argument to below must be a date';
1725
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1726
+ errorMessage = msgPrefix + 'the argument to below must be a number';
1727
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1728
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1729
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1610
1730
  } else {
1611
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1731
+ shouldThrow = false;
1612
1732
  }
1613
1733
 
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
- );
1734
+ if (shouldThrow) {
1735
+ throw new AssertionError(errorMessage, undefined, ssfi);
1621
1736
  }
1622
1737
 
1623
1738
  if (doLength) {
1624
- var len = obj.length;
1739
+ var descriptor = 'length'
1740
+ , itemsCount;
1741
+ if (objType === 'map' || objType === 'set') {
1742
+ descriptor = 'size';
1743
+ itemsCount = obj.size;
1744
+ } else {
1745
+ itemsCount = obj.length;
1746
+ }
1625
1747
  this.assert(
1626
- len < n
1627
- , 'expected #{this} to have a length below #{exp} but got #{act}'
1628
- , 'expected #{this} to not have a length below #{exp}'
1748
+ itemsCount < n
1749
+ , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
1750
+ , 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
1629
1751
  , n
1630
- , len
1752
+ , itemsCount
1631
1753
  );
1632
1754
  } else {
1633
1755
  this.assert(
1634
1756
  obj < n
1635
- , 'expected #{this} to be below ' + n
1636
- , 'expected #{this} to be at least ' + n
1757
+ , 'expected #{this} to be below #{exp}'
1758
+ , 'expected #{this} to be at least #{exp}'
1759
+ , n
1637
1760
  );
1638
1761
  }
1639
1762
  }
@@ -1645,16 +1768,16 @@ module.exports = function (chai, _) {
1645
1768
  /**
1646
1769
  * ### .most(n[, msg])
1647
1770
  *
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
1771
+ * Asserts that the target is a number or a date less than or equal to the given number
1772
+ * or date `n` respectively. However, it's often best to assert that the target is equal to its
1650
1773
  * expected value.
1651
1774
  *
1652
1775
  * expect(1).to.equal(1); // Recommended
1653
1776
  * expect(1).to.be.at.most(2); // Not recommended
1654
1777
  * expect(1).to.be.at.most(1); // Not recommended
1655
1778
  *
1656
- * Add `.lengthOf` earlier in the chain to assert that the value of the
1657
- * target's `length` property is less than or equal to the given number `n`.
1779
+ * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1780
+ * or `size` is less than or equal to the given number `n`.
1658
1781
  *
1659
1782
  * expect('foo').to.have.lengthOf(3); // Recommended
1660
1783
  * expect('foo').to.have.lengthOf.at.most(4); // Not recommended
@@ -1689,37 +1812,54 @@ module.exports = function (chai, _) {
1689
1812
  var obj = flag(this, 'object')
1690
1813
  , doLength = flag(this, 'doLength')
1691
1814
  , flagMsg = flag(this, 'message')
1692
- , ssfi = flag(this, 'ssfi');
1815
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1816
+ , ssfi = flag(this, 'ssfi')
1817
+ , objType = _.type(obj).toLowerCase()
1818
+ , nType = _.type(n).toLowerCase()
1819
+ , errorMessage
1820
+ , shouldThrow = true;
1693
1821
 
1694
- if (doLength) {
1822
+ if (doLength && objType !== 'map' && objType !== 'set') {
1695
1823
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1824
+ }
1825
+
1826
+ if (!doLength && (objType === 'date' && nType !== 'date')) {
1827
+ errorMessage = msgPrefix + 'the argument to most must be a date';
1828
+ } else if (nType !== 'number' && (doLength || objType === 'number')) {
1829
+ errorMessage = msgPrefix + 'the argument to most must be a number';
1830
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1831
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1832
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1696
1833
  } else {
1697
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1834
+ shouldThrow = false;
1698
1835
  }
1699
1836
 
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
- );
1837
+ if (shouldThrow) {
1838
+ throw new AssertionError(errorMessage, undefined, ssfi);
1707
1839
  }
1708
1840
 
1709
1841
  if (doLength) {
1710
- var len = obj.length;
1842
+ var descriptor = 'length'
1843
+ , itemsCount;
1844
+ if (objType === 'map' || objType === 'set') {
1845
+ descriptor = 'size';
1846
+ itemsCount = obj.size;
1847
+ } else {
1848
+ itemsCount = obj.length;
1849
+ }
1711
1850
  this.assert(
1712
- len <= n
1713
- , 'expected #{this} to have a length at most #{exp} but got #{act}'
1714
- , 'expected #{this} to have a length above #{exp}'
1851
+ itemsCount <= n
1852
+ , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
1853
+ , 'expected #{this} to have a ' + descriptor + ' above #{exp}'
1715
1854
  , n
1716
- , len
1855
+ , itemsCount
1717
1856
  );
1718
1857
  } else {
1719
1858
  this.assert(
1720
1859
  obj <= n
1721
- , 'expected #{this} to be at most ' + n
1722
- , 'expected #{this} to be above ' + n
1860
+ , 'expected #{this} to be at most #{exp}'
1861
+ , 'expected #{this} to be above #{exp}'
1862
+ , n
1723
1863
  );
1724
1864
  }
1725
1865
  }
@@ -1730,8 +1870,8 @@ module.exports = function (chai, _) {
1730
1870
  /**
1731
1871
  * ### .within(start, finish[, msg])
1732
1872
  *
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`.
1873
+ * Asserts that the target is a number or a date greater than or equal to the given
1874
+ * number or date `start`, and less than or equal to the given number or date `finish` respectively.
1735
1875
  * However, it's often best to assert that the target is equal to its expected
1736
1876
  * value.
1737
1877
  *
@@ -1740,9 +1880,9 @@ module.exports = function (chai, _) {
1740
1880
  * expect(2).to.be.within(2, 3); // Not recommended
1741
1881
  * expect(2).to.be.within(1, 2); // Not recommended
1742
1882
  *
1743
- * Add `.lengthOf` earlier in the chain to assert that the value of the
1744
- * target's `length` property is greater than or equal to the given number
1745
- * `start`, and less than or equal to the given number `finish`.
1883
+ * Add `.lengthOf` earlier in the chain to assert that the target's `length`
1884
+ * or `size` is greater than or equal to the given number `start`, and less
1885
+ * than or equal to the given number `finish`.
1746
1886
  *
1747
1887
  * expect('foo').to.have.lengthOf(3); // Recommended
1748
1888
  * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended
@@ -1773,32 +1913,51 @@ module.exports = function (chai, _) {
1773
1913
  Assertion.addMethod('within', function (start, finish, msg) {
1774
1914
  if (msg) flag(this, 'message', msg);
1775
1915
  var obj = flag(this, 'object')
1776
- , range = start + '..' + finish
1777
1916
  , doLength = flag(this, 'doLength')
1778
1917
  , flagMsg = flag(this, 'message')
1779
- , ssfi = flag(this, 'ssfi');
1780
-
1781
- if (doLength) {
1918
+ , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1919
+ , ssfi = flag(this, 'ssfi')
1920
+ , objType = _.type(obj).toLowerCase()
1921
+ , startType = _.type(start).toLowerCase()
1922
+ , finishType = _.type(finish).toLowerCase()
1923
+ , errorMessage
1924
+ , shouldThrow = true
1925
+ , range = (startType === 'date' && finishType === 'date')
1926
+ ? start.toUTCString() + '..' + finish.toUTCString()
1927
+ : start + '..' + finish;
1928
+
1929
+ if (doLength && objType !== 'map' && objType !== 'set') {
1782
1930
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1931
+ }
1932
+
1933
+ if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
1934
+ errorMessage = msgPrefix + 'the arguments to within must be dates';
1935
+ } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) {
1936
+ errorMessage = msgPrefix + 'the arguments to within must be numbers';
1937
+ } else if (!doLength && (objType !== 'date' && objType !== 'number')) {
1938
+ var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1939
+ errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1783
1940
  } else {
1784
- new Assertion(obj, flagMsg, ssfi, true).is.a('number');
1941
+ shouldThrow = false;
1785
1942
  }
1786
1943
 
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
- );
1944
+ if (shouldThrow) {
1945
+ throw new AssertionError(errorMessage, undefined, ssfi);
1794
1946
  }
1795
1947
 
1796
1948
  if (doLength) {
1797
- var len = obj.length;
1949
+ var descriptor = 'length'
1950
+ , itemsCount;
1951
+ if (objType === 'map' || objType === 'set') {
1952
+ descriptor = 'size';
1953
+ itemsCount = obj.size;
1954
+ } else {
1955
+ itemsCount = obj.length;
1956
+ }
1798
1957
  this.assert(
1799
- len >= start && len <= finish
1800
- , 'expected #{this} to have a length within ' + range
1801
- , 'expected #{this} to not have a length within ' + range
1958
+ itemsCount >= start && itemsCount <= finish
1959
+ , 'expected #{this} to have a ' + descriptor + ' within ' + range
1960
+ , 'expected #{this} to not have a ' + descriptor + ' within ' + range
1802
1961
  );
1803
1962
  } else {
1804
1963
  this.assert(
@@ -1854,28 +2013,25 @@ module.exports = function (chai, _) {
1854
2013
  var target = flag(this, 'object')
1855
2014
  var ssfi = flag(this, 'ssfi');
1856
2015
  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
2016
 
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
- );
2017
+ try {
2018
+ var isInstanceOf = target instanceof constructor;
2019
+ } catch (err) {
2020
+ if (err instanceof TypeError) {
2021
+ flagMsg = flagMsg ? flagMsg + ': ' : '';
2022
+ throw new AssertionError(
2023
+ flagMsg + 'The instanceof assertion needs a constructor but '
2024
+ + _.type(constructor) + ' was given.',
2025
+ undefined,
2026
+ ssfi
2027
+ );
2028
+ }
2029
+ throw err;
1872
2030
  }
1873
2031
 
1874
- var isInstanceOf = target instanceof constructor
1875
-
1876
2032
  var name = _.getName(constructor);
1877
2033
  if (name === null) {
1878
- name = 'an unnamed constructor';
2034
+ name = 'an unnamed constructor';
1879
2035
  }
1880
2036
 
1881
2037
  this.assert(
@@ -1917,7 +2073,8 @@ module.exports = function (chai, _) {
1917
2073
  *
1918
2074
  * expect({a: 1}).to.have.own.property('a');
1919
2075
  * expect({a: 1}).to.have.own.property('a', 1);
1920
- * expect({a: 1}).to.have.property('b').but.not.own.property('b');
2076
+ * expect({a: 1}).to.have.property('b');
2077
+ * expect({a: 1}).to.not.have.own.property('b');
1921
2078
  *
1922
2079
  * `.deep` and `.own` can be combined.
1923
2080
  *
@@ -1944,7 +2101,7 @@ module.exports = function (chai, _) {
1944
2101
  * Add `.not` earlier in the chain to negate `.property`.
1945
2102
  *
1946
2103
  * expect({a: 1}).to.not.have.property('b');
1947
- *
2104
+ *
1948
2105
  * However, it's dangerous to negate `.property` when providing `val`. The
1949
2106
  * problem is that it creates uncertain expectations by asserting that the
1950
2107
  * target either doesn't have a property with the given key `name`, or that it
@@ -1982,7 +2139,7 @@ module.exports = function (chai, _) {
1982
2139
  *
1983
2140
  * // Not recommended
1984
2141
  * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??');
1985
- *
2142
+ *
1986
2143
  * The above assertion isn't the same thing as not providing `val`. Instead,
1987
2144
  * it's asserting that the target object has a `b` property that's equal to
1988
2145
  * `undefined`.
@@ -2005,10 +2162,31 @@ module.exports = function (chai, _) {
2005
2162
  var isNested = flag(this, 'nested')
2006
2163
  , isOwn = flag(this, 'own')
2007
2164
  , flagMsg = flag(this, 'message')
2008
- , ssfi = flag(this, 'ssfi');
2165
+ , obj = flag(this, 'object')
2166
+ , ssfi = flag(this, 'ssfi')
2167
+ , nameType = typeof name;
2168
+
2169
+ flagMsg = flagMsg ? flagMsg + ': ' : '';
2170
+
2171
+ if (isNested) {
2172
+ if (nameType !== 'string') {
2173
+ throw new AssertionError(
2174
+ flagMsg + 'the argument to property must be a string when using nested syntax',
2175
+ undefined,
2176
+ ssfi
2177
+ );
2178
+ }
2179
+ } else {
2180
+ if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
2181
+ throw new AssertionError(
2182
+ flagMsg + 'the argument to property must be a string, number, or symbol',
2183
+ undefined,
2184
+ ssfi
2185
+ );
2186
+ }
2187
+ }
2009
2188
 
2010
2189
  if (isNested && isOwn) {
2011
- flagMsg = flagMsg ? flagMsg + ': ' : '';
2012
2190
  throw new AssertionError(
2013
2191
  flagMsg + 'The "nested" and "own" flags cannot be combined.',
2014
2192
  undefined,
@@ -2016,9 +2194,16 @@ module.exports = function (chai, _) {
2016
2194
  );
2017
2195
  }
2018
2196
 
2197
+ if (obj === null || obj === undefined) {
2198
+ throw new AssertionError(
2199
+ flagMsg + 'Target cannot be null or undefined.',
2200
+ undefined,
2201
+ ssfi
2202
+ );
2203
+ }
2204
+
2019
2205
  var isDeep = flag(this, 'deep')
2020
2206
  , negate = flag(this, 'negate')
2021
- , obj = flag(this, 'object')
2022
2207
  , pathInfo = isNested ? _.getPathInfo(obj, name) : null
2023
2208
  , value = isNested ? pathInfo.value : obj[name];
2024
2209
 
@@ -2092,7 +2277,7 @@ module.exports = function (chai, _) {
2092
2277
  * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`.
2093
2278
  *
2094
2279
  * expect({a: 1}).to.not.have.ownPropertyDescriptor('b');
2095
- *
2280
+ *
2096
2281
  * However, it's dangerous to negate `.ownPropertyDescriptor` when providing
2097
2282
  * a `descriptor`. The problem is that it creates uncertain expectations by
2098
2283
  * asserting that the target either doesn't have a property descriptor with
@@ -2163,7 +2348,7 @@ module.exports = function (chai, _) {
2163
2348
  * writable: true,
2164
2349
  * value: 2,
2165
2350
  * });
2166
- *
2351
+ *
2167
2352
  * // Recommended
2168
2353
  * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b');
2169
2354
  *
@@ -2220,11 +2405,13 @@ module.exports = function (chai, _) {
2220
2405
  /**
2221
2406
  * ### .lengthOf(n[, msg])
2222
2407
  *
2223
- * Asserts that the target's `length` property is equal to the given number
2408
+ * Asserts that the target's `length` or `size` is equal to the given number
2224
2409
  * `n`.
2225
2410
  *
2226
2411
  * expect([1, 2, 3]).to.have.lengthOf(3);
2227
2412
  * expect('foo').to.have.lengthOf(3);
2413
+ * expect(new Set([1, 2, 3])).to.have.lengthOf(3);
2414
+ * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3);
2228
2415
  *
2229
2416
  * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often
2230
2417
  * best to assert that the target's `length` property is equal to its expected
@@ -2280,17 +2467,29 @@ module.exports = function (chai, _) {
2280
2467
  function assertLength (n, msg) {
2281
2468
  if (msg) flag(this, 'message', msg);
2282
2469
  var obj = flag(this, 'object')
2470
+ , objType = _.type(obj).toLowerCase()
2283
2471
  , flagMsg = flag(this, 'message')
2284
- , ssfi = flag(this, 'ssfi');
2285
- new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
2286
- var len = obj.length;
2472
+ , ssfi = flag(this, 'ssfi')
2473
+ , descriptor = 'length'
2474
+ , itemsCount;
2475
+
2476
+ switch (objType) {
2477
+ case 'map':
2478
+ case 'set':
2479
+ descriptor = 'size';
2480
+ itemsCount = obj.size;
2481
+ break;
2482
+ default:
2483
+ new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
2484
+ itemsCount = obj.length;
2485
+ }
2287
2486
 
2288
2487
  this.assert(
2289
- len == n
2290
- , 'expected #{this} to have a length of #{exp} but got #{act}'
2291
- , 'expected #{this} to not have a length of #{act}'
2488
+ itemsCount == n
2489
+ , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
2490
+ , 'expected #{this} to not have a ' + descriptor + ' of #{act}'
2292
2491
  , n
2293
- , len
2492
+ , itemsCount
2294
2493
  );
2295
2494
  }
2296
2495
 
@@ -2352,8 +2551,8 @@ module.exports = function (chai, _) {
2352
2551
  * message to show when the assertion fails. The message can also be given as
2353
2552
  * the second argument to `expect`.
2354
2553
  *
2355
- * expect('foobar').to.have.string(/taco/, 'nooo why fail??');
2356
- * expect('foobar', 'nooo why fail??').to.have.string(/taco/);
2554
+ * expect('foobar').to.have.string('taco', 'nooo why fail??');
2555
+ * expect('foobar', 'nooo why fail??').to.have.string('taco');
2357
2556
  *
2358
2557
  * @name string
2359
2558
  * @param {String} str
@@ -2380,7 +2579,7 @@ module.exports = function (chai, _) {
2380
2579
  * ### .keys(key1[, key2[, ...]])
2381
2580
  *
2382
2581
  * Asserts that the target object, array, map, or set has the given keys. Only
2383
- * the target's own inherited properties are included in the search.
2582
+ * the target's own inherited properties are included in the search.
2384
2583
  *
2385
2584
  * When the target is an object or array, keys can be provided as one or more
2386
2585
  * string arguments, a single array argument, or a single object argument. In
@@ -2488,6 +2687,7 @@ module.exports = function (chai, _) {
2488
2687
  , isDeep = flag(this, 'deep')
2489
2688
  , str
2490
2689
  , deepStr = ''
2690
+ , actual
2491
2691
  , ok = true
2492
2692
  , flagMsg = flag(this, 'message');
2493
2693
 
@@ -2504,7 +2704,6 @@ module.exports = function (chai, _) {
2504
2704
  if (keysType !== 'Array') {
2505
2705
  keys = Array.prototype.slice.call(arguments);
2506
2706
  }
2507
-
2508
2707
  } else {
2509
2708
  actual = _.getOwnEnumerableProperties(obj);
2510
2709
 
@@ -2537,8 +2736,7 @@ module.exports = function (chai, _) {
2537
2736
  var len = keys.length
2538
2737
  , any = flag(this, 'any')
2539
2738
  , all = flag(this, 'all')
2540
- , expected = keys
2541
- , actual;
2739
+ , expected = keys;
2542
2740
 
2543
2741
  if (!any && !all) {
2544
2742
  all = true;
@@ -2615,7 +2813,7 @@ module.exports = function (chai, _) {
2615
2813
  *
2616
2814
  * When no arguments are provided, `.throw` invokes the target function and
2617
2815
  * asserts that an error is thrown.
2618
- *
2816
+ *
2619
2817
  * var badFn = function () { throw new TypeError('Illegal salmon!'); };
2620
2818
  *
2621
2819
  * expect(badFn).to.throw();
@@ -2667,11 +2865,11 @@ module.exports = function (chai, _) {
2667
2865
  * expect(badFn).to.throw(err, /salmon/);
2668
2866
  *
2669
2867
  * Add `.not` earlier in the chain to negate `.throw`.
2670
- *
2868
+ *
2671
2869
  * var goodFn = function () {};
2672
2870
  *
2673
2871
  * expect(goodFn).to.not.throw();
2674
- *
2872
+ *
2675
2873
  * However, it's dangerous to negate `.throw` when providing any arguments.
2676
2874
  * The problem is that it creates uncertain expectations by asserting that the
2677
2875
  * target either doesn't throw an error, or that it throws an error but of a
@@ -3019,7 +3217,7 @@ module.exports = function (chai, _) {
3019
3217
  * first argument, and asserts that the value returned is truthy.
3020
3218
  *
3021
3219
  * expect(1).to.satisfy(function(num) {
3022
- * return num > 0;
3220
+ * return num > 0;
3023
3221
  * });
3024
3222
  *
3025
3223
  * Add `.not` earlier in the chain to negate `.satisfy`.
@@ -3240,7 +3438,7 @@ module.exports = function (chai, _) {
3240
3438
  var contains = flag(this, 'contains');
3241
3439
  var ordered = flag(this, 'ordered');
3242
3440
 
3243
- var subject, failMsg, failNegateMsg, lengthCheck;
3441
+ var subject, failMsg, failNegateMsg;
3244
3442
 
3245
3443
  if (contains) {
3246
3444
  subject = ordered ? 'an ordered superset' : 'a superset';
@@ -3312,7 +3510,6 @@ module.exports = function (chai, _) {
3312
3510
 
3313
3511
  Assertion.addMethod('oneOf', oneOf);
3314
3512
 
3315
-
3316
3513
  /**
3317
3514
  * ### .change(subject[, prop[, msg]])
3318
3515
  *
@@ -3488,7 +3685,7 @@ module.exports = function (chai, _) {
3488
3685
  *
3489
3686
  * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended
3490
3687
  * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended
3491
- *
3688
+ *
3492
3689
  * When the subject is expected to stay the same, it's often best to assert
3493
3690
  * exactly that.
3494
3691
  *
@@ -3585,7 +3782,7 @@ module.exports = function (chai, _) {
3585
3782
  *
3586
3783
  * When two arguments are provided, `.decrease` asserts that the value of the
3587
3784
  * given object `subject`'s `prop` property is lesser after invoking the
3588
- * target function compared to beforehand.
3785
+ * target function compared to beforehand.
3589
3786
  *
3590
3787
  * var myObj = {val: 1}
3591
3788
  * , subtractTwo = function () { myObj.val -= 2; };
@@ -3607,7 +3804,7 @@ module.exports = function (chai, _) {
3607
3804
  *
3608
3805
  * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended
3609
3806
  * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended
3610
- *
3807
+ *
3611
3808
  * When the subject is expected to stay the same, it's often best to assert
3612
3809
  * exactly that.
3613
3810
  *
@@ -3960,7 +4157,7 @@ module.exports = function (chai, _) {
3960
4157
  var obj = flag(this, 'object');
3961
4158
 
3962
4159
  this.assert(
3963
- typeof obj === "number" && isFinite(obj)
4160
+ typeof obj === 'number' && isFinite(obj)
3964
4161
  , 'expected #{this} to be a finite number'
3965
4162
  , 'expected #{this} to not be a finite number'
3966
4163
  );
@@ -3974,9 +4171,7 @@ module.exports = function (chai, _) {
3974
4171
  * MIT Licensed
3975
4172
  */
3976
4173
 
3977
-
3978
4174
  module.exports = function (chai, util) {
3979
-
3980
4175
  /*!
3981
4176
  * Chai dependencies.
3982
4177
  */
@@ -4013,10 +4208,18 @@ module.exports = function (chai, util) {
4013
4208
  };
4014
4209
 
4015
4210
  /**
4211
+ * ### .fail([message])
4016
4212
  * ### .fail(actual, expected, [message], [operator])
4017
4213
  *
4018
4214
  * Throw a failure. Node.js `assert` module-compatible.
4019
4215
  *
4216
+ * assert.fail();
4217
+ * assert.fail("custom error message");
4218
+ * assert.fail(1, 2);
4219
+ * assert.fail(1, 2, "custom error message");
4220
+ * assert.fail(1, 2, "custom error message", ">");
4221
+ * assert.fail(1, 2, undefined, ">");
4222
+ *
4020
4223
  * @name fail
4021
4224
  * @param {Mixed} actual
4022
4225
  * @param {Mixed} expected
@@ -4027,6 +4230,13 @@ module.exports = function (chai, util) {
4027
4230
  */
4028
4231
 
4029
4232
  assert.fail = function (actual, expected, message, operator) {
4233
+ if (arguments.length < 2) {
4234
+ // Comply with Node's fail([message]) interface
4235
+
4236
+ message = actual;
4237
+ actual = undefined;
4238
+ }
4239
+
4030
4240
  message = message || 'assert.fail()';
4031
4241
  throw new chai.AssertionError(message, {
4032
4242
  actual: actual
@@ -4876,7 +5086,7 @@ module.exports = function (chai, util) {
4876
5086
  * an array, the array is searched for an element that's strictly equal to the
4877
5087
  * given value. When asserting a subset of properties in an object, the object
4878
5088
  * is searched for the given property keys, checking that each one is present
4879
- * and stricty equal to the given property value. For instance:
5089
+ * and strictly equal to the given property value. For instance:
4880
5090
  *
4881
5091
  * var obj1 = {a: 1}
4882
5092
  * , obj2 = {b: 2};
@@ -4903,8 +5113,8 @@ module.exports = function (chai, util) {
4903
5113
  * the absence of a value in an array, a substring in a string, or a subset of
4904
5114
  * properties in an object.
4905
5115
  *
4906
- * assert.notInclude([1,2,3], 4, 'array doesn't contain value');
4907
- * assert.notInclude('foobar', 'baz', 'string doesn't contain substring');
5116
+ * assert.notInclude([1,2,3], 4, "array doesn't contain value");
5117
+ * assert.notInclude('foobar', 'baz', "string doesn't contain substring");
4908
5118
  * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property');
4909
5119
  *
4910
5120
  * Strict equality (===) is used. When asserting the absence of a value in an
@@ -4984,24 +5194,24 @@ module.exports = function (chai, util) {
4984
5194
 
4985
5195
  /**
4986
5196
  * ### .nestedInclude(haystack, needle, [message])
4987
- *
4988
- * Asserts that 'haystack' includes 'needle'.
4989
- * Can be used to assert the inclusion of a subset of properties in an
5197
+ *
5198
+ * Asserts that 'haystack' includes 'needle'.
5199
+ * Can be used to assert the inclusion of a subset of properties in an
4990
5200
  * object.
4991
- * Enables the use of dot- and bracket-notation for referencing nested
5201
+ * Enables the use of dot- and bracket-notation for referencing nested
4992
5202
  * properties.
4993
5203
  * '[]' and '.' in property names can be escaped using double backslashes.
4994
- *
5204
+ *
4995
5205
  * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'});
4996
5206
  * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'});
4997
- *
5207
+ *
4998
5208
  * @name nestedInclude
4999
5209
  * @param {Object} haystack
5000
5210
  * @param {Object} needle
5001
5211
  * @param {String} message
5002
5212
  * @namespace Assert
5003
- * @api public
5004
- */
5213
+ * @api public
5214
+ */
5005
5215
 
5006
5216
  assert.nestedInclude = function (exp, inc, msg) {
5007
5217
  new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc);
@@ -5009,24 +5219,24 @@ module.exports = function (chai, util) {
5009
5219
 
5010
5220
  /**
5011
5221
  * ### .notNestedInclude(haystack, needle, [message])
5012
- *
5013
- * Asserts that 'haystack' does not include 'needle'.
5014
- * Can be used to assert the absence of a subset of properties in an
5222
+ *
5223
+ * Asserts that 'haystack' does not include 'needle'.
5224
+ * Can be used to assert the absence of a subset of properties in an
5015
5225
  * object.
5016
- * Enables the use of dot- and bracket-notation for referencing nested
5017
- * properties.
5226
+ * Enables the use of dot- and bracket-notation for referencing nested
5227
+ * properties.
5018
5228
  * '[]' and '.' in property names can be escaped using double backslashes.
5019
- *
5229
+ *
5020
5230
  * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'});
5021
5231
  * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'});
5022
- *
5232
+ *
5023
5233
  * @name notNestedInclude
5024
5234
  * @param {Object} haystack
5025
5235
  * @param {Object} needle
5026
5236
  * @param {String} message
5027
5237
  * @namespace Assert
5028
- * @api public
5029
- */
5238
+ * @api public
5239
+ */
5030
5240
 
5031
5241
  assert.notNestedInclude = function (exp, inc, msg) {
5032
5242
  new Assertion(exp, msg, assert.notNestedInclude, true)
@@ -5035,23 +5245,23 @@ module.exports = function (chai, util) {
5035
5245
 
5036
5246
  /**
5037
5247
  * ### .deepNestedInclude(haystack, needle, [message])
5038
- *
5248
+ *
5039
5249
  * Asserts that 'haystack' includes 'needle'.
5040
- * Can be used to assert the inclusion of a subset of properties in an
5250
+ * Can be used to assert the inclusion of a subset of properties in an
5041
5251
  * object while checking for deep equality.
5042
- * Enables the use of dot- and bracket-notation for referencing nested
5252
+ * Enables the use of dot- and bracket-notation for referencing nested
5043
5253
  * properties.
5044
5254
  * '[]' and '.' in property names can be escaped using double backslashes.
5045
- *
5255
+ *
5046
5256
  * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}});
5047
5257
  * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}});
5048
- *
5258
+ *
5049
5259
  * @name deepNestedInclude
5050
5260
  * @param {Object} haystack
5051
5261
  * @param {Object} needle
5052
5262
  * @param {String} message
5053
5263
  * @namespace Assert
5054
- * @api public
5264
+ * @api public
5055
5265
  */
5056
5266
 
5057
5267
  assert.deepNestedInclude = function(exp, inc, msg) {
@@ -5061,23 +5271,23 @@ module.exports = function (chai, util) {
5061
5271
 
5062
5272
  /**
5063
5273
  * ### .notDeepNestedInclude(haystack, needle, [message])
5064
- *
5274
+ *
5065
5275
  * Asserts that 'haystack' does not include 'needle'.
5066
- * Can be used to assert the absence of a subset of properties in an
5276
+ * Can be used to assert the absence of a subset of properties in an
5067
5277
  * object while checking for deep equality.
5068
- * Enables the use of dot- and bracket-notation for referencing nested
5278
+ * Enables the use of dot- and bracket-notation for referencing nested
5069
5279
  * properties.
5070
5280
  * '[]' and '.' in property names can be escaped using double backslashes.
5071
- *
5281
+ *
5072
5282
  * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}})
5073
5283
  * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}});
5074
- *
5284
+ *
5075
5285
  * @name notDeepNestedInclude
5076
5286
  * @param {Object} haystack
5077
5287
  * @param {Object} needle
5078
5288
  * @param {String} message
5079
5289
  * @namespace Assert
5080
- * @api public
5290
+ * @api public
5081
5291
  */
5082
5292
 
5083
5293
  assert.notDeepNestedInclude = function(exp, inc, msg) {
@@ -5087,13 +5297,13 @@ module.exports = function (chai, util) {
5087
5297
 
5088
5298
  /**
5089
5299
  * ### .ownInclude(haystack, needle, [message])
5090
- *
5300
+ *
5091
5301
  * Asserts that 'haystack' includes 'needle'.
5092
- * Can be used to assert the inclusion of a subset of properties in an
5302
+ * Can be used to assert the inclusion of a subset of properties in an
5093
5303
  * object while ignoring inherited properties.
5094
- *
5304
+ *
5095
5305
  * assert.ownInclude({ a: 1 }, { a: 1 });
5096
- *
5306
+ *
5097
5307
  * @name ownInclude
5098
5308
  * @param {Object} haystack
5099
5309
  * @param {Object} needle
@@ -5108,15 +5318,15 @@ module.exports = function (chai, util) {
5108
5318
 
5109
5319
  /**
5110
5320
  * ### .notOwnInclude(haystack, needle, [message])
5111
- *
5321
+ *
5112
5322
  * Asserts that 'haystack' includes 'needle'.
5113
- * Can be used to assert the absence of a subset of properties in an
5323
+ * Can be used to assert the absence of a subset of properties in an
5114
5324
  * object while ignoring inherited properties.
5115
- *
5325
+ *
5116
5326
  * Object.prototype.b = 2;
5117
- *
5327
+ *
5118
5328
  * assert.notOwnInclude({ a: 1 }, { b: 2 });
5119
- *
5329
+ *
5120
5330
  * @name notOwnInclude
5121
5331
  * @param {Object} haystack
5122
5332
  * @param {Object} needle
@@ -5131,13 +5341,13 @@ module.exports = function (chai, util) {
5131
5341
 
5132
5342
  /**
5133
5343
  * ### .deepOwnInclude(haystack, needle, [message])
5134
- *
5344
+ *
5135
5345
  * Asserts that 'haystack' includes 'needle'.
5136
- * Can be used to assert the inclusion of a subset of properties in an
5346
+ * Can be used to assert the inclusion of a subset of properties in an
5137
5347
  * object while ignoring inherited properties and checking for deep equality.
5138
- *
5348
+ *
5139
5349
  * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}});
5140
- *
5350
+ *
5141
5351
  * @name deepOwnInclude
5142
5352
  * @param {Object} haystack
5143
5353
  * @param {Object} needle
@@ -5153,13 +5363,13 @@ module.exports = function (chai, util) {
5153
5363
 
5154
5364
  /**
5155
5365
  * ### .notDeepOwnInclude(haystack, needle, [message])
5156
- *
5366
+ *
5157
5367
  * Asserts that 'haystack' includes 'needle'.
5158
- * Can be used to assert the absence of a subset of properties in an
5368
+ * Can be used to assert the absence of a subset of properties in an
5159
5369
  * object while ignoring inherited properties and checking for deep equality.
5160
- *
5370
+ *
5161
5371
  * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}});
5162
- *
5372
+ *
5163
5373
  * @name notDeepOwnInclude
5164
5374
  * @param {Object} haystack
5165
5375
  * @param {Object} needle
@@ -5621,10 +5831,12 @@ module.exports = function (chai, util) {
5621
5831
  /**
5622
5832
  * ### .lengthOf(object, length, [message])
5623
5833
  *
5624
- * Asserts that `object` has a `length` property with the expected value.
5834
+ * Asserts that `object` has a `length` or `size` with the expected value.
5625
5835
  *
5626
5836
  * assert.lengthOf([1,2,3], 3, 'array has length of 3');
5627
5837
  * assert.lengthOf('foobar', 6, 'string has length of 6');
5838
+ * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3');
5839
+ * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3');
5628
5840
  *
5629
5841
  * @name lengthOf
5630
5842
  * @param {Mixed} object
@@ -5645,10 +5857,10 @@ module.exports = function (chai, util) {
5645
5857
  * You can also provide a single object instead of a `keys` array and its keys
5646
5858
  * will be used as the expected set of keys.
5647
5859
  *
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']);
5860
+ * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']);
5861
+ * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337});
5862
+ * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']);
5863
+ * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']);
5652
5864
  *
5653
5865
  * @name hasAnyKeys
5654
5866
  * @param {Mixed} object
@@ -5912,8 +6124,8 @@ module.exports = function (chai, util) {
5912
6124
  * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a
5913
6125
  * message matching `errMsgMatcher`.
5914
6126
  *
5915
- * assert.throws(fn, 'function throws a reference error');
5916
- * assert.throws(fn, /function throws a reference error/);
6127
+ * assert.throws(fn, 'Error thrown must have this msg');
6128
+ * assert.throws(fn, /Error thrown must have a msg that matches this/);
5917
6129
  * assert.throws(fn, ReferenceError);
5918
6130
  * assert.throws(fn, errorInstance);
5919
6131
  * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg');
@@ -7080,10 +7292,18 @@ module.exports = function (chai, util) {
7080
7292
  };
7081
7293
 
7082
7294
  /**
7295
+ * ### .fail([message])
7083
7296
  * ### .fail(actual, expected, [message], [operator])
7084
7297
  *
7085
7298
  * Throw a failure.
7086
7299
  *
7300
+ * expect.fail();
7301
+ * expect.fail("custom error message");
7302
+ * expect.fail(1, 2);
7303
+ * expect.fail(1, 2, "custom error message");
7304
+ * expect.fail(1, 2, "custom error message", ">");
7305
+ * expect.fail(1, 2, undefined, ">");
7306
+ *
7087
7307
  * @name fail
7088
7308
  * @param {Mixed} actual
7089
7309
  * @param {Mixed} expected
@@ -7094,6 +7314,11 @@ module.exports = function (chai, util) {
7094
7314
  */
7095
7315
 
7096
7316
  chai.expect.fail = function (actual, expected, message, operator) {
7317
+ if (arguments.length < 2) {
7318
+ message = actual;
7319
+ actual = undefined;
7320
+ }
7321
+
7097
7322
  message = message || 'expect.fail()';
7098
7323
  throw new chai.AssertionError(message, {
7099
7324
  actual: actual
@@ -7148,10 +7373,19 @@ module.exports = function (chai, util) {
7148
7373
  var should = {};
7149
7374
 
7150
7375
  /**
7376
+ * ### .fail([message])
7151
7377
  * ### .fail(actual, expected, [message], [operator])
7152
7378
  *
7153
7379
  * Throw a failure.
7154
7380
  *
7381
+ * should.fail();
7382
+ * should.fail("custom error message");
7383
+ * should.fail(1, 2);
7384
+ * should.fail(1, 2, "custom error message");
7385
+ * should.fail(1, 2, "custom error message", ">");
7386
+ * should.fail(1, 2, undefined, ">");
7387
+ *
7388
+ *
7155
7389
  * @name fail
7156
7390
  * @param {Mixed} actual
7157
7391
  * @param {Mixed} expected
@@ -7162,6 +7396,11 @@ module.exports = function (chai, util) {
7162
7396
  */
7163
7397
 
7164
7398
  should.fail = function (actual, expected, message, operator) {
7399
+ if (arguments.length < 2) {
7400
+ message = actual;
7401
+ actual = undefined;
7402
+ }
7403
+
7165
7404
  message = message || 'should.fail()';
7166
7405
  throw new chai.AssertionError(message, {
7167
7406
  actual: actual
@@ -7464,8 +7703,6 @@ module.exports = function addChainableMethod(ctx, name, method, chainingBehavior
7464
7703
  };
7465
7704
 
7466
7705
  },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":30,"./transferFlags":32}],10:[function(require,module,exports){
7467
- var config = require('../config');
7468
-
7469
7706
  var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
7470
7707
 
7471
7708
  /*!
@@ -7527,7 +7764,7 @@ module.exports = function addLengthGuard (fn, assertionName, isChainable) {
7527
7764
  return fn;
7528
7765
  };
7529
7766
 
7530
- },{"../config":4}],11:[function(require,module,exports){
7767
+ },{}],11:[function(require,module,exports){
7531
7768
  /*!
7532
7769
  * Chai - addMethod utility
7533
7770
  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
@@ -7636,7 +7873,7 @@ var transferFlags = require('./transferFlags');
7636
7873
  */
7637
7874
 
7638
7875
  module.exports = function addProperty(ctx, name, getter) {
7639
- getter = getter === undefined ? new Function() : getter;
7876
+ getter = getter === undefined ? function () {} : getter;
7640
7877
 
7641
7878
  Object.defineProperty(ctx, name,
7642
7879
  { get: function propertyGetter() {
@@ -7679,7 +7916,7 @@ module.exports = function addProperty(ctx, name, getter) {
7679
7916
  */
7680
7917
 
7681
7918
  /*!
7682
- * Module dependancies
7919
+ * Module dependencies
7683
7920
  */
7684
7921
 
7685
7922
  var inspect = require('./inspect');
@@ -7694,7 +7931,7 @@ var inspect = require('./inspect');
7694
7931
  *
7695
7932
  * @param {Mixed} first element to compare
7696
7933
  * @param {Mixed} second element to compare
7697
- * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
7934
+ * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1
7698
7935
  * @name compareByInspect
7699
7936
  * @namespace Utils
7700
7937
  * @api public
@@ -7720,8 +7957,6 @@ module.exports = function compareByInspect(a, b) {
7720
7957
  *
7721
7958
  * @param {Mixed} obj constructed Assertion
7722
7959
  * @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
7960
  * @namespace Utils
7726
7961
  * @name expectTypes
7727
7962
  * @api public
@@ -7731,8 +7966,9 @@ var AssertionError = require('assertion-error');
7731
7966
  var flag = require('./flag');
7732
7967
  var type = require('type-detect');
7733
7968
 
7734
- module.exports = function expectTypes(obj, types, ssfi) {
7969
+ module.exports = function expectTypes(obj, types) {
7735
7970
  var flagMsg = flag(obj, 'message');
7971
+ var ssfi = flag(obj, 'ssfi');
7736
7972
 
7737
7973
  flagMsg = flagMsg ? flagMsg + ': ' : '';
7738
7974
 
@@ -7740,7 +7976,7 @@ module.exports = function expectTypes(obj, types, ssfi) {
7740
7976
  types = types.map(function (t) { return t.toLowerCase(); });
7741
7977
  types.sort();
7742
7978
 
7743
- // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'
7979
+ // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum'
7744
7980
  var str = types.map(function (t, index) {
7745
7981
  var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';
7746
7982
  var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';
@@ -7758,7 +7994,7 @@ module.exports = function expectTypes(obj, types, ssfi) {
7758
7994
  }
7759
7995
  };
7760
7996
 
7761
- },{"./flag":15,"assertion-error":33,"type-detect":39}],15:[function(require,module,exports){
7997
+ },{"./flag":15,"assertion-error":33,"type-detect":38}],15:[function(require,module,exports){
7762
7998
  /*!
7763
7999
  * Chai - flag utility
7764
8000
  * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
@@ -7851,12 +8087,11 @@ module.exports = function getEnumerableProperties(object) {
7851
8087
  */
7852
8088
 
7853
8089
  /*!
7854
- * Module dependancies
8090
+ * Module dependencies
7855
8091
  */
7856
8092
 
7857
8093
  var flag = require('./flag')
7858
8094
  , getActual = require('./getActual')
7859
- , inspect = require('./inspect')
7860
8095
  , objDisplay = require('./objDisplay');
7861
8096
 
7862
8097
  /**
@@ -7896,7 +8131,7 @@ module.exports = function getMessage(obj, args) {
7896
8131
  return flagMsg ? flagMsg + ': ' + msg : msg;
7897
8132
  };
7898
8133
 
7899
- },{"./flag":15,"./getActual":16,"./inspect":23,"./objDisplay":26}],19:[function(require,module,exports){
8134
+ },{"./flag":15,"./getActual":16,"./objDisplay":26}],19:[function(require,module,exports){
7900
8135
  /*!
7901
8136
  * Chai - getOwnEnumerableProperties utility
7902
8137
  * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com>
@@ -7904,7 +8139,7 @@ module.exports = function getMessage(obj, args) {
7904
8139
  */
7905
8140
 
7906
8141
  /*!
7907
- * Module dependancies
8142
+ * Module dependencies
7908
8143
  */
7909
8144
 
7910
8145
  var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols');
@@ -8168,7 +8403,7 @@ exports.isProxyEnabled = require('./isProxyEnabled');
8168
8403
 
8169
8404
  exports.isNaN = require('./isNaN');
8170
8405
 
8171
- },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":18,"./getOwnEnumerableProperties":19,"./getOwnEnumerablePropertySymbols":20,"./inspect":23,"./isNaN":24,"./isProxyEnabled":25,"./objDisplay":26,"./overwriteChainableMethod":27,"./overwriteMethod":28,"./overwriteProperty":29,"./proxify":30,"./test":31,"./transferFlags":32,"check-error":34,"deep-eql":35,"get-func-name":37,"pathval":38,"type-detect":39}],23:[function(require,module,exports){
8406
+ },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":18,"./getOwnEnumerableProperties":19,"./getOwnEnumerablePropertySymbols":20,"./inspect":23,"./isNaN":24,"./isProxyEnabled":25,"./objDisplay":26,"./overwriteChainableMethod":27,"./overwriteMethod":28,"./overwriteProperty":29,"./proxify":30,"./test":31,"./transferFlags":32,"check-error":34,"deep-eql":35,"get-func-name":36,"pathval":37,"type-detect":38}],23:[function(require,module,exports){
8172
8407
  // This is (almost) directly from Node.js utils
8173
8408
  // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
8174
8409
 
@@ -8257,7 +8492,7 @@ function formatValue(ctx, value, recurseTimes) {
8257
8492
  var container = document.createElementNS(ns, '_');
8258
8493
 
8259
8494
  container.appendChild(value.cloneNode(false));
8260
- html = container.innerHTML
8495
+ var html = container.innerHTML
8261
8496
  .replace('><', '>' + value.innerHTML + '<');
8262
8497
  container.innerHTML = '';
8263
8498
  return html;
@@ -8276,7 +8511,7 @@ function formatValue(ctx, value, recurseTimes) {
8276
8511
 
8277
8512
  var name, nameSuffix;
8278
8513
 
8279
- // Some type of object without properties can be shortcutted.
8514
+ // Some type of object without properties can be shortcut.
8280
8515
  // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
8281
8516
  // a `stack` plus `description` property; ignore those for consistency.
8282
8517
  if (keys.length === 0 || (isError(value) && (
@@ -8367,7 +8602,6 @@ function formatValue(ctx, value, recurseTimes) {
8367
8602
  return reduceToSingleString(output, base, braces);
8368
8603
  }
8369
8604
 
8370
-
8371
8605
  function formatPrimitive(ctx, value) {
8372
8606
  switch (typeof value) {
8373
8607
  case 'undefined':
@@ -8397,12 +8631,10 @@ function formatPrimitive(ctx, value) {
8397
8631
  }
8398
8632
  }
8399
8633
 
8400
-
8401
8634
  function formatError(value) {
8402
8635
  return '[' + Error.prototype.toString.call(value) + ']';
8403
8636
  }
8404
8637
 
8405
-
8406
8638
  function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
8407
8639
  var output = [];
8408
8640
  for (var i = 0, l = value.length; i < l; ++i) {
@@ -8505,12 +8737,8 @@ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
8505
8737
  return name + ': ' + str;
8506
8738
  }
8507
8739
 
8508
-
8509
8740
  function reduceToSingleString(output, base, braces) {
8510
- var numLinesEst = 0;
8511
8741
  var length = output.reduce(function(prev, cur) {
8512
- numLinesEst++;
8513
- if (cur.indexOf('\n') >= 0) numLinesEst++;
8514
8742
  return prev + cur.length + 1;
8515
8743
  }, 0);
8516
8744
 
@@ -8553,7 +8781,7 @@ function objectToString(o) {
8553
8781
  return Object.prototype.toString.call(o);
8554
8782
  }
8555
8783
 
8556
- },{"../config":4,"./getEnumerableProperties":17,"./getProperties":21,"get-func-name":37}],24:[function(require,module,exports){
8784
+ },{"../config":4,"./getEnumerableProperties":17,"./getProperties":21,"get-func-name":36}],24:[function(require,module,exports){
8557
8785
  /*!
8558
8786
  * Chai - isNaN utility
8559
8787
  * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
@@ -8602,7 +8830,7 @@ var config = require('../config');
8602
8830
  */
8603
8831
 
8604
8832
  module.exports = function isProxyEnabled() {
8605
- return config.useProxy &&
8833
+ return config.useProxy &&
8606
8834
  typeof Proxy !== 'undefined' &&
8607
8835
  typeof Reflect !== 'undefined';
8608
8836
  };
@@ -8615,7 +8843,7 @@ module.exports = function isProxyEnabled() {
8615
8843
  */
8616
8844
 
8617
8845
  /*!
8618
- * Module dependancies
8846
+ * Module dependencies
8619
8847
  */
8620
8848
 
8621
8849
  var inspect = require('./inspect');
@@ -8672,7 +8900,7 @@ var transferFlags = require('./transferFlags');
8672
8900
  /**
8673
8901
  * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior)
8674
8902
  *
8675
- * Overwites an already existing chainable method
8903
+ * Overwrites an already existing chainable method
8676
8904
  * and provides access to the previous function or
8677
8905
  * property. Must return functions to be used for
8678
8906
  * name.
@@ -8746,7 +8974,7 @@ var transferFlags = require('./transferFlags');
8746
8974
  /**
8747
8975
  * ### .overwriteMethod(ctx, name, fn)
8748
8976
  *
8749
- * Overwites an already existing method and provides
8977
+ * Overwrites an already existing method and provides
8750
8978
  * access to previous function. Must return function
8751
8979
  * to be used for name.
8752
8980
  *
@@ -8839,7 +9067,7 @@ var transferFlags = require('./transferFlags');
8839
9067
  /**
8840
9068
  * ### .overwriteProperty(ctx, name, fn)
8841
9069
  *
8842
- * Overwites an already existing property getter and provides
9070
+ * Overwrites an already existing property getter and provides
8843
9071
  * access to previous value. Must return function to use as getter.
8844
9072
  *
8845
9073
  * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
@@ -8939,7 +9167,7 @@ var isProxyEnabled = require('./isProxyEnabled');
8939
9167
  * the list of existing properties. However, if a nonChainableMethodName is
8940
9168
  * provided, then the root cause is instead a failure to invoke a non-chainable
8941
9169
  * method prior to reading the non-existent property.
8942
- *
9170
+ *
8943
9171
  * If proxies are unsupported or disabled via the user's Chai config, then
8944
9172
  * return object without modification.
8945
9173
  *
@@ -8970,19 +9198,31 @@ module.exports = function proxify(obj, nonChainableMethodName) {
8970
9198
  nonChainableMethodName + '".');
8971
9199
  }
8972
9200
 
8973
- var orderedProperties = getProperties(target).filter(function(property) {
8974
- return !Object.prototype.hasOwnProperty(property) &&
8975
- builtins.indexOf(property) === -1;
8976
- }).sort(function(a, b) {
8977
- return stringDistance(property, a) - stringDistance(property, b);
9201
+ // If the property is reasonably close to an existing Chai property,
9202
+ // suggest that property to the user. Only suggest properties with a
9203
+ // distance less than 4.
9204
+ var suggestion = null;
9205
+ var suggestionDistance = 4;
9206
+ getProperties(target).forEach(function(prop) {
9207
+ if (
9208
+ !Object.prototype.hasOwnProperty(prop) &&
9209
+ builtins.indexOf(prop) === -1
9210
+ ) {
9211
+ var dist = stringDistanceCapped(
9212
+ property,
9213
+ prop,
9214
+ suggestionDistance
9215
+ );
9216
+ if (dist < suggestionDistance) {
9217
+ suggestion = prop;
9218
+ suggestionDistance = dist;
9219
+ }
9220
+ }
8978
9221
  });
8979
9222
 
8980
- if (orderedProperties.length &&
8981
- stringDistance(orderedProperties[0], property) < 4) {
8982
- // If the property is reasonably close to an existing Chai property,
8983
- // suggest that property to the user.
9223
+ if (suggestion !== null) {
8984
9224
  throw Error('Invalid Chai property: ' + property +
8985
- '. Did you mean "' + orderedProperties[0] + '"?');
9225
+ '. Did you mean "' + suggestion + '"?');
8986
9226
  } else {
8987
9227
  throw Error('Invalid Chai property: ' + property);
8988
9228
  }
@@ -9010,36 +9250,46 @@ module.exports = function proxify(obj, nonChainableMethodName) {
9010
9250
  };
9011
9251
 
9012
9252
  /**
9013
- * # stringDistance(strA, strB)
9014
- * Return the Levenshtein distance between two strings.
9253
+ * # stringDistanceCapped(strA, strB, cap)
9254
+ * Return the Levenshtein distance between two strings, but no more than cap.
9015
9255
  * @param {string} strA
9016
9256
  * @param {string} strB
9017
- * @return {number} the string distance between strA and strB
9257
+ * @param {number} number
9258
+ * @return {number} min(string distance between strA and strB, cap)
9018
9259
  * @api private
9019
9260
  */
9020
9261
 
9021
- function stringDistance(strA, strB, memo) {
9022
- if (!memo) {
9023
- // `memo` is a two-dimensional array containing a cache of distances
9024
- // memo[i][j] is the distance between strA.slice(0, i) and
9025
- // strB.slice(0, j).
9026
- memo = [];
9027
- for (var i = 0; i <= strA.length; i++) {
9028
- memo[i] = [];
9029
- }
9262
+ function stringDistanceCapped(strA, strB, cap) {
9263
+ if (Math.abs(strA.length - strB.length) >= cap) {
9264
+ return cap;
9030
9265
  }
9031
9266
 
9032
- if (!memo[strA.length] || !memo[strA.length][strB.length]) {
9033
- if (strA.length === 0 || strB.length === 0) {
9034
- memo[strA.length][strB.length] = Math.max(strA.length, strB.length);
9035
- } else {
9036
- memo[strA.length][strB.length] = Math.min(
9037
- stringDistance(strA.slice(0, -1), strB, memo) + 1,
9038
- stringDistance(strA, strB.slice(0, -1), memo) + 1,
9039
- stringDistance(strA.slice(0, -1), strB.slice(0, -1), memo) +
9040
- (strA.slice(-1) === strB.slice(-1) ? 0 : 1)
9041
- );
9042
- }
9267
+ var memo = [];
9268
+ // `memo` is a two-dimensional array containing distances.
9269
+ // memo[i][j] is the distance between strA.slice(0, i) and
9270
+ // strB.slice(0, j).
9271
+ for (var i = 0; i <= strA.length; i++) {
9272
+ memo[i] = Array(strB.length + 1).fill(0);
9273
+ memo[i][0] = i;
9274
+ }
9275
+ for (var j = 0; j < strB.length; j++) {
9276
+ memo[0][j] = j;
9277
+ }
9278
+
9279
+ for (var i = 1; i <= strA.length; i++) {
9280
+ var ch = strA.charCodeAt(i - 1);
9281
+ for (var j = 1; j <= strB.length; j++) {
9282
+ if (Math.abs(i - j) >= cap) {
9283
+ memo[i][j] = cap;
9284
+ continue;
9285
+ }
9286
+ memo[i][j] = Math.min(
9287
+ memo[i - 1][j] + 1,
9288
+ memo[i][j - 1] + 1,
9289
+ memo[i - 1][j - 1] +
9290
+ (ch === strB.charCodeAt(j - 1) ? 0 : 1)
9291
+ );
9292
+ }
9043
9293
  }
9044
9294
 
9045
9295
  return memo[strA.length][strB.length];
@@ -9053,7 +9303,7 @@ function stringDistance(strA, strB, memo) {
9053
9303
  */
9054
9304
 
9055
9305
  /*!
9056
- * Module dependancies
9306
+ * Module dependencies
9057
9307
  */
9058
9308
 
9059
9309
  var flag = require('./flag');
@@ -9094,7 +9344,7 @@ module.exports = function test(obj, args) {
9094
9344
  * var newAssertion = new Assertion();
9095
9345
  * utils.transferFlags(assertion, newAssertion);
9096
9346
  *
9097
- * var anotherAsseriton = new Assertion(myObj);
9347
+ * var anotherAssertion = new Assertion(myObj);
9098
9348
  * utils.transferFlags(assertion, anotherAssertion, false);
9099
9349
  *
9100
9350
  * @param {Assertion} assertion the assertion to transfer the flags from
@@ -9191,8 +9441,8 @@ function AssertionError (message, _props, ssf) {
9191
9441
  }
9192
9442
 
9193
9443
  // capture stack trace
9194
- ssf = ssf || arguments.callee;
9195
- if (ssf && Error.captureStackTrace) {
9444
+ ssf = ssf || AssertionError;
9445
+ if (Error.captureStackTrace) {
9196
9446
  Error.captureStackTrace(this, ssf);
9197
9447
  } else {
9198
9448
  try {
@@ -9416,57 +9666,33 @@ module.exports = {
9416
9666
 
9417
9667
  },{}],35:[function(require,module,exports){
9418
9668
  'use strict';
9419
- /* globals Symbol: true, Uint8Array: true, WeakMap: true */
9669
+ /* globals Symbol: false, Uint8Array: false, WeakMap: false */
9420
9670
  /*!
9421
9671
  * deep-eql
9422
9672
  * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
9423
9673
  * MIT Licensed
9424
9674
  */
9425
9675
 
9426
- /*!
9427
- * Module dependencies
9428
- */
9429
-
9430
9676
  var type = require('type-detect');
9431
9677
  function FakeMap() {
9432
- this.clear();
9678
+ this._key = 'chai/deep-eql__' + Math.random() + Date.now();
9433
9679
  }
9680
+
9434
9681
  FakeMap.prototype = {
9435
- clear: function clearMap() {
9436
- this.keys = [];
9437
- this.values = [];
9438
- return this;
9439
- },
9440
- set: function setMap(key, value) {
9441
- var index = this.keys.indexOf(key);
9442
- if (index >= 0) {
9443
- this.values[index] = value;
9444
- } else {
9445
- this.keys.push(key);
9446
- this.values.push(value);
9447
- }
9448
- return this;
9449
- },
9450
9682
  get: function getMap(key) {
9451
- return this.values[this.keys.indexOf(key)];
9683
+ return key[this._key];
9452
9684
  },
9453
- delete: function deleteMap(key) {
9454
- var index = this.keys.indexOf(key);
9455
- if (index >= 0) {
9456
- this.values = this.values.slice(0, index).concat(this.values.slice(index + 1));
9457
- this.keys = this.keys.slice(0, index).concat(this.keys.slice(index + 1));
9685
+ set: function setMap(key, value) {
9686
+ if (Object.isExtensible(key)) {
9687
+ Object.defineProperty(key, this._key, {
9688
+ value: value,
9689
+ configurable: true,
9690
+ });
9458
9691
  }
9459
- return this;
9460
9692
  },
9461
9693
  };
9462
9694
 
9463
- var MemoizeMap = null;
9464
- if (typeof WeakMap === 'function') {
9465
- MemoizeMap = WeakMap;
9466
- } else {
9467
- MemoizeMap = FakeMap;
9468
- }
9469
-
9695
+ var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap;
9470
9696
  /*!
9471
9697
  * Check to see if the MemoizeMap has recorded a result of the two operands
9472
9698
  *
@@ -9895,380 +10121,7 @@ function isPrimitive(value) {
9895
10121
  return value === null || typeof value !== 'object';
9896
10122
  }
9897
10123
 
9898
- },{"type-detect":36}],36:[function(require,module,exports){
9899
- 'use strict';
9900
- /* !
9901
- * type-detect
9902
- * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
9903
- * MIT Licensed
9904
- */
9905
- var getPrototypeOfExists = typeof Object.getPrototypeOf === 'function';
9906
- var promiseExists = typeof Promise === 'function';
9907
- var globalObject = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : self; // eslint-disable-line
9908
- var isDom = 'location' in globalObject && 'document' in globalObject;
9909
- var htmlElementExists = typeof HTMLElement !== 'undefined';
9910
- var isArrayExists = typeof Array.isArray === 'function';
9911
- var symbolExists = typeof Symbol !== 'undefined';
9912
- var mapExists = typeof Map !== 'undefined';
9913
- var setExists = typeof Set !== 'undefined';
9914
- var weakMapExists = typeof WeakMap !== 'undefined';
9915
- var weakSetExists = typeof WeakSet !== 'undefined';
9916
- var dataViewExists = typeof DataView !== 'undefined';
9917
- var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined';
9918
- var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined';
9919
- var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
9920
- var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
9921
- var setIteratorPrototype = getPrototypeOfExists && setEntriesExists && Object.getPrototypeOf(new Set().entries());
9922
- var mapIteratorPrototype = getPrototypeOfExists && mapEntriesExists && Object.getPrototypeOf(new Map().entries());
9923
- var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
9924
- var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
9925
- var stringIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
9926
- var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
9927
- var toStringLeftSliceLength = 8;
9928
- var toStringRightSliceLength = -1;
9929
- /**
9930
- * ### typeOf (obj)
9931
- *
9932
- * Uses `Object.prototype.toString` to determine the type of an object,
9933
- * normalising behaviour across engine versions & well optimised.
9934
- *
9935
- * @param {Mixed} object
9936
- * @return {String} object type
9937
- * @api public
9938
- */
9939
- module.exports = function typeDetect(obj) {
9940
- /* ! Speed optimisation
9941
- * Pre:
9942
- * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
9943
- * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled)
9944
- * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled)
9945
- * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled)
9946
- * function x 2,556,769 ops/sec ±1.73% (77 runs sampled)
9947
- * Post:
9948
- * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled)
9949
- * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled)
9950
- * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled)
9951
- * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled)
9952
- * function x 31,296,870 ops/sec ±0.96% (83 runs sampled)
9953
- */
9954
- var typeofObj = typeof obj;
9955
- if (typeofObj !== 'object') {
9956
- return typeofObj;
9957
- }
9958
-
9959
- /* ! Speed optimisation
9960
- * Pre:
9961
- * null x 28,645,765 ops/sec ±1.17% (82 runs sampled)
9962
- * Post:
9963
- * null x 36,428,962 ops/sec ±1.37% (84 runs sampled)
9964
- */
9965
- if (obj === null) {
9966
- return 'null';
9967
- }
9968
-
9969
- /* ! Spec Conformance
9970
- * Test: `Object.prototype.toString.call(window)``
9971
- * - Node === "[object global]"
9972
- * - Chrome === "[object global]"
9973
- * - Firefox === "[object Window]"
9974
- * - PhantomJS === "[object Window]"
9975
- * - Safari === "[object Window]"
9976
- * - IE 11 === "[object Window]"
9977
- * - IE Edge === "[object Window]"
9978
- * Test: `Object.prototype.toString.call(this)``
9979
- * - Chrome Worker === "[object global]"
9980
- * - Firefox Worker === "[object DedicatedWorkerGlobalScope]"
9981
- * - Safari Worker === "[object DedicatedWorkerGlobalScope]"
9982
- * - IE 11 Worker === "[object WorkerGlobalScope]"
9983
- * - IE Edge Worker === "[object WorkerGlobalScope]"
9984
- */
9985
- if (obj === globalObject) {
9986
- return 'global';
9987
- }
9988
-
9989
- /* ! Speed optimisation
9990
- * Pre:
9991
- * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled)
9992
- * Post:
9993
- * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled)
9994
- */
9995
- if (isArrayExists && Array.isArray(obj)) {
9996
- return 'Array';
9997
- }
9998
-
9999
- if (isDom) {
10000
- /* ! Spec Conformance
10001
- * (https://html.spec.whatwg.org/multipage/browsers.html#location)
10002
- * WhatWG HTML$7.7.3 - The `Location` interface
10003
- * Test: `Object.prototype.toString.call(window.location)``
10004
- * - IE <=11 === "[object Object]"
10005
- * - IE Edge <=13 === "[object Object]"
10006
- */
10007
- if (obj === globalObject.location) {
10008
- return 'Location';
10009
- }
10010
-
10011
- /* ! Spec Conformance
10012
- * (https://html.spec.whatwg.org/#document)
10013
- * WhatWG HTML$3.1.1 - The `Document` object
10014
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10015
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
10016
- * which suggests that browsers should use HTMLTableCellElement for
10017
- * both TD and TH elements. WhatWG separates these.
10018
- * WhatWG HTML states:
10019
- * > For historical reasons, Window objects must also have a
10020
- * > writable, configurable, non-enumerable property named
10021
- * > HTMLDocument whose value is the Document interface object.
10022
- * Test: `Object.prototype.toString.call(document)``
10023
- * - Chrome === "[object HTMLDocument]"
10024
- * - Firefox === "[object HTMLDocument]"
10025
- * - Safari === "[object HTMLDocument]"
10026
- * - IE <=10 === "[object Document]"
10027
- * - IE 11 === "[object HTMLDocument]"
10028
- * - IE Edge <=13 === "[object HTMLDocument]"
10029
- */
10030
- if (obj === globalObject.document) {
10031
- return 'Document';
10032
- }
10033
-
10034
- /* ! Spec Conformance
10035
- * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
10036
- * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
10037
- * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
10038
- * - IE <=10 === "[object MSMimeTypesCollection]"
10039
- */
10040
- if (obj === (globalObject.navigator || {}).mimeTypes) {
10041
- return 'MimeTypeArray';
10042
- }
10043
-
10044
- /* ! Spec Conformance
10045
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10046
- * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
10047
- * Test: `Object.prototype.toString.call(navigator.plugins)``
10048
- * - IE <=10 === "[object MSPluginsCollection]"
10049
- */
10050
- if (obj === (globalObject.navigator || {}).plugins) {
10051
- return 'PluginArray';
10052
- }
10053
-
10054
- /* ! Spec Conformance
10055
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10056
- * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
10057
- * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
10058
- * - IE <=10 === "[object HTMLBlockElement]"
10059
- */
10060
- if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'BLOCKQUOTE') {
10061
- return 'HTMLQuoteElement';
10062
- }
10063
-
10064
- /* ! Spec Conformance
10065
- * (https://html.spec.whatwg.org/#htmltabledatacellelement)
10066
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
10067
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10068
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10069
- * which suggests that browsers should use HTMLTableCellElement for
10070
- * both TD and TH elements. WhatWG separates these.
10071
- * Test: Object.prototype.toString.call(document.createElement('td'))
10072
- * - Chrome === "[object HTMLTableCellElement]"
10073
- * - Firefox === "[object HTMLTableCellElement]"
10074
- * - Safari === "[object HTMLTableCellElement]"
10075
- */
10076
- if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'TD') {
10077
- return 'HTMLTableDataCellElement';
10078
- }
10079
-
10080
- /* ! Spec Conformance
10081
- * (https://html.spec.whatwg.org/#htmltableheadercellelement)
10082
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
10083
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10084
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10085
- * which suggests that browsers should use HTMLTableCellElement for
10086
- * both TD and TH elements. WhatWG separates these.
10087
- * Test: Object.prototype.toString.call(document.createElement('th'))
10088
- * - Chrome === "[object HTMLTableCellElement]"
10089
- * - Firefox === "[object HTMLTableCellElement]"
10090
- * - Safari === "[object HTMLTableCellElement]"
10091
- */
10092
- if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'TH') {
10093
- return 'HTMLTableHeaderCellElement';
10094
- }
10095
- }
10096
-
10097
- /* ! Speed optimisation
10098
- * Pre:
10099
- * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled)
10100
- * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled)
10101
- * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled)
10102
- * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled)
10103
- * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled)
10104
- * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled)
10105
- * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled)
10106
- * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled)
10107
- * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled)
10108
- * Post:
10109
- * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled)
10110
- * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled)
10111
- * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled)
10112
- * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled)
10113
- * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled)
10114
- * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled)
10115
- * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled)
10116
- * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled)
10117
- * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled)
10118
- */
10119
- var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]);
10120
- if (typeof stringTag === 'string') {
10121
- return stringTag;
10122
- }
10123
-
10124
- if (getPrototypeOfExists) {
10125
- var objPrototype = Object.getPrototypeOf(obj);
10126
- /* ! Speed optimisation
10127
- * Pre:
10128
- * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled)
10129
- * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled)
10130
- * Post:
10131
- * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled)
10132
- * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled)
10133
- */
10134
- if (objPrototype === RegExp.prototype) {
10135
- return 'RegExp';
10136
- }
10137
-
10138
- /* ! Speed optimisation
10139
- * Pre:
10140
- * date x 2,130,074 ops/sec ±4.42% (68 runs sampled)
10141
- * Post:
10142
- * date x 3,953,779 ops/sec ±1.35% (77 runs sampled)
10143
- */
10144
- if (objPrototype === Date.prototype) {
10145
- return 'Date';
10146
- }
10147
-
10148
- /* ! Spec Conformance
10149
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag)
10150
- * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
10151
- * Test: `Object.prototype.toString.call(Promise.resolve())``
10152
- * - Chrome <=47 === "[object Object]"
10153
- * - Edge <=20 === "[object Object]"
10154
- * - Firefox 29-Latest === "[object Promise]"
10155
- * - Safari 7.1-Latest === "[object Promise]"
10156
- */
10157
- if (promiseExists && objPrototype === Promise.prototype) {
10158
- return 'Promise';
10159
- }
10160
-
10161
- /* ! Speed optimisation
10162
- * Pre:
10163
- * set x 2,222,186 ops/sec ±1.31% (82 runs sampled)
10164
- * Post:
10165
- * set x 4,545,879 ops/sec ±1.13% (83 runs sampled)
10166
- */
10167
- if (setExists && objPrototype === Set.prototype) {
10168
- return 'Set';
10169
- }
10170
-
10171
- /* ! Speed optimisation
10172
- * Pre:
10173
- * map x 2,396,842 ops/sec ±1.59% (81 runs sampled)
10174
- * Post:
10175
- * map x 4,183,945 ops/sec ±6.59% (82 runs sampled)
10176
- */
10177
- if (mapExists && objPrototype === Map.prototype) {
10178
- return 'Map';
10179
- }
10180
-
10181
- /* ! Speed optimisation
10182
- * Pre:
10183
- * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled)
10184
- * Post:
10185
- * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled)
10186
- */
10187
- if (weakSetExists && objPrototype === WeakSet.prototype) {
10188
- return 'WeakSet';
10189
- }
10190
-
10191
- /* ! Speed optimisation
10192
- * Pre:
10193
- * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled)
10194
- * Post:
10195
- * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled)
10196
- */
10197
- if (weakMapExists && objPrototype === WeakMap.prototype) {
10198
- return 'WeakMap';
10199
- }
10200
-
10201
- /* ! Spec Conformance
10202
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
10203
- * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
10204
- * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
10205
- * - Edge <=13 === "[object Object]"
10206
- */
10207
- if (dataViewExists && objPrototype === DataView.prototype) {
10208
- return 'DataView';
10209
- }
10210
-
10211
- /* ! Spec Conformance
10212
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
10213
- * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
10214
- * Test: `Object.prototype.toString.call(new Map().entries())``
10215
- * - Edge <=13 === "[object Object]"
10216
- */
10217
- if (mapExists && objPrototype === mapIteratorPrototype) {
10218
- return 'Map Iterator';
10219
- }
10220
-
10221
- /* ! Spec Conformance
10222
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
10223
- * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
10224
- * Test: `Object.prototype.toString.call(new Set().entries())``
10225
- * - Edge <=13 === "[object Object]"
10226
- */
10227
- if (setExists && objPrototype === setIteratorPrototype) {
10228
- return 'Set Iterator';
10229
- }
10230
-
10231
- /* ! Spec Conformance
10232
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
10233
- * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
10234
- * Test: `Object.prototype.toString.call([][Symbol.iterator]())``
10235
- * - Edge <=13 === "[object Object]"
10236
- */
10237
- if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
10238
- return 'Array Iterator';
10239
- }
10240
-
10241
- /* ! Spec Conformance
10242
- * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
10243
- * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
10244
- * Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
10245
- * - Edge <=13 === "[object Object]"
10246
- */
10247
- if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
10248
- return 'String Iterator';
10249
- }
10250
-
10251
- /* ! Speed optimisation
10252
- * Pre:
10253
- * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled)
10254
- * Post:
10255
- * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled)
10256
- */
10257
- if (objPrototype === null) {
10258
- return 'Object';
10259
- }
10260
- }
10261
-
10262
- return Object
10263
- .prototype
10264
- .toString
10265
- .call(obj)
10266
- .slice(toStringLeftSliceLength, toStringRightSliceLength);
10267
- };
10268
-
10269
- module.exports.typeDetect = module.exports;
10270
-
10271
- },{}],37:[function(require,module,exports){
10124
+ },{"type-detect":38}],36:[function(require,module,exports){
10272
10125
  'use strict';
10273
10126
 
10274
10127
  /* !
@@ -10314,7 +10167,7 @@ function getFuncName(aFunc) {
10314
10167
 
10315
10168
  module.exports = getFuncName;
10316
10169
 
10317
- },{}],38:[function(require,module,exports){
10170
+ },{}],37:[function(require,module,exports){
10318
10171
  'use strict';
10319
10172
 
10320
10173
  /* !
@@ -10607,8 +10460,12 @@ module.exports = {
10607
10460
  setPathValue: setPathValue,
10608
10461
  };
10609
10462
 
10610
- },{}],39:[function(require,module,exports){
10611
- 'use strict';
10463
+ },{}],38:[function(require,module,exports){
10464
+ (function (global, factory) {
10465
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10466
+ typeof define === 'function' && define.amd ? define(factory) :
10467
+ (global.typeDetect = factory());
10468
+ }(this, (function () { 'use strict';
10612
10469
 
10613
10470
  /* !
10614
10471
  * type-detect
@@ -10616,8 +10473,10 @@ module.exports = {
10616
10473
  * MIT Licensed
10617
10474
  */
10618
10475
  var promiseExists = typeof Promise === 'function';
10619
- var globalObject = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : self; // eslint-disable-line
10620
- var isDom = 'location' in globalObject && 'document' in globalObject;
10476
+
10477
+ /* eslint-disable no-undef */
10478
+ var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist
10479
+
10621
10480
  var symbolExists = typeof Symbol !== 'undefined';
10622
10481
  var mapExists = typeof Map !== 'undefined';
10623
10482
  var setExists = typeof Set !== 'undefined';
@@ -10646,7 +10505,7 @@ var toStringRightSliceLength = -1;
10646
10505
  * @return {String} object type
10647
10506
  * @api public
10648
10507
  */
10649
- module.exports = function typeDetect(obj) {
10508
+ function typeDetect(obj) {
10650
10509
  /* ! Speed optimisation
10651
10510
  * Pre:
10652
10511
  * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled)
@@ -10709,7 +10568,9 @@ module.exports = function typeDetect(obj) {
10709
10568
  return 'Array';
10710
10569
  }
10711
10570
 
10712
- if (isDom) {
10571
+ // Not caching existence of `window` and related properties due to potential
10572
+ // for `window` to be unset before tests in quasi-browser environments.
10573
+ if (typeof window === 'object' && window !== null) {
10713
10574
  /* ! Spec Conformance
10714
10575
  * (https://html.spec.whatwg.org/multipage/browsers.html#location)
10715
10576
  * WhatWG HTML$7.7.3 - The `Location` interface
@@ -10717,7 +10578,7 @@ module.exports = function typeDetect(obj) {
10717
10578
  * - IE <=11 === "[object Object]"
10718
10579
  * - IE Edge <=13 === "[object Object]"
10719
10580
  */
10720
- if (obj === globalObject.location) {
10581
+ if (typeof window.location === 'object' && obj === window.location) {
10721
10582
  return 'Location';
10722
10583
  }
10723
10584
 
@@ -10740,70 +10601,78 @@ module.exports = function typeDetect(obj) {
10740
10601
  * - IE 11 === "[object HTMLDocument]"
10741
10602
  * - IE Edge <=13 === "[object HTMLDocument]"
10742
10603
  */
10743
- if (obj === globalObject.document) {
10604
+ if (typeof window.document === 'object' && obj === window.document) {
10744
10605
  return 'Document';
10745
10606
  }
10746
10607
 
10747
- /* ! Spec Conformance
10748
- * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
10749
- * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
10750
- * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
10751
- * - IE <=10 === "[object MSMimeTypesCollection]"
10752
- */
10753
- if (obj === (globalObject.navigator || {}).mimeTypes) {
10754
- return 'MimeTypeArray';
10755
- }
10608
+ if (typeof window.navigator === 'object') {
10609
+ /* ! Spec Conformance
10610
+ * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
10611
+ * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
10612
+ * Test: `Object.prototype.toString.call(navigator.mimeTypes)``
10613
+ * - IE <=10 === "[object MSMimeTypesCollection]"
10614
+ */
10615
+ if (typeof window.navigator.mimeTypes === 'object' &&
10616
+ obj === window.navigator.mimeTypes) {
10617
+ return 'MimeTypeArray';
10618
+ }
10756
10619
 
10757
- /* ! Spec Conformance
10758
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10759
- * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
10760
- * Test: `Object.prototype.toString.call(navigator.plugins)``
10761
- * - IE <=10 === "[object MSPluginsCollection]"
10762
- */
10763
- if (obj === (globalObject.navigator || {}).plugins) {
10764
- return 'PluginArray';
10620
+ /* ! Spec Conformance
10621
+ * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10622
+ * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
10623
+ * Test: `Object.prototype.toString.call(navigator.plugins)``
10624
+ * - IE <=10 === "[object MSPluginsCollection]"
10625
+ */
10626
+ if (typeof window.navigator.plugins === 'object' &&
10627
+ obj === window.navigator.plugins) {
10628
+ return 'PluginArray';
10629
+ }
10765
10630
  }
10766
10631
 
10767
- /* ! Spec Conformance
10768
- * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10769
- * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
10770
- * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
10771
- * - IE <=10 === "[object HTMLBlockElement]"
10772
- */
10773
- if (obj instanceof HTMLElement && obj.tagName === 'BLOCKQUOTE') {
10774
- return 'HTMLQuoteElement';
10775
- }
10632
+ if ((typeof window.HTMLElement === 'function' ||
10633
+ typeof window.HTMLElement === 'object') &&
10634
+ obj instanceof window.HTMLElement) {
10635
+ /* ! Spec Conformance
10636
+ * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
10637
+ * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
10638
+ * Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
10639
+ * - IE <=10 === "[object HTMLBlockElement]"
10640
+ */
10641
+ if (obj.tagName === 'BLOCKQUOTE') {
10642
+ return 'HTMLQuoteElement';
10643
+ }
10776
10644
 
10777
- /* ! Spec Conformance
10778
- * (https://html.spec.whatwg.org/#htmltabledatacellelement)
10779
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
10780
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10781
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10782
- * which suggests that browsers should use HTMLTableCellElement for
10783
- * both TD and TH elements. WhatWG separates these.
10784
- * Test: Object.prototype.toString.call(document.createElement('td'))
10785
- * - Chrome === "[object HTMLTableCellElement]"
10786
- * - Firefox === "[object HTMLTableCellElement]"
10787
- * - Safari === "[object HTMLTableCellElement]"
10788
- */
10789
- if (obj instanceof HTMLElement && obj.tagName === 'TD') {
10790
- return 'HTMLTableDataCellElement';
10791
- }
10645
+ /* ! Spec Conformance
10646
+ * (https://html.spec.whatwg.org/#htmltabledatacellelement)
10647
+ * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
10648
+ * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10649
+ * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10650
+ * which suggests that browsers should use HTMLTableCellElement for
10651
+ * both TD and TH elements. WhatWG separates these.
10652
+ * Test: Object.prototype.toString.call(document.createElement('td'))
10653
+ * - Chrome === "[object HTMLTableCellElement]"
10654
+ * - Firefox === "[object HTMLTableCellElement]"
10655
+ * - Safari === "[object HTMLTableCellElement]"
10656
+ */
10657
+ if (obj.tagName === 'TD') {
10658
+ return 'HTMLTableDataCellElement';
10659
+ }
10792
10660
 
10793
- /* ! Spec Conformance
10794
- * (https://html.spec.whatwg.org/#htmltableheadercellelement)
10795
- * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
10796
- * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10797
- * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10798
- * which suggests that browsers should use HTMLTableCellElement for
10799
- * both TD and TH elements. WhatWG separates these.
10800
- * Test: Object.prototype.toString.call(document.createElement('th'))
10801
- * - Chrome === "[object HTMLTableCellElement]"
10802
- * - Firefox === "[object HTMLTableCellElement]"
10803
- * - Safari === "[object HTMLTableCellElement]"
10804
- */
10805
- if (obj instanceof HTMLElement && obj.tagName === 'TH') {
10806
- return 'HTMLTableHeaderCellElement';
10661
+ /* ! Spec Conformance
10662
+ * (https://html.spec.whatwg.org/#htmltableheadercellelement)
10663
+ * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
10664
+ * Note: Most browsers currently adher to the W3C DOM Level 2 spec
10665
+ * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
10666
+ * which suggests that browsers should use HTMLTableCellElement for
10667
+ * both TD and TH elements. WhatWG separates these.
10668
+ * Test: Object.prototype.toString.call(document.createElement('th'))
10669
+ * - Chrome === "[object HTMLTableCellElement]"
10670
+ * - Firefox === "[object HTMLTableCellElement]"
10671
+ * - Safari === "[object HTMLTableCellElement]"
10672
+ */
10673
+ if (obj.tagName === 'TH') {
10674
+ return 'HTMLTableHeaderCellElement';
10675
+ }
10807
10676
  }
10808
10677
  }
10809
10678
 
@@ -10975,9 +10844,11 @@ module.exports = function typeDetect(obj) {
10975
10844
  .toString
10976
10845
  .call(obj)
10977
10846
  .slice(toStringLeftSliceLength, toStringRightSliceLength);
10978
- };
10847
+ }
10979
10848
 
10980
- module.exports.typeDetect = module.exports;
10849
+ return typeDetect;
10850
+
10851
+ })));
10981
10852
 
10982
10853
  },{}]},{},[1])(1)
10983
- });
10854
+ });