0
# String Matchers
1
2
Comprehensive string validation including content checks, pattern matching, case sensitivity, length validation, and multi-line operations for robust text assertion capabilities.
3
4
## Capabilities
5
6
### Content Validation
7
8
Matchers for validating string content and character composition.
9
10
```kotlin { .api }
11
/**
12
* Assert that string contains only digits (0-9)
13
* @return The original String value for chaining
14
*/
15
fun String?.shouldContainOnlyDigits(): String?
16
17
/**
18
* Assert that string does not contain only digits
19
* @return The original String value for chaining
20
*/
21
fun String?.shouldNotContainOnlyDigits(): String?
22
23
/**
24
* Assert that string contains at least one digit
25
* @return The original String value for chaining
26
*/
27
fun String?.shouldContainADigit(): String?
28
29
/**
30
* Assert that string contains no digits
31
* @return The original String value for chaining
32
*/
33
fun String?.shouldNotContainADigit(): String?
34
35
/**
36
* Assert that substring appears exactly once in the string
37
* @param substr The substring to search for
38
* @return The original String value for chaining
39
*/
40
infix fun String?.shouldContainOnlyOnce(substr: String): String?
41
42
/**
43
* Assert that substring does not appear exactly once
44
* @param substr The substring to search for
45
* @return The original String value for chaining
46
*/
47
infix fun String?.shouldNotContainOnlyOnce(substr: String): String?
48
49
/**
50
* Create matcher for strings containing only digits
51
* @return Matcher that passes for digit-only strings
52
*/
53
fun containOnlyDigits(): Matcher<String?>
54
55
/**
56
* Create matcher for strings containing at least one digit
57
* @return Matcher that passes for strings with digits
58
*/
59
fun containADigit(): Matcher<String?>
60
61
/**
62
* Create matcher for substring occurrence validation
63
* @param substring The substring to check occurrence count
64
* @return Matcher that passes when substring appears exactly once
65
*/
66
fun containOnlyOnce(substring: String): Matcher<String?>
67
```
68
69
**Usage Examples:**
70
71
```kotlin
72
import io.kotest.matchers.string.*
73
74
val phoneNumber = "1234567890"
75
val mixedText = "abc123def"
76
val uniqueId = "user_123_admin"
77
78
// Content validation
79
phoneNumber.shouldContainOnlyDigits()
80
mixedText.shouldContainADigit()
81
uniqueId shouldContainOnlyOnce "123"
82
83
// Using matcher syntax
84
phoneNumber should containOnlyDigits()
85
mixedText should containADigit()
86
```
87
88
### Emptiness and Whitespace
89
90
Matchers for checking string emptiness and blank states.
91
92
```kotlin { .api }
93
/**
94
* Assert that string is empty (length == 0)
95
* @return The original String value for chaining
96
*/
97
fun String?.shouldBeEmpty(): String?
98
99
/**
100
* Assert that string is not empty
101
* @return The original String value for chaining
102
*/
103
fun String?.shouldNotBeEmpty(): String?
104
105
/**
106
* Assert that string is blank (empty or contains only whitespace)
107
* @return The original String value for chaining
108
*/
109
fun String?.shouldBeBlank(): String?
110
111
/**
112
* Assert that string is not blank
113
* @return The original String value for chaining
114
*/
115
fun String?.shouldNotBeBlank(): String?
116
117
/**
118
* Create matcher for empty string validation
119
* @return Matcher that passes for empty strings
120
*/
121
fun beEmpty(): Matcher<String?>
122
123
/**
124
* Create matcher for blank string validation
125
* @return Matcher that passes for blank strings (empty or whitespace)
126
*/
127
fun beBlank(): Matcher<String?>
128
```
129
130
**Usage Examples:**
131
132
```kotlin
133
import io.kotest.matchers.string.*
134
135
val empty = ""
136
val whitespace = " \t\n"
137
val content = "hello"
138
139
empty.shouldBeEmpty()
140
whitespace.shouldBeBlank()
141
content.shouldNotBeEmpty()
142
content.shouldNotBeBlank()
143
```
144
145
### Length Validation
146
147
Matchers for string length assertions and ranges.
148
149
```kotlin { .api }
150
/**
151
* Assert that string has exact length
152
* @param length The expected length
153
* @return The original String value for chaining
154
*/
155
fun String?.shouldHaveLength(length: Int): String?
156
157
/**
158
* Assert that string does not have specified length
159
* @param length The length that should not match
160
* @return The original String value for chaining
161
*/
162
fun String?.shouldNotHaveLength(length: Int): String?
163
164
/**
165
* Assert that string length is within specified range
166
* @param range IntRange for valid length values
167
* @return The original String value for chaining
168
*/
169
infix fun String?.shouldHaveLengthBetween(range: IntRange): String?
170
171
/**
172
* Assert that string length is between two values (inclusive)
173
* @param min Minimum length (inclusive)
174
* @param max Maximum length (inclusive)
175
* @return The original String value for chaining
176
*/
177
fun String?.shouldHaveLengthBetween(min: Int, max: Int): String?
178
179
/**
180
* Assert that string length is at least specified value
181
* @param length Minimum required length
182
* @return The original String value for chaining
183
*/
184
fun String?.shouldHaveMinLength(length: Int): String?
185
186
/**
187
* Assert that string length is at most specified value
188
* @param length Maximum allowed length
189
* @return The original String value for chaining
190
*/
191
fun String?.shouldHaveMaxLength(length: Int): String?
192
193
/**
194
* Create matcher for exact length validation
195
* @param length The expected length
196
* @return Matcher that passes for strings of exact length
197
*/
198
fun haveLength(length: Int): Matcher<String?>
199
200
/**
201
* Create matcher for length range validation
202
* @param range IntRange for valid length values
203
* @return Matcher that passes for strings within length range
204
*/
205
fun haveLengthBetween(range: IntRange): Matcher<String?>
206
207
/**
208
* Create matcher for minimum length validation
209
* @param length Minimum required length
210
* @return Matcher that passes for strings with at least specified length
211
*/
212
fun haveMinLength(length: Int): Matcher<String?>
213
214
/**
215
* Create matcher for maximum length validation
216
* @param length Maximum allowed length
217
* @return Matcher that passes for strings with at most specified length
218
*/
219
fun haveMaxLength(length: Int): Matcher<String?>
220
```
221
222
**Usage Examples:**
223
224
```kotlin
225
import io.kotest.matchers.string.*
226
227
val password = "secret123"
228
val username = "user"
229
230
password.shouldHaveLength(9)
231
username shouldHaveLengthBetween 3..20
232
password.shouldHaveMinLength(8)
233
username.shouldHaveMaxLength(50)
234
235
// Using matcher syntax
236
password should haveLength(9)
237
username should haveLengthBetween(3..20)
238
```
239
240
### Case Sensitivity
241
242
Matchers for uppercase and lowercase validation.
243
244
```kotlin { .api }
245
/**
246
* Assert that string is all uppercase
247
* @return The original String value for chaining
248
*/
249
fun String?.shouldBeUpperCase(): String?
250
251
/**
252
* Assert that string is not all uppercase
253
* @return The original String value for chaining
254
*/
255
fun String?.shouldNotBeUpperCase(): String?
256
257
/**
258
* Assert that string is all lowercase
259
* @return The original String value for chaining
260
*/
261
fun String?.shouldBeLowerCase(): String?
262
263
/**
264
* Assert that string is not all lowercase
265
* @return The original String value for chaining
266
*/
267
fun String?.shouldNotBeLowerCase(): String?
268
269
/**
270
* Create matcher for uppercase validation
271
* @return Matcher that passes for uppercase strings
272
*/
273
fun beUpperCase(): Matcher<String?>
274
275
/**
276
* Create matcher for lowercase validation
277
* @return Matcher that passes for lowercase strings
278
*/
279
fun beLowerCase(): Matcher<String?>
280
```
281
282
### Prefix and Suffix
283
284
Matchers for string start and end validation.
285
286
```kotlin { .api }
287
/**
288
* Assert that string starts with specified prefix
289
* @param prefix The expected prefix
290
* @return The original String value for chaining
291
*/
292
fun String?.shouldStartWith(prefix: String): String?
293
294
/**
295
* Assert that string does not start with specified prefix
296
* @param prefix The prefix that should not match
297
* @return The original String value for chaining
298
*/
299
fun String?.shouldNotStartWith(prefix: String): String?
300
301
/**
302
* Assert that string ends with specified suffix
303
* @param suffix The expected suffix
304
* @return The original String value for chaining
305
*/
306
fun String?.shouldEndWith(suffix: String): String?
307
308
/**
309
* Assert that string does not end with specified suffix
310
* @param suffix The suffix that should not match
311
* @return The original String value for chaining
312
*/
313
fun String?.shouldNotEndWith(suffix: String): String?
314
315
/**
316
* Assert that string starts with prefix (case-insensitive)
317
* @param prefix The expected prefix
318
* @return The original String value for chaining
319
*/
320
fun String?.shouldStartWithIgnoringCase(prefix: String): String?
321
322
/**
323
* Assert that string ends with suffix (case-insensitive)
324
* @param suffix The expected suffix
325
* @return The original String value for chaining
326
*/
327
fun String?.shouldEndWithIgnoringCase(suffix: String): String?
328
329
/**
330
* Create matcher for prefix validation
331
* @param prefix The expected prefix
332
* @return Matcher that passes for strings starting with prefix
333
*/
334
fun startWith(prefix: String): Matcher<String?>
335
336
/**
337
* Create matcher for suffix validation
338
* @param suffix The expected suffix
339
* @return Matcher that passes for strings ending with suffix
340
*/
341
fun endWith(suffix: String): Matcher<String?>
342
343
/**
344
* Create matcher for case-insensitive prefix validation
345
* @param prefix The expected prefix
346
* @return Matcher that passes for strings starting with prefix (ignoring case)
347
*/
348
fun startWithIgnoringCase(prefix: String): Matcher<String?>
349
350
/**
351
* Create matcher for case-insensitive suffix validation
352
* @param suffix The expected suffix
353
* @return Matcher that passes for strings ending with suffix (ignoring case)
354
*/
355
fun endWithIgnoringCase(suffix: String): Matcher<String?>
356
```
357
358
**Usage Examples:**
359
360
```kotlin
361
import io.kotest.matchers.string.*
362
363
val url = "https://example.com"
364
val filename = "report.PDF"
365
366
// Case-sensitive prefix/suffix
367
url.shouldStartWith("https://")
368
filename.shouldEndWith("PDF")
369
370
// Case-insensitive matching
371
filename.shouldEndWithIgnoringCase("pdf")
372
373
// Using matcher syntax
374
url should startWith("https://")
375
filename should endWithIgnoringCase("pdf")
376
```
377
378
### Containment and Substring
379
380
Matchers for substring presence and containment checks.
381
382
```kotlin { .api }
383
/**
384
* Assert that string contains specified substring
385
* @param substr The substring to search for
386
* @return The original String value for chaining
387
*/
388
infix fun String?.shouldContain(substr: String): String?
389
390
/**
391
* Assert that string does not contain specified substring
392
* @param substr The substring that should not be present
393
* @return The original String value for chaining
394
*/
395
infix fun String?.shouldNotContain(substr: String): String?
396
397
/**
398
* Assert that string contains substring (case-insensitive)
399
* @param substr The substring to search for
400
* @return The original String value for chaining
401
*/
402
fun String?.shouldContainIgnoringCase(substr: String): String?
403
404
/**
405
* Assert that string contains all specified substrings
406
* @param substrings Variable number of substrings to check
407
* @return The original String value for chaining
408
*/
409
fun String?.shouldContainAll(vararg substrings: String): String?
410
411
/**
412
* Assert that string contains any of the specified substrings
413
* @param substrings Variable number of substrings to check
414
* @return The original String value for chaining
415
*/
416
fun String?.shouldContainAnyOf(vararg substrings: String): String?
417
418
/**
419
* Create matcher for substring containment
420
* @param substr The substring to search for
421
* @return Matcher that passes for strings containing the substring
422
*/
423
fun contain(substr: String): Matcher<String?>
424
425
/**
426
* Create matcher for case-insensitive substring containment
427
* @param substr The substring to search for
428
* @return Matcher that passes for strings containing the substring (ignoring case)
429
*/
430
fun containIgnoringCase(substr: String): Matcher<String?>
431
432
/**
433
* Create matcher for multiple substring containment
434
* @param substrings Variable number of required substrings
435
* @return Matcher that passes when all substrings are present
436
*/
437
fun containAll(vararg substrings: String): Matcher<String?>
438
439
/**
440
* Create matcher for any substring containment
441
* @param substrings Variable number of possible substrings
442
* @return Matcher that passes when any substring is present
443
*/
444
fun containAnyOf(vararg substrings: String): Matcher<String?>
445
```
446
447
### Regular Expression Matching
448
449
Matchers for pattern matching using regular expressions.
450
451
```kotlin { .api }
452
/**
453
* Assert that string matches the regular expression
454
* @param regex The regular expression pattern
455
* @return The original String value for chaining
456
*/
457
fun String?.shouldMatch(regex: Regex): String?
458
459
/**
460
* Assert that string matches the regular expression pattern
461
* @param pattern The regex pattern as string
462
* @return The original String value for chaining
463
*/
464
fun String?.shouldMatch(pattern: String): String?
465
466
/**
467
* Assert that string does not match the regular expression
468
* @param regex The regular expression pattern
469
* @return The original String value for chaining
470
*/
471
fun String?.shouldNotMatch(regex: Regex): String?
472
473
/**
474
* Assert that string fully matches the regular expression
475
* @param regex The regular expression pattern
476
* @return The original String value for chaining
477
*/
478
fun String?.shouldFullyMatch(regex: Regex): String?
479
480
/**
481
* Create matcher for regex pattern matching
482
* @param regex The regular expression to match against
483
* @return Matcher that passes for strings matching the pattern
484
*/
485
fun match(regex: Regex): Matcher<String?>
486
487
/**
488
* Create matcher for regex pattern string matching
489
* @param pattern The regex pattern as string
490
* @return Matcher that passes for strings matching the pattern
491
*/
492
fun match(pattern: String): Matcher<String?>
493
494
/**
495
* Create matcher for full regex matching (entire string)
496
* @param regex The regular expression for full matching
497
* @return Matcher that passes when entire string matches pattern
498
*/
499
fun fullyMatch(regex: Regex): Matcher<String?>
500
```
501
502
**Usage Examples:**
503
504
```kotlin
505
import io.kotest.matchers.string.*
506
507
val email = "user@example.com"
508
val phoneNumber = "+1-555-123-4567"
509
val text = "Hello World 123"
510
511
// Regex matching
512
val emailRegex = """^[\w\.-]+@[\w\.-]+\.\w+$""".toRegex()
513
email.shouldMatch(emailRegex)
514
515
// Pattern string matching
516
phoneNumber.shouldMatch("""\+\d{1}-\d{3}-\d{3}-\d{4}""")
517
518
// Full match validation
519
text.shouldFullyMatch("""Hello World \d+""".toRegex())
520
521
// Using matcher syntax
522
email should match(emailRegex)
523
text should fullyMatch("""Hello World \d+""".toRegex())
524
```
525
526
### Multi-line String Operations
527
528
Matchers for handling multi-line strings and line-based operations.
529
530
```kotlin { .api }
531
/**
532
* Assert that string has exactly specified number of lines
533
* @param count The expected line count
534
* @return The original String value for chaining
535
*/
536
fun String?.shouldHaveLineCount(count: Int): String?
537
538
/**
539
* Assert that string does not have specified line count
540
* @param count The line count that should not match
541
* @return The original String value for chaining
542
*/
543
fun String?.shouldNotHaveLineCount(count: Int): String?
544
545
/**
546
* Assert that string is a single line (no line breaks)
547
* @return The original String value for chaining
548
*/
549
fun String?.shouldBeSingleLine(): String?
550
551
/**
552
* Assert that string contains multiple lines
553
* @return The original String value for chaining
554
*/
555
fun String?.shouldBeMultiLine(): String?
556
557
/**
558
* Create matcher for line count validation
559
* @param count The expected number of lines
560
* @return Matcher that passes for strings with exact line count
561
*/
562
fun haveLineCount(count: Int): Matcher<String?>
563
564
/**
565
* Create matcher for single line validation
566
* @return Matcher that passes for single-line strings
567
*/
568
fun beSingleLine(): Matcher<String?>
569
570
/**
571
* Create matcher for multi-line validation
572
* @return Matcher that passes for multi-line strings
573
*/
574
fun beMultiLine(): Matcher<String?>
575
```
576
577
### Equality with Variations
578
579
Enhanced equality matchers with case and whitespace handling.
580
581
```kotlin { .api }
582
/**
583
* Assert that string equals another string ignoring case
584
* @param other The expected string value
585
* @return The original String value for chaining
586
*/
587
fun String?.shouldEqualIgnoringCase(other: String): String?
588
589
/**
590
* Assert that string equals another string ignoring whitespace
591
* @param other The expected string value
592
* @return The original String value for chaining
593
*/
594
fun String?.shouldEqualIgnoringWhitespace(other: String): String?
595
596
/**
597
* Assert that string equals another string ignoring both case and whitespace
598
* @param other The expected string value
599
* @return The original String value for chaining
600
*/
601
fun String?.shouldEqualIgnoringCaseAndWhitespace(other: String): String?
602
603
/**
604
* Create matcher for case-insensitive equality
605
* @param expected The expected string value
606
* @return Matcher that passes for case-insensitive equality
607
*/
608
fun equalIgnoringCase(expected: String): Matcher<String?>
609
610
/**
611
* Create matcher for whitespace-insensitive equality
612
* @param expected The expected string value
613
* @return Matcher that passes ignoring whitespace differences
614
*/
615
fun equalIgnoringWhitespace(expected: String): Matcher<String?>
616
617
/**
618
* Create matcher for case and whitespace insensitive equality
619
* @param expected The expected string value
620
* @return Matcher that passes ignoring case and whitespace differences
621
*/
622
fun equalIgnoringCaseAndWhitespace(expected: String): Matcher<String?>
623
```
624
625
**Usage Examples:**
626
627
```kotlin
628
import io.kotest.matchers.string.*
629
630
val text1 = "Hello World"
631
val text2 = "HELLO WORLD"
632
val text3 = "Hello\n\tWorld "
633
634
// Case-insensitive equality
635
text1.shouldEqualIgnoringCase(text2)
636
637
// Whitespace-insensitive equality
638
text1.shouldEqualIgnoringWhitespace(text3)
639
640
// Combined case and whitespace insensitive
641
text2.shouldEqualIgnoringCaseAndWhitespace(text3)
642
643
// Multi-line validation
644
val multilineText = """
645
Line 1
646
Line 2
647
Line 3
648
""".trimIndent()
649
650
multilineText.shouldHaveLineCount(3)
651
multilineText.shouldBeMultiLine()
652
```
653
654
## Error Handling
655
656
String matchers provide comprehensive error messages for assertion failures:
657
658
- **Content failures**: Show expected vs actual content with highlighting
659
- **Length failures**: Display expected vs actual length with clear bounds
660
- **Case failures**: Indicate case sensitivity requirements and actual case
661
- **Regex failures**: Show the pattern and explain why matching failed
662
- **Substring failures**: Highlight missing or unexpected substrings with position information
663
- **Multi-line failures**: Show line-by-line differences for complex text comparisons
664
665
All string matchers handle null values appropriately and provide null-safe assertions with clear error messages when null handling is incorrect.