chai 5.1.2 → 5.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.
@@ -8,6 +8,7 @@
8
8
  import {Assertion} from '../assertion.js';
9
9
  import {AssertionError} from 'assertion-error';
10
10
  import * as _ from '../utils/index.js';
11
+ import {config} from '../config.js';
11
12
 
12
13
  const {flag} = _;
13
14
 
@@ -42,10 +43,25 @@ const {flag} = _;
42
43
  * @public
43
44
  */
44
45
 
45
- [ 'to', 'be', 'been', 'is'
46
- , 'and', 'has', 'have', 'with'
47
- , 'that', 'which', 'at', 'of'
48
- , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) {
46
+ [
47
+ 'to',
48
+ 'be',
49
+ 'been',
50
+ 'is',
51
+ 'and',
52
+ 'has',
53
+ 'have',
54
+ 'with',
55
+ 'that',
56
+ 'which',
57
+ 'at',
58
+ 'of',
59
+ 'same',
60
+ 'but',
61
+ 'does',
62
+ 'still',
63
+ 'also'
64
+ ].forEach(function (chain) {
49
65
  Assertion.addProperty(chain);
50
66
  });
51
67
 
@@ -239,11 +255,16 @@ Assertion.addProperty('all', function () {
239
255
  });
240
256
 
241
257
  const functionTypes = {
242
- 'function': ['function', 'asyncfunction', 'generatorfunction', 'asyncgeneratorfunction'],
243
- 'asyncfunction': ['asyncfunction', 'asyncgeneratorfunction'],
244
- 'generatorfunction': ['generatorfunction', 'asyncgeneratorfunction'],
245
- 'asyncgeneratorfunction': ['asyncgeneratorfunction']
246
- }
258
+ function: [
259
+ 'function',
260
+ 'asyncfunction',
261
+ 'generatorfunction',
262
+ 'asyncgeneratorfunction'
263
+ ],
264
+ asyncfunction: ['asyncfunction', 'asyncgeneratorfunction'],
265
+ generatorfunction: ['generatorfunction', 'asyncgeneratorfunction'],
266
+ asyncgeneratorfunction: ['asyncgeneratorfunction']
267
+ };
247
268
 
248
269
  /**
249
270
  * ### .a(type[, msg])
@@ -304,25 +325,25 @@ const functionTypes = {
304
325
  * @namespace BDD
305
326
  * @public
306
327
  */
307
- function an (type, msg) {
328
+ function an(type, msg) {
308
329
  if (msg) flag(this, 'message', msg);
309
330
  type = type.toLowerCase();
310
- var obj = flag(this, 'object')
311
- , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
331
+ var obj = flag(this, 'object'),
332
+ article = ~['a', 'e', 'i', 'o', 'u'].indexOf(type.charAt(0)) ? 'an ' : 'a ';
312
333
 
313
334
  const detectedType = _.type(obj).toLowerCase();
314
335
 
315
336
  if (functionTypes['function'].includes(type)) {
316
337
  this.assert(
317
- functionTypes[type].includes(detectedType)
318
- , 'expected #{this} to be ' + article + type
319
- , 'expected #{this} not to be ' + article + type
338
+ functionTypes[type].includes(detectedType),
339
+ 'expected #{this} to be ' + article + type,
340
+ 'expected #{this} not to be ' + article + type
320
341
  );
321
342
  } else {
322
343
  this.assert(
323
- type === detectedType
324
- , 'expected #{this} to be ' + article + type
325
- , 'expected #{this} not to be ' + article + type
344
+ type === detectedType,
345
+ 'expected #{this} to be ' + article + type,
346
+ 'expected #{this} not to be ' + article + type
326
347
  );
327
348
  }
328
349
  }
@@ -343,7 +364,7 @@ function SameValueZero(a, b) {
343
364
  /**
344
365
  *
345
366
  */
346
- function includeChainingBehavior () {
367
+ function includeChainingBehavior() {
347
368
  flag(this, 'contains', true);
348
369
  }
349
370
 
@@ -493,17 +514,17 @@ function includeChainingBehavior () {
493
514
  * @namespace BDD
494
515
  * @public
495
516
  */
496
- function include (val, msg) {
517
+ function include(val, msg) {
497
518
  if (msg) flag(this, 'message', msg);
498
519
 
499
- var obj = flag(this, 'object')
500
- , objType = _.type(obj).toLowerCase()
501
- , flagMsg = flag(this, 'message')
502
- , negate = flag(this, 'negate')
503
- , ssfi = flag(this, 'ssfi')
504
- , isDeep = flag(this, 'deep')
505
- , descriptor = isDeep ? 'deep ' : ''
506
- , isEql = isDeep ? flag(this, 'eql') : SameValueZero;
520
+ var obj = flag(this, 'object'),
521
+ objType = _.type(obj).toLowerCase(),
522
+ flagMsg = flag(this, 'message'),
523
+ negate = flag(this, 'negate'),
524
+ ssfi = flag(this, 'ssfi'),
525
+ isDeep = flag(this, 'deep'),
526
+ descriptor = isDeep ? 'deep ' : '',
527
+ isEql = isDeep ? flag(this, 'eql') : SameValueZero;
507
528
 
508
529
  flagMsg = flagMsg ? flagMsg + ': ' : '';
509
530
 
@@ -546,7 +567,7 @@ function include (val, msg) {
546
567
  if (isDeep) {
547
568
  included = obj.some(function (item) {
548
569
  return isEql(item, val);
549
- })
570
+ });
550
571
  } else {
551
572
  included = obj.indexOf(val) !== -1;
552
573
  }
@@ -558,21 +579,24 @@ function include (val, msg) {
558
579
  // objects with a custom `@@toStringTag`.
559
580
  if (val !== Object(val)) {
560
581
  throw new AssertionError(
561
- flagMsg + 'the given combination of arguments ('
562
- + objType + ' and '
563
- + _.type(val).toLowerCase() + ')'
564
- + ' is invalid for this assertion. '
565
- + 'You can use an array, a map, an object, a set, a string, '
566
- + 'or a weakset instead of a '
567
- + _.type(val).toLowerCase(),
582
+ flagMsg +
583
+ 'the given combination of arguments (' +
584
+ objType +
585
+ ' and ' +
586
+ _.type(val).toLowerCase() +
587
+ ')' +
588
+ ' is invalid for this assertion. ' +
589
+ 'You can use an array, a map, an object, a set, a string, ' +
590
+ 'or a weakset instead of a ' +
591
+ _.type(val).toLowerCase(),
568
592
  undefined,
569
593
  ssfi
570
594
  );
571
595
  }
572
596
 
573
- var props = Object.keys(val)
574
- , firstErr = null
575
- , numErrs = 0;
597
+ var props = Object.keys(val),
598
+ firstErr = null,
599
+ numErrs = 0;
576
600
 
577
601
  props.forEach(function (prop) {
578
602
  var propAssertion = new Assertion(obj);
@@ -607,9 +631,10 @@ function include (val, msg) {
607
631
 
608
632
  // Assert inclusion in collection or substring in a string.
609
633
  this.assert(
610
- included
611
- , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val)
612
- , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val));
634
+ included,
635
+ 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val),
636
+ 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)
637
+ );
613
638
  }
614
639
 
615
640
  Assertion.addChainableMethod('include', include, includeChainingBehavior);
@@ -654,9 +679,10 @@ Assertion.addChainableMethod('includes', include, includeChainingBehavior);
654
679
  */
655
680
  Assertion.addProperty('ok', function () {
656
681
  this.assert(
657
- flag(this, 'object')
658
- , 'expected #{this} to be truthy'
659
- , 'expected #{this} to be falsy');
682
+ flag(this, 'object'),
683
+ 'expected #{this} to be truthy',
684
+ 'expected #{this} to be falsy'
685
+ );
660
686
  });
661
687
 
662
688
  /**
@@ -686,10 +712,10 @@ Assertion.addProperty('ok', function () {
686
712
  */
687
713
  Assertion.addProperty('true', function () {
688
714
  this.assert(
689
- true === flag(this, 'object')
690
- , 'expected #{this} to be true'
691
- , 'expected #{this} to be false'
692
- , flag(this, 'negate') ? false : true
715
+ true === flag(this, 'object'),
716
+ 'expected #{this} to be true',
717
+ 'expected #{this} to be false',
718
+ flag(this, 'negate') ? false : true
693
719
  );
694
720
  });
695
721
 
@@ -697,10 +723,10 @@ Assertion.addProperty('numeric', function () {
697
723
  const object = flag(this, 'object');
698
724
 
699
725
  this.assert(
700
- ['Number', 'BigInt'].includes(_.type(object))
701
- , 'expected #{this} to be numeric'
702
- , 'expected #{this} to not be numeric'
703
- , flag(this, 'negate') ? false : true
726
+ ['Number', 'BigInt'].includes(_.type(object)),
727
+ 'expected #{this} to be numeric',
728
+ 'expected #{this} to not be numeric',
729
+ flag(this, 'negate') ? false : true
704
730
  );
705
731
  });
706
732
 
@@ -720,24 +746,25 @@ Assertion.addProperty('numeric', function () {
720
746
  * @public
721
747
  */
722
748
  Assertion.addProperty('callable', function () {
723
- const val = flag(this, 'object')
724
- const ssfi = flag(this, 'ssfi')
725
- const message = flag(this, 'message')
726
- const msg = message ? `${message}: ` : ''
749
+ const val = flag(this, 'object');
750
+ const ssfi = flag(this, 'ssfi');
751
+ const message = flag(this, 'message');
752
+ const msg = message ? `${message}: ` : '';
727
753
  const negate = flag(this, 'negate');
728
754
 
729
- const assertionMessage = negate ?
730
- `${msg}expected ${_.inspect(val)} not to be a callable function` :
731
- `${msg}expected ${_.inspect(val)} to be a callable function`;
755
+ const assertionMessage = negate
756
+ ? `${msg}expected ${_.inspect(val)} not to be a callable function`
757
+ : `${msg}expected ${_.inspect(val)} to be a callable function`;
732
758
 
733
- const isCallable = ['Function', 'AsyncFunction', 'GeneratorFunction', 'AsyncGeneratorFunction'].includes(_.type(val));
759
+ const isCallable = [
760
+ 'Function',
761
+ 'AsyncFunction',
762
+ 'GeneratorFunction',
763
+ 'AsyncGeneratorFunction'
764
+ ].includes(_.type(val));
734
765
 
735
766
  if ((isCallable && negate) || (!isCallable && !negate)) {
736
- throw new AssertionError(
737
- assertionMessage,
738
- undefined,
739
- ssfi
740
- );
767
+ throw new AssertionError(assertionMessage, undefined, ssfi);
741
768
  }
742
769
  });
743
770
 
@@ -768,10 +795,10 @@ Assertion.addProperty('callable', function () {
768
795
  */
769
796
  Assertion.addProperty('false', function () {
770
797
  this.assert(
771
- false === flag(this, 'object')
772
- , 'expected #{this} to be false'
773
- , 'expected #{this} to be true'
774
- , flag(this, 'negate') ? true : false
798
+ false === flag(this, 'object'),
799
+ 'expected #{this} to be false',
800
+ 'expected #{this} to be true',
801
+ flag(this, 'negate') ? true : false
775
802
  );
776
803
  });
777
804
 
@@ -799,9 +826,9 @@ Assertion.addProperty('false', function () {
799
826
  */
800
827
  Assertion.addProperty('null', function () {
801
828
  this.assert(
802
- null === flag(this, 'object')
803
- , 'expected #{this} to be null'
804
- , 'expected #{this} not to be null'
829
+ null === flag(this, 'object'),
830
+ 'expected #{this} to be null',
831
+ 'expected #{this} not to be null'
805
832
  );
806
833
  });
807
834
 
@@ -829,9 +856,9 @@ Assertion.addProperty('null', function () {
829
856
  */
830
857
  Assertion.addProperty('undefined', function () {
831
858
  this.assert(
832
- undefined === flag(this, 'object')
833
- , 'expected #{this} to be undefined'
834
- , 'expected #{this} not to be undefined'
859
+ undefined === flag(this, 'object'),
860
+ 'expected #{this} to be undefined',
861
+ 'expected #{this} not to be undefined'
835
862
  );
836
863
  });
837
864
 
@@ -859,9 +886,9 @@ Assertion.addProperty('undefined', function () {
859
886
  */
860
887
  Assertion.addProperty('NaN', function () {
861
888
  this.assert(
862
- _.isNaN(flag(this, 'object'))
863
- , 'expected #{this} to be NaN'
864
- , 'expected #{this} not to be NaN'
889
+ _.isNaN(flag(this, 'object')),
890
+ 'expected #{this} to be NaN',
891
+ 'expected #{this} not to be NaN'
865
892
  );
866
893
  });
867
894
 
@@ -897,12 +924,12 @@ Assertion.addProperty('NaN', function () {
897
924
  * @namespace BDD
898
925
  * @public
899
926
  */
900
- function assertExist () {
927
+ function assertExist() {
901
928
  var val = flag(this, 'object');
902
929
  this.assert(
903
- val !== null && val !== undefined
904
- , 'expected #{this} to exist'
905
- , 'expected #{this} to not exist'
930
+ val !== null && val !== undefined,
931
+ 'expected #{this} to exist',
932
+ 'expected #{this} to not exist'
906
933
  );
907
934
  }
908
935
 
@@ -958,10 +985,10 @@ Assertion.addProperty('exists', assertExist);
958
985
  * @public
959
986
  */
960
987
  Assertion.addProperty('empty', function () {
961
- var val = flag(this, 'object')
962
- , ssfi = flag(this, 'ssfi')
963
- , flagMsg = flag(this, 'message')
964
- , itemsCount;
988
+ var val = flag(this, 'object'),
989
+ ssfi = flag(this, 'ssfi'),
990
+ flagMsg = flag(this, 'message'),
991
+ itemsCount;
965
992
 
966
993
  flagMsg = flagMsg ? flagMsg + ': ' : '';
967
994
 
@@ -996,9 +1023,9 @@ Assertion.addProperty('empty', function () {
996
1023
  }
997
1024
 
998
1025
  this.assert(
999
- 0 === itemsCount
1000
- , 'expected #{this} to be empty'
1001
- , 'expected #{this} not to be empty'
1026
+ 0 === itemsCount,
1027
+ 'expected #{this} to be empty',
1028
+ 'expected #{this} not to be empty'
1002
1029
  );
1003
1030
  });
1004
1031
 
@@ -1031,13 +1058,13 @@ Assertion.addProperty('empty', function () {
1031
1058
  * @namespace BDD
1032
1059
  * @public
1033
1060
  */
1034
- function checkArguments () {
1035
- var obj = flag(this, 'object')
1036
- , type = _.type(obj);
1061
+ function checkArguments() {
1062
+ var obj = flag(this, 'object'),
1063
+ type = _.type(obj);
1037
1064
  this.assert(
1038
- 'Arguments' === type
1039
- , 'expected #{this} to be arguments but got ' + type
1040
- , 'expected #{this} to not be arguments'
1065
+ 'Arguments' === type,
1066
+ 'expected #{this} to be arguments but got ' + type,
1067
+ 'expected #{this} to not be arguments'
1041
1068
  );
1042
1069
  }
1043
1070
 
@@ -1088,7 +1115,7 @@ Assertion.addProperty('Arguments', checkArguments);
1088
1115
  * @namespace BDD
1089
1116
  * @public
1090
1117
  */
1091
- function assertEqual (val, msg) {
1118
+ function assertEqual(val, msg) {
1092
1119
  if (msg) flag(this, 'message', msg);
1093
1120
  var obj = flag(this, 'object');
1094
1121
  if (flag(this, 'deep')) {
@@ -1098,12 +1125,12 @@ function assertEqual (val, msg) {
1098
1125
  flag(this, 'lockSsfi', prevLockSsfi);
1099
1126
  } else {
1100
1127
  this.assert(
1101
- val === obj
1102
- , 'expected #{this} to equal #{exp}'
1103
- , 'expected #{this} to not equal #{exp}'
1104
- , val
1105
- , this._obj
1106
- , true
1128
+ val === obj,
1129
+ 'expected #{this} to equal #{exp}',
1130
+ 'expected #{this} to not equal #{exp}',
1131
+ val,
1132
+ this._obj,
1133
+ true
1107
1134
  );
1108
1135
  }
1109
1136
  }
@@ -1156,12 +1183,12 @@ function assertEql(obj, msg) {
1156
1183
  if (msg) flag(this, 'message', msg);
1157
1184
  var eql = flag(this, 'eql');
1158
1185
  this.assert(
1159
- eql(obj, flag(this, 'object'))
1160
- , 'expected #{this} to deeply equal #{exp}'
1161
- , 'expected #{this} to not deeply equal #{exp}'
1162
- , obj
1163
- , this._obj
1164
- , true
1186
+ eql(obj, flag(this, 'object')),
1187
+ 'expected #{this} to deeply equal #{exp}',
1188
+ 'expected #{this} to not deeply equal #{exp}',
1189
+ obj,
1190
+ this._obj,
1191
+ true
1165
1192
  );
1166
1193
  }
1167
1194
 
@@ -1210,32 +1237,44 @@ Assertion.addMethod('eqls', assertEql);
1210
1237
  * @namespace BDD
1211
1238
  * @public
1212
1239
  */
1213
- function assertAbove (n, msg) {
1240
+ function assertAbove(n, msg) {
1214
1241
  if (msg) flag(this, 'message', msg);
1215
- var obj = flag(this, 'object')
1216
- , doLength = flag(this, 'doLength')
1217
- , flagMsg = flag(this, 'message')
1218
- , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1219
- , ssfi = flag(this, 'ssfi')
1220
- , objType = _.type(obj).toLowerCase()
1221
- , nType = _.type(n).toLowerCase();
1242
+ var obj = flag(this, 'object'),
1243
+ doLength = flag(this, 'doLength'),
1244
+ flagMsg = flag(this, 'message'),
1245
+ msgPrefix = flagMsg ? flagMsg + ': ' : '',
1246
+ ssfi = flag(this, 'ssfi'),
1247
+ objType = _.type(obj).toLowerCase(),
1248
+ nType = _.type(n).toLowerCase();
1222
1249
 
1223
1250
  if (doLength && objType !== 'map' && objType !== 'set') {
1224
1251
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1225
1252
  }
1226
1253
 
1227
- if (!doLength && (objType === 'date' && nType !== 'date')) {
1228
- throw new AssertionError(msgPrefix + 'the argument to above must be a date', undefined, ssfi);
1254
+ if (!doLength && objType === 'date' && nType !== 'date') {
1255
+ throw new AssertionError(
1256
+ msgPrefix + 'the argument to above must be a date',
1257
+ undefined,
1258
+ ssfi
1259
+ );
1229
1260
  } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
1230
- throw new AssertionError(msgPrefix + 'the argument to above must be a number', undefined, ssfi);
1231
- } else if (!doLength && (objType !== 'date' && !_.isNumeric(obj))) {
1232
- var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1233
- throw new AssertionError(msgPrefix + 'expected ' + printObj + ' to be a number or a date', undefined, ssfi);
1261
+ throw new AssertionError(
1262
+ msgPrefix + 'the argument to above must be a number',
1263
+ undefined,
1264
+ ssfi
1265
+ );
1266
+ } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) {
1267
+ var printObj = objType === 'string' ? "'" + obj + "'" : obj;
1268
+ throw new AssertionError(
1269
+ msgPrefix + 'expected ' + printObj + ' to be a number or a date',
1270
+ undefined,
1271
+ ssfi
1272
+ );
1234
1273
  }
1235
1274
 
1236
1275
  if (doLength) {
1237
- var descriptor = 'length'
1238
- , itemsCount;
1276
+ var descriptor = 'length',
1277
+ itemsCount;
1239
1278
  if (objType === 'map' || objType === 'set') {
1240
1279
  descriptor = 'size';
1241
1280
  itemsCount = obj.size;
@@ -1243,18 +1282,20 @@ function assertAbove (n, msg) {
1243
1282
  itemsCount = obj.length;
1244
1283
  }
1245
1284
  this.assert(
1246
- itemsCount > n
1247
- , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}'
1248
- , 'expected #{this} to not have a ' + descriptor + ' above #{exp}'
1249
- , n
1250
- , itemsCount
1285
+ itemsCount > n,
1286
+ 'expected #{this} to have a ' +
1287
+ descriptor +
1288
+ ' above #{exp} but got #{act}',
1289
+ 'expected #{this} to not have a ' + descriptor + ' above #{exp}',
1290
+ n,
1291
+ itemsCount
1251
1292
  );
1252
1293
  } else {
1253
1294
  this.assert(
1254
- obj > n
1255
- , 'expected #{this} to be above #{exp}'
1256
- , 'expected #{this} to be at most #{exp}'
1257
- , n
1295
+ obj > n,
1296
+ 'expected #{this} to be above #{exp}',
1297
+ 'expected #{this} to be at most #{exp}',
1298
+ n
1258
1299
  );
1259
1300
  }
1260
1301
  }
@@ -1306,29 +1347,30 @@ Assertion.addMethod('greaterThan', assertAbove);
1306
1347
  * @namespace BDD
1307
1348
  * @public
1308
1349
  */
1309
- function assertLeast (n, msg) {
1350
+ function assertLeast(n, msg) {
1310
1351
  if (msg) flag(this, 'message', msg);
1311
- var obj = flag(this, 'object')
1312
- , doLength = flag(this, 'doLength')
1313
- , flagMsg = flag(this, 'message')
1314
- , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1315
- , ssfi = flag(this, 'ssfi')
1316
- , objType = _.type(obj).toLowerCase()
1317
- , nType = _.type(n).toLowerCase()
1318
- , errorMessage
1319
- , shouldThrow = true;
1352
+ var obj = flag(this, 'object'),
1353
+ doLength = flag(this, 'doLength'),
1354
+ flagMsg = flag(this, 'message'),
1355
+ msgPrefix = flagMsg ? flagMsg + ': ' : '',
1356
+ ssfi = flag(this, 'ssfi'),
1357
+ objType = _.type(obj).toLowerCase(),
1358
+ nType = _.type(n).toLowerCase(),
1359
+ errorMessage,
1360
+ shouldThrow = true;
1320
1361
 
1321
1362
  if (doLength && objType !== 'map' && objType !== 'set') {
1322
1363
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1323
1364
  }
1324
1365
 
1325
- if (!doLength && (objType === 'date' && nType !== 'date')) {
1366
+ if (!doLength && objType === 'date' && nType !== 'date') {
1326
1367
  errorMessage = msgPrefix + 'the argument to least must be a date';
1327
1368
  } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
1328
1369
  errorMessage = msgPrefix + 'the argument to least must be a number';
1329
- } else if (!doLength && (objType !== 'date' && !_.isNumeric(obj))) {
1330
- var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1331
- errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1370
+ } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) {
1371
+ var printObj = objType === 'string' ? "'" + obj + "'" : obj;
1372
+ errorMessage =
1373
+ msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1332
1374
  } else {
1333
1375
  shouldThrow = false;
1334
1376
  }
@@ -1338,8 +1380,8 @@ function assertLeast (n, msg) {
1338
1380
  }
1339
1381
 
1340
1382
  if (doLength) {
1341
- var descriptor = 'length'
1342
- , itemsCount;
1383
+ var descriptor = 'length',
1384
+ itemsCount;
1343
1385
  if (objType === 'map' || objType === 'set') {
1344
1386
  descriptor = 'size';
1345
1387
  itemsCount = obj.size;
@@ -1347,18 +1389,20 @@ function assertLeast (n, msg) {
1347
1389
  itemsCount = obj.length;
1348
1390
  }
1349
1391
  this.assert(
1350
- itemsCount >= n
1351
- , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}'
1352
- , 'expected #{this} to have a ' + descriptor + ' below #{exp}'
1353
- , n
1354
- , itemsCount
1392
+ itemsCount >= n,
1393
+ 'expected #{this} to have a ' +
1394
+ descriptor +
1395
+ ' at least #{exp} but got #{act}',
1396
+ 'expected #{this} to have a ' + descriptor + ' below #{exp}',
1397
+ n,
1398
+ itemsCount
1355
1399
  );
1356
1400
  } else {
1357
1401
  this.assert(
1358
- obj >= n
1359
- , 'expected #{this} to be at least #{exp}'
1360
- , 'expected #{this} to be below #{exp}'
1361
- , n
1402
+ obj >= n,
1403
+ 'expected #{this} to be at least #{exp}',
1404
+ 'expected #{this} to be below #{exp}',
1405
+ n
1362
1406
  );
1363
1407
  }
1364
1408
  }
@@ -1409,29 +1453,30 @@ Assertion.addMethod('greaterThanOrEqual', assertLeast);
1409
1453
  * @namespace BDD
1410
1454
  * @public
1411
1455
  */
1412
- function assertBelow (n, msg) {
1456
+ function assertBelow(n, msg) {
1413
1457
  if (msg) flag(this, 'message', msg);
1414
- var obj = flag(this, 'object')
1415
- , doLength = flag(this, 'doLength')
1416
- , flagMsg = flag(this, 'message')
1417
- , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1418
- , ssfi = flag(this, 'ssfi')
1419
- , objType = _.type(obj).toLowerCase()
1420
- , nType = _.type(n).toLowerCase()
1421
- , errorMessage
1422
- , shouldThrow = true;
1458
+ var obj = flag(this, 'object'),
1459
+ doLength = flag(this, 'doLength'),
1460
+ flagMsg = flag(this, 'message'),
1461
+ msgPrefix = flagMsg ? flagMsg + ': ' : '',
1462
+ ssfi = flag(this, 'ssfi'),
1463
+ objType = _.type(obj).toLowerCase(),
1464
+ nType = _.type(n).toLowerCase(),
1465
+ errorMessage,
1466
+ shouldThrow = true;
1423
1467
 
1424
1468
  if (doLength && objType !== 'map' && objType !== 'set') {
1425
1469
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1426
1470
  }
1427
-
1428
- if (!doLength && (objType === 'date' && nType !== 'date')) {
1471
+
1472
+ if (!doLength && objType === 'date' && nType !== 'date') {
1429
1473
  errorMessage = msgPrefix + 'the argument to below must be a date';
1430
1474
  } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
1431
1475
  errorMessage = msgPrefix + 'the argument to below must be a number';
1432
- } else if (!doLength && (objType !== 'date' && !_.isNumeric(obj))) {
1433
- var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1434
- errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1476
+ } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) {
1477
+ var printObj = objType === 'string' ? "'" + obj + "'" : obj;
1478
+ errorMessage =
1479
+ msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1435
1480
  } else {
1436
1481
  shouldThrow = false;
1437
1482
  }
@@ -1441,8 +1486,8 @@ function assertBelow (n, msg) {
1441
1486
  }
1442
1487
 
1443
1488
  if (doLength) {
1444
- var descriptor = 'length'
1445
- , itemsCount;
1489
+ var descriptor = 'length',
1490
+ itemsCount;
1446
1491
  if (objType === 'map' || objType === 'set') {
1447
1492
  descriptor = 'size';
1448
1493
  itemsCount = obj.size;
@@ -1450,18 +1495,20 @@ function assertBelow (n, msg) {
1450
1495
  itemsCount = obj.length;
1451
1496
  }
1452
1497
  this.assert(
1453
- itemsCount < n
1454
- , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}'
1455
- , 'expected #{this} to not have a ' + descriptor + ' below #{exp}'
1456
- , n
1457
- , itemsCount
1498
+ itemsCount < n,
1499
+ 'expected #{this} to have a ' +
1500
+ descriptor +
1501
+ ' below #{exp} but got #{act}',
1502
+ 'expected #{this} to not have a ' + descriptor + ' below #{exp}',
1503
+ n,
1504
+ itemsCount
1458
1505
  );
1459
1506
  } else {
1460
1507
  this.assert(
1461
- obj < n
1462
- , 'expected #{this} to be below #{exp}'
1463
- , 'expected #{this} to be at least #{exp}'
1464
- , n
1508
+ obj < n,
1509
+ 'expected #{this} to be below #{exp}',
1510
+ 'expected #{this} to be at least #{exp}',
1511
+ n
1465
1512
  );
1466
1513
  }
1467
1514
  }
@@ -1513,29 +1560,30 @@ Assertion.addMethod('lessThan', assertBelow);
1513
1560
  * @namespace BDD
1514
1561
  * @public
1515
1562
  */
1516
- function assertMost (n, msg) {
1563
+ function assertMost(n, msg) {
1517
1564
  if (msg) flag(this, 'message', msg);
1518
- var obj = flag(this, 'object')
1519
- , doLength = flag(this, 'doLength')
1520
- , flagMsg = flag(this, 'message')
1521
- , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1522
- , ssfi = flag(this, 'ssfi')
1523
- , objType = _.type(obj).toLowerCase()
1524
- , nType = _.type(n).toLowerCase()
1525
- , errorMessage
1526
- , shouldThrow = true;
1565
+ var obj = flag(this, 'object'),
1566
+ doLength = flag(this, 'doLength'),
1567
+ flagMsg = flag(this, 'message'),
1568
+ msgPrefix = flagMsg ? flagMsg + ': ' : '',
1569
+ ssfi = flag(this, 'ssfi'),
1570
+ objType = _.type(obj).toLowerCase(),
1571
+ nType = _.type(n).toLowerCase(),
1572
+ errorMessage,
1573
+ shouldThrow = true;
1527
1574
 
1528
1575
  if (doLength && objType !== 'map' && objType !== 'set') {
1529
1576
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1530
1577
  }
1531
1578
 
1532
- if (!doLength && (objType === 'date' && nType !== 'date')) {
1579
+ if (!doLength && objType === 'date' && nType !== 'date') {
1533
1580
  errorMessage = msgPrefix + 'the argument to most must be a date';
1534
1581
  } else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
1535
1582
  errorMessage = msgPrefix + 'the argument to most must be a number';
1536
- } else if (!doLength && (objType !== 'date' && !_.isNumeric(obj))) {
1537
- var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1538
- errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1583
+ } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) {
1584
+ var printObj = objType === 'string' ? "'" + obj + "'" : obj;
1585
+ errorMessage =
1586
+ msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1539
1587
  } else {
1540
1588
  shouldThrow = false;
1541
1589
  }
@@ -1545,8 +1593,8 @@ function assertMost (n, msg) {
1545
1593
  }
1546
1594
 
1547
1595
  if (doLength) {
1548
- var descriptor = 'length'
1549
- , itemsCount;
1596
+ var descriptor = 'length',
1597
+ itemsCount;
1550
1598
  if (objType === 'map' || objType === 'set') {
1551
1599
  descriptor = 'size';
1552
1600
  itemsCount = obj.size;
@@ -1554,18 +1602,20 @@ function assertMost (n, msg) {
1554
1602
  itemsCount = obj.length;
1555
1603
  }
1556
1604
  this.assert(
1557
- itemsCount <= n
1558
- , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}'
1559
- , 'expected #{this} to have a ' + descriptor + ' above #{exp}'
1560
- , n
1561
- , itemsCount
1605
+ itemsCount <= n,
1606
+ 'expected #{this} to have a ' +
1607
+ descriptor +
1608
+ ' at most #{exp} but got #{act}',
1609
+ 'expected #{this} to have a ' + descriptor + ' above #{exp}',
1610
+ n,
1611
+ itemsCount
1562
1612
  );
1563
1613
  } else {
1564
1614
  this.assert(
1565
- obj <= n
1566
- , 'expected #{this} to be at most #{exp}'
1567
- , 'expected #{this} to be above #{exp}'
1568
- , n
1615
+ obj <= n,
1616
+ 'expected #{this} to be at most #{exp}',
1617
+ 'expected #{this} to be above #{exp}',
1618
+ n
1569
1619
  );
1570
1620
  }
1571
1621
  }
@@ -1618,17 +1668,18 @@ Assertion.addMethod('lessThanOrEqual', assertMost);
1618
1668
  */
1619
1669
  Assertion.addMethod('within', function (start, finish, msg) {
1620
1670
  if (msg) flag(this, 'message', msg);
1621
- var obj = flag(this, 'object')
1622
- , doLength = flag(this, 'doLength')
1623
- , flagMsg = flag(this, 'message')
1624
- , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '')
1625
- , ssfi = flag(this, 'ssfi')
1626
- , objType = _.type(obj).toLowerCase()
1627
- , startType = _.type(start).toLowerCase()
1628
- , finishType = _.type(finish).toLowerCase()
1629
- , errorMessage
1630
- , shouldThrow = true
1631
- , range = (startType === 'date' && finishType === 'date')
1671
+ var obj = flag(this, 'object'),
1672
+ doLength = flag(this, 'doLength'),
1673
+ flagMsg = flag(this, 'message'),
1674
+ msgPrefix = flagMsg ? flagMsg + ': ' : '',
1675
+ ssfi = flag(this, 'ssfi'),
1676
+ objType = _.type(obj).toLowerCase(),
1677
+ startType = _.type(start).toLowerCase(),
1678
+ finishType = _.type(finish).toLowerCase(),
1679
+ errorMessage,
1680
+ shouldThrow = true,
1681
+ range =
1682
+ startType === 'date' && finishType === 'date'
1632
1683
  ? start.toISOString() + '..' + finish.toISOString()
1633
1684
  : start + '..' + finish;
1634
1685
 
@@ -1636,13 +1687,21 @@ Assertion.addMethod('within', function (start, finish, msg) {
1636
1687
  new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
1637
1688
  }
1638
1689
 
1639
- if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) {
1690
+ if (
1691
+ !doLength &&
1692
+ objType === 'date' &&
1693
+ (startType !== 'date' || finishType !== 'date')
1694
+ ) {
1640
1695
  errorMessage = msgPrefix + 'the arguments to within must be dates';
1641
- } else if ((!_.isNumeric(start) || !_.isNumeric(finish)) && (doLength || _.isNumeric(obj))) {
1696
+ } else if (
1697
+ (!_.isNumeric(start) || !_.isNumeric(finish)) &&
1698
+ (doLength || _.isNumeric(obj))
1699
+ ) {
1642
1700
  errorMessage = msgPrefix + 'the arguments to within must be numbers';
1643
- } else if (!doLength && (objType !== 'date' && !_.isNumeric(obj))) {
1644
- var printObj = (objType === 'string') ? "'" + obj + "'" : obj;
1645
- errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1701
+ } else if (!doLength && objType !== 'date' && !_.isNumeric(obj)) {
1702
+ var printObj = objType === 'string' ? "'" + obj + "'" : obj;
1703
+ errorMessage =
1704
+ msgPrefix + 'expected ' + printObj + ' to be a number or a date';
1646
1705
  } else {
1647
1706
  shouldThrow = false;
1648
1707
  }
@@ -1652,8 +1711,8 @@ Assertion.addMethod('within', function (start, finish, msg) {
1652
1711
  }
1653
1712
 
1654
1713
  if (doLength) {
1655
- var descriptor = 'length'
1656
- , itemsCount;
1714
+ var descriptor = 'length',
1715
+ itemsCount;
1657
1716
  if (objType === 'map' || objType === 'set') {
1658
1717
  descriptor = 'size';
1659
1718
  itemsCount = obj.size;
@@ -1661,15 +1720,15 @@ Assertion.addMethod('within', function (start, finish, msg) {
1661
1720
  itemsCount = obj.length;
1662
1721
  }
1663
1722
  this.assert(
1664
- itemsCount >= start && itemsCount <= finish
1665
- , 'expected #{this} to have a ' + descriptor + ' within ' + range
1666
- , 'expected #{this} to not have a ' + descriptor + ' within ' + range
1723
+ itemsCount >= start && itemsCount <= finish,
1724
+ 'expected #{this} to have a ' + descriptor + ' within ' + range,
1725
+ 'expected #{this} to not have a ' + descriptor + ' within ' + range
1667
1726
  );
1668
1727
  } else {
1669
1728
  this.assert(
1670
- obj >= start && obj <= finish
1671
- , 'expected #{this} to be within ' + range
1672
- , 'expected #{this} to not be within ' + range
1729
+ obj >= start && obj <= finish,
1730
+ 'expected #{this} to be within ' + range,
1731
+ 'expected #{this} to not be within ' + range
1673
1732
  );
1674
1733
  }
1675
1734
  });
@@ -1712,10 +1771,10 @@ Assertion.addMethod('within', function (start, finish, msg) {
1712
1771
  * @namespace BDD
1713
1772
  * @public
1714
1773
  */
1715
- function assertInstanceOf (constructor, msg) {
1774
+ function assertInstanceOf(constructor, msg) {
1716
1775
  if (msg) flag(this, 'message', msg);
1717
1776
 
1718
- var target = flag(this, 'object')
1777
+ var target = flag(this, 'object');
1719
1778
  var ssfi = flag(this, 'ssfi');
1720
1779
  var flagMsg = flag(this, 'message');
1721
1780
 
@@ -1725,8 +1784,10 @@ function assertInstanceOf (constructor, msg) {
1725
1784
  if (err instanceof TypeError) {
1726
1785
  flagMsg = flagMsg ? flagMsg + ': ' : '';
1727
1786
  throw new AssertionError(
1728
- flagMsg + 'The instanceof assertion needs a constructor but '
1729
- + _.type(constructor) + ' was given.',
1787
+ flagMsg +
1788
+ 'The instanceof assertion needs a constructor but ' +
1789
+ _.type(constructor) +
1790
+ ' was given.',
1730
1791
  undefined,
1731
1792
  ssfi
1732
1793
  );
@@ -1740,11 +1801,11 @@ function assertInstanceOf (constructor, msg) {
1740
1801
  }
1741
1802
 
1742
1803
  this.assert(
1743
- isInstanceOf
1744
- , 'expected #{this} to be an instance of ' + name
1745
- , 'expected #{this} to not be an instance of ' + name
1804
+ isInstanceOf,
1805
+ 'expected #{this} to be an instance of ' + name,
1806
+ 'expected #{this} to not be an instance of ' + name
1746
1807
  );
1747
- };
1808
+ }
1748
1809
 
1749
1810
  Assertion.addMethod('instanceof', assertInstanceOf);
1750
1811
  Assertion.addMethod('instanceOf', assertInstanceOf);
@@ -1859,30 +1920,36 @@ Assertion.addMethod('instanceOf', assertInstanceOf);
1859
1920
  * @namespace BDD
1860
1921
  * @public
1861
1922
  */
1862
- function assertProperty (name, val, msg) {
1923
+ function assertProperty(name, val, msg) {
1863
1924
  if (msg) flag(this, 'message', msg);
1864
1925
 
1865
- var isNested = flag(this, 'nested')
1866
- , isOwn = flag(this, 'own')
1867
- , flagMsg = flag(this, 'message')
1868
- , obj = flag(this, 'object')
1869
- , ssfi = flag(this, 'ssfi')
1870
- , nameType = typeof name;
1926
+ var isNested = flag(this, 'nested'),
1927
+ isOwn = flag(this, 'own'),
1928
+ flagMsg = flag(this, 'message'),
1929
+ obj = flag(this, 'object'),
1930
+ ssfi = flag(this, 'ssfi'),
1931
+ nameType = typeof name;
1871
1932
 
1872
1933
  flagMsg = flagMsg ? flagMsg + ': ' : '';
1873
1934
 
1874
1935
  if (isNested) {
1875
1936
  if (nameType !== 'string') {
1876
1937
  throw new AssertionError(
1877
- flagMsg + 'the argument to property must be a string when using nested syntax',
1938
+ flagMsg +
1939
+ 'the argument to property must be a string when using nested syntax',
1878
1940
  undefined,
1879
1941
  ssfi
1880
1942
  );
1881
1943
  }
1882
1944
  } else {
1883
- if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') {
1945
+ if (
1946
+ nameType !== 'string' &&
1947
+ nameType !== 'number' &&
1948
+ nameType !== 'symbol'
1949
+ ) {
1884
1950
  throw new AssertionError(
1885
- flagMsg + 'the argument to property must be a string, number, or symbol',
1951
+ flagMsg +
1952
+ 'the argument to property must be a string, number, or symbol',
1886
1953
  undefined,
1887
1954
  ssfi
1888
1955
  );
@@ -1905,11 +1972,11 @@ function assertProperty (name, val, msg) {
1905
1972
  );
1906
1973
  }
1907
1974
 
1908
- var isDeep = flag(this, 'deep')
1909
- , negate = flag(this, 'negate')
1910
- , pathInfo = isNested ? _.getPathInfo(obj, name) : null
1911
- , value = isNested ? pathInfo.value : obj[name]
1912
- , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;
1975
+ var isDeep = flag(this, 'deep'),
1976
+ negate = flag(this, 'negate'),
1977
+ pathInfo = isNested ? _.getPathInfo(obj, name) : null,
1978
+ value = isNested ? pathInfo.value : obj[name],
1979
+ isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;
1913
1980
 
1914
1981
  var descriptor = '';
1915
1982
  if (isDeep) descriptor += 'deep ';
@@ -1929,18 +1996,25 @@ function assertProperty (name, val, msg) {
1929
1996
  // favor of the next.
1930
1997
  if (!negate || arguments.length === 1) {
1931
1998
  this.assert(
1932
- hasProperty
1933
- , 'expected #{this} to have ' + descriptor + _.inspect(name)
1934
- , 'expected #{this} to not have ' + descriptor + _.inspect(name));
1999
+ hasProperty,
2000
+ 'expected #{this} to have ' + descriptor + _.inspect(name),
2001
+ 'expected #{this} to not have ' + descriptor + _.inspect(name)
2002
+ );
1935
2003
  }
1936
2004
 
1937
2005
  if (arguments.length > 1) {
1938
2006
  this.assert(
1939
- hasProperty && isEql(val, value)
1940
- , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
1941
- , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}'
1942
- , val
1943
- , value
2007
+ hasProperty && isEql(val, value),
2008
+ 'expected #{this} to have ' +
2009
+ descriptor +
2010
+ _.inspect(name) +
2011
+ ' of #{exp}, but got #{act}',
2012
+ 'expected #{this} to not have ' +
2013
+ descriptor +
2014
+ _.inspect(name) +
2015
+ ' of #{act}',
2016
+ val,
2017
+ value
1944
2018
  );
1945
2019
  }
1946
2020
 
@@ -1951,11 +2025,11 @@ Assertion.addMethod('property', assertProperty);
1951
2025
 
1952
2026
  /**
1953
2027
  *
1954
- * @param {unknown} name
1955
- * @param {unknown} value
1956
- * @param {string} msg
2028
+ * @param {unknown} _name
2029
+ * @param {unknown} _value
2030
+ * @param {string} _msg
1957
2031
  */
1958
- function assertOwnProperty (name, value, msg) {
2032
+ function assertOwnProperty(_name, _value, _msg) {
1959
2033
  flag(this, 'own', true);
1960
2034
  assertProperty.apply(this, arguments);
1961
2035
  }
@@ -2081,7 +2155,7 @@ Assertion.addMethod('haveOwnProperty', assertOwnProperty);
2081
2155
  * @namespace BDD
2082
2156
  * @public
2083
2157
  */
2084
- function assertOwnPropertyDescriptor (name, descriptor, msg) {
2158
+ function assertOwnPropertyDescriptor(name, descriptor, msg) {
2085
2159
  if (typeof descriptor === 'string') {
2086
2160
  msg = descriptor;
2087
2161
  descriptor = null;
@@ -2092,18 +2166,28 @@ function assertOwnPropertyDescriptor (name, descriptor, msg) {
2092
2166
  var eql = flag(this, 'eql');
2093
2167
  if (actualDescriptor && descriptor) {
2094
2168
  this.assert(
2095
- eql(descriptor, actualDescriptor)
2096
- , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)
2097
- , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)
2098
- , descriptor
2099
- , actualDescriptor
2100
- , true
2169
+ eql(descriptor, actualDescriptor),
2170
+ 'expected the own property descriptor for ' +
2171
+ _.inspect(name) +
2172
+ ' on #{this} to match ' +
2173
+ _.inspect(descriptor) +
2174
+ ', got ' +
2175
+ _.inspect(actualDescriptor),
2176
+ 'expected the own property descriptor for ' +
2177
+ _.inspect(name) +
2178
+ ' on #{this} to not match ' +
2179
+ _.inspect(descriptor),
2180
+ descriptor,
2181
+ actualDescriptor,
2182
+ true
2101
2183
  );
2102
2184
  } else {
2103
2185
  this.assert(
2104
- actualDescriptor
2105
- , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)
2106
- , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)
2186
+ actualDescriptor,
2187
+ 'expected #{this} to have an own property descriptor for ' +
2188
+ _.inspect(name),
2189
+ 'expected #{this} to not have an own property descriptor for ' +
2190
+ _.inspect(name)
2107
2191
  );
2108
2192
  }
2109
2193
  flag(this, 'object', actualDescriptor);
@@ -2115,7 +2199,7 @@ Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
2115
2199
  /**
2116
2200
  *
2117
2201
  */
2118
- function assertLengthChain () {
2202
+ function assertLengthChain() {
2119
2203
  flag(this, 'doLength', true);
2120
2204
  }
2121
2205
 
@@ -2176,14 +2260,14 @@ function assertLengthChain () {
2176
2260
  * @namespace BDD
2177
2261
  * @public
2178
2262
  */
2179
- function assertLength (n, msg) {
2263
+ function assertLength(n, msg) {
2180
2264
  if (msg) flag(this, 'message', msg);
2181
- var obj = flag(this, 'object')
2182
- , objType = _.type(obj).toLowerCase()
2183
- , flagMsg = flag(this, 'message')
2184
- , ssfi = flag(this, 'ssfi')
2185
- , descriptor = 'length'
2186
- , itemsCount;
2265
+ var obj = flag(this, 'object'),
2266
+ objType = _.type(obj).toLowerCase(),
2267
+ flagMsg = flag(this, 'message'),
2268
+ ssfi = flag(this, 'ssfi'),
2269
+ descriptor = 'length',
2270
+ itemsCount;
2187
2271
 
2188
2272
  switch (objType) {
2189
2273
  case 'map':
@@ -2197,11 +2281,11 @@ function assertLength (n, msg) {
2197
2281
  }
2198
2282
 
2199
2283
  this.assert(
2200
- itemsCount == n
2201
- , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}'
2202
- , 'expected #{this} to not have a ' + descriptor + ' of #{act}'
2203
- , n
2204
- , itemsCount
2284
+ itemsCount == n,
2285
+ 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}',
2286
+ 'expected #{this} to not have a ' + descriptor + ' of #{act}',
2287
+ n,
2288
+ itemsCount
2205
2289
  );
2206
2290
  }
2207
2291
 
@@ -2239,9 +2323,9 @@ function assertMatch(re, msg) {
2239
2323
  if (msg) flag(this, 'message', msg);
2240
2324
  var obj = flag(this, 'object');
2241
2325
  this.assert(
2242
- re.exec(obj)
2243
- , 'expected #{this} to match ' + re
2244
- , 'expected #{this} not to match ' + re
2326
+ re.exec(obj),
2327
+ 'expected #{this} to match ' + re,
2328
+ 'expected #{this} not to match ' + re
2245
2329
  );
2246
2330
  }
2247
2331
 
@@ -2274,15 +2358,15 @@ Assertion.addMethod('matches', assertMatch);
2274
2358
  */
2275
2359
  Assertion.addMethod('string', function (str, msg) {
2276
2360
  if (msg) flag(this, 'message', msg);
2277
- var obj = flag(this, 'object')
2278
- , flagMsg = flag(this, 'message')
2279
- , ssfi = flag(this, 'ssfi');
2361
+ var obj = flag(this, 'object'),
2362
+ flagMsg = flag(this, 'message'),
2363
+ ssfi = flag(this, 'ssfi');
2280
2364
  new Assertion(obj, flagMsg, ssfi, true).is.a('string');
2281
2365
 
2282
2366
  this.assert(
2283
- ~obj.indexOf(str)
2284
- , 'expected #{this} to contain ' + _.inspect(str)
2285
- , 'expected #{this} to not contain ' + _.inspect(str)
2367
+ ~obj.indexOf(str),
2368
+ 'expected #{this} to contain ' + _.inspect(str),
2369
+ 'expected #{this} to not contain ' + _.inspect(str)
2286
2370
  );
2287
2371
  });
2288
2372
 
@@ -2389,27 +2473,31 @@ Assertion.addMethod('string', function (str, msg) {
2389
2473
  * @namespace BDD
2390
2474
  * @public
2391
2475
  */
2392
- function assertKeys (keys) {
2393
- var obj = flag(this, 'object')
2394
- , objType = _.type(obj)
2395
- , keysType = _.type(keys)
2396
- , ssfi = flag(this, 'ssfi')
2397
- , isDeep = flag(this, 'deep')
2398
- , str
2399
- , deepStr = ''
2400
- , actual
2401
- , ok = true
2402
- , flagMsg = flag(this, 'message');
2476
+ function assertKeys(keys) {
2477
+ var obj = flag(this, 'object'),
2478
+ objType = _.type(obj),
2479
+ keysType = _.type(keys),
2480
+ ssfi = flag(this, 'ssfi'),
2481
+ isDeep = flag(this, 'deep'),
2482
+ str,
2483
+ deepStr = '',
2484
+ actual,
2485
+ ok = true,
2486
+ flagMsg = flag(this, 'message');
2403
2487
 
2404
2488
  flagMsg = flagMsg ? flagMsg + ': ' : '';
2405
- var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments';
2489
+ var mixedArgsMsg =
2490
+ flagMsg +
2491
+ 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments';
2406
2492
 
2407
2493
  if (objType === 'Map' || objType === 'Set') {
2408
2494
  deepStr = isDeep ? 'deeply ' : '';
2409
2495
  actual = [];
2410
2496
 
2411
2497
  // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach.
2412
- obj.forEach(function (val, key) { actual.push(key) });
2498
+ obj.forEach(function (val, key) {
2499
+ actual.push(key);
2500
+ });
2413
2501
 
2414
2502
  if (keysType !== 'Array') {
2415
2503
  keys = Array.prototype.slice.call(arguments);
@@ -2443,11 +2531,11 @@ function assertKeys (keys) {
2443
2531
  throw new AssertionError(flagMsg + 'keys required', undefined, ssfi);
2444
2532
  }
2445
2533
 
2446
- var len = keys.length
2447
- , any = flag(this, 'any')
2448
- , all = flag(this, 'all')
2449
- , expected = keys
2450
- , isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;
2534
+ var len = keys.length,
2535
+ any = flag(this, 'any'),
2536
+ all = flag(this, 'all'),
2537
+ expected = keys,
2538
+ isEql = isDeep ? flag(this, 'eql') : (val1, val2) => val1 === val2;
2451
2539
 
2452
2540
  if (!any && !all) {
2453
2541
  all = true;
@@ -2455,8 +2543,8 @@ function assertKeys (keys) {
2455
2543
 
2456
2544
  // Has any
2457
2545
  if (any) {
2458
- ok = expected.some(function(expectedKey) {
2459
- return actual.some(function(actualKey) {
2546
+ ok = expected.some(function (expectedKey) {
2547
+ return actual.some(function (actualKey) {
2460
2548
  return isEql(expectedKey, actualKey);
2461
2549
  });
2462
2550
  });
@@ -2464,8 +2552,8 @@ function assertKeys (keys) {
2464
2552
 
2465
2553
  // Has all
2466
2554
  if (all) {
2467
- ok = expected.every(function(expectedKey) {
2468
- return actual.some(function(actualKey) {
2555
+ ok = expected.every(function (expectedKey) {
2556
+ return actual.some(function (actualKey) {
2469
2557
  return isEql(expectedKey, actualKey);
2470
2558
  });
2471
2559
  });
@@ -2477,7 +2565,7 @@ function assertKeys (keys) {
2477
2565
 
2478
2566
  // Key string
2479
2567
  if (len > 1) {
2480
- keys = keys.map(function(key) {
2568
+ keys = keys.map(function (key) {
2481
2569
  return _.inspect(key);
2482
2570
  });
2483
2571
  var last = keys.pop();
@@ -2499,12 +2587,12 @@ function assertKeys (keys) {
2499
2587
 
2500
2588
  // Assertion
2501
2589
  this.assert(
2502
- ok
2503
- , 'expected #{this} to ' + deepStr + str
2504
- , 'expected #{this} to not ' + deepStr + str
2505
- , expected.slice(0).sort(_.compareByInspect)
2506
- , actual.sort(_.compareByInspect)
2507
- , true
2590
+ ok,
2591
+ 'expected #{this} to ' + deepStr + str,
2592
+ 'expected #{this} to not ' + deepStr + str,
2593
+ expected.slice(0).sort(_.compareByInspect),
2594
+ actual.sort(_.compareByInspect),
2595
+ true
2508
2596
  );
2509
2597
  }
2510
2598
 
@@ -2670,12 +2758,12 @@ Assertion.addMethod('key', assertKeys);
2670
2758
  * @namespace BDD
2671
2759
  * @public
2672
2760
  */
2673
- function assertThrows (errorLike, errMsgMatcher, msg) {
2761
+ function assertThrows(errorLike, errMsgMatcher, msg) {
2674
2762
  if (msg) flag(this, 'message', msg);
2675
- var obj = flag(this, 'object')
2676
- , ssfi = flag(this, 'ssfi')
2677
- , flagMsg = flag(this, 'message')
2678
- , negate = flag(this, 'negate') || false;
2763
+ var obj = flag(this, 'object'),
2764
+ ssfi = flag(this, 'ssfi'),
2765
+ flagMsg = flag(this, 'message'),
2766
+ negate = flag(this, 'negate') || false;
2679
2767
  new Assertion(obj, flagMsg, ssfi, true).is.a('function');
2680
2768
 
2681
2769
  if (_.isRegExp(errorLike) || typeof errorLike === 'string') {
@@ -2694,7 +2782,8 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2694
2782
 
2695
2783
  // If we have the negate flag enabled and at least one valid argument it means we do expect an error
2696
2784
  // but we want it to match a given set of criteria
2697
- var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined;
2785
+ var everyArgIsUndefined =
2786
+ errorLike === undefined && errMsgMatcher === undefined;
2698
2787
 
2699
2788
  // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible
2700
2789
  // See Issue #551 and PR #683@GitHub
@@ -2703,7 +2792,7 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2703
2792
  var errMsgMatcherFail = false;
2704
2793
 
2705
2794
  // Checking if error was thrown
2706
- if (everyArgIsUndefined || !everyArgIsUndefined && !negate) {
2795
+ if (everyArgIsUndefined || (!everyArgIsUndefined && !negate)) {
2707
2796
  // We need this to display results correctly according to their types
2708
2797
  var errorLikeString = 'an error';
2709
2798
  if (errorLike instanceof Error) {
@@ -2717,7 +2806,10 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2717
2806
  actual = caughtErr.toString();
2718
2807
  } else if (typeof caughtErr === 'string') {
2719
2808
  actual = caughtErr;
2720
- } else if (caughtErr && (typeof caughtErr === 'object' || typeof caughtErr === 'function')) {
2809
+ } else if (
2810
+ caughtErr &&
2811
+ (typeof caughtErr === 'object' || typeof caughtErr === 'function')
2812
+ ) {
2721
2813
  try {
2722
2814
  actual = _.checkError.getConstructorName(caughtErr);
2723
2815
  } catch (_err) {
@@ -2727,18 +2819,21 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2727
2819
  }
2728
2820
 
2729
2821
  this.assert(
2730
- errorWasThrown
2731
- , 'expected #{this} to throw ' + errorLikeString
2732
- , 'expected #{this} to not throw an error but #{act} was thrown'
2733
- , errorLike && errorLike.toString()
2734
- , actual
2822
+ errorWasThrown,
2823
+ 'expected #{this} to throw ' + errorLikeString,
2824
+ 'expected #{this} to not throw an error but #{act} was thrown',
2825
+ errorLike && errorLike.toString(),
2826
+ actual
2735
2827
  );
2736
2828
  }
2737
2829
 
2738
2830
  if (errorLike && caughtErr) {
2739
2831
  // We should compare instances only if `errorLike` is an instance of `Error`
2740
2832
  if (errorLike instanceof Error) {
2741
- var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike);
2833
+ var isCompatibleInstance = _.checkError.compatibleInstance(
2834
+ caughtErr,
2835
+ errorLike
2836
+ );
2742
2837
 
2743
2838
  if (isCompatibleInstance === negate) {
2744
2839
  // These checks were created to ensure we won't fail too soon when we've got both args and a negate
@@ -2747,27 +2842,36 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2747
2842
  errorLikeFail = true;
2748
2843
  } else {
2749
2844
  this.assert(
2750
- negate
2751
- , 'expected #{this} to throw #{exp} but #{act} was thrown'
2752
- , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '')
2753
- , errorLike.toString()
2754
- , caughtErr.toString()
2845
+ negate,
2846
+ 'expected #{this} to throw #{exp} but #{act} was thrown',
2847
+ 'expected #{this} to not throw #{exp}' +
2848
+ (caughtErr && !negate ? ' but #{act} was thrown' : ''),
2849
+ errorLike.toString(),
2850
+ caughtErr.toString()
2755
2851
  );
2756
2852
  }
2757
2853
  }
2758
2854
  }
2759
2855
 
2760
- var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike);
2856
+ var isCompatibleConstructor = _.checkError.compatibleConstructor(
2857
+ caughtErr,
2858
+ errorLike
2859
+ );
2761
2860
  if (isCompatibleConstructor === negate) {
2762
2861
  if (everyArgIsDefined && negate) {
2763
- errorLikeFail = true;
2862
+ errorLikeFail = true;
2764
2863
  } else {
2765
2864
  this.assert(
2766
- negate
2767
- , 'expected #{this} to throw #{exp} but #{act} was thrown'
2768
- , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
2769
- , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
2770
- , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
2865
+ negate,
2866
+ 'expected #{this} to throw #{exp} but #{act} was thrown',
2867
+ 'expected #{this} to not throw #{exp}' +
2868
+ (caughtErr ? ' but #{act} was thrown' : ''),
2869
+ errorLike instanceof Error
2870
+ ? errorLike.toString()
2871
+ : errorLike && _.checkError.getConstructorName(errorLike),
2872
+ caughtErr instanceof Error
2873
+ ? caughtErr.toString()
2874
+ : caughtErr && _.checkError.getConstructorName(caughtErr)
2771
2875
  );
2772
2876
  }
2773
2877
  }
@@ -2777,20 +2881,25 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2777
2881
  // Here we check compatible messages
2778
2882
  var placeholder = 'including';
2779
2883
  if (_.isRegExp(errMsgMatcher)) {
2780
- placeholder = 'matching'
2884
+ placeholder = 'matching';
2781
2885
  }
2782
2886
 
2783
- var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher);
2887
+ var isCompatibleMessage = _.checkError.compatibleMessage(
2888
+ caughtErr,
2889
+ errMsgMatcher
2890
+ );
2784
2891
  if (isCompatibleMessage === negate) {
2785
2892
  if (everyArgIsDefined && negate) {
2786
- errMsgMatcherFail = true;
2893
+ errMsgMatcherFail = true;
2787
2894
  } else {
2788
2895
  this.assert(
2789
- negate
2790
- , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}'
2791
- , 'expected #{this} to throw error not ' + placeholder + ' #{exp}'
2792
- , errMsgMatcher
2793
- , _.checkError.getMessage(caughtErr)
2896
+ negate,
2897
+ 'expected #{this} to throw error ' +
2898
+ placeholder +
2899
+ ' #{exp} but got #{act}',
2900
+ 'expected #{this} to throw error not ' + placeholder + ' #{exp}',
2901
+ errMsgMatcher,
2902
+ _.checkError.getMessage(caughtErr)
2794
2903
  );
2795
2904
  }
2796
2905
  }
@@ -2799,16 +2908,21 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
2799
2908
  // If both assertions failed and both should've matched we throw an error
2800
2909
  if (errorLikeFail && errMsgMatcherFail) {
2801
2910
  this.assert(
2802
- negate
2803
- , 'expected #{this} to throw #{exp} but #{act} was thrown'
2804
- , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '')
2805
- , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike))
2806
- , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr))
2911
+ negate,
2912
+ 'expected #{this} to throw #{exp} but #{act} was thrown',
2913
+ 'expected #{this} to not throw #{exp}' +
2914
+ (caughtErr ? ' but #{act} was thrown' : ''),
2915
+ errorLike instanceof Error
2916
+ ? errorLike.toString()
2917
+ : errorLike && _.checkError.getConstructorName(errorLike),
2918
+ caughtErr instanceof Error
2919
+ ? caughtErr.toString()
2920
+ : caughtErr && _.checkError.getConstructorName(caughtErr)
2807
2921
  );
2808
2922
  }
2809
2923
 
2810
2924
  flag(this, 'object', caughtErr);
2811
- };
2925
+ }
2812
2926
 
2813
2927
  Assertion.addMethod('throw', assertThrows);
2814
2928
  Assertion.addMethod('throws', assertThrows);
@@ -2878,18 +2992,19 @@ Assertion.addMethod('Throw', assertThrows);
2878
2992
  * @namespace BDD
2879
2993
  * @public
2880
2994
  */
2881
- function respondTo (method, msg) {
2995
+ function respondTo(method, msg) {
2882
2996
  if (msg) flag(this, 'message', msg);
2883
- var obj = flag(this, 'object')
2884
- , itself = flag(this, 'itself')
2885
- , context = ('function' === typeof obj && !itself)
2886
- ? obj.prototype[method]
2887
- : obj[method];
2997
+ var obj = flag(this, 'object'),
2998
+ itself = flag(this, 'itself'),
2999
+ context =
3000
+ 'function' === typeof obj && !itself
3001
+ ? obj.prototype[method]
3002
+ : obj[method];
2888
3003
 
2889
3004
  this.assert(
2890
- 'function' === typeof context
2891
- , 'expected #{this} to respond to ' + _.inspect(method)
2892
- , 'expected #{this} to not respond to ' + _.inspect(method)
3005
+ 'function' === typeof context,
3006
+ 'expected #{this} to respond to ' + _.inspect(method),
3007
+ 'expected #{this} to not respond to ' + _.inspect(method)
2893
3008
  );
2894
3009
  }
2895
3010
 
@@ -2956,16 +3071,16 @@ Assertion.addProperty('itself', function () {
2956
3071
  * @namespace BDD
2957
3072
  * @public
2958
3073
  */
2959
- function satisfy (matcher, msg) {
3074
+ function satisfy(matcher, msg) {
2960
3075
  if (msg) flag(this, 'message', msg);
2961
3076
  var obj = flag(this, 'object');
2962
3077
  var result = matcher(obj);
2963
3078
  this.assert(
2964
- result
2965
- , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
2966
- , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
2967
- , flag(this, 'negate') ? false : true
2968
- , result
3079
+ result,
3080
+ 'expected #{this} to satisfy ' + _.objDisplay(matcher),
3081
+ 'expected #{this} to not satisfy' + _.objDisplay(matcher),
3082
+ flag(this, 'negate') ? false : true,
3083
+ result
2969
3084
  );
2970
3085
  }
2971
3086
 
@@ -3011,24 +3126,38 @@ Assertion.addMethod('satisfies', satisfy);
3011
3126
  */
3012
3127
  function closeTo(expected, delta, msg) {
3013
3128
  if (msg) flag(this, 'message', msg);
3014
- var obj = flag(this, 'object')
3015
- , flagMsg = flag(this, 'message')
3016
- , ssfi = flag(this, 'ssfi');
3129
+ var obj = flag(this, 'object'),
3130
+ flagMsg = flag(this, 'message'),
3131
+ ssfi = flag(this, 'ssfi');
3017
3132
 
3018
3133
  new Assertion(obj, flagMsg, ssfi, true).is.numeric;
3019
- let message = 'A `delta` value is required for `closeTo`';
3020
- if (delta == undefined) throw new AssertionError(flagMsg ? `${flagMsg}: ${message}` : message, undefined, ssfi);
3134
+ let message = 'A `delta` value is required for `closeTo`';
3135
+ if (delta == undefined)
3136
+ throw new AssertionError(
3137
+ flagMsg ? `${flagMsg}: ${message}` : message,
3138
+ undefined,
3139
+ ssfi
3140
+ );
3021
3141
  new Assertion(delta, flagMsg, ssfi, true).is.numeric;
3022
- message = 'A `expected` value is required for `closeTo`';
3023
- if (expected == undefined) throw new AssertionError(flagMsg ? `${flagMsg}: ${message}` : message, undefined, ssfi);
3142
+ message = 'A `expected` value is required for `closeTo`';
3143
+ if (expected == undefined)
3144
+ throw new AssertionError(
3145
+ flagMsg ? `${flagMsg}: ${message}` : message,
3146
+ undefined,
3147
+ ssfi
3148
+ );
3024
3149
  new Assertion(expected, flagMsg, ssfi, true).is.numeric;
3025
3150
 
3026
- const abs = (x) => x < 0n ? -x : x;
3151
+ const abs = (x) => (x < 0n ? -x : x);
3152
+
3153
+ // Used to round floating point number precision arithmetics
3154
+ // See: https://stackoverflow.com/a/3644302
3155
+ const strip = (number) => parseFloat(parseFloat(number).toPrecision(12));
3027
3156
 
3028
3157
  this.assert(
3029
- abs(obj - expected) <= delta
3030
- , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
3031
- , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
3158
+ strip(abs(obj - expected)) <= delta,
3159
+ 'expected #{this} to be close to ' + expected + ' +/- ' + delta,
3160
+ 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
3032
3161
  );
3033
3162
  }
3034
3163
 
@@ -3051,7 +3180,7 @@ function isSubsetOf(_subset, _superset, cmp, contains, ordered) {
3051
3180
  superset = superset.slice();
3052
3181
  }
3053
3182
 
3054
- return subset.every(function(elem, idx) {
3183
+ return subset.every(function (elem, idx) {
3055
3184
  if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx];
3056
3185
 
3057
3186
  if (!cmp) {
@@ -3063,7 +3192,7 @@ function isSubsetOf(_subset, _superset, cmp, contains, ordered) {
3063
3192
  return true;
3064
3193
  }
3065
3194
 
3066
- return superset.some(function(elem2, matchIdx) {
3195
+ return superset.some(function (elem2, matchIdx) {
3067
3196
  if (!cmp(elem, elem2)) return false;
3068
3197
 
3069
3198
  // Remove match from superset so not counted twice if duplicate in subset.
@@ -3143,9 +3272,9 @@ function isSubsetOf(_subset, _superset, cmp, contains, ordered) {
3143
3272
  */
3144
3273
  Assertion.addMethod('members', function (subset, msg) {
3145
3274
  if (msg) flag(this, 'message', msg);
3146
- var obj = flag(this, 'object')
3147
- , flagMsg = flag(this, 'message')
3148
- , ssfi = flag(this, 'ssfi');
3275
+ var obj = flag(this, 'object'),
3276
+ flagMsg = flag(this, 'message'),
3277
+ ssfi = flag(this, 'ssfi');
3149
3278
 
3150
3279
  new Assertion(obj, flagMsg, ssfi, true).to.be.iterable;
3151
3280
  new Assertion(subset, flagMsg, ssfi, true).to.be.iterable;
@@ -3162,18 +3291,19 @@ Assertion.addMethod('members', function (subset, msg) {
3162
3291
  } else {
3163
3292
  subject = ordered ? 'ordered members' : 'members';
3164
3293
  failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
3165
- failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}';
3294
+ failNegateMsg =
3295
+ 'expected #{this} to not have the same ' + subject + ' as #{exp}';
3166
3296
  }
3167
3297
 
3168
3298
  var cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined;
3169
3299
 
3170
3300
  this.assert(
3171
- isSubsetOf(subset, obj, cmp, contains, ordered)
3172
- , failMsg
3173
- , failNegateMsg
3174
- , subset
3175
- , obj
3176
- , true
3301
+ isSubsetOf(subset, obj, cmp, contains, ordered),
3302
+ failMsg,
3303
+ failNegateMsg,
3304
+ subset,
3305
+ obj,
3306
+ true
3177
3307
  );
3178
3308
  });
3179
3309
 
@@ -3198,15 +3328,15 @@ Assertion.addMethod('members', function (subset, msg) {
3198
3328
  * @namespace BDD
3199
3329
  * @public
3200
3330
  */
3201
- Assertion.addProperty('iterable', function(msg) {
3331
+ Assertion.addProperty('iterable', function (msg) {
3202
3332
  if (msg) flag(this, 'message', msg);
3203
3333
  var obj = flag(this, 'object');
3204
3334
 
3205
3335
  this.assert(
3206
- obj != undefined && obj[Symbol.iterator]
3207
- , 'expected #{this} to be an iterable'
3208
- , 'expected #{this} to not be an iterable'
3209
- , obj
3336
+ obj != undefined && obj[Symbol.iterator],
3337
+ 'expected #{this} to be an iterable',
3338
+ 'expected #{this} to not be an iterable',
3339
+ obj
3210
3340
  );
3211
3341
  });
3212
3342
 
@@ -3247,40 +3377,44 @@ Assertion.addProperty('iterable', function(msg) {
3247
3377
  * @namespace BDD
3248
3378
  * @public
3249
3379
  */
3250
- function oneOf (list, msg) {
3380
+ function oneOf(list, msg) {
3251
3381
  if (msg) flag(this, 'message', msg);
3252
- var expected = flag(this, 'object')
3253
- , flagMsg = flag(this, 'message')
3254
- , ssfi = flag(this, 'ssfi')
3255
- , contains = flag(this, 'contains')
3256
- , isDeep = flag(this, 'deep')
3257
- , eql = flag(this, 'eql');
3382
+ var expected = flag(this, 'object'),
3383
+ flagMsg = flag(this, 'message'),
3384
+ ssfi = flag(this, 'ssfi'),
3385
+ contains = flag(this, 'contains'),
3386
+ isDeep = flag(this, 'deep'),
3387
+ eql = flag(this, 'eql');
3258
3388
  new Assertion(list, flagMsg, ssfi, true).to.be.an('array');
3259
3389
 
3260
3390
  if (contains) {
3261
3391
  this.assert(
3262
- list.some(function(possibility) { return expected.indexOf(possibility) > -1 })
3263
- , 'expected #{this} to contain one of #{exp}'
3264
- , 'expected #{this} to not contain one of #{exp}'
3265
- , list
3266
- , expected
3392
+ list.some(function (possibility) {
3393
+ return expected.indexOf(possibility) > -1;
3394
+ }),
3395
+ 'expected #{this} to contain one of #{exp}',
3396
+ 'expected #{this} to not contain one of #{exp}',
3397
+ list,
3398
+ expected
3267
3399
  );
3268
3400
  } else {
3269
3401
  if (isDeep) {
3270
3402
  this.assert(
3271
- list.some(function(possibility) { return eql(expected, possibility) })
3272
- , 'expected #{this} to deeply equal one of #{exp}'
3273
- , 'expected #{this} to deeply equal one of #{exp}'
3274
- , list
3275
- , expected
3403
+ list.some(function (possibility) {
3404
+ return eql(expected, possibility);
3405
+ }),
3406
+ 'expected #{this} to deeply equal one of #{exp}',
3407
+ 'expected #{this} to deeply equal one of #{exp}',
3408
+ list,
3409
+ expected
3276
3410
  );
3277
3411
  } else {
3278
3412
  this.assert(
3279
- list.indexOf(expected) > -1
3280
- , 'expected #{this} to be one of #{exp}'
3281
- , 'expected #{this} to not be one of #{exp}'
3282
- , list
3283
- , expected
3413
+ list.indexOf(expected) > -1,
3414
+ 'expected #{this} to be one of #{exp}',
3415
+ 'expected #{this} to not be one of #{exp}',
3416
+ list,
3417
+ expected
3284
3418
  );
3285
3419
  }
3286
3420
  }
@@ -3382,11 +3516,11 @@ Assertion.addMethod('oneOf', oneOf);
3382
3516
  * @namespace BDD
3383
3517
  * @public
3384
3518
  */
3385
- function assertChanges (subject, prop, msg) {
3519
+ function assertChanges(subject, prop, msg) {
3386
3520
  if (msg) flag(this, 'message', msg);
3387
- var fn = flag(this, 'object')
3388
- , flagMsg = flag(this, 'message')
3389
- , ssfi = flag(this, 'ssfi');
3521
+ var fn = flag(this, 'object'),
3522
+ flagMsg = flag(this, 'message'),
3523
+ ssfi = flag(this, 'ssfi');
3390
3524
  new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3391
3525
 
3392
3526
  var initial;
@@ -3411,9 +3545,9 @@ function assertChanges (subject, prop, msg) {
3411
3545
  flag(this, 'realDelta', final !== initial);
3412
3546
 
3413
3547
  this.assert(
3414
- initial !== final
3415
- , 'expected ' + msgObj + ' to change'
3416
- , 'expected ' + msgObj + ' to not change'
3548
+ initial !== final,
3549
+ 'expected ' + msgObj + ' to change',
3550
+ 'expected ' + msgObj + ' to not change'
3417
3551
  );
3418
3552
  }
3419
3553
 
@@ -3498,11 +3632,11 @@ Assertion.addMethod('changes', assertChanges);
3498
3632
  * @namespace BDD
3499
3633
  * @public
3500
3634
  */
3501
- function assertIncreases (subject, prop, msg) {
3635
+ function assertIncreases(subject, prop, msg) {
3502
3636
  if (msg) flag(this, 'message', msg);
3503
- var fn = flag(this, 'object')
3504
- , flagMsg = flag(this, 'message')
3505
- , ssfi = flag(this, 'ssfi');
3637
+ var fn = flag(this, 'object'),
3638
+ flagMsg = flag(this, 'message'),
3639
+ ssfi = flag(this, 'ssfi');
3506
3640
  new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3507
3641
 
3508
3642
  var initial;
@@ -3529,9 +3663,9 @@ function assertIncreases (subject, prop, msg) {
3529
3663
  flag(this, 'realDelta', final - initial);
3530
3664
 
3531
3665
  this.assert(
3532
- final - initial > 0
3533
- , 'expected ' + msgObj + ' to increase'
3534
- , 'expected ' + msgObj + ' to not increase'
3666
+ final - initial > 0,
3667
+ 'expected ' + msgObj + ' to increase',
3668
+ 'expected ' + msgObj + ' to not increase'
3535
3669
  );
3536
3670
  }
3537
3671
 
@@ -3616,11 +3750,11 @@ Assertion.addMethod('increases', assertIncreases);
3616
3750
  * @namespace BDD
3617
3751
  * @public
3618
3752
  */
3619
- function assertDecreases (subject, prop, msg) {
3753
+ function assertDecreases(subject, prop, msg) {
3620
3754
  if (msg) flag(this, 'message', msg);
3621
- var fn = flag(this, 'object')
3622
- , flagMsg = flag(this, 'message')
3623
- , ssfi = flag(this, 'ssfi');
3755
+ var fn = flag(this, 'object'),
3756
+ flagMsg = flag(this, 'message'),
3757
+ ssfi = flag(this, 'ssfi');
3624
3758
  new Assertion(fn, flagMsg, ssfi, true).is.a('function');
3625
3759
 
3626
3760
  var initial;
@@ -3647,9 +3781,9 @@ function assertDecreases (subject, prop, msg) {
3647
3781
  flag(this, 'realDelta', initial - final);
3648
3782
 
3649
3783
  this.assert(
3650
- final - initial < 0
3651
- , 'expected ' + msgObj + ' to decrease'
3652
- , 'expected ' + msgObj + ' to not decrease'
3784
+ final - initial < 0,
3785
+ 'expected ' + msgObj + ' to decrease',
3786
+ 'expected ' + msgObj + ' to not decrease'
3653
3787
  );
3654
3788
  }
3655
3789
 
@@ -3738,9 +3872,9 @@ function assertDelta(delta, msg) {
3738
3872
  }
3739
3873
 
3740
3874
  this.assert(
3741
- expression
3742
- , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta
3743
- , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
3875
+ expression,
3876
+ 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta,
3877
+ 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
3744
3878
  );
3745
3879
  }
3746
3880
 
@@ -3773,7 +3907,7 @@ Assertion.addMethod('by', assertDelta);
3773
3907
  * @namespace BDD
3774
3908
  * @public
3775
3909
  */
3776
- Assertion.addProperty('extensible', function() {
3910
+ Assertion.addProperty('extensible', function () {
3777
3911
  var obj = flag(this, 'object');
3778
3912
 
3779
3913
  // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
@@ -3784,9 +3918,9 @@ Assertion.addProperty('extensible', function() {
3784
3918
  var isExtensible = obj === Object(obj) && Object.isExtensible(obj);
3785
3919
 
3786
3920
  this.assert(
3787
- isExtensible
3788
- , 'expected #{this} to be extensible'
3789
- , 'expected #{this} to not be extensible'
3921
+ isExtensible,
3922
+ 'expected #{this} to be extensible',
3923
+ 'expected #{this} to not be extensible'
3790
3924
  );
3791
3925
  });
3792
3926
 
@@ -3817,7 +3951,7 @@ Assertion.addProperty('extensible', function() {
3817
3951
  * @namespace BDD
3818
3952
  * @public
3819
3953
  */
3820
- Assertion.addProperty('sealed', function() {
3954
+ Assertion.addProperty('sealed', function () {
3821
3955
  var obj = flag(this, 'object');
3822
3956
 
3823
3957
  // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
@@ -3828,9 +3962,9 @@ Assertion.addProperty('sealed', function() {
3828
3962
  var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true;
3829
3963
 
3830
3964
  this.assert(
3831
- isSealed
3832
- , 'expected #{this} to be sealed'
3833
- , 'expected #{this} to not be sealed'
3965
+ isSealed,
3966
+ 'expected #{this} to be sealed',
3967
+ 'expected #{this} to not be sealed'
3834
3968
  );
3835
3969
  });
3836
3970
 
@@ -3858,7 +3992,7 @@ Assertion.addProperty('sealed', function() {
3858
3992
  * @namespace BDD
3859
3993
  * @public
3860
3994
  */
3861
- Assertion.addProperty('frozen', function() {
3995
+ Assertion.addProperty('frozen', function () {
3862
3996
  var obj = flag(this, 'object');
3863
3997
 
3864
3998
  // In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
@@ -3869,9 +4003,9 @@ Assertion.addProperty('frozen', function() {
3869
4003
  var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true;
3870
4004
 
3871
4005
  this.assert(
3872
- isFrozen
3873
- , 'expected #{this} to be frozen'
3874
- , 'expected #{this} to not be frozen'
4006
+ isFrozen,
4007
+ 'expected #{this} to be frozen',
4008
+ 'expected #{this} to not be frozen'
3875
4009
  );
3876
4010
  });
3877
4011
 
@@ -3923,12 +4057,101 @@ Assertion.addProperty('frozen', function() {
3923
4057
  * @namespace BDD
3924
4058
  * @public
3925
4059
  */
3926
- Assertion.addProperty('finite', function(msg) {
4060
+ Assertion.addProperty('finite', function (_msg) {
3927
4061
  var obj = flag(this, 'object');
3928
4062
 
3929
4063
  this.assert(
3930
- typeof obj === 'number' && isFinite(obj)
3931
- , 'expected #{this} to be a finite number'
3932
- , 'expected #{this} to not be a finite number'
4064
+ typeof obj === 'number' && isFinite(obj),
4065
+ 'expected #{this} to be a finite number',
4066
+ 'expected #{this} to not be a finite number'
4067
+ );
4068
+ });
4069
+
4070
+ /**
4071
+ * A subset-aware compare function
4072
+ *
4073
+ * @param {unknown} expected
4074
+ * @param {unknown} actual
4075
+ * @returns {boolean}
4076
+ */
4077
+ function compareSubset(expected, actual) {
4078
+ if (expected === actual) {
4079
+ return true;
4080
+ }
4081
+ if (typeof actual !== typeof expected) {
4082
+ return false;
4083
+ }
4084
+ if (typeof expected !== 'object' || expected === null) {
4085
+ return expected === actual;
4086
+ }
4087
+ if (!actual) {
4088
+ return false;
4089
+ }
4090
+
4091
+ if (Array.isArray(expected)) {
4092
+ if (!Array.isArray(actual)) {
4093
+ return false;
4094
+ }
4095
+ return expected.every(function (exp) {
4096
+ return actual.some(function (act) {
4097
+ return compareSubset(exp, act);
4098
+ });
4099
+ });
4100
+ }
4101
+
4102
+ if (expected instanceof Date) {
4103
+ if (actual instanceof Date) {
4104
+ return expected.getTime() === actual.getTime();
4105
+ } else {
4106
+ return false;
4107
+ }
4108
+ }
4109
+
4110
+ return Object.keys(expected).every(function (key) {
4111
+ var expectedValue = expected[key];
4112
+ var actualValue = actual[key];
4113
+ if (
4114
+ typeof expectedValue === 'object' &&
4115
+ expectedValue !== null &&
4116
+ actualValue !== null
4117
+ ) {
4118
+ return compareSubset(expectedValue, actualValue);
4119
+ }
4120
+ if (typeof expectedValue === 'function') {
4121
+ return expectedValue(actualValue);
4122
+ }
4123
+ return actualValue === expectedValue;
4124
+ });
4125
+ }
4126
+
4127
+ /**
4128
+ * ### .containSubset
4129
+ *
4130
+ * Asserts that the target primitive/object/array structure deeply contains all provided fields
4131
+ * at the same key/depth as the provided structure.
4132
+ *
4133
+ * When comparing arrays, the target must contain the subset of at least one of each object/value in the subset array.
4134
+ * Order does not matter.
4135
+ *
4136
+ * expect({name: {first: "John", last: "Smith"}}).to.containSubset({name: {first: "John"}});
4137
+ *
4138
+ * Add `.not` earlier in the chain to negate the assertion. This will cause the assertion to fail
4139
+ * only if the target DOES contains the provided data at the expected keys/depths.
4140
+ *
4141
+ * @name containSubset
4142
+ * @namespace BDD
4143
+ * @public
4144
+ */
4145
+ Assertion.addMethod('containSubset', function (expected) {
4146
+ const actual = _.flag(this, 'object');
4147
+ const showDiff = config.showDiff;
4148
+
4149
+ this.assert(
4150
+ compareSubset(expected, actual),
4151
+ 'expected #{act} to contain subset #{exp}',
4152
+ 'expected #{act} to not contain subset #{exp}',
4153
+ expected,
4154
+ actual,
4155
+ showDiff
3933
4156
  );
3934
4157
  });