0
# Collection and String Matchers
1
2
Matchers for arrays, objects, strings, and other iterable collections. These matchers provide essential tools for testing data structures, string patterns, and object properties.
3
4
## Capabilities
5
6
### Collection Matchers
7
8
#### toContain
9
10
Checks if an iterable (array, string, etc.) contains a specific item using `indexOf`.
11
12
```javascript { .api }
13
/**
14
* Checks if iterable contains item using indexOf comparison
15
* @param item - Item to search for in the collection
16
*/
17
ExpectationObject.toContain(item: any): void;
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
// Array containment
24
expect(['apple', 'banana', 'cherry']).toContain('banana');
25
expect([1, 2, 3, 4, 5]).toContain(3);
26
27
// String containment
28
expect('Hello World').toContain('World');
29
expect('JavaScript').toContain('Script');
30
31
// Works with any iterable that has indexOf
32
const set = new Set(['a', 'b', 'c']);
33
expect([...set]).toContain('b');
34
```
35
36
#### toContainEqual
37
38
Checks if an iterable contains an item using deep equality comparison.
39
40
```javascript { .api }
41
/**
42
* Checks if iterable contains item using deep equality comparison
43
* @param item - Item to search for using deep equality
44
*/
45
ExpectationObject.toContainEqual(item: any): void;
46
```
47
48
**Usage Examples:**
49
50
```javascript
51
// Object containment with deep equality
52
expect([
53
{name: 'John', age: 30},
54
{name: 'Jane', age: 25}
55
]).toContainEqual({name: 'John', age: 30});
56
57
// Array containment with deep equality
58
expect([[1, 2], [3, 4], [5, 6]]).toContainEqual([3, 4]);
59
60
// Date objects
61
expect([
62
new Date('2023-01-01'),
63
new Date('2023-01-02')
64
]).toContainEqual(new Date('2023-01-01'));
65
```
66
67
#### toHaveLength
68
69
Checks if an object has a specific `length` property value.
70
71
```javascript { .api }
72
/**
73
* Checks if object has specific length property value
74
* @param length - Expected length value
75
*/
76
ExpectationObject.toHaveLength(length: number): void;
77
```
78
79
**Usage Examples:**
80
81
```javascript
82
// Array length
83
expect([1, 2, 3]).toHaveLength(3);
84
expect([]).toHaveLength(0);
85
86
// String length
87
expect('hello').toHaveLength(5);
88
expect('').toHaveLength(0);
89
90
// Custom objects with length property
91
const customArray = {0: 'a', 1: 'b', length: 2};
92
expect(customArray).toHaveLength(2);
93
94
// Function arguments
95
function testArgs() {
96
expect(arguments).toHaveLength(3);
97
}
98
testArgs('a', 'b', 'c');
99
```
100
101
### Object Property Matchers
102
103
#### toHaveProperty
104
105
Checks if an object has a property at the specified path, optionally with a specific value.
106
107
```javascript { .api }
108
/**
109
* Checks if object has property at path, optionally with specific value
110
* @param path - Property path (dot notation supported)
111
* @param value - Optional expected value for the property
112
*/
113
ExpectationObject.toHaveProperty(path: string, value?: any): void;
114
```
115
116
**Usage Examples:**
117
118
```javascript
119
const user = {
120
name: 'John',
121
address: {
122
street: '123 Main St',
123
city: 'Anytown'
124
},
125
preferences: {
126
theme: 'dark',
127
notifications: true
128
}
129
};
130
131
// Check property exists
132
expect(user).toHaveProperty('name');
133
expect(user).toHaveProperty('address');
134
135
// Check property with specific value
136
expect(user).toHaveProperty('name', 'John');
137
expect(user).toHaveProperty('preferences.theme', 'dark');
138
139
// Nested property paths
140
expect(user).toHaveProperty('address.street');
141
expect(user).toHaveProperty('address.street', '123 Main St');
142
expect(user).toHaveProperty('preferences.notifications', true);
143
144
// Array indexing in paths
145
const data = {items: ['a', 'b', 'c']};
146
expect(data).toHaveProperty('items.0', 'a');
147
expect(data).toHaveProperty('items.2', 'c');
148
```
149
150
### String Matchers
151
152
#### toMatch
153
154
Checks if a string matches a regular expression or contains a substring.
155
156
```javascript { .api }
157
/**
158
* Checks if string matches regex pattern or contains substring
159
* @param pattern - RegExp pattern or string to match
160
*/
161
ExpectationObject.toMatch(pattern: string | RegExp): void;
162
```
163
164
**Usage Examples:**
165
166
```javascript
167
// String substring matching
168
expect('Hello World').toMatch('World');
169
expect('JavaScript is awesome').toMatch('Script');
170
171
// Regular expression matching
172
expect('hello@example.com').toMatch(/^[\w\.-]+@[\w\.-]+\.\w+$/);
173
expect('2023-12-25').toMatch(/^\d{4}-\d{2}-\d{2}$/);
174
expect('Phone: (555) 123-4567').toMatch(/\(\d{3}\) \d{3}-\d{4}/);
175
176
// Case-insensitive matching
177
expect('Hello World').toMatch(/hello/i);
178
179
// Testing user input validation
180
const phoneNumber = getUserPhoneNumber();
181
expect(phoneNumber).toMatch(/^\(\d{3}\) \d{3}-\d{4}$/);
182
```
183
184
### Type and Instance Matchers
185
186
#### toBeInstanceOf
187
188
Checks if an object is an instance of a specific constructor/class.
189
190
```javascript { .api }
191
/**
192
* Checks if object is instance of given constructor
193
* @param constructor - Constructor function or class to check against
194
*/
195
ExpectationObject.toBeInstanceOf(constructor: Function): void;
196
```
197
198
**Usage Examples:**
199
200
```javascript
201
// Built-in types
202
expect(new Date()).toBeInstanceOf(Date);
203
expect([1, 2, 3]).toBeInstanceOf(Array);
204
expect(new RegExp('test')).toBeInstanceOf(RegExp);
205
expect(new Error('test')).toBeInstanceOf(Error);
206
207
// Custom classes
208
class User {
209
constructor(name) {
210
this.name = name;
211
}
212
}
213
214
class AdminUser extends User {
215
constructor(name) {
216
super(name);
217
this.isAdmin = true;
218
}
219
}
220
221
const user = new User('John');
222
const admin = new AdminUser('Jane');
223
224
expect(user).toBeInstanceOf(User);
225
expect(admin).toBeInstanceOf(AdminUser);
226
expect(admin).toBeInstanceOf(User); // inheritance works
227
228
// Testing API responses
229
const response = await fetchUserData();
230
expect(response.createdAt).toBeInstanceOf(Date);
231
expect(response.errors).toBeInstanceOf(Array);
232
```
233
234
## Advanced Usage Patterns
235
236
### Complex Object Testing
237
238
```javascript
239
const apiResponse = {
240
users: [
241
{id: 1, name: 'John', emails: ['john@example.com']},
242
{id: 2, name: 'Jane', emails: ['jane@example.com']}
243
],
244
pagination: {
245
total: 2,
246
page: 1
247
}
248
};
249
250
// Test array length and content
251
expect(apiResponse.users).toHaveLength(2);
252
expect(apiResponse.users).toContainEqual({
253
id: 1,
254
name: 'John',
255
emails: ['john@example.com']
256
});
257
258
// Test nested properties
259
expect(apiResponse).toHaveProperty('pagination.total', 2);
260
expect(apiResponse).toHaveProperty('users.0.name', 'John');
261
```
262
263
### String Pattern Validation
264
265
```javascript
266
// Email validation
267
const email = 'user@example.com';
268
expect(email).toMatch(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
269
270
// URL validation
271
const url = 'https://example.com/path';
272
expect(url).toMatch(/^https?:\/\/.+/);
273
274
// Phone number formats
275
const phone = '(555) 123-4567';
276
expect(phone).toMatch(/^\(\d{3}\) \d{3}-\d{4}$/);
277
```
278
279
### Collection Filtering and Searching
280
281
```javascript
282
const products = [
283
{name: 'Laptop', category: 'Electronics', price: 999},
284
{name: 'Book', category: 'Education', price: 29},
285
{name: 'Phone', category: 'Electronics', price: 699}
286
];
287
288
// Check if specific product exists
289
expect(products).toContainEqual({
290
name: 'Laptop',
291
category: 'Electronics',
292
price: 999
293
});
294
295
// Check collection size
296
expect(products).toHaveLength(3);
297
expect(products.filter(p => p.category === 'Electronics')).toHaveLength(2);
298
```
299
300
## Negation Support
301
302
All collection and string matchers support negation:
303
304
```javascript
305
expect(['a', 'b', 'c']).not.toContain('d');
306
expect([1, 2, 3]).not.toContainEqual({id: 1});
307
expect('hello').not.toHaveLength(10);
308
expect({}).not.toHaveProperty('nonexistent');
309
expect('hello').not.toMatch(/\d+/);
310
expect('string').not.toBeInstanceOf(Number);
311
```
312
313
## Promise Support
314
315
All collection and string matchers work with promises:
316
317
```javascript
318
await expect(Promise.resolve(['a', 'b'])).resolves.toContain('a');
319
await expect(Promise.resolve('hello')).resolves.toMatch(/hello/);
320
await expect(Promise.resolve(new Date())).resolves.toBeInstanceOf(Date);
321
```