0
# Assertions
1
2
Comprehensive assertion library with 60+ built-in assertions and logical composition operators. The assertion system provides type-safe validation with detailed failure reporting.
3
4
## Capabilities
5
6
### Core Assertion Functions
7
8
Functions for creating and evaluating assertions.
9
10
```scala { .api }
11
/**
12
* Creates a test result by applying an assertion to a value
13
* @param value - Value to test (computed lazily)
14
* @param assertion - Assertion to apply to the value
15
* @returns Test result indicating success or failure
16
*/
17
def assert[A](value: => A)(assertion: Assertion[A]): TestResult
18
19
/**
20
* Creates an effectful test result by applying an assertion to an effect's result
21
* @param effect - ZIO effect that produces a value to test
22
* @param assertion - Assertion to apply to the effect's result
23
* @returns ZIO effect that produces a test result
24
*/
25
def assertM[R, E, A](effect: ZIO[R, E, A])(assertion: AssertionM[A]): ZIO[R, E, TestResult]
26
```
27
28
### Assertion Composition
29
30
Logical operators for combining assertions.
31
32
```scala { .api }
33
final class Assertion[-A] {
34
/**
35
* Logical AND - succeeds only if both assertions succeed
36
*/
37
def &&[A1 <: A](that: => Assertion[A1]): Assertion[A1]
38
39
/**
40
* Logical OR - succeeds if either assertion succeeds
41
*/
42
def ||[A1 <: A](that: => Assertion[A1]): Assertion[A1]
43
44
/**
45
* Logical negation - succeeds if the assertion fails
46
*/
47
def unary_!(): Assertion[A]
48
49
/**
50
* Add a descriptive label to the assertion
51
*/
52
def label(string: String): Assertion[A]
53
54
/**
55
* Alias for label
56
*/
57
def ??(string: String): Assertion[A]
58
}
59
```
60
61
**Usage Examples:**
62
63
```scala
64
// Combining assertions
65
assert(user.age)(isGreaterThan(18) && isLessThan(100))
66
assert(result)(isRight(equalTo(42)) || isLeft(equalTo("error")))
67
68
// Negation
69
assert(list)(not(isEmpty))
70
assert(user.email)(not(containsString("temp")))
71
72
// Labeled assertions
73
assert(response.status)(equalTo(200) ?? "HTTP OK status")
74
```
75
76
### Equality Assertions
77
78
Assertions for testing equality and basic comparisons.
79
80
```scala { .api }
81
/**
82
* Tests that two values are equal
83
*/
84
def equalTo[A](expected: A): Assertion[A]
85
86
/**
87
* Always succeeds - useful for testing completion
88
*/
89
def anything: Assertion[Any]
90
91
/**
92
* Always fails - useful for testing failure cases
93
*/
94
def nothing: Assertion[Any]
95
```
96
97
### Numeric Assertions
98
99
Assertions for numeric comparisons and ranges.
100
101
```scala { .api }
102
/**
103
* Tests that value is greater than reference
104
*/
105
def isGreaterThan[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
106
107
/**
108
* Tests that value is greater than or equal to reference
109
*/
110
def isGreaterThanEqualTo[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
111
112
/**
113
* Tests that value is less than reference
114
*/
115
def isLessThan[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
116
117
/**
118
* Tests that value is less than or equal to reference
119
*/
120
def isLessThanEqualTo[A](reference: A)(implicit ord: Ordering[A]): Assertion[A]
121
122
/**
123
* Tests that value is within tolerance of reference
124
*/
125
def isWithin[A](reference: A, tolerance: A)(implicit num: Numeric[A]): Assertion[A]
126
127
/**
128
* Tests that numeric value is positive
129
*/
130
def isPositive[A](implicit num: Numeric[A], ord: Ordering[A]): Assertion[A]
131
132
/**
133
* Tests that numeric value is negative
134
*/
135
def isNegative[A](implicit num: Numeric[A], ord: Ordering[A]): Assertion[A]
136
137
/**
138
* Tests that numeric value is zero
139
*/
140
def isZero[A](implicit num: Numeric[A]): Assertion[A]
141
```
142
143
**Usage Examples:**
144
145
```scala
146
assert(temperature)(isGreaterThan(0.0))
147
assert(age)(isGreaterThanEqualTo(18) && isLessThan(120))
148
assert(measurement)(isWithin(10.0, 0.1))
149
assert(balance)(isPositive)
150
assert(profit)(isNegative)
151
```
152
153
### Boolean Assertions
154
155
Assertions specifically for boolean values.
156
157
```scala { .api }
158
/**
159
* Tests that boolean value is true
160
*/
161
val isTrue: Assertion[Boolean]
162
163
/**
164
* Tests that boolean value is false
165
*/
166
val isFalse: Assertion[Boolean]
167
```
168
169
### Collection Assertions
170
171
Assertions for testing collections, iterables, and their properties.
172
173
```scala { .api }
174
/**
175
* Tests that collection is empty
176
*/
177
def isEmpty: Assertion[Iterable[Any]]
178
179
/**
180
* Tests that collection is non-empty
181
*/
182
def isNonEmpty: Assertion[Iterable[Any]]
183
184
/**
185
* Tests collection size against an assertion
186
*/
187
def hasSize[A](assertion: Assertion[Int]): Assertion[Iterable[A]]
188
189
/**
190
* Tests that collection contains specific element
191
*/
192
def contains[A](element: A): Assertion[Iterable[A]]
193
194
/**
195
* Tests that at least one element satisfies the assertion
196
*/
197
def exists[A](assertion: Assertion[A]): Assertion[Iterable[A]]
198
199
/**
200
* Tests that all elements satisfy the assertion
201
*/
202
def forall[A](assertion: Assertion[A]): Assertion[Iterable[A]]
203
204
/**
205
* Tests that collection has same elements as another (order independent)
206
*/
207
def hasSameElements[A](other: Iterable[A]): Assertion[Iterable[A]]
208
209
/**
210
* Tests that collection is a subset of another
211
*/
212
def isSubsetOf[A](other: Iterable[A]): Assertion[Iterable[A]]
213
214
/**
215
* Tests that collection is sorted in ascending order
216
*/
217
def isSorted[A](implicit ord: Ordering[A]): Assertion[Iterable[A]]
218
219
/**
220
* Tests that collection is sorted in descending order
221
*/
222
def isSortedReverse[A](implicit ord: Ordering[A]): Assertion[Iterable[A]]
223
```
224
225
**Usage Examples:**
226
227
```scala
228
assert(emptyList)(isEmpty)
229
assert(users)(hasSize(isGreaterThan(0)))
230
assert(numbers)(contains(42))
231
assert(ages)(forall(isGreaterThan(0)))
232
assert(validEmails)(exists(containsString("@company.com")))
233
assert(sortedNumbers)(isSorted[Int])
234
```
235
236
### String Assertions
237
238
Assertions for string content and patterns.
239
240
```scala { .api }
241
/**
242
* Tests that string starts with prefix
243
*/
244
def startsWith(prefix: String): Assertion[String]
245
246
/**
247
* Tests that string ends with suffix
248
*/
249
def endsWith(suffix: String): Assertion[String]
250
251
/**
252
* Tests that string contains substring
253
*/
254
def containsString(element: String): Assertion[String]
255
256
/**
257
* Tests that string matches regex pattern
258
*/
259
def matches(regex: Regex): Assertion[String]
260
261
/**
262
* Tests that string matches regex pattern (from string)
263
*/
264
def matchesRegex(regex: String): Assertion[String]
265
266
/**
267
* Tests that string is empty
268
*/
269
val isEmptyString: Assertion[String]
270
271
/**
272
* Tests that string is non-empty
273
*/
274
val isNonEmptyString: Assertion[String]
275
```
276
277
**Usage Examples:**
278
279
```scala
280
assert(email)(containsString("@") && endsWith(".com"))
281
assert(phoneNumber)(matchesRegex("\\d{3}-\\d{3}-\\d{4}"))
282
assert(fileName)(startsWith("test_") && endsWith(".scala"))
283
assert(userInput)(isNonEmptyString)
284
```
285
286
### Option Assertions
287
288
Assertions for Option types.
289
290
```scala { .api }
291
/**
292
* Tests that Option is None
293
*/
294
val isNone: Assertion[Option[Any]]
295
296
/**
297
* Tests that Option is Some and value satisfies assertion
298
*/
299
def isSome[A](assertion: Assertion[A]): Assertion[Option[A]]
300
```
301
302
**Usage Examples:**
303
304
```scala
305
assert(optionalResult)(isSome(equalTo(42)))
306
assert(maybeUser)(isSome(hasField("name", _.name, equalTo("John"))))
307
assert(emptyResult)(isNone)
308
```
309
310
### Either Assertions
311
312
Assertions for Either types.
313
314
```scala { .api }
315
/**
316
* Tests that Either is Left and value satisfies assertion
317
*/
318
def isLeft[A](assertion: Assertion[A]): Assertion[Either[A, Any]]
319
320
/**
321
* Tests that Either is Right and value satisfies assertion
322
*/
323
def isRight[A](assertion: Assertion[A]): Assertion[Either[Any, A]]
324
```
325
326
**Usage Examples:**
327
328
```scala
329
assert(parseResult)(isRight(isGreaterThan(0)))
330
assert(validationResult)(isLeft(containsString("invalid")))
331
```
332
333
### Try Assertions
334
335
Assertions for Try types.
336
337
```scala { .api }
338
/**
339
* Tests that Try is Success and value satisfies assertion
340
*/
341
def isSuccess[A](assertion: Assertion[A]): Assertion[Try[A]]
342
343
/**
344
* Tests that Try is Failure and exception satisfies assertion
345
*/
346
def isFailure[A](assertion: Assertion[Throwable]): Assertion[Try[A]]
347
```
348
349
### Exit Assertions
350
351
Assertions for ZIO Exit types.
352
353
```scala { .api }
354
/**
355
* Tests that Exit is successful and value satisfies assertion
356
*/
357
def succeeds[A](assertion: Assertion[A]): Assertion[Exit[Any, A]]
358
359
/**
360
* Tests that Exit failed and error satisfies assertion
361
*/
362
def fails[E](assertion: Assertion[E]): Assertion[Exit[E, Any]]
363
364
/**
365
* Tests that Exit died with exception satisfying assertion
366
*/
367
def dies(assertion: Assertion[Throwable]): Assertion[Exit[Any, Any]]
368
369
/**
370
* Tests that Exit was interrupted
371
*/
372
val isInterrupted: Assertion[Exit[Any, Any]]
373
```
374
375
**Usage Examples:**
376
377
```scala
378
assert(exitResult)(succeeds(equalTo("completed")))
379
assert(failedExit)(fails(isSubtype[IllegalArgumentException]))
380
assert(interruptedExit)(isInterrupted)
381
```
382
383
### Exception Assertions
384
385
Assertions for testing exceptions.
386
387
```scala { .api }
388
/**
389
* Tests that execution throws exception of specific type
390
*/
391
def throws[A <: Throwable]: Assertion[Any]
392
393
/**
394
* Tests that execution throws exception satisfying assertion
395
*/
396
def throwsA[A <: Throwable](assertion: Assertion[A]): Assertion[Any]
397
```
398
399
**Usage Examples:**
400
401
```scala
402
assert(divide(1, 0))(throws[ArithmeticException])
403
assert(parseInvalidJson(json))(throwsA(hasMessage(containsString("syntax"))))
404
```
405
406
### Type Assertions
407
408
Assertions for testing types and subtypes.
409
410
```scala { .api }
411
/**
412
* Tests that value is a subtype and satisfies assertion
413
*/
414
def isSubtype[A](assertion: Assertion[A]): Assertion[Any]
415
416
/**
417
* Tests that value is a case class instance satisfying assertion
418
*/
419
def isCase[A](assertion: Assertion[A]): Assertion[Any]
420
```
421
422
## Types
423
424
### Core Assertion Types
425
426
```scala { .api }
427
/**
428
* Main assertion class for testing values of type A
429
*/
430
final class Assertion[-A]
431
432
/**
433
* Effectful assertion that can perform ZIO operations
434
*/
435
trait AssertionM[-A]
436
437
/**
438
* Result of running assertions - success or failure
439
*/
440
type AssertResult = BoolAlgebra[AssertionValue]
441
442
/**
443
* Effectful assertion result
444
*/
445
type AssertResultM = BoolAlgebraM[Any, Nothing, AssertionValue]
446
447
/**
448
* Value with assertion and execution details
449
*/
450
final case class AssertionValue(
451
assertion: AssertionM[Any],
452
value: Any,
453
result: AssertResult,
454
expression: Option[String] = None,
455
sourceLocation: Option[String] = None
456
)
457
```