@casual-simulation/expect 2.0.18
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/LICENSE +21 -0
- package/README.md +4 -0
- package/index.d.ts +6 -0
- package/index.js +5 -0
- package/index.js.map +1 -0
- package/package.json +35 -0
- package/src/asymmetricMatchers.d.ts +67 -0
- package/src/asymmetricMatchers.js +188 -0
- package/src/asymmetricMatchers.js.map +1 -0
- package/src/diff/cleanupSemantic.d.ts +58 -0
- package/src/diff/cleanupSemantic.js +526 -0
- package/src/diff/cleanupSemantic.js.map +1 -0
- package/src/diff/constants.d.ts +9 -0
- package/src/diff/constants.js +10 -0
- package/src/diff/constants.js.map +1 -0
- package/src/diff/diffLines.d.ts +13 -0
- package/src/diff/diffLines.js +138 -0
- package/src/diff/diffLines.js.map +1 -0
- package/src/diff/diffStrings.d.ts +10 -0
- package/src/diff/diffStrings.js +36 -0
- package/src/diff/diffStrings.js.map +1 -0
- package/src/diff/getAlignedDiffs.d.ts +11 -0
- package/src/diff/getAlignedDiffs.js +187 -0
- package/src/diff/getAlignedDiffs.js.map +1 -0
- package/src/diff/index.d.ts +16 -0
- package/src/diff/index.js +139 -0
- package/src/diff/index.js.map +1 -0
- package/src/diff/joinAlignedDiffs.d.ts +11 -0
- package/src/diff/joinAlignedDiffs.js +191 -0
- package/src/diff/joinAlignedDiffs.js.map +1 -0
- package/src/diff/normalizeDiffOptions.d.ts +10 -0
- package/src/diff/normalizeDiffOptions.js +40 -0
- package/src/diff/normalizeDiffOptions.js.map +1 -0
- package/src/diff/printDiffs.d.ts +11 -0
- package/src/diff/printDiffs.js +46 -0
- package/src/diff/printDiffs.js.map +1 -0
- package/src/diff/types.d.ts +49 -0
- package/src/diff/types.js +2 -0
- package/src/diff/types.js.map +1 -0
- package/src/diff-sequences/index.d.ts +19 -0
- package/src/diff-sequences/index.js +506 -0
- package/src/diff-sequences/index.js.map +1 -0
- package/src/extractExpectedAssertionsErrors.d.ts +11 -0
- package/src/extractExpectedAssertionsErrors.js +58 -0
- package/src/extractExpectedAssertionsErrors.js.map +1 -0
- package/src/get-type/index.d.ts +11 -0
- package/src/get-type/index.js +57 -0
- package/src/get-type/index.js.map +1 -0
- package/src/index.d.ts +16 -0
- package/src/index.js +247 -0
- package/src/index.js.map +1 -0
- package/src/jasmineUtils.d.ts +9 -0
- package/src/jasmineUtils.js +218 -0
- package/src/jasmineUtils.js.map +1 -0
- package/src/jestMatchersObject.d.ts +14 -0
- package/src/jestMatchersObject.js +78 -0
- package/src/jestMatchersObject.js.map +1 -0
- package/src/matcher-utils/Replaceable.d.ts +18 -0
- package/src/matcher-utils/Replaceable.js +57 -0
- package/src/matcher-utils/Replaceable.js.map +1 -0
- package/src/matcher-utils/deepCyclicCopyReplaceable.d.ts +8 -0
- package/src/matcher-utils/deepCyclicCopyReplaceable.js +96 -0
- package/src/matcher-utils/deepCyclicCopyReplaceable.js.map +1 -0
- package/src/matcher-utils/index.d.ts +53 -0
- package/src/matcher-utils/index.js +341 -0
- package/src/matcher-utils/index.js.map +1 -0
- package/src/matchers.d.ts +11 -0
- package/src/matchers.js +575 -0
- package/src/matchers.js.map +1 -0
- package/src/message-util/index.d.ts +11 -0
- package/src/message-util/index.js +34 -0
- package/src/message-util/index.js.map +1 -0
- package/src/pretty-format/collections.d.ts +33 -0
- package/src/pretty-format/collections.js +130 -0
- package/src/pretty-format/collections.js.map +1 -0
- package/src/pretty-format/index.d.ts +25 -0
- package/src/pretty-format/index.js +390 -0
- package/src/pretty-format/index.js.map +1 -0
- package/src/pretty-format/plugins/AsymmetricMatcher.d.ts +12 -0
- package/src/pretty-format/plugins/AsymmetricMatcher.js +53 -0
- package/src/pretty-format/plugins/AsymmetricMatcher.js.map +1 -0
- package/src/pretty-format/plugins/ConvertAnsi.d.ts +12 -0
- package/src/pretty-format/plugins/ConvertAnsi.js +58 -0
- package/src/pretty-format/plugins/ConvertAnsi.js.map +1 -0
- package/src/pretty-format/plugins/DOMCollection.d.ts +12 -0
- package/src/pretty-format/plugins/DOMCollection.js +39 -0
- package/src/pretty-format/plugins/DOMCollection.js.map +1 -0
- package/src/pretty-format/plugins/DOMElement.d.ts +12 -0
- package/src/pretty-format/plugins/DOMElement.js +68 -0
- package/src/pretty-format/plugins/DOMElement.js.map +1 -0
- package/src/pretty-format/plugins/Immutable.d.ts +12 -0
- package/src/pretty-format/plugins/Immutable.js +113 -0
- package/src/pretty-format/plugins/Immutable.js.map +1 -0
- package/src/pretty-format/plugins/ReactTestComponent.d.ts +19 -0
- package/src/pretty-format/plugins/ReactTestComponent.js +29 -0
- package/src/pretty-format/plugins/ReactTestComponent.js.map +1 -0
- package/src/pretty-format/plugins/lib/escapeHTML.d.ts +8 -0
- package/src/pretty-format/plugins/lib/escapeHTML.js +10 -0
- package/src/pretty-format/plugins/lib/escapeHTML.js.map +1 -0
- package/src/pretty-format/plugins/lib/markup.d.ts +14 -0
- package/src/pretty-format/plugins/lib/markup.js +98 -0
- package/src/pretty-format/plugins/lib/markup.js.map +1 -0
- package/src/pretty-format/types.d.ts +109 -0
- package/src/pretty-format/types.js +8 -0
- package/src/pretty-format/types.js.map +1 -0
- package/src/print.d.ts +16 -0
- package/src/print.js +71 -0
- package/src/print.js.map +1 -0
- package/src/spyMatchers.d.ts +10 -0
- package/src/spyMatchers.js +766 -0
- package/src/spyMatchers.js.map +1 -0
- package/src/test-utils/ConditionalTest.d.ts +10 -0
- package/src/test-utils/ConditionalTest.js +25 -0
- package/src/test-utils/ConditionalTest.js.map +1 -0
- package/src/test-utils/alignedAnsiStyleSerializer.d.ts +9 -0
- package/src/test-utils/alignedAnsiStyleSerializer.js +46 -0
- package/src/test-utils/alignedAnsiStyleSerializer.js.map +1 -0
- package/src/test-utils/config.d.ts +10 -0
- package/src/test-utils/config.js +143 -0
- package/src/test-utils/config.js.map +1 -0
- package/src/test-utils/index.d.ts +10 -0
- package/src/test-utils/index.js +10 -0
- package/src/test-utils/index.js.map +1 -0
- package/src/toThrowMatchers.d.ts +12 -0
- package/src/toThrowMatchers.js +258 -0
- package/src/toThrowMatchers.js.map +1 -0
- package/src/types.d.ts +327 -0
- package/src/types.js +9 -0
- package/src/types.js.map +1 -0
- package/src/utils.d.ts +26 -0
- package/src/utils.js +303 -0
- package/src/utils.js.map +1 -0
|
@@ -0,0 +1,766 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { getType, isPrimitive } from './get-type';
|
|
8
|
+
import { DIM_COLOR, EXPECTED_COLOR, RECEIVED_COLOR, diff, ensureExpectedIsNonNegativeInteger, ensureNoExpected, matcherErrorMessage, matcherHint, printExpected, printReceived, printWithType, stringify, } from './matcher-utils';
|
|
9
|
+
import { equals } from './jasmineUtils';
|
|
10
|
+
import { iterableEquality } from './utils';
|
|
11
|
+
// The optional property of matcher context is true if undefined.
|
|
12
|
+
const isExpand = (expand) => expand !== false;
|
|
13
|
+
const PRINT_LIMIT = 3;
|
|
14
|
+
const NO_ARGUMENTS = 'called with 0 arguments';
|
|
15
|
+
const printExpectedArgs = (expected) => expected.length === 0
|
|
16
|
+
? NO_ARGUMENTS
|
|
17
|
+
: expected.map((arg) => printExpected(arg)).join(', ');
|
|
18
|
+
const printReceivedArgs = (received, expected) => received.length === 0
|
|
19
|
+
? NO_ARGUMENTS
|
|
20
|
+
: received
|
|
21
|
+
.map((arg, i) => Array.isArray(expected) &&
|
|
22
|
+
i < expected.length &&
|
|
23
|
+
isEqualValue(expected[i], arg)
|
|
24
|
+
? printCommon(arg)
|
|
25
|
+
: printReceived(arg))
|
|
26
|
+
.join(', ');
|
|
27
|
+
const printCommon = (val) => DIM_COLOR(stringify(val));
|
|
28
|
+
const isEqualValue = (expected, received) => equals(expected, received, [iterableEquality]);
|
|
29
|
+
const isEqualCall = (expected, received) => isEqualValue(expected, received);
|
|
30
|
+
const isEqualReturn = (expected, result) => result.type === 'return' && isEqualValue(expected, result.value);
|
|
31
|
+
const countReturns = (results) => results.reduce((n, result) => (result.type === 'return' ? n + 1 : n), 0);
|
|
32
|
+
const printNumberOfReturns = (countReturns, countCalls) => `\nNumber of returns: ${printReceived(countReturns)}` +
|
|
33
|
+
(countCalls !== countReturns
|
|
34
|
+
? `\nNumber of calls: ${printReceived(countCalls)}`
|
|
35
|
+
: '');
|
|
36
|
+
// Given a label, return a function which given a string,
|
|
37
|
+
// right-aligns it preceding the colon in the label.
|
|
38
|
+
const getRightAlignedPrinter = (label) => {
|
|
39
|
+
// Assume that the label contains a colon.
|
|
40
|
+
const index = label.indexOf(':');
|
|
41
|
+
const suffix = label.slice(index);
|
|
42
|
+
return (string, isExpectedCall) => (isExpectedCall
|
|
43
|
+
? '->' + ' '.repeat(Math.max(0, index - 2 - string.length))
|
|
44
|
+
: ' '.repeat(Math.max(index - string.length))) +
|
|
45
|
+
string +
|
|
46
|
+
suffix;
|
|
47
|
+
};
|
|
48
|
+
const printReceivedCallsNegative = (expected, indexedCalls, isOnlyCall, iExpectedCall) => {
|
|
49
|
+
if (indexedCalls.length === 0) {
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
const label = 'Received: ';
|
|
53
|
+
if (isOnlyCall) {
|
|
54
|
+
return label + printReceivedArgs(indexedCalls[0], expected) + '\n';
|
|
55
|
+
}
|
|
56
|
+
const printAligned = getRightAlignedPrinter(label);
|
|
57
|
+
return ('Received\n' +
|
|
58
|
+
indexedCalls.reduce((printed, [i, args]) => printed +
|
|
59
|
+
printAligned(String(i + 1), i === iExpectedCall) +
|
|
60
|
+
printReceivedArgs(args, expected) +
|
|
61
|
+
'\n', ''));
|
|
62
|
+
};
|
|
63
|
+
const printExpectedReceivedCallsPositive = (expected, indexedCalls, expand, isOnlyCall, iExpectedCall) => {
|
|
64
|
+
const expectedLine = `Expected: ${printExpectedArgs(expected)}\n`;
|
|
65
|
+
if (indexedCalls.length === 0) {
|
|
66
|
+
return expectedLine;
|
|
67
|
+
}
|
|
68
|
+
const label = 'Received: ';
|
|
69
|
+
if (isOnlyCall && (iExpectedCall === 0 || iExpectedCall === undefined)) {
|
|
70
|
+
const received = indexedCalls[0][1];
|
|
71
|
+
if (isLineDiffableCall(expected, received)) {
|
|
72
|
+
// Display diff without indentation.
|
|
73
|
+
const lines = [
|
|
74
|
+
EXPECTED_COLOR('- Expected'),
|
|
75
|
+
RECEIVED_COLOR('+ Received'),
|
|
76
|
+
'',
|
|
77
|
+
];
|
|
78
|
+
const length = Math.max(expected.length, received.length);
|
|
79
|
+
for (let i = 0; i < length; i += 1) {
|
|
80
|
+
if (i < expected.length && i < received.length) {
|
|
81
|
+
if (isEqualValue(expected[i], received[i])) {
|
|
82
|
+
lines.push(` ${printCommon(received[i])},`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (isLineDiffableArg(expected[i], received[i])) {
|
|
86
|
+
const difference = diff(expected[i], received[i], {
|
|
87
|
+
expand,
|
|
88
|
+
});
|
|
89
|
+
if (typeof difference === 'string' &&
|
|
90
|
+
difference.includes('- Expected') &&
|
|
91
|
+
difference.includes('+ Received')) {
|
|
92
|
+
// Omit annotation in case multiple args have diff.
|
|
93
|
+
lines.push(difference.split('\n').slice(3).join('\n') + ',');
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (i < expected.length) {
|
|
99
|
+
lines.push(EXPECTED_COLOR('- ' + stringify(expected[i])) + ',');
|
|
100
|
+
}
|
|
101
|
+
if (i < received.length) {
|
|
102
|
+
lines.push(RECEIVED_COLOR('+ ' + stringify(received[i])) + ',');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return lines.join('\n') + '\n';
|
|
106
|
+
}
|
|
107
|
+
return (expectedLine + label + printReceivedArgs(received, expected) + '\n');
|
|
108
|
+
}
|
|
109
|
+
const printAligned = getRightAlignedPrinter(label);
|
|
110
|
+
return (expectedLine +
|
|
111
|
+
'Received\n' +
|
|
112
|
+
indexedCalls.reduce((printed, [i, received]) => {
|
|
113
|
+
const aligned = printAligned(String(i + 1), i === iExpectedCall);
|
|
114
|
+
return (printed +
|
|
115
|
+
((i === iExpectedCall || iExpectedCall === undefined) &&
|
|
116
|
+
isLineDiffableCall(expected, received)
|
|
117
|
+
? aligned.replace(': ', '\n') +
|
|
118
|
+
printDiffCall(expected, received, expand)
|
|
119
|
+
: aligned + printReceivedArgs(received, expected)) +
|
|
120
|
+
'\n');
|
|
121
|
+
}, ''));
|
|
122
|
+
};
|
|
123
|
+
const indentation = 'Received'.replace(/\w/g, ' ');
|
|
124
|
+
const printDiffCall = (expected, received, expand) => received
|
|
125
|
+
.map((arg, i) => {
|
|
126
|
+
if (i < expected.length) {
|
|
127
|
+
if (isEqualValue(expected[i], arg)) {
|
|
128
|
+
return indentation + ' ' + printCommon(arg) + ',';
|
|
129
|
+
}
|
|
130
|
+
if (isLineDiffableArg(expected[i], arg)) {
|
|
131
|
+
const difference = diff(expected[i], arg, { expand });
|
|
132
|
+
if (typeof difference === 'string' &&
|
|
133
|
+
difference.includes('- Expected') &&
|
|
134
|
+
difference.includes('+ Received')) {
|
|
135
|
+
// Display diff with indentation.
|
|
136
|
+
// Omit annotation in case multiple args have diff.
|
|
137
|
+
return (difference
|
|
138
|
+
.split('\n')
|
|
139
|
+
.slice(3)
|
|
140
|
+
.map((line) => indentation + line)
|
|
141
|
+
.join('\n') + ',');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Display + only if received arg has no corresponding expected arg.
|
|
146
|
+
return (indentation +
|
|
147
|
+
(i < expected.length
|
|
148
|
+
? ' ' + printReceived(arg)
|
|
149
|
+
: RECEIVED_COLOR('+ ' + stringify(arg))) +
|
|
150
|
+
',');
|
|
151
|
+
})
|
|
152
|
+
.join('\n');
|
|
153
|
+
const isLineDiffableCall = (expected, received) => expected.some((arg, i) => i < received.length && isLineDiffableArg(arg, received[i]));
|
|
154
|
+
// Almost redundant with function in jest-matcher-utils,
|
|
155
|
+
// except no line diff for any strings.
|
|
156
|
+
const isLineDiffableArg = (expected, received) => {
|
|
157
|
+
const expectedType = getType(expected);
|
|
158
|
+
const receivedType = getType(received);
|
|
159
|
+
if (expectedType !== receivedType) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
if (isPrimitive(expected)) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
if (expectedType === 'date' ||
|
|
166
|
+
expectedType === 'function' ||
|
|
167
|
+
expectedType === 'regexp') {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
if (expected instanceof Error && received instanceof Error) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
if (expectedType === 'object' &&
|
|
174
|
+
typeof expected.asymmetricMatch === 'function') {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
if (receivedType === 'object' &&
|
|
178
|
+
typeof received.asymmetricMatch === 'function') {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
};
|
|
183
|
+
const printResult = (result, expected) => result.type === 'throw'
|
|
184
|
+
? 'function call threw an error'
|
|
185
|
+
: result.type === 'incomplete'
|
|
186
|
+
? 'function call has not returned yet'
|
|
187
|
+
: isEqualValue(expected, result.value)
|
|
188
|
+
? printCommon(result.value)
|
|
189
|
+
: printReceived(result.value);
|
|
190
|
+
// Return either empty string or one line per indexed result,
|
|
191
|
+
// so additional empty line can separate from `Number of returns` which follows.
|
|
192
|
+
const printReceivedResults = (label, expected, indexedResults, isOnlyCall, iExpectedCall) => {
|
|
193
|
+
if (indexedResults.length === 0) {
|
|
194
|
+
return '';
|
|
195
|
+
}
|
|
196
|
+
if (isOnlyCall && (iExpectedCall === 0 || iExpectedCall === undefined)) {
|
|
197
|
+
return label + printResult(indexedResults[0][1], expected) + '\n';
|
|
198
|
+
}
|
|
199
|
+
const printAligned = getRightAlignedPrinter(label);
|
|
200
|
+
return (label.replace(':', '').trim() +
|
|
201
|
+
'\n' +
|
|
202
|
+
indexedResults.reduce((printed, [i, result]) => printed +
|
|
203
|
+
printAligned(String(i + 1), i === iExpectedCall) +
|
|
204
|
+
printResult(result, expected) +
|
|
205
|
+
'\n', ''));
|
|
206
|
+
};
|
|
207
|
+
const createToBeCalledMatcher = (matcherName) => function (received, expected) {
|
|
208
|
+
const expectedArgument = '';
|
|
209
|
+
const options = {
|
|
210
|
+
isNot: this.isNot,
|
|
211
|
+
promise: this.promise,
|
|
212
|
+
};
|
|
213
|
+
ensureNoExpected(expected, matcherName, options);
|
|
214
|
+
ensureMockOrSpy(received, matcherName, expectedArgument, options);
|
|
215
|
+
const receivedIsSpy = isSpy(received);
|
|
216
|
+
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
|
|
217
|
+
const count = receivedIsSpy
|
|
218
|
+
? received.calls.count()
|
|
219
|
+
: received.mock.calls.length;
|
|
220
|
+
const calls = receivedIsSpy
|
|
221
|
+
? received.calls.all().map((x) => x.args)
|
|
222
|
+
: received.mock.calls;
|
|
223
|
+
const pass = count > 0;
|
|
224
|
+
const message = pass
|
|
225
|
+
? () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
226
|
+
'\n\n' +
|
|
227
|
+
`Expected number of calls: ${printExpected(0)}\n` +
|
|
228
|
+
`Received number of calls: ${printReceived(count)}\n\n` +
|
|
229
|
+
calls
|
|
230
|
+
.reduce((lines, args, i) => {
|
|
231
|
+
if (lines.length < PRINT_LIMIT) {
|
|
232
|
+
lines.push(`${i + 1}: ${printReceivedArgs(args)}`);
|
|
233
|
+
}
|
|
234
|
+
return lines;
|
|
235
|
+
}, [])
|
|
236
|
+
.join('\n')
|
|
237
|
+
: () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
238
|
+
'\n\n' +
|
|
239
|
+
`Expected number of calls: >= ${printExpected(1)}\n` +
|
|
240
|
+
`Received number of calls: ${printReceived(count)}`;
|
|
241
|
+
return { message, pass };
|
|
242
|
+
};
|
|
243
|
+
const createToReturnMatcher = (matcherName) => function (received, expected) {
|
|
244
|
+
const expectedArgument = '';
|
|
245
|
+
const options = {
|
|
246
|
+
isNot: this.isNot,
|
|
247
|
+
promise: this.promise,
|
|
248
|
+
};
|
|
249
|
+
ensureNoExpected(expected, matcherName, options);
|
|
250
|
+
ensureMock(received, matcherName, expectedArgument, options);
|
|
251
|
+
const receivedName = received.getMockName();
|
|
252
|
+
// Count return values that correspond only to calls that returned
|
|
253
|
+
const count = received.mock.results.reduce((n, result) => (result.type === 'return' ? n + 1 : n), 0);
|
|
254
|
+
const pass = count > 0;
|
|
255
|
+
const message = pass
|
|
256
|
+
? () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
257
|
+
'\n\n' +
|
|
258
|
+
`Expected number of returns: ${printExpected(0)}\n` +
|
|
259
|
+
`Received number of returns: ${printReceived(count)}\n\n` +
|
|
260
|
+
received.mock.results
|
|
261
|
+
.reduce((lines, result, i) => {
|
|
262
|
+
if (result.type === 'return' &&
|
|
263
|
+
lines.length < PRINT_LIMIT) {
|
|
264
|
+
lines.push(`${i + 1}: ${printReceived(result.value)}`);
|
|
265
|
+
}
|
|
266
|
+
return lines;
|
|
267
|
+
}, [])
|
|
268
|
+
.join('\n') +
|
|
269
|
+
(received.mock.calls.length !== count
|
|
270
|
+
? `\n\nReceived number of calls: ${printReceived(received.mock.calls.length)}`
|
|
271
|
+
: '')
|
|
272
|
+
: () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
273
|
+
'\n\n' +
|
|
274
|
+
`Expected number of returns: >= ${printExpected(1)}\n` +
|
|
275
|
+
`Received number of returns: ${printReceived(count)}` +
|
|
276
|
+
(received.mock.calls.length !== count
|
|
277
|
+
? `\nReceived number of calls: ${printReceived(received.mock.calls.length)}`
|
|
278
|
+
: '');
|
|
279
|
+
return { message, pass };
|
|
280
|
+
};
|
|
281
|
+
const createToBeCalledTimesMatcher = (matcherName) => function (received, expected) {
|
|
282
|
+
const expectedArgument = 'expected';
|
|
283
|
+
const options = {
|
|
284
|
+
isNot: this.isNot,
|
|
285
|
+
promise: this.promise,
|
|
286
|
+
};
|
|
287
|
+
ensureExpectedIsNonNegativeInteger(expected, matcherName, options);
|
|
288
|
+
ensureMockOrSpy(received, matcherName, expectedArgument, options);
|
|
289
|
+
const receivedIsSpy = isSpy(received);
|
|
290
|
+
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
|
|
291
|
+
const count = receivedIsSpy
|
|
292
|
+
? received.calls.count()
|
|
293
|
+
: received.mock.calls.length;
|
|
294
|
+
const pass = count === expected;
|
|
295
|
+
const message = pass
|
|
296
|
+
? () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
297
|
+
`\n\n` +
|
|
298
|
+
`Expected number of calls: not ${printExpected(expected)}`
|
|
299
|
+
: () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
300
|
+
'\n\n' +
|
|
301
|
+
`Expected number of calls: ${printExpected(expected)}\n` +
|
|
302
|
+
`Received number of calls: ${printReceived(count)}`;
|
|
303
|
+
return { message, pass };
|
|
304
|
+
};
|
|
305
|
+
const createToReturnTimesMatcher = (matcherName) => function (received, expected) {
|
|
306
|
+
const expectedArgument = 'expected';
|
|
307
|
+
const options = {
|
|
308
|
+
isNot: this.isNot,
|
|
309
|
+
promise: this.promise,
|
|
310
|
+
};
|
|
311
|
+
ensureExpectedIsNonNegativeInteger(expected, matcherName, options);
|
|
312
|
+
ensureMock(received, matcherName, expectedArgument, options);
|
|
313
|
+
const receivedName = received.getMockName();
|
|
314
|
+
// Count return values that correspond only to calls that returned
|
|
315
|
+
const count = received.mock.results.reduce((n, result) => (result.type === 'return' ? n + 1 : n), 0);
|
|
316
|
+
const pass = count === expected;
|
|
317
|
+
const message = pass
|
|
318
|
+
? () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
319
|
+
`\n\n` +
|
|
320
|
+
`Expected number of returns: not ${printExpected(expected)}` +
|
|
321
|
+
(received.mock.calls.length !== count
|
|
322
|
+
? `\n\nReceived number of calls: ${printReceived(received.mock.calls.length)}`
|
|
323
|
+
: '')
|
|
324
|
+
: () => matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
325
|
+
'\n\n' +
|
|
326
|
+
`Expected number of returns: ${printExpected(expected)}\n` +
|
|
327
|
+
`Received number of returns: ${printReceived(count)}` +
|
|
328
|
+
(received.mock.calls.length !== count
|
|
329
|
+
? `\nReceived number of calls: ${printReceived(received.mock.calls.length)}`
|
|
330
|
+
: '');
|
|
331
|
+
return { message, pass };
|
|
332
|
+
};
|
|
333
|
+
const createToBeCalledWithMatcher = (matcherName) => function (received, ...expected) {
|
|
334
|
+
const expectedArgument = '...expected';
|
|
335
|
+
const options = {
|
|
336
|
+
isNot: this.isNot,
|
|
337
|
+
promise: this.promise,
|
|
338
|
+
};
|
|
339
|
+
ensureMockOrSpy(received, matcherName, expectedArgument, options);
|
|
340
|
+
const receivedIsSpy = isSpy(received);
|
|
341
|
+
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
|
|
342
|
+
const calls = receivedIsSpy
|
|
343
|
+
? received.calls.all().map((x) => x.args)
|
|
344
|
+
: received.mock.calls;
|
|
345
|
+
const pass = calls.some((call) => isEqualCall(expected, call));
|
|
346
|
+
const message = pass
|
|
347
|
+
? () => {
|
|
348
|
+
// Some examples of calls that are equal to expected value.
|
|
349
|
+
const indexedCalls = [];
|
|
350
|
+
let i = 0;
|
|
351
|
+
while (i < calls.length &&
|
|
352
|
+
indexedCalls.length < PRINT_LIMIT) {
|
|
353
|
+
if (isEqualCall(expected, calls[i])) {
|
|
354
|
+
indexedCalls.push([i, calls[i]]);
|
|
355
|
+
}
|
|
356
|
+
i += 1;
|
|
357
|
+
}
|
|
358
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
359
|
+
'\n\n' +
|
|
360
|
+
`Expected: not ${printExpectedArgs(expected)}\n` +
|
|
361
|
+
(calls.length === 1 &&
|
|
362
|
+
stringify(calls[0]) === stringify(expected)
|
|
363
|
+
? ''
|
|
364
|
+
: printReceivedCallsNegative(expected, indexedCalls, calls.length === 1)) +
|
|
365
|
+
`\nNumber of calls: ${printReceived(calls.length)}`);
|
|
366
|
+
}
|
|
367
|
+
: () => {
|
|
368
|
+
// Some examples of calls that are not equal to expected value.
|
|
369
|
+
const indexedCalls = [];
|
|
370
|
+
let i = 0;
|
|
371
|
+
while (i < calls.length &&
|
|
372
|
+
indexedCalls.length < PRINT_LIMIT) {
|
|
373
|
+
indexedCalls.push([i, calls[i]]);
|
|
374
|
+
i += 1;
|
|
375
|
+
}
|
|
376
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
377
|
+
'\n\n' +
|
|
378
|
+
printExpectedReceivedCallsPositive(expected, indexedCalls, isExpand(this.expand), calls.length === 1) +
|
|
379
|
+
`\nNumber of calls: ${printReceived(calls.length)}`);
|
|
380
|
+
};
|
|
381
|
+
return { message, pass };
|
|
382
|
+
};
|
|
383
|
+
const createToReturnWithMatcher = (matcherName) => function (received, expected) {
|
|
384
|
+
const expectedArgument = 'expected';
|
|
385
|
+
const options = {
|
|
386
|
+
isNot: this.isNot,
|
|
387
|
+
promise: this.promise,
|
|
388
|
+
};
|
|
389
|
+
ensureMock(received, matcherName, expectedArgument, options);
|
|
390
|
+
const receivedName = received.getMockName();
|
|
391
|
+
const { calls, results } = received.mock;
|
|
392
|
+
const pass = results.some((result) => isEqualReturn(expected, result));
|
|
393
|
+
const message = pass
|
|
394
|
+
? () => {
|
|
395
|
+
// Some examples of results that are equal to expected value.
|
|
396
|
+
const indexedResults = [];
|
|
397
|
+
let i = 0;
|
|
398
|
+
while (i < results.length &&
|
|
399
|
+
indexedResults.length < PRINT_LIMIT) {
|
|
400
|
+
if (isEqualReturn(expected, results[i])) {
|
|
401
|
+
indexedResults.push([i, results[i]]);
|
|
402
|
+
}
|
|
403
|
+
i += 1;
|
|
404
|
+
}
|
|
405
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
406
|
+
'\n\n' +
|
|
407
|
+
`Expected: not ${printExpected(expected)}\n` +
|
|
408
|
+
(results.length === 1 &&
|
|
409
|
+
results[0].type === 'return' &&
|
|
410
|
+
stringify(results[0].value) === stringify(expected)
|
|
411
|
+
? ''
|
|
412
|
+
: printReceivedResults('Received: ', expected, indexedResults, results.length === 1)) +
|
|
413
|
+
printNumberOfReturns(countReturns(results), calls.length));
|
|
414
|
+
}
|
|
415
|
+
: () => {
|
|
416
|
+
// Some examples of results that are not equal to expected value.
|
|
417
|
+
const indexedResults = [];
|
|
418
|
+
let i = 0;
|
|
419
|
+
while (i < results.length &&
|
|
420
|
+
indexedResults.length < PRINT_LIMIT) {
|
|
421
|
+
indexedResults.push([i, results[i]]);
|
|
422
|
+
i += 1;
|
|
423
|
+
}
|
|
424
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
425
|
+
'\n\n' +
|
|
426
|
+
`Expected: ${printExpected(expected)}\n` +
|
|
427
|
+
printReceivedResults('Received: ', expected, indexedResults, results.length === 1) +
|
|
428
|
+
printNumberOfReturns(countReturns(results), calls.length));
|
|
429
|
+
};
|
|
430
|
+
return { message, pass };
|
|
431
|
+
};
|
|
432
|
+
const createLastCalledWithMatcher = (matcherName) => function (received, ...expected) {
|
|
433
|
+
const expectedArgument = '...expected';
|
|
434
|
+
const options = {
|
|
435
|
+
isNot: this.isNot,
|
|
436
|
+
promise: this.promise,
|
|
437
|
+
};
|
|
438
|
+
ensureMockOrSpy(received, matcherName, expectedArgument, options);
|
|
439
|
+
const receivedIsSpy = isSpy(received);
|
|
440
|
+
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
|
|
441
|
+
const calls = receivedIsSpy
|
|
442
|
+
? received.calls.all().map((x) => x.args)
|
|
443
|
+
: received.mock.calls;
|
|
444
|
+
const iLast = calls.length - 1;
|
|
445
|
+
const pass = iLast >= 0 && isEqualCall(expected, calls[iLast]);
|
|
446
|
+
const message = pass
|
|
447
|
+
? () => {
|
|
448
|
+
const indexedCalls = [];
|
|
449
|
+
if (iLast > 0) {
|
|
450
|
+
// Display preceding call as context.
|
|
451
|
+
indexedCalls.push([iLast - 1, calls[iLast - 1]]);
|
|
452
|
+
}
|
|
453
|
+
indexedCalls.push([iLast, calls[iLast]]);
|
|
454
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
455
|
+
'\n\n' +
|
|
456
|
+
`Expected: not ${printExpectedArgs(expected)}\n` +
|
|
457
|
+
(calls.length === 1 &&
|
|
458
|
+
stringify(calls[0]) === stringify(expected)
|
|
459
|
+
? ''
|
|
460
|
+
: printReceivedCallsNegative(expected, indexedCalls, calls.length === 1, iLast)) +
|
|
461
|
+
`\nNumber of calls: ${printReceived(calls.length)}`);
|
|
462
|
+
}
|
|
463
|
+
: () => {
|
|
464
|
+
const indexedCalls = [];
|
|
465
|
+
if (iLast >= 0) {
|
|
466
|
+
if (iLast > 0) {
|
|
467
|
+
let i = iLast - 1;
|
|
468
|
+
// Is there a preceding call that is equal to expected args?
|
|
469
|
+
while (i >= 0 && !isEqualCall(expected, calls[i])) {
|
|
470
|
+
i -= 1;
|
|
471
|
+
}
|
|
472
|
+
if (i < 0) {
|
|
473
|
+
i = iLast - 1; // otherwise, preceding call
|
|
474
|
+
}
|
|
475
|
+
indexedCalls.push([i, calls[i]]);
|
|
476
|
+
}
|
|
477
|
+
indexedCalls.push([iLast, calls[iLast]]);
|
|
478
|
+
}
|
|
479
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
480
|
+
'\n\n' +
|
|
481
|
+
printExpectedReceivedCallsPositive(expected, indexedCalls, isExpand(this.expand), calls.length === 1, iLast) +
|
|
482
|
+
`\nNumber of calls: ${printReceived(calls.length)}`);
|
|
483
|
+
};
|
|
484
|
+
return { message, pass };
|
|
485
|
+
};
|
|
486
|
+
const createLastReturnedMatcher = (matcherName) => function (received, expected) {
|
|
487
|
+
const expectedArgument = 'expected';
|
|
488
|
+
const options = {
|
|
489
|
+
isNot: this.isNot,
|
|
490
|
+
promise: this.promise,
|
|
491
|
+
};
|
|
492
|
+
ensureMock(received, matcherName, expectedArgument, options);
|
|
493
|
+
const receivedName = received.getMockName();
|
|
494
|
+
const { calls, results } = received.mock;
|
|
495
|
+
const iLast = results.length - 1;
|
|
496
|
+
const pass = iLast >= 0 && isEqualReturn(expected, results[iLast]);
|
|
497
|
+
const message = pass
|
|
498
|
+
? () => {
|
|
499
|
+
const indexedResults = [];
|
|
500
|
+
if (iLast > 0) {
|
|
501
|
+
// Display preceding result as context.
|
|
502
|
+
indexedResults.push([iLast - 1, results[iLast - 1]]);
|
|
503
|
+
}
|
|
504
|
+
indexedResults.push([iLast, results[iLast]]);
|
|
505
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
506
|
+
'\n\n' +
|
|
507
|
+
`Expected: not ${printExpected(expected)}\n` +
|
|
508
|
+
(results.length === 1 &&
|
|
509
|
+
results[0].type === 'return' &&
|
|
510
|
+
stringify(results[0].value) === stringify(expected)
|
|
511
|
+
? ''
|
|
512
|
+
: printReceivedResults('Received: ', expected, indexedResults, results.length === 1, iLast)) +
|
|
513
|
+
printNumberOfReturns(countReturns(results), calls.length));
|
|
514
|
+
}
|
|
515
|
+
: () => {
|
|
516
|
+
const indexedResults = [];
|
|
517
|
+
if (iLast >= 0) {
|
|
518
|
+
if (iLast > 0) {
|
|
519
|
+
let i = iLast - 1;
|
|
520
|
+
// Is there a preceding result that is equal to expected value?
|
|
521
|
+
while (i >= 0 &&
|
|
522
|
+
!isEqualReturn(expected, results[i])) {
|
|
523
|
+
i -= 1;
|
|
524
|
+
}
|
|
525
|
+
if (i < 0) {
|
|
526
|
+
i = iLast - 1; // otherwise, preceding result
|
|
527
|
+
}
|
|
528
|
+
indexedResults.push([i, results[i]]);
|
|
529
|
+
}
|
|
530
|
+
indexedResults.push([iLast, results[iLast]]);
|
|
531
|
+
}
|
|
532
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
533
|
+
'\n\n' +
|
|
534
|
+
`Expected: ${printExpected(expected)}\n` +
|
|
535
|
+
printReceivedResults('Received: ', expected, indexedResults, results.length === 1, iLast) +
|
|
536
|
+
printNumberOfReturns(countReturns(results), calls.length));
|
|
537
|
+
};
|
|
538
|
+
return { message, pass };
|
|
539
|
+
};
|
|
540
|
+
const createNthCalledWithMatcher = (matcherName) => function (received, nth, ...expected) {
|
|
541
|
+
const expectedArgument = 'n';
|
|
542
|
+
const options = {
|
|
543
|
+
expectedColor: (arg) => arg,
|
|
544
|
+
isNot: this.isNot,
|
|
545
|
+
promise: this.promise,
|
|
546
|
+
secondArgument: '...expected',
|
|
547
|
+
};
|
|
548
|
+
ensureMockOrSpy(received, matcherName, expectedArgument, options);
|
|
549
|
+
if (!Number.isSafeInteger(nth) || nth < 1) {
|
|
550
|
+
throw new Error(matcherErrorMessage(matcherHint(matcherName, undefined, expectedArgument, options), `${expectedArgument} must be a positive integer`, printWithType(expectedArgument, nth, stringify)));
|
|
551
|
+
}
|
|
552
|
+
const receivedIsSpy = isSpy(received);
|
|
553
|
+
const receivedName = receivedIsSpy ? 'spy' : received.getMockName();
|
|
554
|
+
const calls = receivedIsSpy
|
|
555
|
+
? received.calls.all().map((x) => x.args)
|
|
556
|
+
: received.mock.calls;
|
|
557
|
+
const length = calls.length;
|
|
558
|
+
const iNth = nth - 1;
|
|
559
|
+
const pass = iNth < length && isEqualCall(expected, calls[iNth]);
|
|
560
|
+
const message = pass
|
|
561
|
+
? () => {
|
|
562
|
+
// Display preceding and following calls,
|
|
563
|
+
// in case assertions fails because index is off by one.
|
|
564
|
+
const indexedCalls = [];
|
|
565
|
+
if (iNth - 1 >= 0) {
|
|
566
|
+
indexedCalls.push([iNth - 1, calls[iNth - 1]]);
|
|
567
|
+
}
|
|
568
|
+
indexedCalls.push([iNth, calls[iNth]]);
|
|
569
|
+
if (iNth + 1 < length) {
|
|
570
|
+
indexedCalls.push([iNth + 1, calls[iNth + 1]]);
|
|
571
|
+
}
|
|
572
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
573
|
+
'\n\n' +
|
|
574
|
+
`n: ${nth}\n` +
|
|
575
|
+
`Expected: not ${printExpectedArgs(expected)}\n` +
|
|
576
|
+
(calls.length === 1 &&
|
|
577
|
+
stringify(calls[0]) === stringify(expected)
|
|
578
|
+
? ''
|
|
579
|
+
: printReceivedCallsNegative(expected, indexedCalls, calls.length === 1, iNth)) +
|
|
580
|
+
`\nNumber of calls: ${printReceived(calls.length)}`);
|
|
581
|
+
}
|
|
582
|
+
: () => {
|
|
583
|
+
// Display preceding and following calls:
|
|
584
|
+
// * nearest call that is equal to expected args
|
|
585
|
+
// * otherwise, adjacent call
|
|
586
|
+
// in case assertions fails because of index, especially off by one.
|
|
587
|
+
const indexedCalls = [];
|
|
588
|
+
if (iNth < length) {
|
|
589
|
+
if (iNth - 1 >= 0) {
|
|
590
|
+
let i = iNth - 1;
|
|
591
|
+
// Is there a preceding call that is equal to expected args?
|
|
592
|
+
while (i >= 0 && !isEqualCall(expected, calls[i])) {
|
|
593
|
+
i -= 1;
|
|
594
|
+
}
|
|
595
|
+
if (i < 0) {
|
|
596
|
+
i = iNth - 1; // otherwise, adjacent call
|
|
597
|
+
}
|
|
598
|
+
indexedCalls.push([i, calls[i]]);
|
|
599
|
+
}
|
|
600
|
+
indexedCalls.push([iNth, calls[iNth]]);
|
|
601
|
+
if (iNth + 1 < length) {
|
|
602
|
+
let i = iNth + 1;
|
|
603
|
+
// Is there a following call that is equal to expected args?
|
|
604
|
+
while (i < length &&
|
|
605
|
+
!isEqualCall(expected, calls[i])) {
|
|
606
|
+
i += 1;
|
|
607
|
+
}
|
|
608
|
+
if (i >= length) {
|
|
609
|
+
i = iNth + 1; // otherwise, adjacent call
|
|
610
|
+
}
|
|
611
|
+
indexedCalls.push([i, calls[i]]);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
else if (length > 0) {
|
|
615
|
+
// The number of received calls is fewer than the expected number.
|
|
616
|
+
let i = length - 1;
|
|
617
|
+
// Is there a call that is equal to expected args?
|
|
618
|
+
while (i >= 0 && !isEqualCall(expected, calls[i])) {
|
|
619
|
+
i -= 1;
|
|
620
|
+
}
|
|
621
|
+
if (i < 0) {
|
|
622
|
+
i = length - 1; // otherwise, last call
|
|
623
|
+
}
|
|
624
|
+
indexedCalls.push([i, calls[i]]);
|
|
625
|
+
}
|
|
626
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
627
|
+
'\n\n' +
|
|
628
|
+
`n: ${nth}\n` +
|
|
629
|
+
printExpectedReceivedCallsPositive(expected, indexedCalls, isExpand(this.expand), calls.length === 1, iNth) +
|
|
630
|
+
`\nNumber of calls: ${printReceived(calls.length)}`);
|
|
631
|
+
};
|
|
632
|
+
return { message, pass };
|
|
633
|
+
};
|
|
634
|
+
const createNthReturnedWithMatcher = (matcherName) => function (received, nth, expected) {
|
|
635
|
+
const expectedArgument = 'n';
|
|
636
|
+
const options = {
|
|
637
|
+
expectedColor: (arg) => arg,
|
|
638
|
+
isNot: this.isNot,
|
|
639
|
+
promise: this.promise,
|
|
640
|
+
secondArgument: 'expected',
|
|
641
|
+
};
|
|
642
|
+
ensureMock(received, matcherName, expectedArgument, options);
|
|
643
|
+
if (!Number.isSafeInteger(nth) || nth < 1) {
|
|
644
|
+
throw new Error(matcherErrorMessage(matcherHint(matcherName, undefined, expectedArgument, options), `${expectedArgument} must be a positive integer`, printWithType(expectedArgument, nth, stringify)));
|
|
645
|
+
}
|
|
646
|
+
const receivedName = received.getMockName();
|
|
647
|
+
const { calls, results } = received.mock;
|
|
648
|
+
const length = results.length;
|
|
649
|
+
const iNth = nth - 1;
|
|
650
|
+
const pass = iNth < length && isEqualReturn(expected, results[iNth]);
|
|
651
|
+
const message = pass
|
|
652
|
+
? () => {
|
|
653
|
+
// Display preceding and following results,
|
|
654
|
+
// in case assertions fails because index is off by one.
|
|
655
|
+
const indexedResults = [];
|
|
656
|
+
if (iNth - 1 >= 0) {
|
|
657
|
+
indexedResults.push([iNth - 1, results[iNth - 1]]);
|
|
658
|
+
}
|
|
659
|
+
indexedResults.push([iNth, results[iNth]]);
|
|
660
|
+
if (iNth + 1 < length) {
|
|
661
|
+
indexedResults.push([iNth + 1, results[iNth + 1]]);
|
|
662
|
+
}
|
|
663
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
664
|
+
'\n\n' +
|
|
665
|
+
`n: ${nth}\n` +
|
|
666
|
+
`Expected: not ${printExpected(expected)}\n` +
|
|
667
|
+
(results.length === 1 &&
|
|
668
|
+
results[0].type === 'return' &&
|
|
669
|
+
stringify(results[0].value) === stringify(expected)
|
|
670
|
+
? ''
|
|
671
|
+
: printReceivedResults('Received: ', expected, indexedResults, results.length === 1, iNth)) +
|
|
672
|
+
printNumberOfReturns(countReturns(results), calls.length));
|
|
673
|
+
}
|
|
674
|
+
: () => {
|
|
675
|
+
// Display preceding and following results:
|
|
676
|
+
// * nearest result that is equal to expected value
|
|
677
|
+
// * otherwise, adjacent result
|
|
678
|
+
// in case assertions fails because of index, especially off by one.
|
|
679
|
+
const indexedResults = [];
|
|
680
|
+
if (iNth < length) {
|
|
681
|
+
if (iNth - 1 >= 0) {
|
|
682
|
+
let i = iNth - 1;
|
|
683
|
+
// Is there a preceding result that is equal to expected value?
|
|
684
|
+
while (i >= 0 &&
|
|
685
|
+
!isEqualReturn(expected, results[i])) {
|
|
686
|
+
i -= 1;
|
|
687
|
+
}
|
|
688
|
+
if (i < 0) {
|
|
689
|
+
i = iNth - 1; // otherwise, adjacent result
|
|
690
|
+
}
|
|
691
|
+
indexedResults.push([i, results[i]]);
|
|
692
|
+
}
|
|
693
|
+
indexedResults.push([iNth, results[iNth]]);
|
|
694
|
+
if (iNth + 1 < length) {
|
|
695
|
+
let i = iNth + 1;
|
|
696
|
+
// Is there a following result that is equal to expected value?
|
|
697
|
+
while (i < length &&
|
|
698
|
+
!isEqualReturn(expected, results[i])) {
|
|
699
|
+
i += 1;
|
|
700
|
+
}
|
|
701
|
+
if (i >= length) {
|
|
702
|
+
i = iNth + 1; // otherwise, adjacent result
|
|
703
|
+
}
|
|
704
|
+
indexedResults.push([i, results[i]]);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
else if (length > 0) {
|
|
708
|
+
// The number of received calls is fewer than the expected number.
|
|
709
|
+
let i = length - 1;
|
|
710
|
+
// Is there a result that is equal to expected value?
|
|
711
|
+
while (i >= 0 && !isEqualReturn(expected, results[i])) {
|
|
712
|
+
i -= 1;
|
|
713
|
+
}
|
|
714
|
+
if (i < 0) {
|
|
715
|
+
i = length - 1; // otherwise, last result
|
|
716
|
+
}
|
|
717
|
+
indexedResults.push([i, results[i]]);
|
|
718
|
+
}
|
|
719
|
+
return (matcherHint(matcherName, receivedName, expectedArgument, options) +
|
|
720
|
+
'\n\n' +
|
|
721
|
+
`n: ${nth}\n` +
|
|
722
|
+
`Expected: ${printExpected(expected)}\n` +
|
|
723
|
+
printReceivedResults('Received: ', expected, indexedResults, results.length === 1, iNth) +
|
|
724
|
+
printNumberOfReturns(countReturns(results), calls.length));
|
|
725
|
+
};
|
|
726
|
+
return { message, pass };
|
|
727
|
+
};
|
|
728
|
+
const spyMatchers = {
|
|
729
|
+
lastCalledWith: createLastCalledWithMatcher('lastCalledWith'),
|
|
730
|
+
lastReturnedWith: createLastReturnedMatcher('lastReturnedWith'),
|
|
731
|
+
nthCalledWith: createNthCalledWithMatcher('nthCalledWith'),
|
|
732
|
+
nthReturnedWith: createNthReturnedWithMatcher('nthReturnedWith'),
|
|
733
|
+
toBeCalled: createToBeCalledMatcher('toBeCalled'),
|
|
734
|
+
toBeCalledTimes: createToBeCalledTimesMatcher('toBeCalledTimes'),
|
|
735
|
+
toBeCalledWith: createToBeCalledWithMatcher('toBeCalledWith'),
|
|
736
|
+
toHaveBeenCalled: createToBeCalledMatcher('toHaveBeenCalled'),
|
|
737
|
+
toHaveBeenCalledTimes: createToBeCalledTimesMatcher('toHaveBeenCalledTimes'),
|
|
738
|
+
toHaveBeenCalledWith: createToBeCalledWithMatcher('toHaveBeenCalledWith'),
|
|
739
|
+
toHaveBeenLastCalledWith: createLastCalledWithMatcher('toHaveBeenLastCalledWith'),
|
|
740
|
+
toHaveBeenNthCalledWith: createNthCalledWithMatcher('toHaveBeenNthCalledWith'),
|
|
741
|
+
toHaveLastReturnedWith: createLastReturnedMatcher('toHaveLastReturnedWith'),
|
|
742
|
+
toHaveNthReturnedWith: createNthReturnedWithMatcher('toHaveNthReturnedWith'),
|
|
743
|
+
toHaveReturned: createToReturnMatcher('toHaveReturned'),
|
|
744
|
+
toHaveReturnedTimes: createToReturnTimesMatcher('toHaveReturnedTimes'),
|
|
745
|
+
toHaveReturnedWith: createToReturnWithMatcher('toHaveReturnedWith'),
|
|
746
|
+
toReturn: createToReturnMatcher('toReturn'),
|
|
747
|
+
toReturnTimes: createToReturnTimesMatcher('toReturnTimes'),
|
|
748
|
+
toReturnWith: createToReturnWithMatcher('toReturnWith'),
|
|
749
|
+
};
|
|
750
|
+
const isMock = (received) => received != null && received._isMockFunction === true;
|
|
751
|
+
const isSpy = (received) => received != null &&
|
|
752
|
+
received.calls != null &&
|
|
753
|
+
typeof received.calls.all === 'function' &&
|
|
754
|
+
typeof received.calls.count === 'function';
|
|
755
|
+
const ensureMockOrSpy = (received, matcherName, expectedArgument, options) => {
|
|
756
|
+
if (!isMock(received) && !isSpy(received)) {
|
|
757
|
+
throw new Error(matcherErrorMessage(matcherHint(matcherName, undefined, expectedArgument, options), `${RECEIVED_COLOR('received')} value must be a mock or spy function`, printWithType('Received', received, printReceived)));
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
const ensureMock = (received, matcherName, expectedArgument, options) => {
|
|
761
|
+
if (!isMock(received)) {
|
|
762
|
+
throw new Error(matcherErrorMessage(matcherHint(matcherName, undefined, expectedArgument, options), `${RECEIVED_COLOR('received')} value must be a mock function`, printWithType('Received', received, printReceived)));
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
export default spyMatchers;
|
|
766
|
+
//# sourceMappingURL=spyMatchers.js.map
|