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.
- package/.prettierrc.json +10 -0
- package/chai.js +520 -220
- package/eslint.config.js +14 -0
- package/lib/chai/assertion.js +37 -21
- package/lib/chai/config.js +0 -2
- package/lib/chai/core/assertions.js +698 -475
- package/lib/chai/interface/assert.js +425 -248
- package/lib/chai/interface/expect.js +11 -7
- package/lib/chai/interface/should.js +26 -20
- package/lib/chai/utils/addChainableMethod.js +66 -67
- package/lib/chai/utils/addLengthGuard.js +18 -5
- package/lib/chai/utils/addMethod.js +1 -2
- package/lib/chai/utils/addProperty.js +27 -28
- package/lib/chai/utils/expectTypes.js +15 -7
- package/lib/chai/utils/getMessage.js +16 -10
- package/lib/chai/utils/index.js +8 -2
- package/lib/chai/utils/inspect.js +2 -2
- package/lib/chai/utils/isNaN.js +1 -20
- package/lib/chai/utils/isProxyEnabled.js +4 -2
- package/lib/chai/utils/objDisplay.js +7 -6
- package/lib/chai/utils/overwriteChainableMethod.js +10 -9
- package/lib/chai/utils/overwriteMethod.js +4 -5
- package/lib/chai/utils/overwriteProperty.js +38 -39
- package/lib/chai/utils/proxify.js +31 -21
- package/lib/chai/utils/test.js +2 -2
- package/lib/chai/utils/transferFlags.js +7 -2
- package/lib/chai/utils/type-detect.js +1 -1
- package/lib/chai.js +2 -1
- package/package.json +11 -5
- package/lib/chai/utils/getEnumerableProperties.js +0 -25
- package/register-assert.cjs +0 -3
- package/register-expect.cjs +0 -3
- package/register-should.cjs +0 -3
|
@@ -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
|
-
[
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
325
|
-
|
|
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
|
|
517
|
+
function include(val, msg) {
|
|
497
518
|
if (msg) flag(this, 'message', msg);
|
|
498
519
|
|
|
499
|
-
var obj = flag(this, 'object')
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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 +
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
-
|
|
575
|
-
|
|
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
|
-
|
|
612
|
-
|
|
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
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
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
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
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 = [
|
|
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
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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
|
-
|
|
833
|
-
|
|
834
|
-
|
|
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
|
-
|
|
863
|
-
|
|
864
|
-
|
|
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
|
-
|
|
904
|
-
|
|
905
|
-
|
|
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
|
-
|
|
963
|
-
|
|
964
|
-
|
|
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
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
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
|
-
|
|
1061
|
+
function checkArguments() {
|
|
1062
|
+
var obj = flag(this, 'object'),
|
|
1063
|
+
type = _.type(obj);
|
|
1037
1064
|
this.assert(
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
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
|
|
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
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
,
|
|
1105
|
-
|
|
1106
|
-
|
|
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
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
,
|
|
1163
|
-
|
|
1164
|
-
|
|
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
|
|
1240
|
+
function assertAbove(n, msg) {
|
|
1214
1241
|
if (msg) flag(this, 'message', msg);
|
|
1215
|
-
var obj = flag(this, 'object')
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
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 &&
|
|
1228
|
-
throw new AssertionError(
|
|
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(
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
,
|
|
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
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
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
|
|
1350
|
+
function assertLeast(n, msg) {
|
|
1310
1351
|
if (msg) flag(this, 'message', msg);
|
|
1311
|
-
var obj = flag(this, 'object')
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
,
|
|
1319
|
-
|
|
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 &&
|
|
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 &&
|
|
1330
|
-
var printObj =
|
|
1331
|
-
errorMessage =
|
|
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
|
-
|
|
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
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
,
|
|
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
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
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
|
|
1456
|
+
function assertBelow(n, msg) {
|
|
1413
1457
|
if (msg) flag(this, 'message', msg);
|
|
1414
|
-
var obj = flag(this, 'object')
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
,
|
|
1422
|
-
|
|
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 &&
|
|
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 &&
|
|
1433
|
-
var printObj =
|
|
1434
|
-
errorMessage =
|
|
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
|
-
|
|
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
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
,
|
|
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
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
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
|
|
1563
|
+
function assertMost(n, msg) {
|
|
1517
1564
|
if (msg) flag(this, 'message', msg);
|
|
1518
|
-
var obj = flag(this, 'object')
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
,
|
|
1526
|
-
|
|
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 &&
|
|
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 &&
|
|
1537
|
-
var printObj =
|
|
1538
|
-
errorMessage =
|
|
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
|
-
|
|
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
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
,
|
|
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
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
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
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
,
|
|
1630
|
-
|
|
1631
|
-
|
|
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 (
|
|
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 (
|
|
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 &&
|
|
1644
|
-
var printObj =
|
|
1645
|
-
errorMessage =
|
|
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
|
-
|
|
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
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
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
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
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
|
|
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 +
|
|
1729
|
-
|
|
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
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
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
|
|
1923
|
+
function assertProperty(name, val, msg) {
|
|
1863
1924
|
if (msg) flag(this, 'message', msg);
|
|
1864
1925
|
|
|
1865
|
-
var isNested = flag(this, 'nested')
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
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 +
|
|
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 (
|
|
1945
|
+
if (
|
|
1946
|
+
nameType !== 'string' &&
|
|
1947
|
+
nameType !== 'number' &&
|
|
1948
|
+
nameType !== 'symbol'
|
|
1949
|
+
) {
|
|
1884
1950
|
throw new AssertionError(
|
|
1885
|
-
flagMsg +
|
|
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
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
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
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
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
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
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}
|
|
1955
|
-
* @param {unknown}
|
|
1956
|
-
* @param {string}
|
|
2028
|
+
* @param {unknown} _name
|
|
2029
|
+
* @param {unknown} _value
|
|
2030
|
+
* @param {string} _msg
|
|
1957
2031
|
*/
|
|
1958
|
-
function assertOwnProperty
|
|
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
|
|
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
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
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
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
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
|
|
2263
|
+
function assertLength(n, msg) {
|
|
2180
2264
|
if (msg) flag(this, 'message', msg);
|
|
2181
|
-
var obj = flag(this, 'object')
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
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
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
,
|
|
2204
|
-
|
|
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
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
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
|
-
|
|
2279
|
-
|
|
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
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
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
|
|
2393
|
-
var obj = flag(this, 'object')
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
,
|
|
2399
|
-
|
|
2400
|
-
,
|
|
2401
|
-
|
|
2402
|
-
|
|
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 =
|
|
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) {
|
|
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
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
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
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
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
|
|
2761
|
+
function assertThrows(errorLike, errMsgMatcher, msg) {
|
|
2674
2762
|
if (msg) flag(this, 'message', msg);
|
|
2675
|
-
var obj = flag(this, 'object')
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
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 =
|
|
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 (
|
|
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
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
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(
|
|
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
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
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(
|
|
2856
|
+
var isCompatibleConstructor = _.checkError.compatibleConstructor(
|
|
2857
|
+
caughtErr,
|
|
2858
|
+
errorLike
|
|
2859
|
+
);
|
|
2761
2860
|
if (isCompatibleConstructor === negate) {
|
|
2762
2861
|
if (everyArgIsDefined && negate) {
|
|
2763
|
-
|
|
2862
|
+
errorLikeFail = true;
|
|
2764
2863
|
} else {
|
|
2765
2864
|
this.assert(
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
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(
|
|
2887
|
+
var isCompatibleMessage = _.checkError.compatibleMessage(
|
|
2888
|
+
caughtErr,
|
|
2889
|
+
errMsgMatcher
|
|
2890
|
+
);
|
|
2784
2891
|
if (isCompatibleMessage === negate) {
|
|
2785
2892
|
if (everyArgIsDefined && negate) {
|
|
2786
|
-
|
|
2893
|
+
errMsgMatcherFail = true;
|
|
2787
2894
|
} else {
|
|
2788
2895
|
this.assert(
|
|
2789
|
-
negate
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
,
|
|
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
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
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
|
|
2995
|
+
function respondTo(method, msg) {
|
|
2882
2996
|
if (msg) flag(this, 'message', msg);
|
|
2883
|
-
var obj = flag(this, 'object')
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
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
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
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
|
|
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
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
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
|
-
|
|
3016
|
-
|
|
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 =
|
|
3020
|
-
if (delta == undefined)
|
|
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 =
|
|
3023
|
-
if (expected == undefined)
|
|
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
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
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
|
-
|
|
3148
|
-
|
|
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 =
|
|
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
|
-
|
|
3172
|
-
,
|
|
3173
|
-
,
|
|
3174
|
-
,
|
|
3175
|
-
,
|
|
3176
|
-
|
|
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
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
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
|
|
3380
|
+
function oneOf(list, msg) {
|
|
3251
3381
|
if (msg) flag(this, 'message', msg);
|
|
3252
|
-
var expected = flag(this, 'object')
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
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) {
|
|
3263
|
-
|
|
3264
|
-
,
|
|
3265
|
-
,
|
|
3266
|
-
,
|
|
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) {
|
|
3272
|
-
|
|
3273
|
-
,
|
|
3274
|
-
,
|
|
3275
|
-
,
|
|
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
|
-
|
|
3281
|
-
|
|
3282
|
-
,
|
|
3283
|
-
|
|
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
|
|
3519
|
+
function assertChanges(subject, prop, msg) {
|
|
3386
3520
|
if (msg) flag(this, 'message', msg);
|
|
3387
|
-
var fn = flag(this, 'object')
|
|
3388
|
-
|
|
3389
|
-
|
|
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
|
-
|
|
3416
|
-
|
|
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
|
|
3635
|
+
function assertIncreases(subject, prop, msg) {
|
|
3502
3636
|
if (msg) flag(this, 'message', msg);
|
|
3503
|
-
var fn = flag(this, 'object')
|
|
3504
|
-
|
|
3505
|
-
|
|
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
|
-
|
|
3534
|
-
|
|
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
|
|
3753
|
+
function assertDecreases(subject, prop, msg) {
|
|
3620
3754
|
if (msg) flag(this, 'message', msg);
|
|
3621
|
-
var fn = flag(this, 'object')
|
|
3622
|
-
|
|
3623
|
-
|
|
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
|
-
|
|
3652
|
-
|
|
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
|
-
|
|
3743
|
-
|
|
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
|
-
|
|
3789
|
-
|
|
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
|
-
|
|
3833
|
-
|
|
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
|
-
|
|
3874
|
-
|
|
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(
|
|
4060
|
+
Assertion.addProperty('finite', function (_msg) {
|
|
3927
4061
|
var obj = flag(this, 'object');
|
|
3928
4062
|
|
|
3929
4063
|
this.assert(
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
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
|
});
|