or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdfakes.mdindex.mdmatchers.mdmocks.mdpromises.mdsandbox.mdspies.mdstubs.mdtimers.md

matchers.mddocs/

0

# Argument Matching

1

2

Sinon's matcher system provides flexible argument matching for creating sophisticated test assertions and stub behaviors. Matchers allow you to specify patterns instead of exact values, making tests more robust and expressive.

3

4

## Capabilities

5

6

### Basic Type Matchers

7

8

Match arguments based on their JavaScript types.

9

10

```javascript { .api }

11

declare namespace match {

12

/** Matches any value (always returns true) */

13

const any: SinonMatcher;

14

15

/** Matches any defined value (not null or undefined) */

16

const defined: SinonMatcher;

17

18

/** Matches truthy values */

19

const truthy: SinonMatcher;

20

21

/** Matches falsy values */

22

const falsy: SinonMatcher;

23

24

/** Matches boolean values */

25

const bool: SinonMatcher;

26

27

/** Matches number values (including NaN) */

28

const number: SinonMatcher;

29

30

/** Matches string values */

31

const string: SinonMatcher;

32

33

/** Matches object values (including arrays, functions, etc.) */

34

const object: SinonMatcher;

35

36

/** Matches function values */

37

const func: SinonMatcher;

38

39

/** Matches array values */

40

const array: SinonMatcher;

41

42

/** Matches regular expression values */

43

const regexp: SinonMatcher;

44

45

/** Matches Date objects */

46

const date: SinonMatcher;

47

48

/** Matches Symbol values */

49

const symbol: SinonMatcher;

50

51

/** Matches Map objects */

52

const map: SinonMatcher;

53

54

/** Matches Set objects */

55

const set: SinonMatcher;

56

}

57

```

58

59

**Usage Examples:**

60

61

```javascript

62

import { match } from "sinon";

63

64

const spy = sinon.spy();

65

66

spy("hello", 42, true, {}, []);

67

68

// Use type matchers in assertions

69

sinon.assert.calledWith(spy, match.string, match.number, match.bool, match.object, match.array);

70

71

// Use in stub configurations

72

const stub = sinon.stub();

73

stub.withArgs(match.string).returns("string argument");

74

stub.withArgs(match.number).returns("number argument");

75

76

console.log(stub("test")); // "string argument"

77

console.log(stub(123)); // "number argument"

78

```

79

80

### Value Matchers

81

82

Match arguments based on specific values or references.

83

84

```javascript { .api }

85

declare namespace match {

86

/**

87

* Matches the exact same reference (using ===)

88

* @param value - Value to match by reference

89

* @returns Matcher for the exact reference

90

*/

91

function same(value: any): SinonMatcher;

92

93

/**

94

* Matches values with specific typeof result

95

* @param type - Expected typeof string

96

* @returns Matcher for the typeof result

97

*/

98

function typeOf(type: string): SinonMatcher;

99

100

/**

101

* Matches instances of a specific constructor

102

* @param constructor - Constructor function to match against

103

* @returns Matcher for instanceof check

104

*/

105

function instanceOf(constructor: Function): SinonMatcher;

106

}

107

```

108

109

**Usage Examples:**

110

111

```javascript

112

const obj = { name: "test" };

113

const spy = sinon.spy();

114

115

spy(obj, new Date(), "hello");

116

117

// Match by reference

118

sinon.assert.calledWith(spy, match.same(obj));

119

120

// Match by typeof

121

sinon.assert.calledWith(spy, match.object, match.typeOf("object"), match.typeOf("string"));

122

123

// Match by instanceof

124

sinon.assert.calledWith(spy, match.object, match.instanceOf(Date), match.string);

125

```

126

127

### Property Matchers

128

129

Match objects based on their properties and property values.

130

131

```javascript { .api }

132

declare namespace match {

133

/**

134

* Matches objects that have a specific property

135

* @param property - Property name to check for

136

* @param value - Optional expected property value

137

* @returns Matcher for property existence and value

138

*/

139

function has(property: string, value?: any): SinonMatcher;

140

141

/**

142

* Matches objects that have a specific own property (not inherited)

143

* @param property - Property name that must be own property

144

* @param value - Optional expected property value

145

* @returns Matcher for own property existence and value

146

*/

147

function hasOwn(property: string, value?: any): SinonMatcher;

148

149

/**

150

* Matches objects that have nested property paths

151

* @param path - Dot-separated property path (e.g., "user.profile.name")

152

* @param value - Optional expected nested property value

153

* @returns Matcher for nested property existence and value

154

*/

155

function hasNested(path: string, value?: any): SinonMatcher;

156

}

157

```

158

159

**Usage Examples:**

160

161

```javascript

162

const spy = sinon.spy();

163

164

const user = {

165

id: 1,

166

name: "John",

167

profile: {

168

email: "john@example.com",

169

settings: { theme: "dark" }

170

}

171

};

172

173

spy(user);

174

175

// Match by property existence

176

sinon.assert.calledWith(spy, match.has("name"));

177

sinon.assert.calledWith(spy, match.has("id", 1));

178

179

// Match by own property (not inherited)

180

sinon.assert.calledWith(spy, match.hasOwn("name"));

181

182

// Match nested properties

183

sinon.assert.calledWith(spy, match.hasNested("profile.email"));

184

sinon.assert.calledWith(spy, match.hasNested("profile.settings.theme", "dark"));

185

```

186

187

### Numeric Matchers

188

189

Match numbers based on ranges and comparisons.

190

191

```javascript { .api }

192

declare namespace match {

193

/**

194

* Matches numbers greater than specified value

195

* @param value - Minimum value (exclusive)

196

* @returns Matcher for numbers greater than value

197

*/

198

function greaterThan(value: number): SinonMatcher;

199

200

/**

201

* Matches numbers greater than or equal to specified value

202

* @param value - Minimum value (inclusive)

203

* @returns Matcher for numbers >= value

204

*/

205

function atLeast(value: number): SinonMatcher;

206

207

/**

208

* Matches numbers less than specified value

209

* @param value - Maximum value (exclusive)

210

* @returns Matcher for numbers less than value

211

*/

212

function lessThan(value: number): SinonMatcher;

213

214

/**

215

* Matches numbers less than or equal to specified value

216

* @param value - Maximum value (inclusive)

217

* @returns Matcher for numbers <= value

218

*/

219

function atMost(value: number): SinonMatcher;

220

}

221

```

222

223

**Usage Examples:**

224

225

```javascript

226

const spy = sinon.spy();

227

228

spy(25, 100, 5);

229

230

// Numeric comparisons

231

sinon.assert.calledWith(spy, match.greaterThan(18)); // 25 > 18

232

sinon.assert.calledWith(spy, match.atLeast(25)); // 25 >= 25

233

sinon.assert.calledWith(spy, match.lessThan(200)); // 100 < 200

234

sinon.assert.calledWith(spy, match.atMost(10)); // 5 <= 10

235

236

// Use in stubs

237

const stub = sinon.stub();

238

stub.withArgs(match.greaterThan(50)).returns("large number");

239

stub.withArgs(match.atMost(50)).returns("small number");

240

241

console.log(stub(100)); // "large number"

242

console.log(stub(25)); // "small number"

243

```

244

245

### String Matchers

246

247

Match strings based on patterns and content.

248

249

```javascript { .api }

250

declare namespace match {

251

/**

252

* Matches strings that start with specified prefix

253

* @param prefix - Required string prefix

254

* @returns Matcher for strings starting with prefix

255

*/

256

function startsWith(prefix: string): SinonMatcher;

257

258

/**

259

* Matches strings that end with specified suffix

260

* @param suffix - Required string suffix

261

* @returns Matcher for strings ending with suffix

262

*/

263

function endsWith(suffix: string): SinonMatcher;

264

265

/**

266

* Matches strings that contain specified substring

267

* @param substring - Required substring

268

* @returns Matcher for strings containing substring

269

*/

270

function includes(substring: string): SinonMatcher;

271

}

272

```

273

274

**Usage Examples:**

275

276

```javascript

277

const spy = sinon.spy();

278

279

spy("hello world", "testing123", "world hello");

280

281

// String pattern matching

282

sinon.assert.calledWith(spy, match.startsWith("hello"));

283

sinon.assert.calledWith(spy, match.endsWith("123"));

284

sinon.assert.calledWith(spy, match.includes("world"));

285

286

// Combine multiple string patterns

287

sinon.assert.calledWith(spy,

288

match.startsWith("hello").and(match.includes("world"))

289

);

290

```

291

292

### Array and Collection Matchers

293

294

Match arrays and collections based on content and structure.

295

296

```javascript { .api }

297

declare namespace match {

298

/**

299

* Matches arrays where every element matches the provided matcher

300

* @param matcher - Matcher that all elements must satisfy

301

* @returns Matcher for arrays where all elements match

302

*/

303

function every(matcher: SinonMatcher): SinonMatcher;

304

305

/**

306

* Matches arrays where at least one element matches the provided matcher

307

* @param matcher - Matcher that at least one element must satisfy

308

* @returns Matcher for arrays where some elements match

309

*/

310

function some(matcher: SinonMatcher): SinonMatcher;

311

312

/**

313

* Matches arrays that contain all specified elements (order doesn't matter)

314

* @param elements - Elements that must be present in array

315

* @returns Matcher for arrays containing all elements

316

*/

317

function arrayContaining(elements: any[]): SinonMatcher;

318

319

/**

320

* Matches arrays or objects by deep equality

321

* @param value - Value to match by deep comparison

322

* @returns Matcher for deep equality

323

*/

324

function deepEquals(value: any): SinonMatcher;

325

326

/**

327

* Matches arrays with specific length

328

* @param length - Expected array length

329

* @returns Matcher for arrays with exact length

330

*/

331

function arrayWithLength(length: number): SinonMatcher;

332

}

333

```

334

335

**Usage Examples:**

336

337

```javascript

338

const spy = sinon.spy();

339

340

spy([1, 2, 3], ["a", "b", "c"], [5, 10, 15]);

341

342

// Array content matching

343

sinon.assert.calledWith(spy, match.every(match.number));

344

sinon.assert.calledWith(spy, match.some(match.string));

345

sinon.assert.calledWith(spy, match.arrayContaining([1, 3])); // Contains 1 and 3

346

347

// Array structure matching

348

sinon.assert.calledWith(spy, match.arrayWithLength(3));

349

350

// Deep equality

351

const expectedData = { items: [1, 2, 3], total: 3 };

352

spy(expectedData);

353

sinon.assert.calledWith(spy, match.deepEquals(expectedData));

354

```

355

356

### Custom Matchers

357

358

Create custom matchers with predicate functions.

359

360

```javascript { .api }

361

declare namespace match {

362

/**

363

* Creates a custom matcher using a predicate function

364

* @param predicate - Function that returns true for matching values

365

* @param message - Optional description for the matcher

366

* @returns Custom matcher based on predicate

367

*/

368

function (predicate: (value: any) => boolean, message?: string): SinonMatcher;

369

}

370

```

371

372

**Usage Examples:**

373

374

```javascript

375

const spy = sinon.spy();

376

377

// Custom matchers with predicates

378

const isEven = match((n) => n % 2 === 0, "even number");

379

const isValidEmail = match((email) => email.includes("@"), "valid email");

380

const isPositive = match((n) => n > 0, "positive number");

381

382

spy(4, "test@example.com", -5);

383

384

sinon.assert.calledWith(spy, isEven); // 4 is even

385

sinon.assert.calledWith(spy, isValidEmail); // has @

386

sinon.assert.neverCalledWith(spy, isPositive); // -5 is not positive

387

388

// Use in stubs

389

const stub = sinon.stub();

390

stub.withArgs(isEven).returns("even");

391

stub.withArgs(isPositive).returns("positive");

392

393

console.log(stub(4)); // "even"

394

console.log(stub(3)); // undefined (no match)

395

```

396

397

### Matcher Combinations

398

399

Combine multiple matchers using logical operators.

400

401

```javascript { .api }

402

interface SinonMatcher {

403

/**

404

* Combine matchers with logical AND

405

* @param matcher - Matcher to combine with AND logic

406

* @returns Combined matcher (both must match)

407

*/

408

and(matcher: SinonMatcher): SinonMatcher;

409

410

/**

411

* Combine matchers with logical OR

412

* @param matcher - Matcher to combine with OR logic

413

* @returns Combined matcher (either can match)

414

*/

415

or(matcher: SinonMatcher): SinonMatcher;

416

}

417

```

418

419

**Usage Examples:**

420

421

```javascript

422

const spy = sinon.spy();

423

424

spy("hello123", 42, "world");

425

426

// Combine matchers with AND

427

const stringWithNumbers = match.string.and(match.includes("123"));

428

sinon.assert.calledWith(spy, stringWithNumbers);

429

430

// Combine matchers with OR

431

const stringOrNumber = match.string.or(match.number);

432

sinon.assert.calledWith(spy, stringOrNumber); // Matches first and second args

433

434

// Complex combinations

435

const validId = match.number.and(match.greaterThan(0));

436

const validName = match.string.and(match.startsWith("user_"));

437

const validIdentifier = validId.or(validName);

438

439

const stub = sinon.stub();

440

stub.withArgs(validIdentifier).returns("valid");

441

442

console.log(stub(42)); // "valid" (positive number)

443

console.log(stub("user_123")); // "valid" (starts with user_)

444

console.log(stub(-1)); // undefined (negative number)

445

```

446

447

### Matcher Usage in Different Contexts

448

449

Using matchers across various Sinon features.

450

451

**Usage Examples:**

452

453

```javascript

454

// In spy assertions

455

const spy = sinon.spy();

456

spy({ id: 1, name: "test" });

457

sinon.assert.calledWith(spy, match.has("id", 1));

458

459

// In stub behaviors

460

const stub = sinon.stub();

461

stub.withArgs(match.string, match.number).returns("string and number");

462

stub.withArgs(match.object).callsFake((obj) => `Object with ${Object.keys(obj).length} keys`);

463

464

// In mock expectations

465

const obj = { process: () => {} };

466

const mock = sinon.mock(obj);

467

mock.expects("process").withArgs(match.array, match.func);

468

469

// In fake verification

470

const fake = sinon.fake();

471

fake([1, 2, 3], () => {});

472

console.log(fake.calledWith(match.every(match.number), match.func)); // true

473

```

474

475

### Built-in Matcher Utilities

476

477

Additional utility matchers for common patterns.

478

479

```javascript { .api }

480

declare namespace match {

481

/** Matches null values */

482

const nullValue: SinonMatcher;

483

484

/** Matches undefined values */

485

const undef: SinonMatcher;

486

487

/** Matches NaN values */

488

const nan: SinonMatcher;

489

490

/** Matches positive numbers (> 0) */

491

const positive: SinonMatcher;

492

493

/** Matches negative numbers (< 0) */

494

const negative: SinonMatcher;

495

496

/** Matches integer numbers */

497

const integer: SinonMatcher;

498

499

/** Matches float numbers */

500

const float: SinonMatcher;

501

}

502

```

503

504

**Usage Examples:**

505

506

```javascript

507

const spy = sinon.spy();

508

509

spy(null, undefined, NaN, 3.14, -5, 42);

510

511

// Use built-in utility matchers

512

sinon.assert.calledWith(spy, match.nullValue);

513

sinon.assert.calledWith(spy, match.undef);

514

sinon.assert.calledWith(spy, match.nan);

515

sinon.assert.calledWith(spy, match.float); // 3.14

516

sinon.assert.calledWith(spy, match.negative); // -5

517

sinon.assert.calledWith(spy, match.integer); // 42

518

```

519

520

## Types

521

522

```javascript { .api }

523

interface SinonMatcher {

524

/** Test if a value matches this matcher */

525

test(value: any): boolean;

526

527

/** Combine with another matcher using AND logic */

528

and(matcher: SinonMatcher): SinonMatcher;

529

530

/** Combine with another matcher using OR logic */

531

or(matcher: SinonMatcher): SinonMatcher;

532

533

/** String representation of the matcher */

534

toString(): string;

535

}

536

537

interface SinonMatch {

538

// Basic matchers

539

any: SinonMatcher;

540

defined: SinonMatcher;

541

truthy: SinonMatcher;

542

falsy: SinonMatcher;

543

bool: SinonMatcher;

544

number: SinonMatcher;

545

string: SinonMatcher;

546

object: SinonMatcher;

547

func: SinonMatcher;

548

array: SinonMatcher;

549

regexp: SinonMatcher;

550

date: SinonMatcher;

551

552

// Value matchers

553

same(value: any): SinonMatcher;

554

typeOf(type: string): SinonMatcher;

555

instanceOf(constructor: Function): SinonMatcher;

556

557

// Property matchers

558

has(property: string, value?: any): SinonMatcher;

559

hasOwn(property: string, value?: any): SinonMatcher;

560

hasNested(path: string, value?: any): SinonMatcher;

561

562

// Numeric matchers

563

greaterThan(value: number): SinonMatcher;

564

lessThan(value: number): SinonMatcher;

565

atLeast(value: number): SinonMatcher;

566

atMost(value: number): SinonMatcher;

567

568

// String matchers

569

startsWith(prefix: string): SinonMatcher;

570

endsWith(suffix: string): SinonMatcher;

571

includes(substring: string): SinonMatcher;

572

573

// Collection matchers

574

every(matcher: SinonMatcher): SinonMatcher;

575

some(matcher: SinonMatcher): SinonMatcher;

576

arrayContaining(elements: any[]): SinonMatcher;

577

deepEquals(value: any): SinonMatcher;

578

579

// Custom matcher

580

(predicate: (value: any) => boolean, message?: string): SinonMatcher;

581

}

582

```