chai 5.1.1 → 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 +575 -242
- 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 +716 -492
- package/lib/chai/interface/assert.js +463 -247
- 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 +13 -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
|
|
|
@@ -233,18 +249,22 @@ Assertion.addProperty('any', function () {
|
|
|
233
249
|
* @namespace BDD
|
|
234
250
|
* @public
|
|
235
251
|
*/
|
|
236
|
-
|
|
237
252
|
Assertion.addProperty('all', function () {
|
|
238
253
|
flag(this, 'all', true);
|
|
239
254
|
flag(this, 'any', false);
|
|
240
255
|
});
|
|
241
256
|
|
|
242
257
|
const functionTypes = {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
258
|
+
function: [
|
|
259
|
+
'function',
|
|
260
|
+
'asyncfunction',
|
|
261
|
+
'generatorfunction',
|
|
262
|
+
'asyncgeneratorfunction'
|
|
263
|
+
],
|
|
264
|
+
asyncfunction: ['asyncfunction', 'asyncgeneratorfunction'],
|
|
265
|
+
generatorfunction: ['generatorfunction', 'asyncgeneratorfunction'],
|
|
266
|
+
asyncgeneratorfunction: ['asyncgeneratorfunction']
|
|
267
|
+
};
|
|
248
268
|
|
|
249
269
|
/**
|
|
250
270
|
* ### .a(type[, msg])
|
|
@@ -305,25 +325,25 @@ const functionTypes = {
|
|
|
305
325
|
* @namespace BDD
|
|
306
326
|
* @public
|
|
307
327
|
*/
|
|
308
|
-
function an
|
|
328
|
+
function an(type, msg) {
|
|
309
329
|
if (msg) flag(this, 'message', msg);
|
|
310
330
|
type = type.toLowerCase();
|
|
311
|
-
var obj = flag(this, 'object')
|
|
312
|
-
|
|
331
|
+
var obj = flag(this, 'object'),
|
|
332
|
+
article = ~['a', 'e', 'i', 'o', 'u'].indexOf(type.charAt(0)) ? 'an ' : 'a ';
|
|
313
333
|
|
|
314
334
|
const detectedType = _.type(obj).toLowerCase();
|
|
315
335
|
|
|
316
336
|
if (functionTypes['function'].includes(type)) {
|
|
317
337
|
this.assert(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
338
|
+
functionTypes[type].includes(detectedType),
|
|
339
|
+
'expected #{this} to be ' + article + type,
|
|
340
|
+
'expected #{this} not to be ' + article + type
|
|
321
341
|
);
|
|
322
342
|
} else {
|
|
323
343
|
this.assert(
|
|
324
|
-
type === detectedType
|
|
325
|
-
|
|
326
|
-
|
|
344
|
+
type === detectedType,
|
|
345
|
+
'expected #{this} to be ' + article + type,
|
|
346
|
+
'expected #{this} not to be ' + article + type
|
|
327
347
|
);
|
|
328
348
|
}
|
|
329
349
|
}
|
|
@@ -344,7 +364,7 @@ function SameValueZero(a, b) {
|
|
|
344
364
|
/**
|
|
345
365
|
*
|
|
346
366
|
*/
|
|
347
|
-
function includeChainingBehavior
|
|
367
|
+
function includeChainingBehavior() {
|
|
348
368
|
flag(this, 'contains', true);
|
|
349
369
|
}
|
|
350
370
|
|
|
@@ -494,17 +514,17 @@ function includeChainingBehavior () {
|
|
|
494
514
|
* @namespace BDD
|
|
495
515
|
* @public
|
|
496
516
|
*/
|
|
497
|
-
function include
|
|
517
|
+
function include(val, msg) {
|
|
498
518
|
if (msg) flag(this, 'message', msg);
|
|
499
519
|
|
|
500
|
-
var obj = flag(this, 'object')
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
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;
|
|
508
528
|
|
|
509
529
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
510
530
|
|
|
@@ -547,7 +567,7 @@ function include (val, msg) {
|
|
|
547
567
|
if (isDeep) {
|
|
548
568
|
included = obj.some(function (item) {
|
|
549
569
|
return isEql(item, val);
|
|
550
|
-
})
|
|
570
|
+
});
|
|
551
571
|
} else {
|
|
552
572
|
included = obj.indexOf(val) !== -1;
|
|
553
573
|
}
|
|
@@ -559,21 +579,24 @@ function include (val, msg) {
|
|
|
559
579
|
// objects with a custom `@@toStringTag`.
|
|
560
580
|
if (val !== Object(val)) {
|
|
561
581
|
throw new AssertionError(
|
|
562
|
-
flagMsg +
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
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(),
|
|
569
592
|
undefined,
|
|
570
593
|
ssfi
|
|
571
594
|
);
|
|
572
595
|
}
|
|
573
596
|
|
|
574
|
-
var props = Object.keys(val)
|
|
575
|
-
|
|
576
|
-
|
|
597
|
+
var props = Object.keys(val),
|
|
598
|
+
firstErr = null,
|
|
599
|
+
numErrs = 0;
|
|
577
600
|
|
|
578
601
|
props.forEach(function (prop) {
|
|
579
602
|
var propAssertion = new Assertion(obj);
|
|
@@ -608,9 +631,10 @@ function include (val, msg) {
|
|
|
608
631
|
|
|
609
632
|
// Assert inclusion in collection or substring in a string.
|
|
610
633
|
this.assert(
|
|
611
|
-
included
|
|
612
|
-
|
|
613
|
-
|
|
634
|
+
included,
|
|
635
|
+
'expected #{this} to ' + descriptor + 'include ' + _.inspect(val),
|
|
636
|
+
'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)
|
|
637
|
+
);
|
|
614
638
|
}
|
|
615
639
|
|
|
616
640
|
Assertion.addChainableMethod('include', include, includeChainingBehavior);
|
|
@@ -655,9 +679,10 @@ Assertion.addChainableMethod('includes', include, includeChainingBehavior);
|
|
|
655
679
|
*/
|
|
656
680
|
Assertion.addProperty('ok', function () {
|
|
657
681
|
this.assert(
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
682
|
+
flag(this, 'object'),
|
|
683
|
+
'expected #{this} to be truthy',
|
|
684
|
+
'expected #{this} to be falsy'
|
|
685
|
+
);
|
|
661
686
|
});
|
|
662
687
|
|
|
663
688
|
/**
|
|
@@ -687,10 +712,21 @@ Assertion.addProperty('ok', function () {
|
|
|
687
712
|
*/
|
|
688
713
|
Assertion.addProperty('true', function () {
|
|
689
714
|
this.assert(
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
715
|
+
true === flag(this, 'object'),
|
|
716
|
+
'expected #{this} to be true',
|
|
717
|
+
'expected #{this} to be false',
|
|
718
|
+
flag(this, 'negate') ? false : true
|
|
719
|
+
);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
Assertion.addProperty('numeric', function () {
|
|
723
|
+
const object = flag(this, 'object');
|
|
724
|
+
|
|
725
|
+
this.assert(
|
|
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
|
|
694
730
|
);
|
|
695
731
|
});
|
|
696
732
|
|
|
@@ -710,24 +746,25 @@ Assertion.addProperty('true', function () {
|
|
|
710
746
|
* @public
|
|
711
747
|
*/
|
|
712
748
|
Assertion.addProperty('callable', function () {
|
|
713
|
-
const val = flag(this, 'object')
|
|
714
|
-
const ssfi = flag(this, 'ssfi')
|
|
715
|
-
const message = flag(this, 'message')
|
|
716
|
-
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}: ` : '';
|
|
717
753
|
const negate = flag(this, 'negate');
|
|
718
754
|
|
|
719
|
-
const assertionMessage = negate
|
|
720
|
-
`${msg}expected ${_.inspect(val)} not to be a callable function`
|
|
721
|
-
`${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`;
|
|
722
758
|
|
|
723
|
-
const isCallable = [
|
|
759
|
+
const isCallable = [
|
|
760
|
+
'Function',
|
|
761
|
+
'AsyncFunction',
|
|
762
|
+
'GeneratorFunction',
|
|
763
|
+
'AsyncGeneratorFunction'
|
|
764
|
+
].includes(_.type(val));
|
|
724
765
|
|
|
725
766
|
if ((isCallable && negate) || (!isCallable && !negate)) {
|
|
726
|
-
throw new AssertionError(
|
|
727
|
-
assertionMessage,
|
|
728
|
-
undefined,
|
|
729
|
-
ssfi
|
|
730
|
-
);
|
|
767
|
+
throw new AssertionError(assertionMessage, undefined, ssfi);
|
|
731
768
|
}
|
|
732
769
|
});
|
|
733
770
|
|
|
@@ -758,10 +795,10 @@ Assertion.addProperty('callable', function () {
|
|
|
758
795
|
*/
|
|
759
796
|
Assertion.addProperty('false', function () {
|
|
760
797
|
this.assert(
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
798
|
+
false === flag(this, 'object'),
|
|
799
|
+
'expected #{this} to be false',
|
|
800
|
+
'expected #{this} to be true',
|
|
801
|
+
flag(this, 'negate') ? true : false
|
|
765
802
|
);
|
|
766
803
|
});
|
|
767
804
|
|
|
@@ -789,9 +826,9 @@ Assertion.addProperty('false', function () {
|
|
|
789
826
|
*/
|
|
790
827
|
Assertion.addProperty('null', function () {
|
|
791
828
|
this.assert(
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
829
|
+
null === flag(this, 'object'),
|
|
830
|
+
'expected #{this} to be null',
|
|
831
|
+
'expected #{this} not to be null'
|
|
795
832
|
);
|
|
796
833
|
});
|
|
797
834
|
|
|
@@ -819,9 +856,9 @@ Assertion.addProperty('null', function () {
|
|
|
819
856
|
*/
|
|
820
857
|
Assertion.addProperty('undefined', function () {
|
|
821
858
|
this.assert(
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
859
|
+
undefined === flag(this, 'object'),
|
|
860
|
+
'expected #{this} to be undefined',
|
|
861
|
+
'expected #{this} not to be undefined'
|
|
825
862
|
);
|
|
826
863
|
});
|
|
827
864
|
|
|
@@ -849,9 +886,9 @@ Assertion.addProperty('undefined', function () {
|
|
|
849
886
|
*/
|
|
850
887
|
Assertion.addProperty('NaN', function () {
|
|
851
888
|
this.assert(
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
889
|
+
_.isNaN(flag(this, 'object')),
|
|
890
|
+
'expected #{this} to be NaN',
|
|
891
|
+
'expected #{this} not to be NaN'
|
|
855
892
|
);
|
|
856
893
|
});
|
|
857
894
|
|
|
@@ -887,12 +924,12 @@ Assertion.addProperty('NaN', function () {
|
|
|
887
924
|
* @namespace BDD
|
|
888
925
|
* @public
|
|
889
926
|
*/
|
|
890
|
-
function assertExist
|
|
927
|
+
function assertExist() {
|
|
891
928
|
var val = flag(this, 'object');
|
|
892
929
|
this.assert(
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
930
|
+
val !== null && val !== undefined,
|
|
931
|
+
'expected #{this} to exist',
|
|
932
|
+
'expected #{this} to not exist'
|
|
896
933
|
);
|
|
897
934
|
}
|
|
898
935
|
|
|
@@ -948,10 +985,10 @@ Assertion.addProperty('exists', assertExist);
|
|
|
948
985
|
* @public
|
|
949
986
|
*/
|
|
950
987
|
Assertion.addProperty('empty', function () {
|
|
951
|
-
var val = flag(this, 'object')
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
988
|
+
var val = flag(this, 'object'),
|
|
989
|
+
ssfi = flag(this, 'ssfi'),
|
|
990
|
+
flagMsg = flag(this, 'message'),
|
|
991
|
+
itemsCount;
|
|
955
992
|
|
|
956
993
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
957
994
|
|
|
@@ -986,9 +1023,9 @@ Assertion.addProperty('empty', function () {
|
|
|
986
1023
|
}
|
|
987
1024
|
|
|
988
1025
|
this.assert(
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1026
|
+
0 === itemsCount,
|
|
1027
|
+
'expected #{this} to be empty',
|
|
1028
|
+
'expected #{this} not to be empty'
|
|
992
1029
|
);
|
|
993
1030
|
});
|
|
994
1031
|
|
|
@@ -1021,13 +1058,13 @@ Assertion.addProperty('empty', function () {
|
|
|
1021
1058
|
* @namespace BDD
|
|
1022
1059
|
* @public
|
|
1023
1060
|
*/
|
|
1024
|
-
function checkArguments
|
|
1025
|
-
var obj = flag(this, 'object')
|
|
1026
|
-
|
|
1061
|
+
function checkArguments() {
|
|
1062
|
+
var obj = flag(this, 'object'),
|
|
1063
|
+
type = _.type(obj);
|
|
1027
1064
|
this.assert(
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1065
|
+
'Arguments' === type,
|
|
1066
|
+
'expected #{this} to be arguments but got ' + type,
|
|
1067
|
+
'expected #{this} to not be arguments'
|
|
1031
1068
|
);
|
|
1032
1069
|
}
|
|
1033
1070
|
|
|
@@ -1078,7 +1115,7 @@ Assertion.addProperty('Arguments', checkArguments);
|
|
|
1078
1115
|
* @namespace BDD
|
|
1079
1116
|
* @public
|
|
1080
1117
|
*/
|
|
1081
|
-
function assertEqual
|
|
1118
|
+
function assertEqual(val, msg) {
|
|
1082
1119
|
if (msg) flag(this, 'message', msg);
|
|
1083
1120
|
var obj = flag(this, 'object');
|
|
1084
1121
|
if (flag(this, 'deep')) {
|
|
@@ -1088,12 +1125,12 @@ function assertEqual (val, msg) {
|
|
|
1088
1125
|
flag(this, 'lockSsfi', prevLockSsfi);
|
|
1089
1126
|
} else {
|
|
1090
1127
|
this.assert(
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
,
|
|
1095
|
-
|
|
1096
|
-
|
|
1128
|
+
val === obj,
|
|
1129
|
+
'expected #{this} to equal #{exp}',
|
|
1130
|
+
'expected #{this} to not equal #{exp}',
|
|
1131
|
+
val,
|
|
1132
|
+
this._obj,
|
|
1133
|
+
true
|
|
1097
1134
|
);
|
|
1098
1135
|
}
|
|
1099
1136
|
}
|
|
@@ -1146,12 +1183,12 @@ function assertEql(obj, msg) {
|
|
|
1146
1183
|
if (msg) flag(this, 'message', msg);
|
|
1147
1184
|
var eql = flag(this, 'eql');
|
|
1148
1185
|
this.assert(
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
,
|
|
1153
|
-
|
|
1154
|
-
|
|
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
|
|
1155
1192
|
);
|
|
1156
1193
|
}
|
|
1157
1194
|
|
|
@@ -1200,40 +1237,44 @@ Assertion.addMethod('eqls', assertEql);
|
|
|
1200
1237
|
* @namespace BDD
|
|
1201
1238
|
* @public
|
|
1202
1239
|
*/
|
|
1203
|
-
function assertAbove
|
|
1240
|
+
function assertAbove(n, msg) {
|
|
1204
1241
|
if (msg) flag(this, 'message', msg);
|
|
1205
|
-
var obj = flag(this, 'object')
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
, errorMessage
|
|
1213
|
-
, shouldThrow = true;
|
|
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();
|
|
1214
1249
|
|
|
1215
1250
|
if (doLength && objType !== 'map' && objType !== 'set') {
|
|
1216
1251
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1217
1252
|
}
|
|
1218
1253
|
|
|
1219
|
-
if (!doLength &&
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
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
|
+
);
|
|
1260
|
+
} else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
|
|
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
|
+
);
|
|
1232
1273
|
}
|
|
1233
1274
|
|
|
1234
1275
|
if (doLength) {
|
|
1235
|
-
var descriptor = 'length'
|
|
1236
|
-
|
|
1276
|
+
var descriptor = 'length',
|
|
1277
|
+
itemsCount;
|
|
1237
1278
|
if (objType === 'map' || objType === 'set') {
|
|
1238
1279
|
descriptor = 'size';
|
|
1239
1280
|
itemsCount = obj.size;
|
|
@@ -1241,18 +1282,20 @@ function assertAbove (n, msg) {
|
|
|
1241
1282
|
itemsCount = obj.length;
|
|
1242
1283
|
}
|
|
1243
1284
|
this.assert(
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
,
|
|
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
|
|
1249
1292
|
);
|
|
1250
1293
|
} else {
|
|
1251
1294
|
this.assert(
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1295
|
+
obj > n,
|
|
1296
|
+
'expected #{this} to be above #{exp}',
|
|
1297
|
+
'expected #{this} to be at most #{exp}',
|
|
1298
|
+
n
|
|
1256
1299
|
);
|
|
1257
1300
|
}
|
|
1258
1301
|
}
|
|
@@ -1299,34 +1342,35 @@ Assertion.addMethod('greaterThan', assertAbove);
|
|
|
1299
1342
|
* @name least
|
|
1300
1343
|
* @alias gte
|
|
1301
1344
|
* @alias greaterThanOrEqual
|
|
1302
|
-
* @param {
|
|
1345
|
+
* @param {unknown} n
|
|
1303
1346
|
* @param {string} msg _optional_
|
|
1304
1347
|
* @namespace BDD
|
|
1305
1348
|
* @public
|
|
1306
1349
|
*/
|
|
1307
|
-
function assertLeast
|
|
1350
|
+
function assertLeast(n, msg) {
|
|
1308
1351
|
if (msg) flag(this, 'message', msg);
|
|
1309
|
-
var obj = flag(this, 'object')
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
,
|
|
1317
|
-
|
|
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;
|
|
1318
1361
|
|
|
1319
1362
|
if (doLength && objType !== 'map' && objType !== 'set') {
|
|
1320
1363
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1321
1364
|
}
|
|
1322
1365
|
|
|
1323
|
-
if (!doLength &&
|
|
1366
|
+
if (!doLength && objType === 'date' && nType !== 'date') {
|
|
1324
1367
|
errorMessage = msgPrefix + 'the argument to least must be a date';
|
|
1325
|
-
} else if (
|
|
1368
|
+
} else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
|
|
1326
1369
|
errorMessage = msgPrefix + 'the argument to least must be a number';
|
|
1327
|
-
} else if (!doLength &&
|
|
1328
|
-
var printObj =
|
|
1329
|
-
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';
|
|
1330
1374
|
} else {
|
|
1331
1375
|
shouldThrow = false;
|
|
1332
1376
|
}
|
|
@@ -1336,8 +1380,8 @@ function assertLeast (n, msg) {
|
|
|
1336
1380
|
}
|
|
1337
1381
|
|
|
1338
1382
|
if (doLength) {
|
|
1339
|
-
var descriptor = 'length'
|
|
1340
|
-
|
|
1383
|
+
var descriptor = 'length',
|
|
1384
|
+
itemsCount;
|
|
1341
1385
|
if (objType === 'map' || objType === 'set') {
|
|
1342
1386
|
descriptor = 'size';
|
|
1343
1387
|
itemsCount = obj.size;
|
|
@@ -1345,18 +1389,20 @@ function assertLeast (n, msg) {
|
|
|
1345
1389
|
itemsCount = obj.length;
|
|
1346
1390
|
}
|
|
1347
1391
|
this.assert(
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
,
|
|
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
|
|
1353
1399
|
);
|
|
1354
1400
|
} else {
|
|
1355
1401
|
this.assert(
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1402
|
+
obj >= n,
|
|
1403
|
+
'expected #{this} to be at least #{exp}',
|
|
1404
|
+
'expected #{this} to be below #{exp}',
|
|
1405
|
+
n
|
|
1360
1406
|
);
|
|
1361
1407
|
}
|
|
1362
1408
|
}
|
|
@@ -1402,34 +1448,35 @@ Assertion.addMethod('greaterThanOrEqual', assertLeast);
|
|
|
1402
1448
|
* @name below
|
|
1403
1449
|
* @alias lt
|
|
1404
1450
|
* @alias lessThan
|
|
1405
|
-
* @param {
|
|
1451
|
+
* @param {unknown} n
|
|
1406
1452
|
* @param {string} msg _optional_
|
|
1407
1453
|
* @namespace BDD
|
|
1408
1454
|
* @public
|
|
1409
1455
|
*/
|
|
1410
|
-
function assertBelow
|
|
1456
|
+
function assertBelow(n, msg) {
|
|
1411
1457
|
if (msg) flag(this, 'message', msg);
|
|
1412
|
-
var obj = flag(this, 'object')
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
,
|
|
1420
|
-
|
|
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;
|
|
1421
1467
|
|
|
1422
1468
|
if (doLength && objType !== 'map' && objType !== 'set') {
|
|
1423
1469
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1424
1470
|
}
|
|
1425
1471
|
|
|
1426
|
-
if (!doLength &&
|
|
1472
|
+
if (!doLength && objType === 'date' && nType !== 'date') {
|
|
1427
1473
|
errorMessage = msgPrefix + 'the argument to below must be a date';
|
|
1428
|
-
} else if (
|
|
1474
|
+
} else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
|
|
1429
1475
|
errorMessage = msgPrefix + 'the argument to below must be a number';
|
|
1430
|
-
} else if (!doLength &&
|
|
1431
|
-
var printObj =
|
|
1432
|
-
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';
|
|
1433
1480
|
} else {
|
|
1434
1481
|
shouldThrow = false;
|
|
1435
1482
|
}
|
|
@@ -1439,8 +1486,8 @@ function assertBelow (n, msg) {
|
|
|
1439
1486
|
}
|
|
1440
1487
|
|
|
1441
1488
|
if (doLength) {
|
|
1442
|
-
var descriptor = 'length'
|
|
1443
|
-
|
|
1489
|
+
var descriptor = 'length',
|
|
1490
|
+
itemsCount;
|
|
1444
1491
|
if (objType === 'map' || objType === 'set') {
|
|
1445
1492
|
descriptor = 'size';
|
|
1446
1493
|
itemsCount = obj.size;
|
|
@@ -1448,18 +1495,20 @@ function assertBelow (n, msg) {
|
|
|
1448
1495
|
itemsCount = obj.length;
|
|
1449
1496
|
}
|
|
1450
1497
|
this.assert(
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
,
|
|
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
|
|
1456
1505
|
);
|
|
1457
1506
|
} else {
|
|
1458
1507
|
this.assert(
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1508
|
+
obj < n,
|
|
1509
|
+
'expected #{this} to be below #{exp}',
|
|
1510
|
+
'expected #{this} to be at least #{exp}',
|
|
1511
|
+
n
|
|
1463
1512
|
);
|
|
1464
1513
|
}
|
|
1465
1514
|
}
|
|
@@ -1506,34 +1555,35 @@ Assertion.addMethod('lessThan', assertBelow);
|
|
|
1506
1555
|
* @name most
|
|
1507
1556
|
* @alias lte
|
|
1508
1557
|
* @alias lessThanOrEqual
|
|
1509
|
-
* @param {
|
|
1558
|
+
* @param {unknown} n
|
|
1510
1559
|
* @param {string} msg _optional_
|
|
1511
1560
|
* @namespace BDD
|
|
1512
1561
|
* @public
|
|
1513
1562
|
*/
|
|
1514
|
-
function assertMost
|
|
1563
|
+
function assertMost(n, msg) {
|
|
1515
1564
|
if (msg) flag(this, 'message', msg);
|
|
1516
|
-
var obj = flag(this, 'object')
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
,
|
|
1524
|
-
|
|
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;
|
|
1525
1574
|
|
|
1526
1575
|
if (doLength && objType !== 'map' && objType !== 'set') {
|
|
1527
1576
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1528
1577
|
}
|
|
1529
1578
|
|
|
1530
|
-
if (!doLength &&
|
|
1579
|
+
if (!doLength && objType === 'date' && nType !== 'date') {
|
|
1531
1580
|
errorMessage = msgPrefix + 'the argument to most must be a date';
|
|
1532
|
-
} else if (
|
|
1581
|
+
} else if (!_.isNumeric(n) && (doLength || _.isNumeric(obj))) {
|
|
1533
1582
|
errorMessage = msgPrefix + 'the argument to most must be a number';
|
|
1534
|
-
} else if (!doLength &&
|
|
1535
|
-
var printObj =
|
|
1536
|
-
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';
|
|
1537
1587
|
} else {
|
|
1538
1588
|
shouldThrow = false;
|
|
1539
1589
|
}
|
|
@@ -1543,8 +1593,8 @@ function assertMost (n, msg) {
|
|
|
1543
1593
|
}
|
|
1544
1594
|
|
|
1545
1595
|
if (doLength) {
|
|
1546
|
-
var descriptor = 'length'
|
|
1547
|
-
|
|
1596
|
+
var descriptor = 'length',
|
|
1597
|
+
itemsCount;
|
|
1548
1598
|
if (objType === 'map' || objType === 'set') {
|
|
1549
1599
|
descriptor = 'size';
|
|
1550
1600
|
itemsCount = obj.size;
|
|
@@ -1552,18 +1602,20 @@ function assertMost (n, msg) {
|
|
|
1552
1602
|
itemsCount = obj.length;
|
|
1553
1603
|
}
|
|
1554
1604
|
this.assert(
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
,
|
|
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
|
|
1560
1612
|
);
|
|
1561
1613
|
} else {
|
|
1562
1614
|
this.assert(
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1615
|
+
obj <= n,
|
|
1616
|
+
'expected #{this} to be at most #{exp}',
|
|
1617
|
+
'expected #{this} to be above #{exp}',
|
|
1618
|
+
n
|
|
1567
1619
|
);
|
|
1568
1620
|
}
|
|
1569
1621
|
}
|
|
@@ -1608,25 +1660,26 @@ Assertion.addMethod('lessThanOrEqual', assertMost);
|
|
|
1608
1660
|
* expect(4, 'nooo why fail??').to.be.within(1, 3);
|
|
1609
1661
|
*
|
|
1610
1662
|
* @name within
|
|
1611
|
-
* @param {
|
|
1612
|
-
* @param {
|
|
1663
|
+
* @param {unknown} start lower bound inclusive
|
|
1664
|
+
* @param {unknown} finish upper bound inclusive
|
|
1613
1665
|
* @param {string} msg _optional_
|
|
1614
1666
|
* @namespace BDD
|
|
1615
1667
|
* @public
|
|
1616
1668
|
*/
|
|
1617
1669
|
Assertion.addMethod('within', function (start, finish, msg) {
|
|
1618
1670
|
if (msg) flag(this, 'message', msg);
|
|
1619
|
-
var obj = flag(this, 'object')
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
,
|
|
1628
|
-
|
|
1629
|
-
|
|
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'
|
|
1630
1683
|
? start.toISOString() + '..' + finish.toISOString()
|
|
1631
1684
|
: start + '..' + finish;
|
|
1632
1685
|
|
|
@@ -1634,13 +1687,21 @@ Assertion.addMethod('within', function (start, finish, msg) {
|
|
|
1634
1687
|
new Assertion(obj, flagMsg, ssfi, true).to.have.property('length');
|
|
1635
1688
|
}
|
|
1636
1689
|
|
|
1637
|
-
if (
|
|
1690
|
+
if (
|
|
1691
|
+
!doLength &&
|
|
1692
|
+
objType === 'date' &&
|
|
1693
|
+
(startType !== 'date' || finishType !== 'date')
|
|
1694
|
+
) {
|
|
1638
1695
|
errorMessage = msgPrefix + 'the arguments to within must be dates';
|
|
1639
|
-
} else if (
|
|
1696
|
+
} else if (
|
|
1697
|
+
(!_.isNumeric(start) || !_.isNumeric(finish)) &&
|
|
1698
|
+
(doLength || _.isNumeric(obj))
|
|
1699
|
+
) {
|
|
1640
1700
|
errorMessage = msgPrefix + 'the arguments to within must be numbers';
|
|
1641
|
-
} else if (!doLength &&
|
|
1642
|
-
var printObj =
|
|
1643
|
-
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';
|
|
1644
1705
|
} else {
|
|
1645
1706
|
shouldThrow = false;
|
|
1646
1707
|
}
|
|
@@ -1650,8 +1711,8 @@ Assertion.addMethod('within', function (start, finish, msg) {
|
|
|
1650
1711
|
}
|
|
1651
1712
|
|
|
1652
1713
|
if (doLength) {
|
|
1653
|
-
var descriptor = 'length'
|
|
1654
|
-
|
|
1714
|
+
var descriptor = 'length',
|
|
1715
|
+
itemsCount;
|
|
1655
1716
|
if (objType === 'map' || objType === 'set') {
|
|
1656
1717
|
descriptor = 'size';
|
|
1657
1718
|
itemsCount = obj.size;
|
|
@@ -1659,15 +1720,15 @@ Assertion.addMethod('within', function (start, finish, msg) {
|
|
|
1659
1720
|
itemsCount = obj.length;
|
|
1660
1721
|
}
|
|
1661
1722
|
this.assert(
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1723
|
+
itemsCount >= start && itemsCount <= finish,
|
|
1724
|
+
'expected #{this} to have a ' + descriptor + ' within ' + range,
|
|
1725
|
+
'expected #{this} to not have a ' + descriptor + ' within ' + range
|
|
1665
1726
|
);
|
|
1666
1727
|
} else {
|
|
1667
1728
|
this.assert(
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1729
|
+
obj >= start && obj <= finish,
|
|
1730
|
+
'expected #{this} to be within ' + range,
|
|
1731
|
+
'expected #{this} to not be within ' + range
|
|
1671
1732
|
);
|
|
1672
1733
|
}
|
|
1673
1734
|
});
|
|
@@ -1710,10 +1771,10 @@ Assertion.addMethod('within', function (start, finish, msg) {
|
|
|
1710
1771
|
* @namespace BDD
|
|
1711
1772
|
* @public
|
|
1712
1773
|
*/
|
|
1713
|
-
function assertInstanceOf
|
|
1774
|
+
function assertInstanceOf(constructor, msg) {
|
|
1714
1775
|
if (msg) flag(this, 'message', msg);
|
|
1715
1776
|
|
|
1716
|
-
var target = flag(this, 'object')
|
|
1777
|
+
var target = flag(this, 'object');
|
|
1717
1778
|
var ssfi = flag(this, 'ssfi');
|
|
1718
1779
|
var flagMsg = flag(this, 'message');
|
|
1719
1780
|
|
|
@@ -1723,8 +1784,10 @@ function assertInstanceOf (constructor, msg) {
|
|
|
1723
1784
|
if (err instanceof TypeError) {
|
|
1724
1785
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
1725
1786
|
throw new AssertionError(
|
|
1726
|
-
flagMsg +
|
|
1727
|
-
|
|
1787
|
+
flagMsg +
|
|
1788
|
+
'The instanceof assertion needs a constructor but ' +
|
|
1789
|
+
_.type(constructor) +
|
|
1790
|
+
' was given.',
|
|
1728
1791
|
undefined,
|
|
1729
1792
|
ssfi
|
|
1730
1793
|
);
|
|
@@ -1738,11 +1801,11 @@ function assertInstanceOf (constructor, msg) {
|
|
|
1738
1801
|
}
|
|
1739
1802
|
|
|
1740
1803
|
this.assert(
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1804
|
+
isInstanceOf,
|
|
1805
|
+
'expected #{this} to be an instance of ' + name,
|
|
1806
|
+
'expected #{this} to not be an instance of ' + name
|
|
1744
1807
|
);
|
|
1745
|
-
}
|
|
1808
|
+
}
|
|
1746
1809
|
|
|
1747
1810
|
Assertion.addMethod('instanceof', assertInstanceOf);
|
|
1748
1811
|
Assertion.addMethod('instanceOf', assertInstanceOf);
|
|
@@ -1857,30 +1920,36 @@ Assertion.addMethod('instanceOf', assertInstanceOf);
|
|
|
1857
1920
|
* @namespace BDD
|
|
1858
1921
|
* @public
|
|
1859
1922
|
*/
|
|
1860
|
-
function assertProperty
|
|
1923
|
+
function assertProperty(name, val, msg) {
|
|
1861
1924
|
if (msg) flag(this, 'message', msg);
|
|
1862
1925
|
|
|
1863
|
-
var isNested = flag(this, 'nested')
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
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;
|
|
1869
1932
|
|
|
1870
1933
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
1871
1934
|
|
|
1872
1935
|
if (isNested) {
|
|
1873
1936
|
if (nameType !== 'string') {
|
|
1874
1937
|
throw new AssertionError(
|
|
1875
|
-
flagMsg +
|
|
1938
|
+
flagMsg +
|
|
1939
|
+
'the argument to property must be a string when using nested syntax',
|
|
1876
1940
|
undefined,
|
|
1877
1941
|
ssfi
|
|
1878
1942
|
);
|
|
1879
1943
|
}
|
|
1880
1944
|
} else {
|
|
1881
|
-
if (
|
|
1945
|
+
if (
|
|
1946
|
+
nameType !== 'string' &&
|
|
1947
|
+
nameType !== 'number' &&
|
|
1948
|
+
nameType !== 'symbol'
|
|
1949
|
+
) {
|
|
1882
1950
|
throw new AssertionError(
|
|
1883
|
-
flagMsg +
|
|
1951
|
+
flagMsg +
|
|
1952
|
+
'the argument to property must be a string, number, or symbol',
|
|
1884
1953
|
undefined,
|
|
1885
1954
|
ssfi
|
|
1886
1955
|
);
|
|
@@ -1903,11 +1972,11 @@ function assertProperty (name, val, msg) {
|
|
|
1903
1972
|
);
|
|
1904
1973
|
}
|
|
1905
1974
|
|
|
1906
|
-
var isDeep = flag(this, 'deep')
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
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;
|
|
1911
1980
|
|
|
1912
1981
|
var descriptor = '';
|
|
1913
1982
|
if (isDeep) descriptor += 'deep ';
|
|
@@ -1927,18 +1996,25 @@ function assertProperty (name, val, msg) {
|
|
|
1927
1996
|
// favor of the next.
|
|
1928
1997
|
if (!negate || arguments.length === 1) {
|
|
1929
1998
|
this.assert(
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1999
|
+
hasProperty,
|
|
2000
|
+
'expected #{this} to have ' + descriptor + _.inspect(name),
|
|
2001
|
+
'expected #{this} to not have ' + descriptor + _.inspect(name)
|
|
2002
|
+
);
|
|
1933
2003
|
}
|
|
1934
2004
|
|
|
1935
2005
|
if (arguments.length > 1) {
|
|
1936
2006
|
this.assert(
|
|
1937
|
-
hasProperty && isEql(val, value)
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
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
|
|
1942
2018
|
);
|
|
1943
2019
|
}
|
|
1944
2020
|
|
|
@@ -1949,11 +2025,11 @@ Assertion.addMethod('property', assertProperty);
|
|
|
1949
2025
|
|
|
1950
2026
|
/**
|
|
1951
2027
|
*
|
|
1952
|
-
* @param {unknown}
|
|
1953
|
-
* @param {unknown}
|
|
1954
|
-
* @param {string}
|
|
2028
|
+
* @param {unknown} _name
|
|
2029
|
+
* @param {unknown} _value
|
|
2030
|
+
* @param {string} _msg
|
|
1955
2031
|
*/
|
|
1956
|
-
function assertOwnProperty
|
|
2032
|
+
function assertOwnProperty(_name, _value, _msg) {
|
|
1957
2033
|
flag(this, 'own', true);
|
|
1958
2034
|
assertProperty.apply(this, arguments);
|
|
1959
2035
|
}
|
|
@@ -2079,7 +2155,7 @@ Assertion.addMethod('haveOwnProperty', assertOwnProperty);
|
|
|
2079
2155
|
* @namespace BDD
|
|
2080
2156
|
* @public
|
|
2081
2157
|
*/
|
|
2082
|
-
function assertOwnPropertyDescriptor
|
|
2158
|
+
function assertOwnPropertyDescriptor(name, descriptor, msg) {
|
|
2083
2159
|
if (typeof descriptor === 'string') {
|
|
2084
2160
|
msg = descriptor;
|
|
2085
2161
|
descriptor = null;
|
|
@@ -2090,18 +2166,28 @@ function assertOwnPropertyDescriptor (name, descriptor, msg) {
|
|
|
2090
2166
|
var eql = flag(this, 'eql');
|
|
2091
2167
|
if (actualDescriptor && descriptor) {
|
|
2092
2168
|
this.assert(
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
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
|
|
2099
2183
|
);
|
|
2100
2184
|
} else {
|
|
2101
2185
|
this.assert(
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
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)
|
|
2105
2191
|
);
|
|
2106
2192
|
}
|
|
2107
2193
|
flag(this, 'object', actualDescriptor);
|
|
@@ -2113,7 +2199,7 @@ Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);
|
|
|
2113
2199
|
/**
|
|
2114
2200
|
*
|
|
2115
2201
|
*/
|
|
2116
|
-
function assertLengthChain
|
|
2202
|
+
function assertLengthChain() {
|
|
2117
2203
|
flag(this, 'doLength', true);
|
|
2118
2204
|
}
|
|
2119
2205
|
|
|
@@ -2174,14 +2260,14 @@ function assertLengthChain () {
|
|
|
2174
2260
|
* @namespace BDD
|
|
2175
2261
|
* @public
|
|
2176
2262
|
*/
|
|
2177
|
-
function assertLength
|
|
2263
|
+
function assertLength(n, msg) {
|
|
2178
2264
|
if (msg) flag(this, 'message', msg);
|
|
2179
|
-
var obj = flag(this, 'object')
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
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;
|
|
2185
2271
|
|
|
2186
2272
|
switch (objType) {
|
|
2187
2273
|
case 'map':
|
|
@@ -2195,11 +2281,11 @@ function assertLength (n, msg) {
|
|
|
2195
2281
|
}
|
|
2196
2282
|
|
|
2197
2283
|
this.assert(
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
,
|
|
2202
|
-
|
|
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
|
|
2203
2289
|
);
|
|
2204
2290
|
}
|
|
2205
2291
|
|
|
@@ -2237,9 +2323,9 @@ function assertMatch(re, msg) {
|
|
|
2237
2323
|
if (msg) flag(this, 'message', msg);
|
|
2238
2324
|
var obj = flag(this, 'object');
|
|
2239
2325
|
this.assert(
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2326
|
+
re.exec(obj),
|
|
2327
|
+
'expected #{this} to match ' + re,
|
|
2328
|
+
'expected #{this} not to match ' + re
|
|
2243
2329
|
);
|
|
2244
2330
|
}
|
|
2245
2331
|
|
|
@@ -2272,15 +2358,15 @@ Assertion.addMethod('matches', assertMatch);
|
|
|
2272
2358
|
*/
|
|
2273
2359
|
Assertion.addMethod('string', function (str, msg) {
|
|
2274
2360
|
if (msg) flag(this, 'message', msg);
|
|
2275
|
-
var obj = flag(this, 'object')
|
|
2276
|
-
|
|
2277
|
-
|
|
2361
|
+
var obj = flag(this, 'object'),
|
|
2362
|
+
flagMsg = flag(this, 'message'),
|
|
2363
|
+
ssfi = flag(this, 'ssfi');
|
|
2278
2364
|
new Assertion(obj, flagMsg, ssfi, true).is.a('string');
|
|
2279
2365
|
|
|
2280
2366
|
this.assert(
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2367
|
+
~obj.indexOf(str),
|
|
2368
|
+
'expected #{this} to contain ' + _.inspect(str),
|
|
2369
|
+
'expected #{this} to not contain ' + _.inspect(str)
|
|
2284
2370
|
);
|
|
2285
2371
|
});
|
|
2286
2372
|
|
|
@@ -2387,27 +2473,31 @@ Assertion.addMethod('string', function (str, msg) {
|
|
|
2387
2473
|
* @namespace BDD
|
|
2388
2474
|
* @public
|
|
2389
2475
|
*/
|
|
2390
|
-
function assertKeys
|
|
2391
|
-
var obj = flag(this, 'object')
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
,
|
|
2397
|
-
|
|
2398
|
-
,
|
|
2399
|
-
|
|
2400
|
-
|
|
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');
|
|
2401
2487
|
|
|
2402
2488
|
flagMsg = flagMsg ? flagMsg + ': ' : '';
|
|
2403
|
-
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';
|
|
2404
2492
|
|
|
2405
2493
|
if (objType === 'Map' || objType === 'Set') {
|
|
2406
2494
|
deepStr = isDeep ? 'deeply ' : '';
|
|
2407
2495
|
actual = [];
|
|
2408
2496
|
|
|
2409
2497
|
// Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach.
|
|
2410
|
-
obj.forEach(function (val, key) {
|
|
2498
|
+
obj.forEach(function (val, key) {
|
|
2499
|
+
actual.push(key);
|
|
2500
|
+
});
|
|
2411
2501
|
|
|
2412
2502
|
if (keysType !== 'Array') {
|
|
2413
2503
|
keys = Array.prototype.slice.call(arguments);
|
|
@@ -2441,11 +2531,11 @@ function assertKeys (keys) {
|
|
|
2441
2531
|
throw new AssertionError(flagMsg + 'keys required', undefined, ssfi);
|
|
2442
2532
|
}
|
|
2443
2533
|
|
|
2444
|
-
var len = keys.length
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
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;
|
|
2449
2539
|
|
|
2450
2540
|
if (!any && !all) {
|
|
2451
2541
|
all = true;
|
|
@@ -2453,8 +2543,8 @@ function assertKeys (keys) {
|
|
|
2453
2543
|
|
|
2454
2544
|
// Has any
|
|
2455
2545
|
if (any) {
|
|
2456
|
-
ok = expected.some(function(expectedKey) {
|
|
2457
|
-
return actual.some(function(actualKey) {
|
|
2546
|
+
ok = expected.some(function (expectedKey) {
|
|
2547
|
+
return actual.some(function (actualKey) {
|
|
2458
2548
|
return isEql(expectedKey, actualKey);
|
|
2459
2549
|
});
|
|
2460
2550
|
});
|
|
@@ -2462,8 +2552,8 @@ function assertKeys (keys) {
|
|
|
2462
2552
|
|
|
2463
2553
|
// Has all
|
|
2464
2554
|
if (all) {
|
|
2465
|
-
ok = expected.every(function(expectedKey) {
|
|
2466
|
-
return actual.some(function(actualKey) {
|
|
2555
|
+
ok = expected.every(function (expectedKey) {
|
|
2556
|
+
return actual.some(function (actualKey) {
|
|
2467
2557
|
return isEql(expectedKey, actualKey);
|
|
2468
2558
|
});
|
|
2469
2559
|
});
|
|
@@ -2475,7 +2565,7 @@ function assertKeys (keys) {
|
|
|
2475
2565
|
|
|
2476
2566
|
// Key string
|
|
2477
2567
|
if (len > 1) {
|
|
2478
|
-
keys = keys.map(function(key) {
|
|
2568
|
+
keys = keys.map(function (key) {
|
|
2479
2569
|
return _.inspect(key);
|
|
2480
2570
|
});
|
|
2481
2571
|
var last = keys.pop();
|
|
@@ -2497,12 +2587,12 @@ function assertKeys (keys) {
|
|
|
2497
2587
|
|
|
2498
2588
|
// Assertion
|
|
2499
2589
|
this.assert(
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
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
|
|
2506
2596
|
);
|
|
2507
2597
|
}
|
|
2508
2598
|
|
|
@@ -2668,12 +2758,12 @@ Assertion.addMethod('key', assertKeys);
|
|
|
2668
2758
|
* @namespace BDD
|
|
2669
2759
|
* @public
|
|
2670
2760
|
*/
|
|
2671
|
-
function assertThrows
|
|
2761
|
+
function assertThrows(errorLike, errMsgMatcher, msg) {
|
|
2672
2762
|
if (msg) flag(this, 'message', msg);
|
|
2673
|
-
var obj = flag(this, 'object')
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2763
|
+
var obj = flag(this, 'object'),
|
|
2764
|
+
ssfi = flag(this, 'ssfi'),
|
|
2765
|
+
flagMsg = flag(this, 'message'),
|
|
2766
|
+
negate = flag(this, 'negate') || false;
|
|
2677
2767
|
new Assertion(obj, flagMsg, ssfi, true).is.a('function');
|
|
2678
2768
|
|
|
2679
2769
|
if (_.isRegExp(errorLike) || typeof errorLike === 'string') {
|
|
@@ -2692,7 +2782,8 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2692
2782
|
|
|
2693
2783
|
// If we have the negate flag enabled and at least one valid argument it means we do expect an error
|
|
2694
2784
|
// but we want it to match a given set of criteria
|
|
2695
|
-
var everyArgIsUndefined =
|
|
2785
|
+
var everyArgIsUndefined =
|
|
2786
|
+
errorLike === undefined && errMsgMatcher === undefined;
|
|
2696
2787
|
|
|
2697
2788
|
// If we've got the negate flag enabled and both args, we should only fail if both aren't compatible
|
|
2698
2789
|
// See Issue #551 and PR #683@GitHub
|
|
@@ -2701,7 +2792,7 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2701
2792
|
var errMsgMatcherFail = false;
|
|
2702
2793
|
|
|
2703
2794
|
// Checking if error was thrown
|
|
2704
|
-
if (everyArgIsUndefined || !everyArgIsUndefined && !negate) {
|
|
2795
|
+
if (everyArgIsUndefined || (!everyArgIsUndefined && !negate)) {
|
|
2705
2796
|
// We need this to display results correctly according to their types
|
|
2706
2797
|
var errorLikeString = 'an error';
|
|
2707
2798
|
if (errorLike instanceof Error) {
|
|
@@ -2715,7 +2806,10 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2715
2806
|
actual = caughtErr.toString();
|
|
2716
2807
|
} else if (typeof caughtErr === 'string') {
|
|
2717
2808
|
actual = caughtErr;
|
|
2718
|
-
} else if (
|
|
2809
|
+
} else if (
|
|
2810
|
+
caughtErr &&
|
|
2811
|
+
(typeof caughtErr === 'object' || typeof caughtErr === 'function')
|
|
2812
|
+
) {
|
|
2719
2813
|
try {
|
|
2720
2814
|
actual = _.checkError.getConstructorName(caughtErr);
|
|
2721
2815
|
} catch (_err) {
|
|
@@ -2725,18 +2819,21 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2725
2819
|
}
|
|
2726
2820
|
|
|
2727
2821
|
this.assert(
|
|
2728
|
-
errorWasThrown
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
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
|
|
2733
2827
|
);
|
|
2734
2828
|
}
|
|
2735
2829
|
|
|
2736
2830
|
if (errorLike && caughtErr) {
|
|
2737
2831
|
// We should compare instances only if `errorLike` is an instance of `Error`
|
|
2738
2832
|
if (errorLike instanceof Error) {
|
|
2739
|
-
var isCompatibleInstance = _.checkError.compatibleInstance(
|
|
2833
|
+
var isCompatibleInstance = _.checkError.compatibleInstance(
|
|
2834
|
+
caughtErr,
|
|
2835
|
+
errorLike
|
|
2836
|
+
);
|
|
2740
2837
|
|
|
2741
2838
|
if (isCompatibleInstance === negate) {
|
|
2742
2839
|
// These checks were created to ensure we won't fail too soon when we've got both args and a negate
|
|
@@ -2745,27 +2842,36 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2745
2842
|
errorLikeFail = true;
|
|
2746
2843
|
} else {
|
|
2747
2844
|
this.assert(
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
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()
|
|
2753
2851
|
);
|
|
2754
2852
|
}
|
|
2755
2853
|
}
|
|
2756
2854
|
}
|
|
2757
2855
|
|
|
2758
|
-
var isCompatibleConstructor = _.checkError.compatibleConstructor(
|
|
2856
|
+
var isCompatibleConstructor = _.checkError.compatibleConstructor(
|
|
2857
|
+
caughtErr,
|
|
2858
|
+
errorLike
|
|
2859
|
+
);
|
|
2759
2860
|
if (isCompatibleConstructor === negate) {
|
|
2760
2861
|
if (everyArgIsDefined && negate) {
|
|
2761
|
-
|
|
2862
|
+
errorLikeFail = true;
|
|
2762
2863
|
} else {
|
|
2763
2864
|
this.assert(
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
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)
|
|
2769
2875
|
);
|
|
2770
2876
|
}
|
|
2771
2877
|
}
|
|
@@ -2775,20 +2881,25 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2775
2881
|
// Here we check compatible messages
|
|
2776
2882
|
var placeholder = 'including';
|
|
2777
2883
|
if (_.isRegExp(errMsgMatcher)) {
|
|
2778
|
-
placeholder = 'matching'
|
|
2884
|
+
placeholder = 'matching';
|
|
2779
2885
|
}
|
|
2780
2886
|
|
|
2781
|
-
var isCompatibleMessage = _.checkError.compatibleMessage(
|
|
2887
|
+
var isCompatibleMessage = _.checkError.compatibleMessage(
|
|
2888
|
+
caughtErr,
|
|
2889
|
+
errMsgMatcher
|
|
2890
|
+
);
|
|
2782
2891
|
if (isCompatibleMessage === negate) {
|
|
2783
2892
|
if (everyArgIsDefined && negate) {
|
|
2784
|
-
|
|
2893
|
+
errMsgMatcherFail = true;
|
|
2785
2894
|
} else {
|
|
2786
2895
|
this.assert(
|
|
2787
|
-
negate
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
,
|
|
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)
|
|
2792
2903
|
);
|
|
2793
2904
|
}
|
|
2794
2905
|
}
|
|
@@ -2797,16 +2908,21 @@ function assertThrows (errorLike, errMsgMatcher, msg) {
|
|
|
2797
2908
|
// If both assertions failed and both should've matched we throw an error
|
|
2798
2909
|
if (errorLikeFail && errMsgMatcherFail) {
|
|
2799
2910
|
this.assert(
|
|
2800
|
-
negate
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
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)
|
|
2805
2921
|
);
|
|
2806
2922
|
}
|
|
2807
2923
|
|
|
2808
2924
|
flag(this, 'object', caughtErr);
|
|
2809
|
-
}
|
|
2925
|
+
}
|
|
2810
2926
|
|
|
2811
2927
|
Assertion.addMethod('throw', assertThrows);
|
|
2812
2928
|
Assertion.addMethod('throws', assertThrows);
|
|
@@ -2876,18 +2992,19 @@ Assertion.addMethod('Throw', assertThrows);
|
|
|
2876
2992
|
* @namespace BDD
|
|
2877
2993
|
* @public
|
|
2878
2994
|
*/
|
|
2879
|
-
function respondTo
|
|
2995
|
+
function respondTo(method, msg) {
|
|
2880
2996
|
if (msg) flag(this, 'message', msg);
|
|
2881
|
-
var obj = flag(this, 'object')
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
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];
|
|
2886
3003
|
|
|
2887
3004
|
this.assert(
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
3005
|
+
'function' === typeof context,
|
|
3006
|
+
'expected #{this} to respond to ' + _.inspect(method),
|
|
3007
|
+
'expected #{this} to not respond to ' + _.inspect(method)
|
|
2891
3008
|
);
|
|
2892
3009
|
}
|
|
2893
3010
|
|
|
@@ -2954,16 +3071,16 @@ Assertion.addProperty('itself', function () {
|
|
|
2954
3071
|
* @namespace BDD
|
|
2955
3072
|
* @public
|
|
2956
3073
|
*/
|
|
2957
|
-
function satisfy
|
|
3074
|
+
function satisfy(matcher, msg) {
|
|
2958
3075
|
if (msg) flag(this, 'message', msg);
|
|
2959
3076
|
var obj = flag(this, 'object');
|
|
2960
3077
|
var result = matcher(obj);
|
|
2961
3078
|
this.assert(
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
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
|
|
2967
3084
|
);
|
|
2968
3085
|
}
|
|
2969
3086
|
|
|
@@ -3009,25 +3126,38 @@ Assertion.addMethod('satisfies', satisfy);
|
|
|
3009
3126
|
*/
|
|
3010
3127
|
function closeTo(expected, delta, msg) {
|
|
3011
3128
|
if (msg) flag(this, 'message', msg);
|
|
3012
|
-
var obj = flag(this, 'object')
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
new Assertion(obj, flagMsg, ssfi, true).is.
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
var deltaMessage = delta === undefined ? ", and a delta is required" : "";
|
|
3129
|
+
var obj = flag(this, 'object'),
|
|
3130
|
+
flagMsg = flag(this, 'message'),
|
|
3131
|
+
ssfi = flag(this, 'ssfi');
|
|
3132
|
+
|
|
3133
|
+
new Assertion(obj, flagMsg, ssfi, true).is.numeric;
|
|
3134
|
+
let message = 'A `delta` value is required for `closeTo`';
|
|
3135
|
+
if (delta == undefined)
|
|
3020
3136
|
throw new AssertionError(
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3137
|
+
flagMsg ? `${flagMsg}: ${message}` : message,
|
|
3138
|
+
undefined,
|
|
3139
|
+
ssfi
|
|
3024
3140
|
);
|
|
3025
|
-
|
|
3141
|
+
new Assertion(delta, flagMsg, ssfi, true).is.numeric;
|
|
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
|
+
);
|
|
3149
|
+
new Assertion(expected, flagMsg, ssfi, true).is.numeric;
|
|
3150
|
+
|
|
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));
|
|
3026
3156
|
|
|
3027
3157
|
this.assert(
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
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
|
|
3031
3161
|
);
|
|
3032
3162
|
}
|
|
3033
3163
|
|
|
@@ -3050,7 +3180,7 @@ function isSubsetOf(_subset, _superset, cmp, contains, ordered) {
|
|
|
3050
3180
|
superset = superset.slice();
|
|
3051
3181
|
}
|
|
3052
3182
|
|
|
3053
|
-
return subset.every(function(elem, idx) {
|
|
3183
|
+
return subset.every(function (elem, idx) {
|
|
3054
3184
|
if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx];
|
|
3055
3185
|
|
|
3056
3186
|
if (!cmp) {
|
|
@@ -3062,7 +3192,7 @@ function isSubsetOf(_subset, _superset, cmp, contains, ordered) {
|
|
|
3062
3192
|
return true;
|
|
3063
3193
|
}
|
|
3064
3194
|
|
|
3065
|
-
return superset.some(function(elem2, matchIdx) {
|
|
3195
|
+
return superset.some(function (elem2, matchIdx) {
|
|
3066
3196
|
if (!cmp(elem, elem2)) return false;
|
|
3067
3197
|
|
|
3068
3198
|
// Remove match from superset so not counted twice if duplicate in subset.
|
|
@@ -3142,9 +3272,9 @@ function isSubsetOf(_subset, _superset, cmp, contains, ordered) {
|
|
|
3142
3272
|
*/
|
|
3143
3273
|
Assertion.addMethod('members', function (subset, msg) {
|
|
3144
3274
|
if (msg) flag(this, 'message', msg);
|
|
3145
|
-
var obj = flag(this, 'object')
|
|
3146
|
-
|
|
3147
|
-
|
|
3275
|
+
var obj = flag(this, 'object'),
|
|
3276
|
+
flagMsg = flag(this, 'message'),
|
|
3277
|
+
ssfi = flag(this, 'ssfi');
|
|
3148
3278
|
|
|
3149
3279
|
new Assertion(obj, flagMsg, ssfi, true).to.be.iterable;
|
|
3150
3280
|
new Assertion(subset, flagMsg, ssfi, true).to.be.iterable;
|
|
@@ -3161,18 +3291,19 @@ Assertion.addMethod('members', function (subset, msg) {
|
|
|
3161
3291
|
} else {
|
|
3162
3292
|
subject = ordered ? 'ordered members' : 'members';
|
|
3163
3293
|
failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}';
|
|
3164
|
-
failNegateMsg =
|
|
3294
|
+
failNegateMsg =
|
|
3295
|
+
'expected #{this} to not have the same ' + subject + ' as #{exp}';
|
|
3165
3296
|
}
|
|
3166
3297
|
|
|
3167
3298
|
var cmp = flag(this, 'deep') ? flag(this, 'eql') : undefined;
|
|
3168
3299
|
|
|
3169
3300
|
this.assert(
|
|
3170
|
-
|
|
3171
|
-
,
|
|
3172
|
-
,
|
|
3173
|
-
,
|
|
3174
|
-
,
|
|
3175
|
-
|
|
3301
|
+
isSubsetOf(subset, obj, cmp, contains, ordered),
|
|
3302
|
+
failMsg,
|
|
3303
|
+
failNegateMsg,
|
|
3304
|
+
subset,
|
|
3305
|
+
obj,
|
|
3306
|
+
true
|
|
3176
3307
|
);
|
|
3177
3308
|
});
|
|
3178
3309
|
|
|
@@ -3197,15 +3328,15 @@ Assertion.addMethod('members', function (subset, msg) {
|
|
|
3197
3328
|
* @namespace BDD
|
|
3198
3329
|
* @public
|
|
3199
3330
|
*/
|
|
3200
|
-
Assertion.addProperty('iterable', function(msg) {
|
|
3331
|
+
Assertion.addProperty('iterable', function (msg) {
|
|
3201
3332
|
if (msg) flag(this, 'message', msg);
|
|
3202
3333
|
var obj = flag(this, 'object');
|
|
3203
3334
|
|
|
3204
3335
|
this.assert(
|
|
3205
|
-
obj != undefined && obj[Symbol.iterator]
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3336
|
+
obj != undefined && obj[Symbol.iterator],
|
|
3337
|
+
'expected #{this} to be an iterable',
|
|
3338
|
+
'expected #{this} to not be an iterable',
|
|
3339
|
+
obj
|
|
3209
3340
|
);
|
|
3210
3341
|
});
|
|
3211
3342
|
|
|
@@ -3246,40 +3377,44 @@ Assertion.addProperty('iterable', function(msg) {
|
|
|
3246
3377
|
* @namespace BDD
|
|
3247
3378
|
* @public
|
|
3248
3379
|
*/
|
|
3249
|
-
function oneOf
|
|
3380
|
+
function oneOf(list, msg) {
|
|
3250
3381
|
if (msg) flag(this, 'message', msg);
|
|
3251
|
-
var expected = flag(this, 'object')
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
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');
|
|
3257
3388
|
new Assertion(list, flagMsg, ssfi, true).to.be.an('array');
|
|
3258
3389
|
|
|
3259
3390
|
if (contains) {
|
|
3260
3391
|
this.assert(
|
|
3261
|
-
list.some(function(possibility) {
|
|
3262
|
-
|
|
3263
|
-
,
|
|
3264
|
-
,
|
|
3265
|
-
,
|
|
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
|
|
3266
3399
|
);
|
|
3267
3400
|
} else {
|
|
3268
3401
|
if (isDeep) {
|
|
3269
3402
|
this.assert(
|
|
3270
|
-
list.some(function(possibility) {
|
|
3271
|
-
|
|
3272
|
-
,
|
|
3273
|
-
,
|
|
3274
|
-
,
|
|
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
|
|
3275
3410
|
);
|
|
3276
3411
|
} else {
|
|
3277
3412
|
this.assert(
|
|
3278
|
-
list.indexOf(expected) > -1
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
,
|
|
3282
|
-
|
|
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
|
|
3283
3418
|
);
|
|
3284
3419
|
}
|
|
3285
3420
|
}
|
|
@@ -3381,11 +3516,11 @@ Assertion.addMethod('oneOf', oneOf);
|
|
|
3381
3516
|
* @namespace BDD
|
|
3382
3517
|
* @public
|
|
3383
3518
|
*/
|
|
3384
|
-
function assertChanges
|
|
3519
|
+
function assertChanges(subject, prop, msg) {
|
|
3385
3520
|
if (msg) flag(this, 'message', msg);
|
|
3386
|
-
var fn = flag(this, 'object')
|
|
3387
|
-
|
|
3388
|
-
|
|
3521
|
+
var fn = flag(this, 'object'),
|
|
3522
|
+
flagMsg = flag(this, 'message'),
|
|
3523
|
+
ssfi = flag(this, 'ssfi');
|
|
3389
3524
|
new Assertion(fn, flagMsg, ssfi, true).is.a('function');
|
|
3390
3525
|
|
|
3391
3526
|
var initial;
|
|
@@ -3410,9 +3545,9 @@ function assertChanges (subject, prop, msg) {
|
|
|
3410
3545
|
flag(this, 'realDelta', final !== initial);
|
|
3411
3546
|
|
|
3412
3547
|
this.assert(
|
|
3413
|
-
initial !== final
|
|
3414
|
-
|
|
3415
|
-
|
|
3548
|
+
initial !== final,
|
|
3549
|
+
'expected ' + msgObj + ' to change',
|
|
3550
|
+
'expected ' + msgObj + ' to not change'
|
|
3416
3551
|
);
|
|
3417
3552
|
}
|
|
3418
3553
|
|
|
@@ -3497,11 +3632,11 @@ Assertion.addMethod('changes', assertChanges);
|
|
|
3497
3632
|
* @namespace BDD
|
|
3498
3633
|
* @public
|
|
3499
3634
|
*/
|
|
3500
|
-
function assertIncreases
|
|
3635
|
+
function assertIncreases(subject, prop, msg) {
|
|
3501
3636
|
if (msg) flag(this, 'message', msg);
|
|
3502
|
-
var fn = flag(this, 'object')
|
|
3503
|
-
|
|
3504
|
-
|
|
3637
|
+
var fn = flag(this, 'object'),
|
|
3638
|
+
flagMsg = flag(this, 'message'),
|
|
3639
|
+
ssfi = flag(this, 'ssfi');
|
|
3505
3640
|
new Assertion(fn, flagMsg, ssfi, true).is.a('function');
|
|
3506
3641
|
|
|
3507
3642
|
var initial;
|
|
@@ -3528,9 +3663,9 @@ function assertIncreases (subject, prop, msg) {
|
|
|
3528
3663
|
flag(this, 'realDelta', final - initial);
|
|
3529
3664
|
|
|
3530
3665
|
this.assert(
|
|
3531
|
-
final - initial > 0
|
|
3532
|
-
|
|
3533
|
-
|
|
3666
|
+
final - initial > 0,
|
|
3667
|
+
'expected ' + msgObj + ' to increase',
|
|
3668
|
+
'expected ' + msgObj + ' to not increase'
|
|
3534
3669
|
);
|
|
3535
3670
|
}
|
|
3536
3671
|
|
|
@@ -3615,11 +3750,11 @@ Assertion.addMethod('increases', assertIncreases);
|
|
|
3615
3750
|
* @namespace BDD
|
|
3616
3751
|
* @public
|
|
3617
3752
|
*/
|
|
3618
|
-
function assertDecreases
|
|
3753
|
+
function assertDecreases(subject, prop, msg) {
|
|
3619
3754
|
if (msg) flag(this, 'message', msg);
|
|
3620
|
-
var fn = flag(this, 'object')
|
|
3621
|
-
|
|
3622
|
-
|
|
3755
|
+
var fn = flag(this, 'object'),
|
|
3756
|
+
flagMsg = flag(this, 'message'),
|
|
3757
|
+
ssfi = flag(this, 'ssfi');
|
|
3623
3758
|
new Assertion(fn, flagMsg, ssfi, true).is.a('function');
|
|
3624
3759
|
|
|
3625
3760
|
var initial;
|
|
@@ -3646,9 +3781,9 @@ function assertDecreases (subject, prop, msg) {
|
|
|
3646
3781
|
flag(this, 'realDelta', initial - final);
|
|
3647
3782
|
|
|
3648
3783
|
this.assert(
|
|
3649
|
-
final - initial < 0
|
|
3650
|
-
|
|
3651
|
-
|
|
3784
|
+
final - initial < 0,
|
|
3785
|
+
'expected ' + msgObj + ' to decrease',
|
|
3786
|
+
'expected ' + msgObj + ' to not decrease'
|
|
3652
3787
|
);
|
|
3653
3788
|
}
|
|
3654
3789
|
|
|
@@ -3737,9 +3872,9 @@ function assertDelta(delta, msg) {
|
|
|
3737
3872
|
}
|
|
3738
3873
|
|
|
3739
3874
|
this.assert(
|
|
3740
|
-
expression
|
|
3741
|
-
|
|
3742
|
-
|
|
3875
|
+
expression,
|
|
3876
|
+
'expected ' + msgObj + ' to ' + behavior + ' by ' + delta,
|
|
3877
|
+
'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta
|
|
3743
3878
|
);
|
|
3744
3879
|
}
|
|
3745
3880
|
|
|
@@ -3772,7 +3907,7 @@ Assertion.addMethod('by', assertDelta);
|
|
|
3772
3907
|
* @namespace BDD
|
|
3773
3908
|
* @public
|
|
3774
3909
|
*/
|
|
3775
|
-
Assertion.addProperty('extensible', function() {
|
|
3910
|
+
Assertion.addProperty('extensible', function () {
|
|
3776
3911
|
var obj = flag(this, 'object');
|
|
3777
3912
|
|
|
3778
3913
|
// In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
|
|
@@ -3783,9 +3918,9 @@ Assertion.addProperty('extensible', function() {
|
|
|
3783
3918
|
var isExtensible = obj === Object(obj) && Object.isExtensible(obj);
|
|
3784
3919
|
|
|
3785
3920
|
this.assert(
|
|
3786
|
-
isExtensible
|
|
3787
|
-
|
|
3788
|
-
|
|
3921
|
+
isExtensible,
|
|
3922
|
+
'expected #{this} to be extensible',
|
|
3923
|
+
'expected #{this} to not be extensible'
|
|
3789
3924
|
);
|
|
3790
3925
|
});
|
|
3791
3926
|
|
|
@@ -3816,7 +3951,7 @@ Assertion.addProperty('extensible', function() {
|
|
|
3816
3951
|
* @namespace BDD
|
|
3817
3952
|
* @public
|
|
3818
3953
|
*/
|
|
3819
|
-
Assertion.addProperty('sealed', function() {
|
|
3954
|
+
Assertion.addProperty('sealed', function () {
|
|
3820
3955
|
var obj = flag(this, 'object');
|
|
3821
3956
|
|
|
3822
3957
|
// In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
|
|
@@ -3827,9 +3962,9 @@ Assertion.addProperty('sealed', function() {
|
|
|
3827
3962
|
var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true;
|
|
3828
3963
|
|
|
3829
3964
|
this.assert(
|
|
3830
|
-
isSealed
|
|
3831
|
-
|
|
3832
|
-
|
|
3965
|
+
isSealed,
|
|
3966
|
+
'expected #{this} to be sealed',
|
|
3967
|
+
'expected #{this} to not be sealed'
|
|
3833
3968
|
);
|
|
3834
3969
|
});
|
|
3835
3970
|
|
|
@@ -3857,7 +3992,7 @@ Assertion.addProperty('sealed', function() {
|
|
|
3857
3992
|
* @namespace BDD
|
|
3858
3993
|
* @public
|
|
3859
3994
|
*/
|
|
3860
|
-
Assertion.addProperty('frozen', function() {
|
|
3995
|
+
Assertion.addProperty('frozen', function () {
|
|
3861
3996
|
var obj = flag(this, 'object');
|
|
3862
3997
|
|
|
3863
3998
|
// In ES5, if the argument to this method is a primitive, then it will cause a TypeError.
|
|
@@ -3868,9 +4003,9 @@ Assertion.addProperty('frozen', function() {
|
|
|
3868
4003
|
var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true;
|
|
3869
4004
|
|
|
3870
4005
|
this.assert(
|
|
3871
|
-
isFrozen
|
|
3872
|
-
|
|
3873
|
-
|
|
4006
|
+
isFrozen,
|
|
4007
|
+
'expected #{this} to be frozen',
|
|
4008
|
+
'expected #{this} to not be frozen'
|
|
3874
4009
|
);
|
|
3875
4010
|
});
|
|
3876
4011
|
|
|
@@ -3922,12 +4057,101 @@ Assertion.addProperty('frozen', function() {
|
|
|
3922
4057
|
* @namespace BDD
|
|
3923
4058
|
* @public
|
|
3924
4059
|
*/
|
|
3925
|
-
Assertion.addProperty('finite', function(
|
|
4060
|
+
Assertion.addProperty('finite', function (_msg) {
|
|
3926
4061
|
var obj = flag(this, 'object');
|
|
3927
4062
|
|
|
3928
4063
|
this.assert(
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
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
|
|
3932
4156
|
);
|
|
3933
4157
|
});
|