or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdindex.mdlifecycle-hooks.mdmocking.mdsubprocess-testing.mdtest-organization.md

assertions.mddocs/

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.