0
# Value Validation
1
2
Functions for validating types and values in matcher operations, ensuring proper input types and throwing informative errors when validation fails.
3
4
## Capabilities
5
6
### Ensure No Expected
7
8
Validates that a matcher doesn't receive an unexpected expected argument.
9
10
```typescript { .api }
11
/**
12
* Validate that matcher doesn't receive an expected argument
13
* @param expected - Expected value to check
14
* @param matcherName - Name of the matcher
15
* @param options - Formatting options
16
* @throws Error if expected is not undefined
17
*/
18
function ensureNoExpected(
19
expected: unknown,
20
matcherName: string,
21
options?: MatcherHintOptions
22
): void;
23
```
24
25
**Usage Examples:**
26
27
```typescript
28
import { ensureNoExpected } from "jest-matcher-utils";
29
30
// Validate that matcher takes no expected argument
31
function toBeEmpty(received: unknown, expected: unknown) {
32
// This matcher should not receive an expected argument
33
ensureNoExpected(expected, 'toBeEmpty');
34
35
// Continue with matcher logic...
36
}
37
38
// With custom options
39
function toHaveBeenCalled(received: unknown, expected: unknown) {
40
ensureNoExpected(expected, 'toHaveBeenCalled', {
41
isDirectExpectCall: true
42
});
43
}
44
45
// Throws descriptive error if expected is provided:
46
// Error: expect(received).toBeEmpty()
47
//
48
// Matcher error: this matcher must not have an expected argument
49
//
50
// Expected has type: number
51
// Expected has value: 42
52
```
53
54
### Ensure Actual Is Number
55
56
Validates that the actual (received) value is a number or bigint.
57
58
```typescript { .api }
59
/**
60
* Validate that actual value is a number or bigint
61
* @param actual - Actual value to validate
62
* @param matcherName - Name of the matcher
63
* @param options - Formatting options
64
* @throws Error if actual is not number or bigint
65
*/
66
function ensureActualIsNumber(
67
actual: unknown,
68
matcherName: string,
69
options?: MatcherHintOptions
70
): void;
71
```
72
73
**Usage Examples:**
74
75
```typescript
76
import { ensureActualIsNumber } from "jest-matcher-utils";
77
78
// Validate received value is numeric
79
function toBeGreaterThan(received: unknown, expected: number) {
80
ensureActualIsNumber(received, 'toBeGreaterThan');
81
82
// Now safe to use received as number
83
return (received as number) > expected;
84
}
85
86
// Works with bigint too
87
function toBeLessThan(received: unknown, expected: bigint) {
88
ensureActualIsNumber(received, 'toBeLessThan');
89
// received is validated as number | bigint
90
}
91
92
// With options for negated matchers
93
function toBePositive(received: unknown) {
94
ensureActualIsNumber(received, 'toBePositive', { isNot: false });
95
}
96
97
// Throws descriptive error for invalid types:
98
// Error: expect(received).toBeGreaterThan(expected)
99
//
100
// Matcher error: received value must be a number or bigint
101
//
102
// Received has type: string
103
// Received has value: "not a number"
104
```
105
106
### Ensure Expected Is Number
107
108
Validates that the expected value is a number or bigint.
109
110
```typescript { .api }
111
/**
112
* Validate that expected value is a number or bigint
113
* @param expected - Expected value to validate
114
* @param matcherName - Name of the matcher
115
* @param options - Formatting options
116
* @throws Error if expected is not number or bigint
117
*/
118
function ensureExpectedIsNumber(
119
expected: unknown,
120
matcherName: string,
121
options?: MatcherHintOptions
122
): void;
123
```
124
125
**Usage Examples:**
126
127
```typescript
128
import { ensureExpectedIsNumber } from "jest-matcher-utils";
129
130
// Validate expected value is numeric
131
function toBeCloseTo(received: number, expected: unknown, precision = 2) {
132
ensureExpectedIsNumber(expected, 'toBeCloseTo');
133
134
// Now safe to use expected as number
135
const diff = Math.abs(received - (expected as number));
136
return diff < Math.pow(10, -precision);
137
}
138
139
// Custom validation messages
140
function toBeWithinRange(received: number, min: unknown, max: number) {
141
ensureExpectedIsNumber(min, 'toBeWithinRange', {
142
secondArgument: 'min'
143
});
144
}
145
146
// Throws error for invalid expected types:
147
// Error: expect(received).toBeCloseTo(expected)
148
//
149
// Matcher error: expected value must be a number or bigint
150
//
151
// Expected has type: string
152
// Expected has value: "42"
153
```
154
155
### Ensure Numbers
156
157
Validates that both actual and expected values are numbers or bigints.
158
159
```typescript { .api }
160
/**
161
* Validate that both actual and expected values are numbers or bigints
162
* @param actual - Actual value to validate
163
* @param expected - Expected value to validate
164
* @param matcherName - Name of the matcher
165
* @param options - Formatting options
166
* @throws Error if either value is not number or bigint
167
*/
168
function ensureNumbers(
169
actual: unknown,
170
expected: unknown,
171
matcherName: string,
172
options?: MatcherHintOptions
173
): void;
174
```
175
176
**Usage Examples:**
177
178
```typescript
179
import { ensureNumbers } from "jest-matcher-utils";
180
181
// Validate both values are numeric
182
function toBeGreaterThan(received: unknown, expected: unknown) {
183
ensureNumbers(received, expected, 'toBeGreaterThan');
184
185
// Both values are now validated as number | bigint
186
return (received as number) > (expected as number);
187
}
188
189
// Common pattern for arithmetic matchers
190
function toBeCloseTo(received: unknown, expected: unknown, precision = 2) {
191
ensureNumbers(received, expected, 'toBeCloseTo');
192
193
const diff = Math.abs((received as number) - (expected as number));
194
return diff < Math.pow(10, -precision);
195
}
196
197
// Validates both and throws for first invalid value found
198
```
199
200
### Ensure Expected Is Non-Negative Integer
201
202
Validates that the expected value is a non-negative integer (safe integer ≥ 0).
203
204
```typescript { .api }
205
/**
206
* Validate that expected value is a non-negative integer
207
* @param expected - Expected value to validate
208
* @param matcherName - Name of the matcher
209
* @param options - Formatting options
210
* @throws Error if expected is not a non-negative integer
211
*/
212
function ensureExpectedIsNonNegativeInteger(
213
expected: unknown,
214
matcherName: string,
215
options?: MatcherHintOptions
216
): void;
217
```
218
219
**Usage Examples:**
220
221
```typescript
222
import { ensureExpectedIsNonNegativeInteger } from "jest-matcher-utils";
223
224
// Validate expected is a valid array length/index
225
function toHaveLength(received: unknown[], expected: unknown) {
226
ensureExpectedIsNonNegativeInteger(expected, 'toHaveLength');
227
228
// expected is now validated as non-negative integer
229
return received.length === expected;
230
}
231
232
// For precision arguments
233
function toBeCloseTo(received: number, expected: number, precision: unknown = 2) {
234
ensureExpectedIsNonNegativeInteger(precision, 'toBeCloseTo', {
235
secondArgument: 'precision'
236
});
237
}
238
239
// Validation rules:
240
// - Must be a number (not bigint)
241
// - Must be a safe integer (Number.isSafeInteger)
242
// - Must be >= 0
243
244
// Valid values: 0, 1, 2, 100, Number.MAX_SAFE_INTEGER
245
// Invalid values: -1, 1.5, NaN, Infinity, "5", null
246
247
// Throws error for invalid values:
248
// Error: expect(received).toHaveLength(expected)
249
//
250
// Matcher error: expected value must be a non-negative integer
251
//
252
// Expected has type: number
253
// Expected has value: -1
254
```
255
256
## Error Handling
257
258
All validation functions throw errors using the `matcherErrorMessage` format, providing:
259
260
- Clear matcher hint showing expected usage
261
- Descriptive error message explaining the validation requirement
262
- Specific type and value information using `printWithType` when validation fails
263
264
The errors integrate seamlessly with Jest's error reporting system to provide clear feedback to developers about incorrect matcher usage.