0
# String Assertions
1
2
Methods for testing string content, patterns, and formatting.
3
4
## String Pattern Testing
5
6
### startWith()
7
8
Test that a string starts with a specified prefix.
9
10
```javascript { .api }
11
/**
12
* Assert that the string starts with the specified prefix
13
* @param prefix - The expected prefix string
14
* @param description - Optional error message
15
* @returns This assertion for chaining
16
*/
17
startWith(prefix: string, description?: string): Assertion;
18
```
19
20
**Usage:**
21
```javascript
22
import should from 'should';
23
24
'hello world'.should.startWith('hello');
25
'JavaScript'.should.startWith('Java');
26
'test123'.should.startWith('test');
27
28
// Case sensitive
29
'Hello'.should.not.startWith('hello');
30
'Hello'.should.startWith('H');
31
32
// Empty string
33
'anything'.should.startWith('');
34
''.should.startWith('');
35
36
// With description
37
const filename = 'config.json';
38
filename.should.startWith('config', 'Filename should start with config');
39
40
// Chaining with other assertions
41
const url = 'https://example.com';
42
url.should.startWith('https').and.be.a.String();
43
```
44
45
### endWith()
46
47
Test that a string ends with a specified suffix.
48
49
```javascript { .api }
50
/**
51
* Assert that the string ends with the specified suffix
52
* @param suffix - The expected suffix string
53
* @param description - Optional error message
54
* @returns This assertion for chaining
55
*/
56
endWith(suffix: string, description?: string): Assertion;
57
```
58
59
**Usage:**
60
```javascript
61
'hello world'.should.endWith('world');
62
'test.js'.should.endWith('.js');
63
'document.pdf'.should.endWith('.pdf');
64
65
// Case sensitive
66
'Hello'.should.not.endWith('LLO');
67
'Hello'.should.endWith('o');
68
69
// Empty string
70
'anything'.should.endWith('');
71
''.should.endWith('');
72
73
// With description
74
const email = 'user@example.com';
75
email.should.endWith('.com', 'Email should end with .com domain');
76
77
// File extension validation
78
const jsFile = 'script.js';
79
jsFile.should.endWith('.js').and.be.a.String();
80
```
81
82
## Advanced String Testing
83
84
### match()
85
86
Test that a string matches a pattern, function, or object matcher.
87
88
```javascript { .api }
89
/**
90
* Assert that the string matches the specified pattern, function, or object
91
* @param pattern - RegExp, function, or object to match against
92
* @param description - Optional error message
93
* @returns This assertion for chaining
94
*/
95
match(pattern: RegExp | Function | object, description?: string): Assertion;
96
```
97
98
**Usage:**
99
```javascript
100
// Regular expression matching
101
'hello123'.should.match(/^hello\d+$/);
102
'test@example.com'.should.match(/\w+@\w+\.\w+/);
103
'2023-12-25'.should.match(/^\d{4}-\d{2}-\d{2}$/);
104
105
// Case insensitive regex
106
'Hello World'.should.match(/hello world/i);
107
108
// Function matching
109
'positive123'.should.match(str => str.includes('positive'));
110
'test'.should.match(str => str.length === 4);
111
112
// Object matching (for complex patterns)
113
const phonePattern = {
114
test: (str) => /^\d{3}-\d{3}-\d{4}$/.test(str)
115
};
116
'123-456-7890'.should.match(phonePattern);
117
118
// With description
119
const password = 'MyPassword123!';
120
password.should.match(/^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])/,
121
'Password should contain uppercase, digit, and special character');
122
```
123
124
## Practical String Validation Examples
125
126
### Email Validation
127
```javascript
128
function validateEmail(email) {
129
email.should.be.a.String();
130
email.should.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
131
email.should.not.be.empty();
132
133
// Additional checks
134
email.should.not.startWith('@');
135
email.should.not.endWith('@');
136
email.should.match(/@/); // Must contain @
137
}
138
139
// Usage
140
const validEmail = 'user@example.com';
141
validateEmail(validEmail);
142
```
143
144
### URL Validation
145
```javascript
146
function validateURL(url) {
147
url.should.be.a.String();
148
url.should.match(/^https?:\/\//); // Must start with http:// or https://
149
url.should.not.be.empty();
150
}
151
152
// Protocol-specific validation
153
function validateHTTPS(url) {
154
url.should.startWith('https://');
155
url.should.not.startWith('http://');
156
}
157
158
const secureUrl = 'https://secure.example.com';
159
validateHTTPS(secureUrl);
160
```
161
162
### File Path Validation
163
```javascript
164
function validateJavaScriptFile(filepath) {
165
filepath.should.be.a.String();
166
filepath.should.endWith('.js');
167
filepath.should.not.be.empty();
168
}
169
170
function validateImageFile(filepath) {
171
filepath.should.be.a.String();
172
filepath.should.match(/\.(jpg|jpeg|png|gif|webp)$/i);
173
}
174
175
const jsFile = 'components/Header.js';
176
validateJavaScriptFile(jsFile);
177
178
const imageFile = 'assets/logo.PNG';
179
validateImageFile(imageFile);
180
```
181
182
### Format Validation
183
```javascript
184
// Phone number formats
185
function validatePhoneNumber(phone) {
186
phone.should.be.a.String();
187
phone.should.match(/^\(\d{3}\) \d{3}-\d{4}$|^\d{3}-\d{3}-\d{4}$/);
188
}
189
190
// Date formats
191
function validateDateFormat(date) {
192
date.should.be.a.String();
193
date.should.match(/^\d{4}-\d{2}-\d{2}$/); // YYYY-MM-DD
194
}
195
196
// Time formats
197
function validateTimeFormat(time) {
198
time.should.be.a.String();
199
time.should.match(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/); // HH:MM (24-hour)
200
}
201
202
validatePhoneNumber('(555) 123-4567');
203
validateDateFormat('2023-12-25');
204
validateTimeFormat('14:30');
205
```
206
207
### Content Validation
208
```javascript
209
// Password strength
210
function validateStrongPassword(password) {
211
password.should.be.a.String();
212
password.should.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
213
'Password must contain uppercase, lowercase, digit, special char, min 8 chars');
214
}
215
216
// Username validation
217
function validateUsername(username) {
218
username.should.be.a.String();
219
username.should.match(/^[a-zA-Z0-9_-]{3,20}$/);
220
username.should.not.startWith('-');
221
username.should.not.endWith('-');
222
}
223
224
// HTML tag validation
225
function validateHTMLTag(tag) {
226
tag.should.be.a.String();
227
tag.should.startWith('<');
228
tag.should.endWith('>');
229
tag.should.match(/^<\/?[a-zA-Z][\w-]*(?:\s[^>]*)?>/);
230
}
231
232
validateUsername('user_123');
233
validateHTMLTag('<div class="container">');
234
```
235
236
### Text Content Analysis
237
```javascript
238
// Check for specific content
239
function validateContainsKeywords(text, keywords) {
240
text.should.be.a.String();
241
keywords.forEach(keyword => {
242
text.should.match(new RegExp(keyword, 'i')); // Case insensitive
243
});
244
}
245
246
// Code validation
247
function validateJavaScriptCode(code) {
248
code.should.be.a.String();
249
code.should.not.be.empty();
250
251
// Should contain function or variable declarations
252
code.should.match(/\b(function|const|let|var|class)\b/);
253
}
254
255
// Markdown validation
256
function validateMarkdownHeader(text) {
257
text.should.be.a.String();
258
text.should.startWith('#');
259
text.should.match(/^#{1,6}\s+/); // 1-6 # followed by space
260
}
261
262
const jsCode = 'const hello = () => "world";';
263
validateJavaScriptCode(jsCode);
264
265
const header = '## Section Title';
266
validateMarkdownHeader(header);
267
```
268
269
## String-Specific Methods
270
271
String assertions in Should.js focus on content testing, prefix/suffix validation, and pattern matching specifically for string values.
272
273
**Note**: The `match()` method shown above also works with collections and has additional variants (`matchEach()`, `matchEvery()`, `matchAny()`, `matchSome()`). These are general collection methods, not string-specific. For complete documentation on pattern matching capabilities, see [Pattern Matching](./pattern-matching.md).
274
275
## String Length and Emptiness
276
277
String assertions can be combined with length and emptiness tests:
278
279
```javascript
280
const text = 'Hello World';
281
282
// Length validation
283
text.should.be.a.String().and.have.length(11);
284
text.should.not.be.empty();
285
286
// Pattern with length constraints
287
const code = 'ABC123';
288
code.should.match(/^[A-Z]{3}\d{3}$/).and.have.length(6);
289
290
// Minimum/maximum length with content validation
291
const title = 'My Article Title';
292
title.should.be.a.String()
293
.and.have.property('length').above(5)
294
.and.below(50);
295
title.should.not.be.empty();
296
```
297
298
## Case Sensitivity Examples
299
300
```javascript
301
// Case-sensitive matching
302
'JavaScript'.should.startWith('Java'); // ✓
303
'JavaScript'.should.not.startWith('java'); // ✓
304
305
'test.JS'.should.endWith('.JS'); // ✓
306
'test.JS'.should.not.endWith('.js'); // ✓
307
308
// Case-insensitive with regex
309
'Hello World'.should.match(/hello/i); // ✓
310
'Hello World'.should.not.match(/hello/); // ✓ (case sensitive fails)
311
312
// Custom case-insensitive validation
313
function validateExtension(filename, ext) {
314
filename.should.be.a.String();
315
filename.should.match(new RegExp(`\\.${ext}$`, 'i'));
316
}
317
318
validateExtension('document.PDF', 'pdf'); // ✓
319
validateExtension('image.JPG', 'jpg'); // ✓
320
```
321
322
## Negation and Chaining
323
324
All string assertions support negation and can be chained:
325
326
```javascript
327
const filename = 'document.txt';
328
329
// Multiple conditions
330
filename.should.be.a.String()
331
.and.not.be.empty()
332
.and.startWith('doc')
333
.and.endWith('.txt')
334
.and.match(/^[a-z]+\.(txt|doc)$/);
335
336
// Negation examples
337
filename.should.not.startWith('test');
338
filename.should.not.endWith('.js');
339
filename.should.not.match(/^\d+/); // Should not start with digits
340
```