0
# Assertions
1
2
Comprehensive assertion library providing deep equality, pattern matching, type checking, error handling, and promise testing with detailed failure reporting. The TAP assertion API includes over 30 methods for thorough testing.
3
4
## Core Imports
5
6
```typescript
7
import { test, ok, same, throws, equal } from "tap";
8
// All assertion methods are available on the test instance 't'
9
```
10
11
## Types
12
13
```typescript { .api }
14
type MessageExtra = [] | [msg: string, extra?: Extra] | [extra: Extra];
15
16
type ThrowsArgs =
17
| []
18
| [msg: string, extra?: Extra]
19
| [wanted: ErrorMatch, ...messageExtra: MessageExtra];
20
21
interface Extra {
22
[key: string]: any;
23
compareOptions?: CompareOptions;
24
// Additional optional properties for test metadata
25
}
26
27
type ErrorMatch = Error | typeof Error | RegExp | { message?: string | RegExp; [k: string]: any };
28
```
29
30
## Capabilities
31
32
### Basic Assertions
33
34
Core assertion methods for testing truthiness and basic conditions.
35
36
```typescript { .api }
37
/**
38
* Verify that the value is truthy
39
*/
40
function ok(obj: any, ...[msg, extra]: MessageExtra): boolean;
41
42
/**
43
* Verify that the value is not truthy
44
*/
45
function notOk(obj: any, ...[msg, extra]: MessageExtra): boolean;
46
47
/**
48
* A passing (ok) Test Point
49
*/
50
function pass(...[msg, extra]: MessageExtra): boolean;
51
52
/**
53
* A failing (not ok) Test Point
54
*/
55
function fail(...[msg, extra]: MessageExtra): boolean;
56
```
57
58
**Usage Examples:**
59
60
```typescript
61
import { test } from "tap";
62
63
test("basic assertions", (t) => {
64
t.ok(true, "true is truthy");
65
t.ok(1, "1 is truthy");
66
t.ok("hello", "non-empty string is truthy");
67
68
t.notOk(false, "false is falsy");
69
t.notOk(0, "0 is falsy");
70
t.notOk("", "empty string is falsy");
71
72
t.pass("this always passes");
73
// t.fail("this would always fail");
74
75
t.end();
76
});
77
```
78
79
### Equality Assertions
80
81
Deep comparison methods for testing equality and inequality with different comparison strategies.
82
83
```typescript { .api }
84
/**
85
* Verify that the values are equal (strict equality with type guard)
86
*/
87
function equal<T extends unknown>(
88
found: any,
89
wanted: T,
90
...[msg, extra]: MessageExtra
91
): found is T;
92
93
/**
94
* Verify that the values are not equal (strict inequality)
95
*/
96
function not(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
97
98
/**
99
* Verify that the value is loosely equivalent to the supplied pattern
100
*/
101
function same(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
102
103
/**
104
* Verify that the value is not loosely equivalent to the supplied pattern
105
*/
106
function notSame(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
107
108
/**
109
* Verify that the value is strictly equivalent to the supplied pattern
110
*/
111
function strictSame<T extends unknown>(
112
found: any,
113
wanted: T,
114
...[msg, extra]: MessageExtra
115
): found is T;
116
117
/**
118
* Verify that the value is not strictly equivalent to the supplied pattern
119
*/
120
function strictNotSame(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
121
```
122
123
**Usage Examples:**
124
125
```typescript
126
test("equality assertions", (t) => {
127
// Strict equality with type guard
128
t.equal(5, 5, "numbers are strictly equal");
129
t.not("1", 1, "string and number are not equal");
130
131
// Deep object equality
132
t.same({ a: 1, b: 2 }, { a: 1, b: 2 }, "objects are loosely equal");
133
t.strictSame([1, 2, 3], [1, 2, 3], "arrays are strictly equal");
134
135
// Inequality
136
t.notSame({ a: 1 }, { a: 2 }, "objects are different");
137
t.strictNotSame("1", 1, "string and number are strictly different");
138
139
t.end();
140
});
141
```
142
143
### Object Property Assertions
144
145
Methods for testing object properties and structure with various comparison modes.
146
147
```typescript { .api }
148
/**
149
* Verify that the object has all properties and values in the pattern (loose comparison)
150
*/
151
function has(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
152
153
/**
154
* Verify that the object does NOT have all properties and values in the pattern (loose comparison)
155
*/
156
function notHas(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
157
158
/**
159
* Verify that the value has all properties and values in the pattern (strict comparison)
160
*/
161
function hasStrict(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
162
163
/**
164
* Verify that the value does NOT contain all properties and values in the pattern (strict comparison)
165
*/
166
function notHasStrict(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
167
```
168
169
**Usage Examples:**
170
171
```typescript
172
test("property assertions", (t) => {
173
const user = { name: "Alice", age: 30, active: true };
174
175
t.has(user, { name: "Alice" }, "user has name property");
176
t.has(user, { name: "Alice", age: 30 }, "user has name and age");
177
t.notHas(user, { email: "test@example.com" }, "user doesn't have email");
178
179
// Strict comparison
180
t.hasStrict(user, { age: 30 }, "user has exact age");
181
t.notHasStrict(user, { age: "30" }, "user age is number, not string");
182
183
t.end();
184
});
185
```
186
187
### Property Existence Methods
188
189
Methods for checking individual or multiple property existence.
190
191
```typescript { .api }
192
/**
193
* Verify that the object has the wanted property, anywhere in its prototype chain
194
*/
195
function hasProp<T extends {}>(
196
found: T,
197
wanted: string | number | symbol,
198
...[msg, extra]: MessageExtra
199
): boolean;
200
201
/**
202
* Verify that the object has the wanted property, using Object#hasOwnProperty
203
*/
204
function hasOwnProp<T extends {}>(
205
found: T,
206
wanted: string | number | symbol,
207
...[msg, extra]: MessageExtra
208
): boolean;
209
210
/**
211
* Verify that the object has all properties in the wanted list, anywhere in its prototype chain
212
*/
213
function hasProps<T extends {}>(
214
found: T,
215
wanted: Iterable<string | number | symbol>,
216
...[msg, extra]: MessageExtra
217
): boolean;
218
219
/**
220
* Verify that the object has all properties in the wanted list, using Object#hasOwnProperties()
221
*/
222
function hasOwnProps<T extends {}>(
223
found: T,
224
wanted: Iterable<string | number | symbol>,
225
...[msg, extra]: MessageExtra
226
): boolean;
227
228
/**
229
* Verify that the object has all properties in the wanted list and no others, using Object#hasOwnProperties()
230
*/
231
function hasOwnPropsOnly<T extends {}>(
232
found: T,
233
wanted: Iterable<string | number | symbol>,
234
...[msg, extra]: MessageExtra
235
): boolean;
236
```
237
238
**Usage Examples:**
239
240
```typescript
241
test("property existence", (t) => {
242
const obj = { a: 1, b: 2, c: 3 };
243
244
t.hasProp(obj, "a", "object has property 'a'");
245
t.hasOwnProp(obj, "b", "object has own property 'b'");
246
247
t.hasProps(obj, ["a", "b"], "object has properties a and b");
248
t.hasOwnProps(obj, ["a", "b", "c"], "object has all own properties");
249
t.hasOwnPropsOnly(obj, ["a", "b", "c"], "object has exactly these properties");
250
251
t.end();
252
});
253
```
254
255
### Pattern Matching
256
257
Advanced pattern matching with regular expressions and object patterns.
258
259
```typescript { .api }
260
/**
261
* Verify that the value matches the pattern provided
262
*/
263
function match(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
264
265
/**
266
* Verify that the value does NOT match the pattern provided
267
*/
268
function notMatch(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
269
270
/**
271
* Verify that the value matches the pattern provided, with no extra properties
272
*/
273
function matchOnly(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
274
275
/**
276
* Verify that the value does not match the pattern or has extra properties
277
*/
278
function notMatchOnly(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
279
280
/**
281
* Verify that the value matches the pattern provided, but fail if any fields only match via type coercion
282
*/
283
function matchStrict(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
284
285
/**
286
* Verify that the value does not match the pattern provided, without type coercion
287
*/
288
function notMatchStrict(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
289
290
/**
291
* Verify that the value matches the pattern provided strictly, with no extra properties
292
*/
293
function matchOnlyStrict(found: any, wanted: any, ...[msg, extra]: MessageExtra): boolean;
294
295
/**
296
* Verify that the value does not match the pattern strictly or has extra properties
297
*/
298
function notMatchOnlyStrict(found: any, doNotWant: any, ...[msg, extra]: MessageExtra): boolean;
299
```
300
301
**Usage Examples:**
302
303
```typescript
304
test("pattern matching", (t) => {
305
// Regex matching
306
t.match("hello world", /world/, "string contains 'world'");
307
t.notMatch("hello", /goodbye/, "string doesn't contain 'goodbye'");
308
309
// Object pattern matching
310
const response = { status: "success", data: { id: 123, name: "test" } };
311
t.match(response, { status: "success" }, "response has success status");
312
t.matchOnly({ a: 1 }, { a: 1 }, "exact match with no extra properties");
313
314
// Strict matching prevents type coercion
315
t.matchStrict({ a: 1 }, { a: Number }, "matches constructor type");
316
// t.matchStrict({ a: 1 }, { a: '1' }, 'this would fail due to type coercion');
317
318
t.end();
319
});
320
```
321
322
### Type Checking
323
324
Type checking assertion methods.
325
326
```typescript { .api }
327
/**
328
* Verify that the value is of the type specified
329
* Type can be either a string, or a constructor.
330
* If a string, then it can match either the `typeof` result or 'null' for `null` values,
331
* or the `name` property of the object's constructor.
332
*/
333
function type(
334
obj: any,
335
klass: string | Function,
336
...[msg, extra]: MessageExtra
337
): boolean;
338
```
339
340
**Usage Examples:**
341
342
```typescript
343
test("type checking", (t) => {
344
t.type("hello", "string", "value is a string");
345
t.type(123, "number", "value is a number");
346
t.type([], Array, "value is an array");
347
t.type(new Date(), Date, "value is a Date object");
348
349
t.end();
350
});
351
```
352
353
### Exception Testing
354
355
Methods for testing function throws and error conditions.
356
357
```typescript { .api }
358
/**
359
* Verify that the function throws an error.
360
* Thrown error is tested against the `wanted` param if provided, using `t.match()`.
361
* Returns false on failure, or the error object thrown on success
362
*/
363
function throws(
364
fn: Function | (() => any),
365
...[wanted, msg, extra]: ThrowsArgs
366
): boolean | Error;
367
368
/**
369
* Returns the error object if it throws and that does not fail the test
370
* (by virtue of being marked skip or todo). Otherwise returns the passing status.
371
*/
372
function doesNotThrow(
373
fn: Function | (() => any),
374
...[msg, extra]: MessageExtra
375
): boolean | Error;
376
377
/**
378
* Assert that an error object is not provided.
379
* Useful for asserting that a callback did not receive an error.
380
*/
381
function error(er: unknown, ...[msg, extra]: MessageExtra): boolean;
382
```
383
384
**Usage Examples:**
385
386
```typescript
387
test("exception testing", (t) => {
388
// Test that function throws
389
t.throws(() => { throw new Error("test error"); }, "function throws error");
390
391
// Test specific error message
392
t.throws(
393
() => { throw new Error("specific message"); },
394
{ message: "specific message" },
395
"function throws expected error"
396
);
397
398
// Test that function doesn't throw
399
t.doesNotThrow(() => { return "ok"; }, "function doesn't throw");
400
401
// Test no error occurred
402
t.error(null, "no error occurred");
403
t.error(undefined, "no error occurred");
404
405
t.end();
406
});
407
```
408
409
### Promise Testing
410
411
Assertions for testing Promise resolution, rejection, and resolved values.
412
413
```typescript { .api }
414
/**
415
* Resolves to the error object rejected if it rejects as expected,
416
* 'false' if it does not, or 'true' if it fails to reject but is marked as skip/todo.
417
*/
418
async function rejects<T extends any = any>(
419
fnOrPromise: (() => Promise<T>) | Promise<T>,
420
...[wanted, msg, extra]: ThrowsArgs
421
): Promise<boolean | Error>;
422
423
/**
424
* Resolves to 'true' if the promise resolves successfully, 'false' if
425
* it rejects and fails, or the rejection error if it rejects but the
426
* failure is accepted by being marked todo or skip
427
*/
428
async function resolves<T extends any = any>(
429
fnOrPromise: Promise<T> | (() => Promise<T>),
430
...[msg, extra]: MessageExtra
431
): Promise<boolean | Error>;
432
433
/**
434
* Test the resolved promise result with `t.match()`
435
* Resolves to true if it passes, false if the promise rejects or the match fails
436
*/
437
async function resolveMatch<T extends any = any>(
438
fnOrPromise: Promise<T> | (() => Promise<T>),
439
wanted: any,
440
...[msg, extra]: MessageExtra
441
): Promise<boolean>;
442
```
443
444
**Usage Examples:**
445
446
```typescript
447
test("promise testing", async (t) => {
448
// Test promise rejection
449
await t.rejects(
450
Promise.reject(new Error("failed")),
451
"promise should reject"
452
);
453
454
// Test promise resolution
455
await t.resolves(
456
Promise.resolve("success"),
457
"promise should resolve"
458
);
459
460
// Test resolved value matches pattern
461
await t.resolveMatch(
462
Promise.resolve({ status: "ok", data: [1, 2, 3] }),
463
{ status: "ok" },
464
"resolved value matches expected pattern"
465
);
466
467
// Test async function
468
await t.resolves(
469
async () => {
470
const result = await someAsyncOperation();
471
return result;
472
},
473
"async function resolves successfully"
474
);
475
});
476
```
477
478
### Event Testing
479
480
Assert that events are emitted by event emitters.
481
482
```typescript { .api }
483
/**
484
* Asserts that the emitter emits the specified event before the test ends.
485
* Returns a promise that resolves when the event is emitted.
486
* Note that waiting on the returned promise within a test can deadlock
487
* the test, if the event never emits.
488
*/
489
function emits(
490
emitter: EventEmitter | EventTarget,
491
event: string,
492
...[msg, extra]: MessageExtra
493
): Promise<void>;
494
```
495
496
**Usage Examples:**
497
498
```typescript
499
import { EventEmitter } from "events";
500
501
test("event assertions", (t) => {
502
const emitter = new EventEmitter();
503
504
t.emits(emitter, "data", "emitter will emit data event");
505
506
// Trigger the event
507
setTimeout(() => {
508
emitter.emit("data", { id: 123 });
509
}, 10);
510
511
t.end();
512
});
513
514
test("async event waiting", async (t) => {
515
const emitter = new EventEmitter();
516
517
// Start listening for the event
518
const eventPromise = t.emits(emitter, "ready", "ready event will be emitted");
519
520
// Trigger the event asynchronously
521
setTimeout(() => emitter.emit("ready"), 50);
522
523
// Wait for the event to fire
524
await eventPromise;
525
526
t.pass("event was successfully emitted");
527
});
528
```
529
530
## Important Implementation Notes
531
532
### MessageExtra Pattern
533
534
All assertion methods use a rest parameter pattern `...[msg, extra]: MessageExtra` where:
535
- `MessageExtra` can be empty `[]`, just a message `[string]`, just extra data `[Extra]`, or both `[string, Extra]`
536
- This provides flexible parameter handling for all assertion methods
537
538
### Return Types
539
540
Many assertion methods return `boolean | Error`:
541
- `boolean` for normal pass/fail results
542
- `Error` object when an error occurs but the test is marked as todo/skip
543
544
### Type Guards
545
546
Some methods like `equal` and `strictSame` include TypeScript type guards (`found is T`) that narrow the type of the tested value when the assertion passes.
547
548
### Async Assertions
549
550
Promise-related assertions (`rejects`, `resolves`, `resolveMatch`) are async functions that return Promises, allowing for proper async/await usage in tests.