rescript-vitest-extras 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,627 @@
1
+ /**
2
+ * Vitest Assert API bindings.
3
+ *
4
+ * These bindings wrap Vitest's chai-based assert API with ergonomic ReScript types.
5
+ * Organized into submodules for type-specific assertions.
6
+ */
7
+ /** Abstract type for the assert object from vitest */
8
+ type t
9
+
10
+ @module("vitest") @val external assertObj: t = "assert"
11
+
12
+ // ============================================================================
13
+ // Core Assertions
14
+ // ============================================================================
15
+
16
+ /** Asserts that `expression` is truthy. */
17
+ @send
18
+ external assert_: (t, 'a, ~message: string=?) => unit = "ok"
19
+
20
+ @inline
21
+ let assert_ = (~message=?, value) => assertObj->assert_(value, ~message?)
22
+
23
+ /** Force an assertion failure with an optional message. */
24
+ @module("vitest") @scope("expect")
25
+ external fail: (~message: string=?) => unit = "unreachable"
26
+
27
+ // ============================================================================
28
+ // Equality
29
+ // ============================================================================
30
+
31
+ @send external equalBinding: (t, 'a, 'a, ~message: string=?) => unit = "equal"
32
+
33
+ /** Non-strict equality comparison (==). */
34
+ @inline
35
+ let equal = (~message=?, actual, expected) => assertObj->equalBinding(actual, expected, ~message?)
36
+
37
+ @send external notEqualBinding: (t, 'a, 'a, ~message: string=?) => unit = "notEqual"
38
+
39
+ /** Non-strict inequality comparison (!=). */
40
+ @inline
41
+ let notEqual = (~message=?, actual, expected) =>
42
+ assertObj->notEqualBinding(actual, expected, ~message?)
43
+
44
+ @send external strictEqualBinding: (t, 'a, 'a, ~message: string=?) => unit = "strictEqual"
45
+
46
+ /** Strict equality comparison (===). */
47
+ @inline
48
+ let strictEqual = (~message=?, actual, expected) =>
49
+ assertObj->strictEqualBinding(actual, expected, ~message?)
50
+
51
+ @send external notStrictEqualBinding: (t, 'a, 'a, ~message: string=?) => unit = "notStrictEqual"
52
+
53
+ /** Strict inequality comparison (!==). */
54
+ @inline
55
+ let notStrictEqual = (~message=?, actual, expected) =>
56
+ assertObj->notStrictEqualBinding(actual, expected, ~message?)
57
+
58
+ @send external deepEqualBinding: (t, 'a, 'a, ~message: string=?) => unit = "deepEqual"
59
+
60
+ /** Deep equality comparison. */
61
+ @inline
62
+ let deepEqual = (~message=?, actual, expected) =>
63
+ assertObj->deepEqualBinding(actual, expected, ~message?)
64
+
65
+ @send external notDeepEqualBinding: (t, 'a, 'a, ~message: string=?) => unit = "notDeepEqual"
66
+
67
+ /** Deep inequality comparison. */
68
+ @inline
69
+ let notDeepEqual = (~message=?, actual, expected) =>
70
+ assertObj->notDeepEqualBinding(actual, expected, ~message?)
71
+
72
+ // ============================================================================
73
+ // Numeric Comparisons
74
+ // ============================================================================
75
+
76
+ @send external isAboveBinding: (t, float, float, ~message: string=?) => unit = "isAbove"
77
+
78
+ /** Asserts that `value > target`. */
79
+ @inline
80
+ let isAbove = (~message=?, value, target) => assertObj->isAboveBinding(value, target, ~message?)
81
+
82
+ @send external isAtLeastBinding: (t, float, float, ~message: string=?) => unit = "isAtLeast"
83
+
84
+ /** Asserts that `value >= target`. */
85
+ @inline
86
+ let isAtLeast = (~message=?, value, target) => assertObj->isAtLeastBinding(value, target, ~message?)
87
+
88
+ @send external isBelowBinding: (t, float, float, ~message: string=?) => unit = "isBelow"
89
+
90
+ /** Asserts that `value < target`. */
91
+ @inline
92
+ let isBelow = (~message=?, value, target) => assertObj->isBelowBinding(value, target, ~message?)
93
+
94
+ @send external isAtMostBinding: (t, float, float, ~message: string=?) => unit = "isAtMost"
95
+
96
+ /** Asserts that `value <= target`. */
97
+ @inline
98
+ let isAtMost = (~message=?, value, target) => assertObj->isAtMostBinding(value, target, ~message?)
99
+
100
+ @send
101
+ external closeToBinding: (t, float, float, float, ~message: string=?) => unit = "closeTo"
102
+
103
+ /** Asserts that `actual` is within +/- `delta` of `expected`. */
104
+ @inline
105
+ let closeTo = (~message=?, actual, expected, ~delta) =>
106
+ assertObj->closeToBinding(actual, expected, delta, ~message?)
107
+
108
+ /** Alias for `closeTo`. */
109
+ let approximately = closeTo
110
+
111
+ // ============================================================================
112
+ // Boolean Assertions
113
+ // ============================================================================
114
+
115
+ @send external isTrueBinding: (t, bool, ~message: string=?) => unit = "isTrue"
116
+
117
+ /** Asserts that `value` is exactly `true`. */
118
+ @inline
119
+ let isTrue = (~message=?, value) => assertObj->isTrueBinding(value, ~message?)
120
+
121
+ @send external isNotTrueBinding: (t, bool, ~message: string=?) => unit = "isNotTrue"
122
+
123
+ /** Asserts that `value` is not exactly `true`. */
124
+ @inline
125
+ let isNotTrue = (~message=?, value) => assertObj->isNotTrueBinding(value, ~message?)
126
+
127
+ @send external isFalseBinding: (t, bool, ~message: string=?) => unit = "isFalse"
128
+
129
+ /** Asserts that `value` is exactly `false`. */
130
+ @inline
131
+ let isFalse = (~message=?, value) => assertObj->isFalseBinding(value, ~message?)
132
+
133
+ @send external isNotFalseBinding: (t, bool, ~message: string=?) => unit = "isNotFalse"
134
+
135
+ /** Asserts that `value` is not exactly `false`. */
136
+ @inline
137
+ let isNotFalse = (~message=?, value) => assertObj->isNotFalseBinding(value, ~message?)
138
+
139
+ // ============================================================================
140
+ // NaN and Finite Assertions
141
+ // ============================================================================
142
+
143
+ @send external isNaNBinding: (t, float, ~message: string=?) => unit = "isNaN"
144
+
145
+ /** Asserts that `value` is `NaN`. */
146
+ @inline
147
+ let isNaN = (~message=?, value) => assertObj->isNaNBinding(value, ~message?)
148
+
149
+ @send external isNotNaNBinding: (t, float, ~message: string=?) => unit = "isNotNaN"
150
+
151
+ /** Asserts that `value` is not `NaN`. */
152
+ @inline
153
+ let isNotNaN = (~message=?, value) => assertObj->isNotNaNBinding(value, ~message?)
154
+
155
+ @send external isFiniteBinding: (t, float, ~message: string=?) => unit = "isFinite"
156
+
157
+ /** Asserts that `value` is finite (not NaN or Infinity). */
158
+ @inline
159
+ let isFinite = (~message=?, value) => assertObj->isFiniteBinding(value, ~message?)
160
+
161
+ // ============================================================================
162
+ // Regex Matching
163
+ // ============================================================================
164
+
165
+ @send external matchBinding: (t, string, RegExp.t, ~message: string=?) => unit = "match"
166
+
167
+ /** Asserts that `value` matches the regular expression. */
168
+ @inline
169
+ let match_ = (~message=?, value, regexp) => assertObj->matchBinding(value, regexp, ~message?)
170
+
171
+ @send external notMatchBinding: (t, string, RegExp.t, ~message: string=?) => unit = "notMatch"
172
+
173
+ /** Asserts that `value` does not match the regular expression. */
174
+ @inline
175
+ let notMatch = (~message=?, value, regexp) => assertObj->notMatchBinding(value, regexp, ~message?)
176
+
177
+ // ============================================================================
178
+ // oneOf
179
+ // ============================================================================
180
+
181
+ @send
182
+ external oneOfBinding: (t, 'a, array<'a>, ~message: string=?) => unit = "oneOf"
183
+
184
+ /** Asserts that `value` is one of the values in `list`. */
185
+ @inline
186
+ let oneOf = (~message=?, value, list) => assertObj->oneOfBinding(value, list, ~message?)
187
+
188
+ // ============================================================================
189
+ // Exception Assertions
190
+ // ============================================================================
191
+
192
+ @send external throwsBinding: (t, unit => 'a, ~message: string=?) => unit = "throws"
193
+
194
+ /** Asserts that `fn` throws an exception. */
195
+ @inline
196
+ let throws = (~message=?, fn) => assertObj->throwsBinding(fn, ~message?)
197
+
198
+ @send
199
+ external throwsWithMatchBinding: (t, unit => 'a, RegExp.t, ~message: string=?) => unit = "throws"
200
+
201
+ /** Asserts that `fn` throws an exception matching the regexp. */
202
+ @inline
203
+ let throwsWithMatch = (~message=?, fn, regexp) =>
204
+ assertObj->throwsWithMatchBinding(fn, regexp, ~message?)
205
+
206
+ @send external doesNotThrowBinding: (t, unit => 'a, ~message: string=?) => unit = "doesNotThrow"
207
+
208
+ /** Asserts that `fn` does not throw an exception. */
209
+ @inline
210
+ let doesNotThrow = (~message=?, fn) => assertObj->doesNotThrowBinding(fn, ~message?)
211
+
212
+ // ============================================================================
213
+ // Object State Assertions
214
+ // ============================================================================
215
+
216
+ @send external isExtensibleBinding: (t, 'a, ~message: string=?) => unit = "isExtensible"
217
+
218
+ /** Asserts that `object` is extensible (can have new properties added). */
219
+ @inline
220
+ let isExtensible = (~message=?, object) => assertObj->isExtensibleBinding(object, ~message?)
221
+
222
+ @send external isNotExtensibleBinding: (t, 'a, ~message: string=?) => unit = "isNotExtensible"
223
+
224
+ /** Asserts that `object` is not extensible. */
225
+ @inline
226
+ let isNotExtensible = (~message=?, object) => assertObj->isNotExtensibleBinding(object, ~message?)
227
+
228
+ @send external isSealedBinding: (t, 'a, ~message: string=?) => unit = "isSealed"
229
+
230
+ /** Asserts that `object` is sealed (properties cannot be added or deleted). */
231
+ @inline
232
+ let isSealed = (~message=?, object) => assertObj->isSealedBinding(object, ~message?)
233
+
234
+ @send external isNotSealedBinding: (t, 'a, ~message: string=?) => unit = "isNotSealed"
235
+
236
+ /** Asserts that `object` is not sealed. */
237
+ @inline
238
+ let isNotSealed = (~message=?, object) => assertObj->isNotSealedBinding(object, ~message?)
239
+
240
+ @send external isFrozenBinding: (t, 'a, ~message: string=?) => unit = "isFrozen"
241
+
242
+ /** Asserts that `object` is frozen (cannot be modified at all). */
243
+ @inline
244
+ let isFrozen = (~message=?, object) => assertObj->isFrozenBinding(object, ~message?)
245
+
246
+ @send external isNotFrozenBinding: (t, 'a, ~message: string=?) => unit = "isNotFrozen"
247
+
248
+ /** Asserts that `object` is not frozen. */
249
+ @inline
250
+ let isNotFrozen = (~message=?, object) => assertObj->isNotFrozenBinding(object, ~message?)
251
+
252
+ // ============================================================================
253
+ // Null Assertions
254
+ // ============================================================================
255
+
256
+ module Null = {
257
+ @send external isNullBinding: (t, 'a, ~message: string=?) => unit = "isNull"
258
+
259
+ /** Asserts that `value` is `null`. */
260
+ @inline
261
+ let isNull = (~message=?, value: Null.t<'a>): unit => assertObj->isNullBinding(value, ~message?)
262
+
263
+ @send external isNotNullBinding: (t, 'a, ~message: string=?) => unit = "isNotNull"
264
+
265
+ /** Asserts that `value` is not `null`. */
266
+ @inline
267
+ let isNotNull = (~message=?, value: Null.t<'a>): unit =>
268
+ assertObj->isNotNullBinding(value, ~message?)
269
+ }
270
+
271
+ // ============================================================================
272
+ // Undefined Assertions
273
+ // ============================================================================
274
+
275
+ module Undefined = {
276
+ @send external isUndefinedBinding: (t, 'a, ~message: string=?) => unit = "isUndefined"
277
+
278
+ /** Asserts that `value` is `undefined`. */
279
+ @inline
280
+ let isUndefined = (~message=?, value: undefined<'a>): unit =>
281
+ assertObj->isUndefinedBinding(value, ~message?)
282
+
283
+ @send external isDefinedBinding: (t, 'a, ~message: string=?) => unit = "isDefined"
284
+
285
+ /** Asserts that `value` is not `undefined`. */
286
+ @inline
287
+ let isDefined = (~message=?, value: undefined<'a>): unit =>
288
+ assertObj->isDefinedBinding(value, ~message?)
289
+ }
290
+
291
+ // ============================================================================
292
+ // Nullable Assertions (null | undefined | value)
293
+ // ============================================================================
294
+
295
+ module Nullable = {
296
+ @send external isNullBinding: (t, 'a, ~message: string=?) => unit = "isNull"
297
+
298
+ /** Asserts that `value` is `null`. */
299
+ @inline
300
+ let isNull = (~message=?, value: Nullable.t<'a>): unit =>
301
+ assertObj->isNullBinding(value, ~message?)
302
+
303
+ @send external isNotNullBinding: (t, 'a, ~message: string=?) => unit = "isNotNull"
304
+
305
+ /** Asserts that `value` is not `null` (may still be undefined). */
306
+ @inline
307
+ let isNotNull = (~message=?, value: Nullable.t<'a>): unit =>
308
+ assertObj->isNotNullBinding(value, ~message?)
309
+
310
+ @send external isUndefinedBinding: (t, 'a, ~message: string=?) => unit = "isUndefined"
311
+
312
+ /** Asserts that `value` is `undefined`. */
313
+ @inline
314
+ let isUndefined = (~message=?, value: Nullable.t<'a>): unit =>
315
+ assertObj->isUndefinedBinding(value, ~message?)
316
+
317
+ @send external isDefinedBinding: (t, 'a, ~message: string=?) => unit = "isDefined"
318
+
319
+ /** Asserts that `value` is not `undefined` (may still be null). */
320
+ @inline
321
+ let isDefined = (~message=?, value: Nullable.t<'a>): unit =>
322
+ assertObj->isDefinedBinding(value, ~message?)
323
+
324
+ @send external existsBinding: (t, 'a, ~message: string=?) => unit = "exists"
325
+
326
+ /** Asserts that `value` is neither `null` nor `undefined`. */
327
+ @inline
328
+ let exists = (~message=?, value: Nullable.t<'a>): unit =>
329
+ assertObj->existsBinding(value, ~message?)
330
+
331
+ @send external notExistsBinding: (t, 'a, ~message: string=?) => unit = "notExists"
332
+
333
+ /** Asserts that `value` is `null` or `undefined`. */
334
+ @inline
335
+ let notExists = (~message=?, value: Nullable.t<'a>): unit =>
336
+ assertObj->notExistsBinding(value, ~message?)
337
+ }
338
+
339
+ // ============================================================================
340
+ // Array Assertions
341
+ // ============================================================================
342
+
343
+ module Array = {
344
+ @send external isEmptyBinding: (t, 'a, ~message: string=?) => unit = "isEmpty"
345
+
346
+ /** Asserts that `arr` is empty (has length 0). */
347
+ @inline
348
+ let isEmpty = (~message=?, arr: array<'a>): unit => assertObj->isEmptyBinding(arr, ~message?)
349
+
350
+ @send external isNotEmptyBinding: (t, 'a, ~message: string=?) => unit = "isNotEmpty"
351
+
352
+ /** Asserts that `arr` is not empty. */
353
+ @inline
354
+ let isNotEmpty = (~message=?, arr: array<'a>): unit =>
355
+ assertObj->isNotEmptyBinding(arr, ~message?)
356
+
357
+ @send external lengthOfBinding: (t, 'a, int, ~message: string=?) => unit = "lengthOf"
358
+
359
+ /** Asserts that `arr` has a `length` equal to `expected`. */
360
+ @inline
361
+ let lengthOf = (~message=?, arr: array<'a>, expected) =>
362
+ assertObj->lengthOfBinding(arr, expected, ~message?)
363
+
364
+ @send
365
+ external includeBinding: (t, array<'a>, 'a, ~message: string=?) => unit = "include"
366
+
367
+ /** Asserts that `haystack` array contains `needle`. */
368
+ @inline
369
+ let includes = (~message=?, haystack, needle) =>
370
+ assertObj->includeBinding(haystack, needle, ~message?)
371
+
372
+ @send
373
+ external notIncludeBinding: (t, array<'a>, 'a, ~message: string=?) => unit = "notInclude"
374
+
375
+ /** Asserts that `haystack` array does not contain `needle`. */
376
+ @inline
377
+ let notIncludes = (~message=?, haystack, needle) =>
378
+ assertObj->notIncludeBinding(haystack, needle, ~message?)
379
+
380
+ @send
381
+ external sameMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit = "sameMembers"
382
+
383
+ /** Asserts that `actual` and `expected` have the same members (in any order). */
384
+ @inline
385
+ let sameMembers = (~message=?, actual, expected) =>
386
+ assertObj->sameMembersBinding(actual, expected, ~message?)
387
+
388
+ @send
389
+ external notSameMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
390
+ "notSameMembers"
391
+
392
+ /** Asserts that `actual` and `expected` do not have the same members. */
393
+ @inline
394
+ let notSameMembers = (~message=?, actual, expected) =>
395
+ assertObj->notSameMembersBinding(actual, expected, ~message?)
396
+
397
+ @send
398
+ external sameDeepMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
399
+ "sameDeepMembers"
400
+
401
+ /** Asserts that `actual` and `expected` have the same members (deep comparison, any order). */
402
+ @inline
403
+ let sameDeepMembers = (~message=?, actual, expected) =>
404
+ assertObj->sameDeepMembersBinding(actual, expected, ~message?)
405
+
406
+ @send
407
+ external notSameDeepMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
408
+ "notSameDeepMembers"
409
+
410
+ /** Asserts that `actual` and `expected` do not have the same members (deep comparison). */
411
+ @inline
412
+ let notSameDeepMembers = (~message=?, actual, expected) =>
413
+ assertObj->notSameDeepMembersBinding(actual, expected, ~message?)
414
+
415
+ @send
416
+ external sameOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
417
+ "sameOrderedMembers"
418
+
419
+ /** Asserts that `actual` and `expected` have the same members in the same order. */
420
+ @inline
421
+ let sameOrderedMembers = (~message=?, actual, expected) =>
422
+ assertObj->sameOrderedMembersBinding(actual, expected, ~message?)
423
+
424
+ @send
425
+ external notSameOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
426
+ "notSameOrderedMembers"
427
+
428
+ /** Asserts that `actual` and `expected` do not have the same members in order. */
429
+ @inline
430
+ let notSameOrderedMembers = (~message=?, actual, expected) =>
431
+ assertObj->notSameOrderedMembersBinding(actual, expected, ~message?)
432
+
433
+ @send
434
+ external sameDeepOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
435
+ "sameDeepOrderedMembers"
436
+
437
+ /** Asserts that `actual` and `expected` have the same members in order (deep comparison). */
438
+ @inline
439
+ let sameDeepOrderedMembers = (~message=?, actual, expected) =>
440
+ assertObj->sameDeepOrderedMembersBinding(actual, expected, ~message?)
441
+
442
+ @send
443
+ external notSameDeepOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
444
+ "notSameDeepOrderedMembers"
445
+
446
+ /** Asserts that `actual` and `expected` do not have the same members in order (deep comparison). */
447
+ @inline
448
+ let notSameDeepOrderedMembers = (~message=?, actual, expected) =>
449
+ assertObj->notSameDeepOrderedMembersBinding(actual, expected, ~message?)
450
+
451
+ @send
452
+ external includeMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
453
+ "includeMembers"
454
+
455
+ /** Asserts that `superset` contains all members of `subset` (in any order). */
456
+ @inline
457
+ let includeMembers = (~message=?, superset, subset) =>
458
+ assertObj->includeMembersBinding(superset, subset, ~message?)
459
+
460
+ @send
461
+ external notIncludeMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
462
+ "notIncludeMembers"
463
+
464
+ /** Asserts that `superset` does not contain all members of `subset`. */
465
+ @inline
466
+ let notIncludeMembers = (~message=?, superset, subset) =>
467
+ assertObj->notIncludeMembersBinding(superset, subset, ~message?)
468
+
469
+ @send
470
+ external includeDeepMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
471
+ "includeDeepMembers"
472
+
473
+ /** Asserts that `superset` contains all members of `subset` (deep comparison). */
474
+ @inline
475
+ let includeDeepMembers = (~message=?, superset, subset) =>
476
+ assertObj->includeDeepMembersBinding(superset, subset, ~message?)
477
+
478
+ @send
479
+ external notIncludeDeepMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
480
+ "notIncludeDeepMembers"
481
+
482
+ /** Asserts that `superset` does not contain all members of `subset` (deep comparison). */
483
+ @inline
484
+ let notIncludeDeepMembers = (~message=?, superset, subset) =>
485
+ assertObj->notIncludeDeepMembersBinding(superset, subset, ~message?)
486
+
487
+ @send
488
+ external includeOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
489
+ "includeOrderedMembers"
490
+
491
+ /** Asserts that `superset` contains `subset` in the same order (as a contiguous subsequence). */
492
+ @inline
493
+ let includeOrderedMembers = (~message=?, superset, subset) =>
494
+ assertObj->includeOrderedMembersBinding(superset, subset, ~message?)
495
+
496
+ @send
497
+ external notIncludeOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
498
+ "notIncludeOrderedMembers"
499
+
500
+ /** Asserts that `superset` does not contain `subset` as a contiguous subsequence. */
501
+ @inline
502
+ let notIncludeOrderedMembers = (~message=?, superset, subset) =>
503
+ assertObj->notIncludeOrderedMembersBinding(superset, subset, ~message?)
504
+
505
+ @send
506
+ external includeDeepOrderedMembersBinding: (t, array<'a>, array<'a>, ~message: string=?) => unit =
507
+ "includeDeepOrderedMembers"
508
+
509
+ /** Asserts that `superset` contains `subset` in order (deep comparison). */
510
+ @inline
511
+ let includeDeepOrderedMembers = (~message=?, superset, subset) =>
512
+ assertObj->includeDeepOrderedMembersBinding(superset, subset, ~message?)
513
+
514
+ @send
515
+ external notIncludeDeepOrderedMembersBinding: (
516
+ t,
517
+ array<'a>,
518
+ array<'a>,
519
+ ~message: string=?,
520
+ ) => unit = "notIncludeDeepOrderedMembers"
521
+
522
+ /** Asserts that `superset` does not contain `subset` in order (deep comparison). */
523
+ @inline
524
+ let notIncludeDeepOrderedMembers = (~message=?, superset, subset) =>
525
+ assertObj->notIncludeDeepOrderedMembersBinding(superset, subset, ~message?)
526
+ }
527
+
528
+ // ============================================================================
529
+ // String Assertions
530
+ // ============================================================================
531
+
532
+ module String = {
533
+ @send external isEmptyBinding: (t, 'a, ~message: string=?) => unit = "isEmpty"
534
+
535
+ /** Asserts that `str` is empty (has length 0). */
536
+ @inline
537
+ let isEmpty = (~message=?, str: string): unit => assertObj->isEmptyBinding(str, ~message?)
538
+
539
+ @send external isNotEmptyBinding: (t, 'a, ~message: string=?) => unit = "isNotEmpty"
540
+
541
+ /** Asserts that `str` is not empty. */
542
+ @inline
543
+ let isNotEmpty = (~message=?, str: string): unit => assertObj->isNotEmptyBinding(str, ~message?)
544
+
545
+ @send external lengthOfBinding: (t, 'a, int, ~message: string=?) => unit = "lengthOf"
546
+
547
+ /** Asserts that `str` has a `length` equal to `expected`. */
548
+ @inline
549
+ let lengthOf = (~message=?, str: string, expected) =>
550
+ assertObj->lengthOfBinding(str, expected, ~message?)
551
+
552
+ @send
553
+ external includeBinding: (t, string, string, ~message: string=?) => unit = "include"
554
+
555
+ /** Asserts that `haystack` string contains `needle` substring. */
556
+ @inline
557
+ let includes = (~message=?, haystack, needle) =>
558
+ assertObj->includeBinding(haystack, needle, ~message?)
559
+
560
+ @send
561
+ external notIncludeBinding: (t, string, string, ~message: string=?) => unit = "notInclude"
562
+
563
+ /** Asserts that `haystack` string does not contain `needle` substring. */
564
+ @inline
565
+ let notIncludes = (~message=?, haystack, needle) =>
566
+ assertObj->notIncludeBinding(haystack, needle, ~message?)
567
+ }
568
+
569
+ // ============================================================================
570
+ // Result Ergonomic Assertions
571
+ // ============================================================================
572
+
573
+ module Result = {
574
+ /**
575
+ * Asserts that `result` is `Ok`.
576
+ */
577
+ let isOk = (~message=?, result: result<'a, 'e>): unit => {
578
+ switch result {
579
+ | Ok(_) => ()
580
+ | Error(_) =>
581
+ let msg = message->Option.getOr("Expected Result to be Ok, but got Error")
582
+ fail(~message=msg)
583
+ }
584
+ }
585
+
586
+ /**
587
+ * Asserts that `result` is `Error`.
588
+ */
589
+ let isError = (~message=?, result: result<'a, 'e>): unit => {
590
+ switch result {
591
+ | Error(_) => ()
592
+ | Ok(_) =>
593
+ let msg = message->Option.getOr("Expected Result to be Error, but got Ok")
594
+ fail(~message=msg)
595
+ }
596
+ }
597
+ }
598
+
599
+ // ============================================================================
600
+ // Option Ergonomic Assertions
601
+ // ============================================================================
602
+
603
+ module Option = {
604
+ /**
605
+ * Asserts that `option` is `Some`.
606
+ */
607
+ let isSome = (~message=?, opt: option<'a>): unit => {
608
+ switch opt {
609
+ | Some(_) => ()
610
+ | None =>
611
+ let msg = message->Option.getOr("Expected Option to be Some, but got None")
612
+ fail(~message=msg)
613
+ }
614
+ }
615
+
616
+ /**
617
+ * Asserts that `option` is `None`.
618
+ */
619
+ let isNone = (~message=?, opt: option<'a>): unit => {
620
+ switch opt {
621
+ | None => ()
622
+ | Some(_) =>
623
+ let msg = message->Option.getOr("Expected Option to be None, but got Some")
624
+ fail(~message=msg)
625
+ }
626
+ }
627
+ }