or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-assertions.mdconfiguration.mdcontainment-assertions.mderror-assertions.mdindex.mdnumber-assertions.mdpattern-matching.mdpromise-assertions.mdproperty-assertions.mdstring-assertions.mdtype-assertions.md

pattern-matching.mddocs/

0

# Pattern Matching

1

2

Methods for advanced pattern matching, validation, and testing using regular expressions, functions, and object matchers.

3

4

## Core Pattern Matching

5

6

### match()

7

8

Test that a value matches a pattern using regular expressions, functions, or object matchers.

9

10

```javascript { .api }

11

/**

12

* Assert that the value matches the specified pattern, function, or object

13

* @param pattern - RegExp, function, or object to match against

14

* @param description - Optional error message

15

* @returns This assertion for chaining

16

*/

17

match(pattern: RegExp | Function | object, description?: string): Assertion;

18

```

19

20

**Usage:**

21

22

```javascript

23

import should from 'should';

24

25

// String matching with RegExp

26

'hello123'.should.match(/^hello\d+$/);

27

'test@example.com'.should.match(/\w+@\w+\.\w+/);

28

29

// Function matching - return boolean

30

'positive123'.should.match(str => str.includes('positive'));

31

(42).should.match(num => num > 0);

32

33

// Function matching - throw for detailed assertion

34

const user = { name: 'John', age: 25 };

35

user.should.match(obj => {

36

obj.should.have.property('name').which.is.a.String();

37

obj.should.have.property('age').which.is.above(18);

38

});

39

40

// Object matching - matches properties recursively

41

const data = { a: 'foo', c: 'barfoo', d: 42 };

42

data.should.match({

43

a: /foo$/,

44

c: str => str.includes('bar'),

45

d: 42

46

});

47

48

// Array matching - matches by index

49

[10, 'abc', { d: 10 }].should.match({

50

'0': 10,

51

'1': /^ab/,

52

'2': obj => obj.should.have.property('d', 10)

53

});

54

```

55

56

## Collection Pattern Matching

57

58

### matchEach() / matchEvery()

59

60

Test that every element in a collection matches a pattern.

61

62

```javascript { .api }

63

/**

64

* Assert that every element matches the pattern

65

* @param pattern - RegExp, string, or function to match against

66

* @param description - Optional error message

67

* @returns This assertion for chaining

68

*/

69

matchEach(pattern: RegExp | string | Function, description?: string): Assertion;

70

/**

71

* Alias for matchEach - assert that every element matches the pattern

72

*/

73

matchEvery(pattern: RegExp | string | Function, description?: string): Assertion;

74

```

75

76

**Usage:**

77

78

```javascript

79

// Array - all elements match pattern

80

['hello', 'world', 'test'].should.matchEach(/\w+/);

81

[1, 2, 3, 4, 5].should.matchEach(num => num > 0);

82

83

// String matching

84

['apple', 'banana', 'cherry'].should.matchEach(str => str.length > 3);

85

86

// Array - all identical values

87

['a', 'a', 'a'].should.matchEach('a');

88

[42, 42, 42].should.matchEach(42);

89

90

// Object values - all match pattern

91

{ x: 'apple', y: 'banana', z: 'cherry' }.should.matchEach(/\w+/);

92

{ a: 10, b: 20, c: 30 }.should.matchEach(num => num > 5);

93

94

// Complex validation with functions

95

const words = ['hello', 'world', 'javascript'];

96

words.should.matchEach(word => {

97

word.should.be.a.String();

98

word.should.have.property('length').above(3);

99

});

100

101

const numbers = [1, 2, 3, 4, 5];

102

numbers.should.matchEach(n => {

103

n.should.be.a.Number();

104

n.should.be.above(0);

105

});

106

```

107

108

### matchAny() / matchSome()

109

110

Test that at least one element in a collection matches a pattern.

111

112

```javascript { .api }

113

/**

114

* Assert that at least one element matches the pattern

115

* @param pattern - RegExp, string, or function to match against

116

* @param description - Optional error message

117

* @returns This assertion for chaining

118

*/

119

matchAny(pattern: RegExp | string | Function, description?: string): Assertion;

120

/**

121

* Alias for matchAny - assert that at least one element matches the pattern

122

*/

123

matchSome(pattern: RegExp | string | Function, description?: string): Assertion;

124

```

125

126

**Usage:**

127

128

```javascript

129

// Array - at least one matches

130

['hello', 'world', 'test'].should.matchAny(/^w/); // 'world' matches

131

[1, -2, 3].should.matchAny(num => num < 0); // -2 matches

132

133

// String matching

134

['apple', 'banana', 'cherry'].should.matchAny(str => str.startsWith('b')); // 'banana'

135

136

// Mixed array - some match, some don't

137

['abc', 123, 'def'].should.matchAny(/\w+/); // strings match

138

139

// Object values - at least one matches

140

{ x: 'apple', y: 'banana', z: 'cherry' }.should.matchAny(/^b/); // 'banana'

141

{ a: 'test', b: 'hello', c: 'world' }.should.matchAny('hello');

142

143

// Complex validation

144

const mixed = ['short', 'a', 'medium'];

145

mixed.should.matchAny(word => word.length > 5); // 'medium' matches

146

147

// Validation - at least one valid email

148

const emails = ['invalid', 'test@example.com', 'also-invalid'];

149

emails.should.matchAny(/\w+@\w+\.\w+/);

150

```

151

152

## Advanced Pattern Matching Examples

153

154

### String Validation

155

156

```javascript

157

// Email format validation

158

const email = 'user@example.com';

159

email.should.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);

160

161

// URL validation

162

const url = 'https://secure.example.com/path';

163

url.should.match(/^https?:\/\/[\w.-]+\/.*$/);

164

165

// Phone number formats

166

const phone = '(555) 123-4567';

167

phone.should.match(/^\(\d{3}\) \d{3}-\d{4}$/);

168

```

169

170

### Object Structure Validation

171

172

```javascript

173

// API response validation

174

const response = {

175

status: 'success',

176

data: { id: 123, name: 'John' },

177

timestamp: '2023-12-25T10:00:00Z'

178

};

179

180

response.should.match({

181

status: str => ['success', 'error'].includes(str),

182

data: obj => {

183

obj.should.have.property('id').which.is.a.Number();

184

obj.should.have.property('name').which.is.a.String();

185

},

186

timestamp: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/

187

});

188

```

189

190

### Collection Validation

191

192

```javascript

193

// All user objects have required fields

194

const users = [

195

{ id: 1, name: 'Alice', email: 'alice@test.com' },

196

{ id: 2, name: 'Bob', email: 'bob@test.com' }

197

];

198

199

users.should.matchEach(user => {

200

user.should.have.property('id').which.is.a.Number();

201

user.should.have.property('name').which.is.a.String();

202

user.should.have.property('email').which.match(/@/);

203

});

204

205

// At least one admin user

206

const roles = ['user', 'admin', 'user', 'guest'];

207

roles.should.matchAny('admin');

208

209

// All scores are passing grades

210

const scores = [85, 92, 78, 88, 95];

211

scores.should.matchEach(score => score >= 70);

212

```

213

214

### Error Message Validation

215

216

```javascript

217

// Validate error has expected properties and message pattern

218

const error = new Error('Network timeout after 5000ms');

219

error.should.match({

220

message: /timeout after \d+ms/,

221

name: 'Error'

222

});

223

224

// Custom error validation

225

function validateAPIError(err) {

226

err.should.match({

227

status: num => [400, 401, 403, 404, 500].includes(num),

228

message: str => str.length > 0,

229

details: obj => obj.should.be.an.Object()

230

});

231

}

232

```

233

234

### Data Type Validation

235

236

```javascript

237

// Mixed data validation

238

const data = [42, 'hello', true, { key: 'value' }, [1, 2, 3]];

239

240

// At least one of each type

241

data.should.matchAny(item => typeof item === 'number');

242

data.should.matchAny(item => typeof item === 'string');

243

data.should.matchAny(item => typeof item === 'boolean');

244

data.should.matchAny(item => Array.isArray(item));

245

data.should.matchAny(item => typeof item === 'object' && !Array.isArray(item));

246

247

// All elements are truthy

248

const values = [1, 'test', true, {}, []];

249

values.should.matchEach(val => !!val);

250

```

251

252

## Pattern Matching Best Practices

253

254

### Use Appropriate Patterns

255

256

```javascript

257

// Good: Specific regex for known format

258

'2023-12-25'.should.match(/^\d{4}-\d{2}-\d{2}$/);

259

260

// Good: Function for complex logic

261

user.should.match(u => {

262

u.should.have.property('age').which.is.above(18);

263

return u.role === 'admin' || u.permissions.includes('write');

264

});

265

266

// Good: Object matching for structure validation

267

response.should.match({

268

data: arr => arr.should.be.an.Array(),

269

pagination: obj => {

270

obj.should.have.properties('page', 'limit', 'total');

271

}

272

});

273

```

274

275

### Combine with Type Assertions

276

277

```javascript

278

// Ensure type before pattern matching

279

const value = '123-45-6789';

280

value.should.be.a.String().and.match(/^\d{3}-\d{2}-\d{4}$/);

281

282

// Collection type before element matching

283

const items = ['a', 'b', 'c'];

284

items.should.be.an.Array().and.matchEach(/^[a-z]$/);

285

```

286

287

### Error Handling

288

289

```javascript

290

// Descriptive error messages

291

const password = 'weak';

292

password.should.match(

293

/^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,}$/,

294

'Password must contain uppercase, digit, special char, min 8 chars'

295

);

296

297

// Validate before matching

298

function validateConfig(config) {

299

config.should.be.an.Object('Config must be an object');

300

config.should.match({

301

env: str => ['dev', 'staging', 'prod'].includes(str),

302

port: num => num > 0 && num < 65536,

303

database: obj => obj.should.have.properties('host', 'port', 'name')

304

});

305

}

306

```