schematox 1.2.2 → 1.2.3

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.
@@ -1,1684 +0,0 @@
1
- import * as x from '../../'
2
- import * as fixture from '../fixtures'
3
-
4
- import type { StructSharedKeys } from '../type'
5
-
6
- describe('Type inference and parse by schema/construct/struct (foldA)', () => {
7
- it('required', () => {
8
- const schema = {
9
- type: 'array',
10
- of: { type: 'boolean' },
11
- } as const satisfies x.Schema
12
-
13
- const struct = x.array(x.boolean())
14
-
15
- type ExpectedSubj = boolean[]
16
-
17
- const subjects: Array<ExpectedSubj> = [
18
- [true, false],
19
- [false, true],
20
- ]
21
-
22
- foldA: {
23
- const construct = x.makeStruct(schema)
24
-
25
- /* ensure that schema/construct/struct/~standard subject types are identical */
26
-
27
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
28
-
29
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
30
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
31
-
32
- type SchemaSubj = x.Infer<typeof schema>
33
-
34
- x.tCh<SchemaSubj, ExpectedSubj>()
35
- x.tCh<ExpectedSubj, SchemaSubj>()
36
-
37
- type StructSubj = x.Infer<typeof struct.__schema>
38
-
39
- x.tCh<StructSubj, ExpectedSubj>()
40
- x.tCh<ExpectedSubj, StructSubj>()
41
-
42
- type StandardSubj = NonNullable<
43
- (typeof struct)['~standard']['types']
44
- >['output']
45
-
46
- x.tCh<StandardSubj, ExpectedSubj>()
47
- x.tCh<ExpectedSubj, StandardSubj>()
48
-
49
- /* parsed either type check */
50
-
51
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
52
-
53
- const parsed = x.parse(schema, undefined)
54
-
55
- type SchemaParsed = typeof parsed
56
-
57
- x.tCh<SchemaParsed, ExpectedParsed>()
58
- x.tCh<ExpectedParsed, SchemaParsed>()
59
-
60
- type ConstructParsed = ReturnType<typeof construct.parse>
61
-
62
- x.tCh<ConstructParsed, ExpectedParsed>()
63
- x.tCh<ExpectedParsed, ConstructParsed>()
64
-
65
- type StructParsed = ReturnType<typeof struct.parse>
66
-
67
- x.tCh<StructParsed, ExpectedParsed>()
68
- x.tCh<ExpectedParsed, StructParsed>()
69
-
70
- type StandardParsed = Extract<
71
- ReturnType<(typeof struct)['~standard']['validate']>,
72
- { value: unknown }
73
- >['value']
74
-
75
- x.tCh<StandardParsed, ExpectedSubj>()
76
- x.tCh<ExpectedSubj, StandardParsed>()
77
-
78
- /* runtime schema check */
79
-
80
- expect(struct.__schema).toStrictEqual(schema)
81
- expect(construct.__schema).toStrictEqual(schema)
82
- expect(construct.__schema === schema).toBe(false)
83
-
84
- /* parse result check */
85
-
86
- for (const subj of subjects) {
87
- const schemaParsed = x.parse(schema, subj)
88
-
89
- expect(schemaParsed.error).toBe(undefined)
90
- expect(schemaParsed.data).toStrictEqual(subj)
91
-
92
- const constructParsed = construct.parse(subj)
93
-
94
- expect(constructParsed.error).toBe(undefined)
95
- expect(constructParsed.data).toStrictEqual(subj)
96
-
97
- const structParsed = struct.parse(subj)
98
-
99
- expect(structParsed.error).toBe(undefined)
100
- expect(structParsed.data).toStrictEqual(subj)
101
-
102
- const standardParsed = struct['~standard'].validate(subj)
103
-
104
- if (standardParsed instanceof Promise) {
105
- throw Error('Not expected')
106
- }
107
-
108
- if (standardParsed.issues !== undefined) {
109
- throw Error('not expected')
110
- }
111
-
112
- expect(standardParsed.value).toStrictEqual(subj)
113
- }
114
- }
115
- })
116
-
117
- it('optional', () => {
118
- const schema = {
119
- type: 'array',
120
- of: { type: 'boolean' },
121
- optional: true,
122
- } as const satisfies x.Schema
123
-
124
- const struct = x.array(x.boolean()).optional()
125
-
126
- type ExpectedSubj = boolean[] | undefined
127
-
128
- const subjects: Array<ExpectedSubj> = [
129
- [true, false],
130
- [false, true],
131
- undefined,
132
- ]
133
-
134
- foldA: {
135
- const construct = x.makeStruct(schema)
136
-
137
- /* ensure that schema/construct/struct/~standard subject types are identical */
138
-
139
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
140
-
141
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
142
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
143
-
144
- type SchemaSubj = x.Infer<typeof schema>
145
-
146
- x.tCh<SchemaSubj, ExpectedSubj>()
147
- x.tCh<ExpectedSubj, SchemaSubj>()
148
-
149
- type StructSubj = x.Infer<typeof struct.__schema>
150
-
151
- x.tCh<StructSubj, ExpectedSubj>()
152
- x.tCh<ExpectedSubj, StructSubj>()
153
-
154
- type StandardSubj = NonNullable<
155
- (typeof struct)['~standard']['types']
156
- >['output']
157
-
158
- x.tCh<StandardSubj, ExpectedSubj>()
159
- x.tCh<ExpectedSubj, StandardSubj>()
160
-
161
- /* parsed either type check */
162
-
163
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
164
-
165
- const parsed = x.parse(schema, undefined)
166
-
167
- type SchemaParsed = typeof parsed
168
-
169
- x.tCh<SchemaParsed, ExpectedParsed>()
170
- x.tCh<ExpectedParsed, SchemaParsed>()
171
-
172
- type ConstructParsed = ReturnType<typeof construct.parse>
173
-
174
- x.tCh<ConstructParsed, ExpectedParsed>()
175
- x.tCh<ExpectedParsed, ConstructParsed>()
176
-
177
- type StructParsed = ReturnType<typeof struct.parse>
178
-
179
- x.tCh<StructParsed, ExpectedParsed>()
180
- x.tCh<ExpectedParsed, StructParsed>()
181
-
182
- type StandardParsed = Extract<
183
- ReturnType<(typeof struct)['~standard']['validate']>,
184
- { value: unknown }
185
- >['value']
186
-
187
- x.tCh<StandardParsed, ExpectedSubj>()
188
- x.tCh<ExpectedSubj, StandardParsed>()
189
-
190
- /* runtime schema check */
191
-
192
- expect(struct.__schema).toStrictEqual(schema)
193
- expect(construct.__schema).toStrictEqual(schema)
194
- expect(construct.__schema === schema).toBe(false)
195
-
196
- /* parse result check */
197
-
198
- for (const subj of subjects) {
199
- const schemaParsed = x.parse(schema, subj)
200
-
201
- expect(schemaParsed.error).toBe(undefined)
202
- expect(schemaParsed.data).toStrictEqual(subj)
203
-
204
- const constructParsed = construct.parse(subj)
205
-
206
- expect(constructParsed.error).toBe(undefined)
207
- expect(constructParsed.data).toStrictEqual(subj)
208
-
209
- const structParsed = struct.parse(subj)
210
-
211
- expect(structParsed.error).toBe(undefined)
212
- expect(structParsed.data).toStrictEqual(subj)
213
-
214
- const standardParsed = struct['~standard'].validate(subj)
215
-
216
- if (standardParsed instanceof Promise) {
217
- throw Error('Not expected')
218
- }
219
-
220
- if (standardParsed.issues !== undefined) {
221
- throw Error('not expected')
222
- }
223
-
224
- expect(standardParsed.value).toStrictEqual(subj)
225
- }
226
- }
227
- })
228
-
229
- it('nullable', () => {
230
- const schema = {
231
- type: 'array',
232
- of: { type: 'boolean' },
233
- nullable: true,
234
- } as const satisfies x.Schema
235
-
236
- const struct = x.array(x.boolean()).nullable()
237
-
238
- type ExpectedSubj = boolean[] | null
239
-
240
- const subjects: Array<ExpectedSubj> = [[true, false], [false, true], null]
241
-
242
- foldA: {
243
- const construct = x.makeStruct(schema)
244
-
245
- /* ensure that schema/construct/struct/~standard subject types are identical */
246
-
247
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
248
-
249
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
250
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
251
-
252
- type SchemaSubj = x.Infer<typeof schema>
253
-
254
- x.tCh<SchemaSubj, ExpectedSubj>()
255
- x.tCh<ExpectedSubj, SchemaSubj>()
256
-
257
- type StructSubj = x.Infer<typeof struct.__schema>
258
-
259
- x.tCh<StructSubj, ExpectedSubj>()
260
- x.tCh<ExpectedSubj, StructSubj>()
261
-
262
- type StandardSubj = NonNullable<
263
- (typeof struct)['~standard']['types']
264
- >['output']
265
-
266
- x.tCh<StandardSubj, ExpectedSubj>()
267
- x.tCh<ExpectedSubj, StandardSubj>()
268
-
269
- /* parsed either type check */
270
-
271
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
272
-
273
- const parsed = x.parse(schema, undefined)
274
-
275
- type SchemaParsed = typeof parsed
276
-
277
- x.tCh<SchemaParsed, ExpectedParsed>()
278
- x.tCh<ExpectedParsed, SchemaParsed>()
279
-
280
- type ConstructParsed = ReturnType<typeof construct.parse>
281
-
282
- x.tCh<ConstructParsed, ExpectedParsed>()
283
- x.tCh<ExpectedParsed, ConstructParsed>()
284
-
285
- type StructParsed = ReturnType<typeof struct.parse>
286
-
287
- x.tCh<StructParsed, ExpectedParsed>()
288
- x.tCh<ExpectedParsed, StructParsed>()
289
-
290
- type StandardParsed = Extract<
291
- ReturnType<(typeof struct)['~standard']['validate']>,
292
- { value: unknown }
293
- >['value']
294
-
295
- x.tCh<StandardParsed, ExpectedSubj>()
296
- x.tCh<ExpectedSubj, StandardParsed>()
297
-
298
- /* runtime schema check */
299
-
300
- expect(struct.__schema).toStrictEqual(schema)
301
- expect(construct.__schema).toStrictEqual(schema)
302
- expect(construct.__schema === schema).toBe(false)
303
-
304
- /* parse result check */
305
-
306
- for (const subj of subjects) {
307
- const schemaParsed = x.parse(schema, subj)
308
-
309
- expect(schemaParsed.error).toBe(undefined)
310
- expect(schemaParsed.data).toStrictEqual(subj)
311
-
312
- const constructParsed = construct.parse(subj)
313
-
314
- expect(constructParsed.error).toBe(undefined)
315
- expect(constructParsed.data).toStrictEqual(subj)
316
-
317
- const structParsed = struct.parse(subj)
318
-
319
- expect(structParsed.error).toBe(undefined)
320
- expect(structParsed.data).toStrictEqual(subj)
321
-
322
- const standardParsed = struct['~standard'].validate(subj)
323
-
324
- if (standardParsed instanceof Promise) {
325
- throw Error('Not expected')
326
- }
327
-
328
- if (standardParsed.issues !== undefined) {
329
- throw Error('not expected')
330
- }
331
-
332
- expect(standardParsed.value).toStrictEqual(subj)
333
- }
334
- }
335
- })
336
-
337
- it('minLength', () => {
338
- const schema = {
339
- type: 'array',
340
- of: { type: 'boolean' },
341
- minLength: 2,
342
- } as const satisfies x.Schema
343
-
344
- const struct = x.array(x.boolean()).minLength(schema.minLength)
345
-
346
- type ExpectedSubj = boolean[]
347
-
348
- const subjects: Array<ExpectedSubj> = [
349
- [true, false],
350
- [false, true],
351
- ]
352
-
353
- foldA: {
354
- const construct = x.makeStruct(schema)
355
-
356
- /* ensure that schema/construct/struct/~standard subject types are identical */
357
-
358
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
359
-
360
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
361
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
362
-
363
- type SchemaSubj = x.Infer<typeof schema>
364
-
365
- x.tCh<SchemaSubj, ExpectedSubj>()
366
- x.tCh<ExpectedSubj, SchemaSubj>()
367
-
368
- type StructSubj = x.Infer<typeof struct.__schema>
369
-
370
- x.tCh<StructSubj, ExpectedSubj>()
371
- x.tCh<ExpectedSubj, StructSubj>()
372
-
373
- type StandardSubj = NonNullable<
374
- (typeof struct)['~standard']['types']
375
- >['output']
376
-
377
- x.tCh<StandardSubj, ExpectedSubj>()
378
- x.tCh<ExpectedSubj, StandardSubj>()
379
-
380
- /* parsed either type check */
381
-
382
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
383
-
384
- const parsed = x.parse(schema, undefined)
385
-
386
- type SchemaParsed = typeof parsed
387
-
388
- x.tCh<SchemaParsed, ExpectedParsed>()
389
- x.tCh<ExpectedParsed, SchemaParsed>()
390
-
391
- type ConstructParsed = ReturnType<typeof construct.parse>
392
-
393
- x.tCh<ConstructParsed, ExpectedParsed>()
394
- x.tCh<ExpectedParsed, ConstructParsed>()
395
-
396
- type StructParsed = ReturnType<typeof struct.parse>
397
-
398
- x.tCh<StructParsed, ExpectedParsed>()
399
- x.tCh<ExpectedParsed, StructParsed>()
400
-
401
- type StandardParsed = Extract<
402
- ReturnType<(typeof struct)['~standard']['validate']>,
403
- { value: unknown }
404
- >['value']
405
-
406
- x.tCh<StandardParsed, ExpectedSubj>()
407
- x.tCh<ExpectedSubj, StandardParsed>()
408
-
409
- /* runtime schema check */
410
-
411
- expect(struct.__schema).toStrictEqual(schema)
412
- expect(construct.__schema).toStrictEqual(schema)
413
- expect(construct.__schema === schema).toBe(false)
414
-
415
- /* parse result check */
416
-
417
- for (const subj of subjects) {
418
- const schemaParsed = x.parse(schema, subj)
419
-
420
- expect(schemaParsed.error).toBe(undefined)
421
- expect(schemaParsed.data).toStrictEqual(subj)
422
-
423
- const constructParsed = construct.parse(subj)
424
-
425
- expect(constructParsed.error).toBe(undefined)
426
- expect(constructParsed.data).toStrictEqual(subj)
427
-
428
- const structParsed = struct.parse(subj)
429
-
430
- expect(structParsed.error).toBe(undefined)
431
- expect(structParsed.data).toStrictEqual(subj)
432
-
433
- const standardParsed = struct['~standard'].validate(subj)
434
-
435
- if (standardParsed instanceof Promise) {
436
- throw Error('Not expected')
437
- }
438
-
439
- if (standardParsed.issues !== undefined) {
440
- throw Error('not expected')
441
- }
442
-
443
- expect(standardParsed.value).toStrictEqual(subj)
444
- }
445
- }
446
- })
447
-
448
- it('maxLength', () => {
449
- const schema = {
450
- type: 'array',
451
- of: { type: 'boolean' },
452
- maxLength: 2,
453
- } as const satisfies x.Schema
454
-
455
- const struct = x.array(x.boolean()).maxLength(schema.maxLength)
456
-
457
- type ExpectedSubj = boolean[]
458
-
459
- const subjects: Array<ExpectedSubj> = [
460
- [true, false],
461
- [false, true],
462
- ]
463
-
464
- foldA: {
465
- const construct = x.makeStruct(schema)
466
-
467
- /* ensure that schema/construct/struct/~standard subject types are identical */
468
-
469
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
470
-
471
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
472
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
473
-
474
- type SchemaSubj = x.Infer<typeof schema>
475
-
476
- x.tCh<SchemaSubj, ExpectedSubj>()
477
- x.tCh<ExpectedSubj, SchemaSubj>()
478
-
479
- type StructSubj = x.Infer<typeof struct.__schema>
480
-
481
- x.tCh<StructSubj, ExpectedSubj>()
482
- x.tCh<ExpectedSubj, StructSubj>()
483
-
484
- type StandardSubj = NonNullable<
485
- (typeof struct)['~standard']['types']
486
- >['output']
487
-
488
- x.tCh<StandardSubj, ExpectedSubj>()
489
- x.tCh<ExpectedSubj, StandardSubj>()
490
-
491
- /* parsed either type check */
492
-
493
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
494
-
495
- const parsed = x.parse(schema, undefined)
496
-
497
- type SchemaParsed = typeof parsed
498
-
499
- x.tCh<SchemaParsed, ExpectedParsed>()
500
- x.tCh<ExpectedParsed, SchemaParsed>()
501
-
502
- type ConstructParsed = ReturnType<typeof construct.parse>
503
-
504
- x.tCh<ConstructParsed, ExpectedParsed>()
505
- x.tCh<ExpectedParsed, ConstructParsed>()
506
-
507
- type StructParsed = ReturnType<typeof struct.parse>
508
-
509
- x.tCh<StructParsed, ExpectedParsed>()
510
- x.tCh<ExpectedParsed, StructParsed>()
511
-
512
- type StandardParsed = Extract<
513
- ReturnType<(typeof struct)['~standard']['validate']>,
514
- { value: unknown }
515
- >['value']
516
-
517
- x.tCh<StandardParsed, ExpectedSubj>()
518
- x.tCh<ExpectedSubj, StandardParsed>()
519
-
520
- /* runtime schema check */
521
-
522
- expect(struct.__schema).toStrictEqual(schema)
523
- expect(construct.__schema).toStrictEqual(schema)
524
- expect(construct.__schema === schema).toBe(false)
525
-
526
- /* parse result check */
527
-
528
- for (const subj of subjects) {
529
- const schemaParsed = x.parse(schema, subj)
530
-
531
- expect(schemaParsed.error).toBe(undefined)
532
- expect(schemaParsed.data).toStrictEqual(subj)
533
-
534
- const constructParsed = construct.parse(subj)
535
-
536
- expect(constructParsed.error).toBe(undefined)
537
- expect(constructParsed.data).toStrictEqual(subj)
538
-
539
- const structParsed = struct.parse(subj)
540
-
541
- expect(structParsed.error).toBe(undefined)
542
- expect(structParsed.data).toStrictEqual(subj)
543
-
544
- const standardParsed = struct['~standard'].validate(subj)
545
-
546
- if (standardParsed instanceof Promise) {
547
- throw Error('Not expected')
548
- }
549
-
550
- if (standardParsed.issues !== undefined) {
551
- throw Error('not expected')
552
- }
553
-
554
- expect(standardParsed.value).toStrictEqual(subj)
555
- }
556
- }
557
- })
558
-
559
- it('optional + nullable + minLength + maxLength', () => {
560
- const schema = {
561
- type: 'array',
562
- of: { type: 'boolean' },
563
- minLength: 2,
564
- maxLength: 2,
565
- optional: true,
566
- nullable: true,
567
- } as const satisfies x.Schema
568
-
569
- const struct = x
570
- .array(x.boolean())
571
- .minLength(schema.minLength)
572
- .maxLength(schema.maxLength)
573
- .optional()
574
- .nullable()
575
-
576
- type ExpectedSubj = boolean[] | undefined | null
577
-
578
- const subjects: Array<ExpectedSubj> = [
579
- [true, false],
580
- [false, true],
581
- undefined,
582
- null,
583
- ]
584
-
585
- foldA: {
586
- const construct = x.makeStruct(schema)
587
-
588
- /* ensure that schema/construct/struct/~standard subject types are identical */
589
-
590
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
591
-
592
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
593
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
594
-
595
- type SchemaSubj = x.Infer<typeof schema>
596
-
597
- x.tCh<SchemaSubj, ExpectedSubj>()
598
- x.tCh<ExpectedSubj, SchemaSubj>()
599
-
600
- type StructSubj = x.Infer<typeof struct.__schema>
601
-
602
- x.tCh<StructSubj, ExpectedSubj>()
603
- x.tCh<ExpectedSubj, StructSubj>()
604
-
605
- type StandardSubj = NonNullable<
606
- (typeof struct)['~standard']['types']
607
- >['output']
608
-
609
- x.tCh<StandardSubj, ExpectedSubj>()
610
- x.tCh<ExpectedSubj, StandardSubj>()
611
-
612
- /* parsed either type check */
613
-
614
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
615
-
616
- const parsed = x.parse(schema, undefined)
617
-
618
- type SchemaParsed = typeof parsed
619
-
620
- x.tCh<SchemaParsed, ExpectedParsed>()
621
- x.tCh<ExpectedParsed, SchemaParsed>()
622
-
623
- type ConstructParsed = ReturnType<typeof construct.parse>
624
-
625
- x.tCh<ConstructParsed, ExpectedParsed>()
626
- x.tCh<ExpectedParsed, ConstructParsed>()
627
-
628
- type StructParsed = ReturnType<typeof struct.parse>
629
-
630
- x.tCh<StructParsed, ExpectedParsed>()
631
- x.tCh<ExpectedParsed, StructParsed>()
632
-
633
- type StandardParsed = Extract<
634
- ReturnType<(typeof struct)['~standard']['validate']>,
635
- { value: unknown }
636
- >['value']
637
-
638
- x.tCh<StandardParsed, ExpectedSubj>()
639
- x.tCh<ExpectedSubj, StandardParsed>()
640
-
641
- /* runtime schema check */
642
-
643
- expect(struct.__schema).toStrictEqual(schema)
644
- expect(construct.__schema).toStrictEqual(schema)
645
- expect(construct.__schema === schema).toBe(false)
646
-
647
- /* parse result check */
648
-
649
- for (const subj of subjects) {
650
- const schemaParsed = x.parse(schema, subj)
651
-
652
- expect(schemaParsed.error).toBe(undefined)
653
- expect(schemaParsed.data).toStrictEqual(subj)
654
-
655
- const constructParsed = construct.parse(subj)
656
-
657
- expect(constructParsed.error).toBe(undefined)
658
- expect(constructParsed.data).toStrictEqual(subj)
659
-
660
- const structParsed = struct.parse(subj)
661
-
662
- expect(structParsed.error).toBe(undefined)
663
- expect(structParsed.data).toStrictEqual(subj)
664
-
665
- const standardParsed = struct['~standard'].validate(subj)
666
-
667
- if (standardParsed instanceof Promise) {
668
- throw Error('Not expected')
669
- }
670
-
671
- if (standardParsed.issues !== undefined) {
672
- throw Error('not expected')
673
- }
674
-
675
- expect(standardParsed.value).toStrictEqual(subj)
676
- }
677
- }
678
- })
679
- })
680
-
681
- describe('Struct parameter keys reduction and schema immutability (foldB)', () => {
682
- it('optional', () => {
683
- const schema = {
684
- type: 'array',
685
- of: { type: 'boolean' },
686
- optional: true,
687
- } as const satisfies x.Schema
688
-
689
- const prevStruct = x.array(x.boolean())
690
- const struct = prevStruct.optional()
691
-
692
- type ExpectedKeys =
693
- | StructSharedKeys
694
- | 'description'
695
- | 'maxLength'
696
- | 'minLength'
697
- | 'nullable'
698
-
699
- foldB: {
700
- const construct = x.makeStruct(schema)
701
-
702
- /* ensure that struct keys are reduced after application */
703
-
704
- type StructKeys = keyof typeof struct
705
-
706
- x.tCh<StructKeys, ExpectedKeys>()
707
- x.tCh<ExpectedKeys, StructKeys>()
708
-
709
- type ConstructKeys = keyof typeof construct
710
-
711
- x.tCh<ConstructKeys, ExpectedKeys>()
712
- x.tCh<ExpectedKeys, ConstructKeys>()
713
-
714
- /* ensure that construct/struct schema types are identical */
715
-
716
- type ExpectedSchema = typeof schema
717
- type StructSchema = typeof struct.__schema
718
-
719
- x.tCh<StructSchema, ExpectedSchema>()
720
- x.tCh<ExpectedSchema, StructSchema>()
721
-
722
- type ConstructSchema = typeof struct.__schema
723
-
724
- x.tCh<ConstructSchema, ExpectedSchema>()
725
- x.tCh<ExpectedSchema, ConstructSchema>()
726
-
727
- /* runtime schema check */
728
-
729
- expect(struct.__schema).toStrictEqual(schema)
730
- expect(construct.__schema).toStrictEqual(schema)
731
- expect(construct.__schema === schema).toBe(false)
732
-
733
- /* runtime schema parameter application immutability check */
734
-
735
- expect(prevStruct.__schema === struct.__schema).toBe(false)
736
- }
737
- })
738
-
739
- it('optional + nullable', () => {
740
- const schema = {
741
- type: 'array',
742
- of: { type: 'boolean' },
743
- optional: true,
744
- nullable: true,
745
- } as const satisfies x.Schema
746
-
747
- const prevStruct = x.array(x.boolean()).optional()
748
- const struct = prevStruct.nullable()
749
-
750
- type ExpectedKeys =
751
- | StructSharedKeys
752
- | 'description'
753
- | 'maxLength'
754
- | 'minLength'
755
-
756
- foldB: {
757
- const construct = x.makeStruct(schema)
758
-
759
- /* ensure that struct keys are reduced after application */
760
-
761
- type StructKeys = keyof typeof struct
762
-
763
- x.tCh<StructKeys, ExpectedKeys>()
764
- x.tCh<ExpectedKeys, StructKeys>()
765
-
766
- type ConstructKeys = keyof typeof construct
767
-
768
- x.tCh<ConstructKeys, ExpectedKeys>()
769
- x.tCh<ExpectedKeys, ConstructKeys>()
770
-
771
- /* ensure that construct/struct schema types are identical */
772
-
773
- type ExpectedSchema = typeof schema
774
- type StructSchema = typeof struct.__schema
775
-
776
- x.tCh<StructSchema, ExpectedSchema>()
777
- x.tCh<ExpectedSchema, StructSchema>()
778
-
779
- type ConstructSchema = typeof struct.__schema
780
-
781
- x.tCh<ConstructSchema, ExpectedSchema>()
782
- x.tCh<ExpectedSchema, ConstructSchema>()
783
-
784
- /* runtime schema check */
785
-
786
- expect(struct.__schema).toStrictEqual(schema)
787
- expect(construct.__schema).toStrictEqual(schema)
788
- expect(construct.__schema === schema).toBe(false)
789
-
790
- /* runtime schema parameter application immutability check */
791
-
792
- expect(prevStruct.__schema === struct.__schema).toBe(false)
793
- }
794
- })
795
-
796
- it('optional + nullable + minLength', () => {
797
- const schema = {
798
- type: 'array',
799
- of: { type: 'boolean' },
800
- optional: true,
801
- nullable: true,
802
- minLength: 2,
803
- } as const satisfies x.Schema
804
-
805
- const prevStruct = x.array(x.boolean()).optional().nullable()
806
- const struct = prevStruct.minLength(schema.minLength)
807
-
808
- type ExpectedKeys = StructSharedKeys | 'description' | 'maxLength'
809
-
810
- foldB: {
811
- const construct = x.makeStruct(schema)
812
-
813
- /* ensure that struct keys are reduced after application */
814
-
815
- type StructKeys = keyof typeof struct
816
-
817
- x.tCh<StructKeys, ExpectedKeys>()
818
- x.tCh<ExpectedKeys, StructKeys>()
819
-
820
- type ConstructKeys = keyof typeof construct
821
-
822
- x.tCh<ConstructKeys, ExpectedKeys>()
823
- x.tCh<ExpectedKeys, ConstructKeys>()
824
-
825
- /* ensure that construct/struct schema types are identical */
826
-
827
- type ExpectedSchema = typeof schema
828
- type StructSchema = typeof struct.__schema
829
-
830
- x.tCh<StructSchema, ExpectedSchema>()
831
- x.tCh<ExpectedSchema, StructSchema>()
832
-
833
- type ConstructSchema = typeof struct.__schema
834
-
835
- x.tCh<ConstructSchema, ExpectedSchema>()
836
- x.tCh<ExpectedSchema, ConstructSchema>()
837
-
838
- /* runtime schema check */
839
-
840
- expect(struct.__schema).toStrictEqual(schema)
841
- expect(construct.__schema).toStrictEqual(schema)
842
- expect(construct.__schema === schema).toBe(false)
843
-
844
- /* runtime schema parameter application immutability check */
845
-
846
- expect(prevStruct.__schema === struct.__schema).toBe(false)
847
- }
848
- })
849
-
850
- it('optional + nullable + minLength + maxLength', () => {
851
- const schema = {
852
- type: 'array',
853
- of: { type: 'boolean' },
854
- optional: true,
855
- nullable: true,
856
- minLength: 2,
857
- maxLength: 2,
858
- } as const satisfies x.Schema
859
-
860
- const prevStruct = x
861
- .array(x.boolean())
862
- .optional()
863
- .nullable()
864
- .minLength(schema.minLength)
865
-
866
- const struct = prevStruct.maxLength(schema.maxLength)
867
-
868
- type ExpectedKeys = StructSharedKeys | 'description'
869
-
870
- foldB: {
871
- const construct = x.makeStruct(schema)
872
-
873
- /* ensure that struct keys are reduced after application */
874
-
875
- type StructKeys = keyof typeof struct
876
-
877
- x.tCh<StructKeys, ExpectedKeys>()
878
- x.tCh<ExpectedKeys, StructKeys>()
879
-
880
- type ConstructKeys = keyof typeof construct
881
-
882
- x.tCh<ConstructKeys, ExpectedKeys>()
883
- x.tCh<ExpectedKeys, ConstructKeys>()
884
-
885
- /* ensure that construct/struct schema types are identical */
886
-
887
- type ExpectedSchema = typeof schema
888
- type StructSchema = typeof struct.__schema
889
-
890
- x.tCh<StructSchema, ExpectedSchema>()
891
- x.tCh<ExpectedSchema, StructSchema>()
892
-
893
- type ConstructSchema = typeof struct.__schema
894
-
895
- x.tCh<ConstructSchema, ExpectedSchema>()
896
- x.tCh<ExpectedSchema, ConstructSchema>()
897
-
898
- /* runtime schema check */
899
-
900
- expect(struct.__schema).toStrictEqual(schema)
901
- expect(construct.__schema).toStrictEqual(schema)
902
- expect(construct.__schema === schema).toBe(false)
903
-
904
- /* runtime schema parameter application immutability check */
905
-
906
- expect(prevStruct.__schema === struct.__schema).toBe(false)
907
- }
908
- })
909
-
910
- it('optional + nullable + minLength + maxLength + description', () => {
911
- const schema = {
912
- type: 'array',
913
- of: { type: 'boolean' },
914
- optional: true,
915
- nullable: true,
916
- minLength: 2,
917
- maxLength: 2,
918
- description: 'x',
919
- } as const satisfies x.Schema
920
-
921
- const prevStruct = x
922
- .array(x.boolean())
923
- .optional()
924
- .nullable()
925
- .minLength(schema.minLength)
926
- .maxLength(schema.maxLength)
927
-
928
- const struct = prevStruct.description(schema.description)
929
-
930
- type ExpectedKeys = StructSharedKeys
931
-
932
- foldB: {
933
- const construct = x.makeStruct(schema)
934
-
935
- /* ensure that struct keys are reduced after application */
936
-
937
- type StructKeys = keyof typeof struct
938
-
939
- x.tCh<StructKeys, ExpectedKeys>()
940
- x.tCh<ExpectedKeys, StructKeys>()
941
-
942
- type ConstructKeys = keyof typeof construct
943
-
944
- x.tCh<ConstructKeys, ExpectedKeys>()
945
- x.tCh<ExpectedKeys, ConstructKeys>()
946
-
947
- /* ensure that construct/struct schema types are identical */
948
-
949
- type ExpectedSchema = typeof schema
950
- type StructSchema = typeof struct.__schema
951
-
952
- x.tCh<StructSchema, ExpectedSchema>()
953
- x.tCh<ExpectedSchema, StructSchema>()
954
-
955
- type ConstructSchema = typeof struct.__schema
956
-
957
- x.tCh<ConstructSchema, ExpectedSchema>()
958
- x.tCh<ExpectedSchema, ConstructSchema>()
959
-
960
- /* runtime schema check */
961
-
962
- expect(struct.__schema).toStrictEqual(schema)
963
- expect(construct.__schema).toStrictEqual(schema)
964
- expect(construct.__schema === schema).toBe(false)
965
-
966
- /* runtime schema parameter application immutability check */
967
-
968
- expect(prevStruct.__schema === struct.__schema).toBe(false)
969
- }
970
- })
971
-
972
- it('description + maxLength + minLength + nullable + optional', () => {
973
- const schema = {
974
- type: 'array',
975
- of: { type: 'boolean' },
976
- optional: true,
977
- nullable: true,
978
- minLength: 2,
979
- maxLength: 2,
980
- description: 'x',
981
- } as const satisfies x.Schema
982
-
983
- const prevStruct = x
984
- .array(x.boolean())
985
- .description(schema.description)
986
- .maxLength(schema.maxLength)
987
- .minLength(schema.minLength)
988
- .nullable()
989
-
990
- const struct = prevStruct.optional()
991
-
992
- type ExpectedKeys = StructSharedKeys
993
-
994
- foldB: {
995
- const construct = x.makeStruct(schema)
996
-
997
- /* ensure that struct keys are reduced after application */
998
-
999
- type StructKeys = keyof typeof struct
1000
-
1001
- x.tCh<StructKeys, ExpectedKeys>()
1002
- x.tCh<ExpectedKeys, StructKeys>()
1003
-
1004
- type ConstructKeys = keyof typeof construct
1005
-
1006
- x.tCh<ConstructKeys, ExpectedKeys>()
1007
- x.tCh<ExpectedKeys, ConstructKeys>()
1008
-
1009
- /* ensure that construct/struct schema types are identical */
1010
-
1011
- type ExpectedSchema = typeof schema
1012
- type StructSchema = typeof struct.__schema
1013
-
1014
- x.tCh<StructSchema, ExpectedSchema>()
1015
- x.tCh<ExpectedSchema, StructSchema>()
1016
-
1017
- type ConstructSchema = typeof struct.__schema
1018
-
1019
- x.tCh<ConstructSchema, ExpectedSchema>()
1020
- x.tCh<ExpectedSchema, ConstructSchema>()
1021
-
1022
- /* runtime schema check */
1023
-
1024
- expect(struct.__schema).toStrictEqual(schema)
1025
- expect(construct.__schema).toStrictEqual(schema)
1026
- expect(construct.__schema === schema).toBe(false)
1027
-
1028
- /* runtime schema parameter application immutability check */
1029
-
1030
- expect(prevStruct.__schema === struct.__schema).toBe(false)
1031
- }
1032
- })
1033
- })
1034
-
1035
- describe('ERROR_CODE.invalidType (foldC, foldE)', () => {
1036
- it('iterate over fixture.DATA_TYPE', () => {
1037
- const schema = {
1038
- type: 'array',
1039
- of: { type: 'boolean' },
1040
- } as const satisfies x.Schema
1041
-
1042
- const struct = x.array(x.boolean())
1043
- const source = fixture.DATA_TYPE
1044
-
1045
- foldC: {
1046
- const construct = x.makeStruct(schema)
1047
-
1048
- for (const [kind, types] of source) {
1049
- if (kind === schema.type) {
1050
- continue
1051
- }
1052
-
1053
- for (const subject of types) {
1054
- const expectedError = [
1055
- {
1056
- code: x.ERROR_CODE.invalidType,
1057
- schema: schema,
1058
- subject: subject,
1059
- path: [],
1060
- },
1061
- ]
1062
-
1063
- const parsedSchema = x.parse(schema, subject)
1064
- const parsedConstruct = construct.parse(subject)
1065
- const parsedStruct = struct.parse(subject)
1066
-
1067
- expect(parsedSchema.error).toStrictEqual(expectedError)
1068
- expect(parsedConstruct.error).toStrictEqual(expectedError)
1069
- expect(parsedStruct.error).toStrictEqual(expectedError)
1070
-
1071
- const parsedStandard = struct['~standard'].validate(subject)
1072
-
1073
- if (parsedStandard instanceof Promise) {
1074
- throw Error('Not expected')
1075
- }
1076
-
1077
- expect(parsedStandard.issues).toStrictEqual([
1078
- { message: x.ERROR_CODE.invalidType, path: [] },
1079
- ])
1080
- }
1081
- }
1082
- }
1083
- })
1084
-
1085
- it('InvalidSubject error of nested schema should have correct path/schema/subject', () => {
1086
- const schema = {
1087
- type: 'array',
1088
- of: { type: 'array', of: { type: 'boolean' } },
1089
- } as const satisfies x.Schema
1090
-
1091
- const struct = x.array(x.array(x.boolean()))
1092
- const samples: Array<
1093
- [
1094
- subj: unknown[],
1095
- invalidSubj: unknown,
1096
- invalidSubjSchema: x.Schema,
1097
- errorPath: x.ErrorPath,
1098
- ]
1099
- > = [
1100
- [[[null, false, true]], null, schema.of.of, [0, 0]],
1101
- [[[], [null, false, true]], null, schema.of.of, [1, 0]],
1102
- [[[], [], [null, false, true]], null, schema.of.of, [2, 0]],
1103
- [[[true, 'str', true]], 'str', schema.of.of, [0, 1]],
1104
- [[[], [true, 'str', true]], 'str', schema.of.of, [1, 1]],
1105
- [[[], [], [true, 'str', true]], 'str', schema.of.of, [2, 1]],
1106
- [[[true, false, 69]], 69, schema.of.of, [0, 2]],
1107
- [[[], [true, false, 69]], 69, schema.of.of, [1, 2]],
1108
- [[[], [], [true, false, 69]], 69, schema.of.of, [2, 2]],
1109
- ]
1110
-
1111
- foldE: {
1112
- const construct = x.makeStruct(schema)
1113
-
1114
- for (const [subject, invalidSubj, invalidSubjSchema, path] of samples) {
1115
- const expectedError = [
1116
- {
1117
- path,
1118
- code: x.ERROR_CODE.invalidType,
1119
- schema: invalidSubjSchema,
1120
- subject: invalidSubj,
1121
- },
1122
- ]
1123
-
1124
- const parsedSchema = x.parse(schema, subject)
1125
- const parsedConstruct = construct.parse(subject)
1126
- const parsedStruct = struct.parse(subject)
1127
-
1128
- expect(parsedSchema.error).toStrictEqual(expectedError)
1129
- expect(parsedConstruct.error).toStrictEqual(expectedError)
1130
- expect(parsedStruct.error).toStrictEqual(expectedError)
1131
-
1132
- const parsedStandard = struct['~standard'].validate(subject)
1133
-
1134
- if (parsedStandard instanceof Promise) {
1135
- throw Error('Not expected')
1136
- }
1137
-
1138
- expect(parsedStandard.issues).toStrictEqual([
1139
- { path, message: x.ERROR_CODE.invalidType },
1140
- ])
1141
- }
1142
- }
1143
- })
1144
-
1145
- it('multiple errors', () => {
1146
- const schema = {
1147
- type: 'array',
1148
- of: { type: 'boolean' },
1149
- } as const satisfies x.Schema
1150
-
1151
- const struct = x.array(x.boolean())
1152
-
1153
- const construct = x.makeStruct(schema)
1154
-
1155
- const subject = [null, true, undefined]
1156
-
1157
- const expectedError: x.InvalidSubject[] = [
1158
- {
1159
- code: x.ERROR_CODE.invalidType,
1160
- path: [0],
1161
- schema: schema.of,
1162
- subject: null,
1163
- },
1164
- {
1165
- code: x.ERROR_CODE.invalidType,
1166
- path: [2],
1167
- schema: schema.of,
1168
- subject: undefined,
1169
- },
1170
- ]
1171
-
1172
- const parsedSchema = x.parse(schema, subject)
1173
- const parsedStruct = struct.parse(subject)
1174
- const parsedConstruct = construct.parse(subject)
1175
-
1176
- expect(parsedSchema.error).toStrictEqual(expectedError)
1177
- expect(parsedStruct.error).toStrictEqual(expectedError)
1178
- expect(parsedConstruct.error).toStrictEqual(expectedError)
1179
- })
1180
- })
1181
-
1182
- describe('ERROR_CODE.invalidRange (foldD)', () => {
1183
- it('minLength', () => {
1184
- const schema = {
1185
- type: 'array',
1186
- of: { type: 'boolean' },
1187
- minLength: 3,
1188
- } as const satisfies x.Schema
1189
-
1190
- const struct = x.array(x.boolean()).minLength(schema.minLength)
1191
- const subjects = [[], [false], [false, true]]
1192
-
1193
- foldD: {
1194
- const construct = x.makeStruct(schema)
1195
-
1196
- for (const subject of subjects) {
1197
- const expectedError = [
1198
- {
1199
- code: x.ERROR_CODE.invalidRange,
1200
- schema: schema,
1201
- subject: subject,
1202
- path: [],
1203
- },
1204
- ]
1205
-
1206
- const parsedSchema = x.parse(schema, subject)
1207
- const parsedConstruct = construct.parse(subject)
1208
- const parsedStruct = struct.parse(subject)
1209
-
1210
- expect(parsedSchema.error).toStrictEqual(expectedError)
1211
- expect(parsedConstruct.error).toStrictEqual(expectedError)
1212
- expect(parsedStruct.error).toStrictEqual(expectedError)
1213
-
1214
- const parsedStandard = struct['~standard'].validate(subject)
1215
-
1216
- if (parsedStandard instanceof Promise) {
1217
- throw Error('Not expected')
1218
- }
1219
-
1220
- expect(parsedStandard.issues).toStrictEqual([
1221
- { message: x.ERROR_CODE.invalidRange, path: [] },
1222
- ])
1223
- }
1224
- }
1225
- })
1226
-
1227
- it('maxLength', () => {
1228
- const schema = {
1229
- type: 'array',
1230
- of: { type: 'boolean' },
1231
- maxLength: 0,
1232
- } as const satisfies x.Schema
1233
-
1234
- const struct = x.array(x.boolean()).maxLength(schema.maxLength)
1235
- const subjects = [[false], [false, true], [false, true, false]]
1236
-
1237
- foldD: {
1238
- const construct = x.makeStruct(schema)
1239
-
1240
- for (const subject of subjects) {
1241
- const expectedError = [
1242
- {
1243
- code: x.ERROR_CODE.invalidRange,
1244
- schema: schema,
1245
- subject: subject,
1246
- path: [],
1247
- },
1248
- ]
1249
-
1250
- const parsedSchema = x.parse(schema, subject)
1251
- const parsedConstruct = construct.parse(subject)
1252
- const parsedStruct = struct.parse(subject)
1253
-
1254
- expect(parsedSchema.error).toStrictEqual(expectedError)
1255
- expect(parsedConstruct.error).toStrictEqual(expectedError)
1256
- expect(parsedStruct.error).toStrictEqual(expectedError)
1257
-
1258
- const parsedStandard = struct['~standard'].validate(subject)
1259
-
1260
- if (parsedStandard instanceof Promise) {
1261
- throw Error('Not expected')
1262
- }
1263
-
1264
- expect(parsedStandard.issues).toStrictEqual([
1265
- { message: x.ERROR_CODE.invalidRange, path: [] },
1266
- ])
1267
- }
1268
- }
1269
- })
1270
-
1271
- it('minLength + maxLength', () => {
1272
- const schema = {
1273
- type: 'array',
1274
- of: { type: 'boolean' },
1275
- maxLength: 2,
1276
- minLength: 2,
1277
- } as const satisfies x.Schema
1278
-
1279
- const struct = x
1280
- .array(x.boolean())
1281
- .minLength(schema.minLength)
1282
- .maxLength(schema.maxLength)
1283
-
1284
- const subjects = [[], [false], [false, true, false]]
1285
-
1286
- foldD: {
1287
- const construct = x.makeStruct(schema)
1288
-
1289
- for (const subject of subjects) {
1290
- const expectedError = [
1291
- {
1292
- code: x.ERROR_CODE.invalidRange,
1293
- schema: schema,
1294
- subject: subject,
1295
- path: [],
1296
- },
1297
- ]
1298
-
1299
- const parsedSchema = x.parse(schema, subject)
1300
- const parsedConstruct = construct.parse(subject)
1301
- const parsedStruct = struct.parse(subject)
1302
-
1303
- expect(parsedSchema.error).toStrictEqual(expectedError)
1304
- expect(parsedConstruct.error).toStrictEqual(expectedError)
1305
- expect(parsedStruct.error).toStrictEqual(expectedError)
1306
-
1307
- const parsedStandard = struct['~standard'].validate(subject)
1308
-
1309
- if (parsedStandard instanceof Promise) {
1310
- throw Error('Not expected')
1311
- }
1312
-
1313
- expect(parsedStandard.issues).toStrictEqual([
1314
- { message: x.ERROR_CODE.invalidRange, path: [] },
1315
- ])
1316
- }
1317
- }
1318
- })
1319
- })
1320
-
1321
- describe('Compound schema specifics (foldA)', () => {
1322
- it('nested primitive schema: optional + nullable + brand', () => {
1323
- const schema = {
1324
- type: 'array',
1325
- of: {
1326
- type: 'boolean',
1327
- optional: true,
1328
- nullable: true,
1329
- brand: ['x', 'y'],
1330
- },
1331
- } as const satisfies x.Schema
1332
-
1333
- const struct = x.array(
1334
- x
1335
- .boolean()
1336
- .optional()
1337
- .nullable()
1338
- .brand(...schema.of.brand)
1339
- )
1340
-
1341
- type Branded = boolean & { __x: 'y' }
1342
- type ExpectedSubj = Array<Branded | undefined | null>
1343
-
1344
- const subjects = [
1345
- [],
1346
- [undefined],
1347
- [null],
1348
- [true as Branded],
1349
- [false as Branded, undefined, null],
1350
- ] as const satisfies Array<ExpectedSubj>
1351
-
1352
- foldA: {
1353
- const construct = x.makeStruct(schema)
1354
-
1355
- /* ensure that schema/construct/struct/~standard subject types are identical */
1356
-
1357
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
1358
-
1359
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
1360
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
1361
-
1362
- type SchemaSubj = x.Infer<typeof schema>
1363
-
1364
- x.tCh<SchemaSubj, ExpectedSubj>()
1365
- x.tCh<ExpectedSubj, SchemaSubj>()
1366
-
1367
- type StructSubj = x.Infer<typeof struct.__schema>
1368
-
1369
- x.tCh<StructSubj, ExpectedSubj>()
1370
- x.tCh<ExpectedSubj, StructSubj>()
1371
-
1372
- type StandardSubj = NonNullable<
1373
- (typeof struct)['~standard']['types']
1374
- >['output']
1375
-
1376
- x.tCh<StandardSubj, ExpectedSubj>()
1377
- x.tCh<ExpectedSubj, StandardSubj>()
1378
-
1379
- /* parsed either type check */
1380
-
1381
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
1382
-
1383
- const parsed = x.parse(schema, undefined)
1384
-
1385
- type SchemaParsed = typeof parsed
1386
-
1387
- x.tCh<SchemaParsed, ExpectedParsed>()
1388
- x.tCh<ExpectedParsed, SchemaParsed>()
1389
-
1390
- type ConstructParsed = ReturnType<typeof construct.parse>
1391
-
1392
- x.tCh<ConstructParsed, ExpectedParsed>()
1393
- x.tCh<ExpectedParsed, ConstructParsed>()
1394
-
1395
- type StructParsed = ReturnType<typeof struct.parse>
1396
-
1397
- x.tCh<StructParsed, ExpectedParsed>()
1398
- x.tCh<ExpectedParsed, StructParsed>()
1399
-
1400
- type StandardParsed = Extract<
1401
- ReturnType<(typeof struct)['~standard']['validate']>,
1402
- { value: unknown }
1403
- >['value']
1404
-
1405
- x.tCh<StandardParsed, ExpectedSubj>()
1406
- x.tCh<ExpectedSubj, StandardParsed>()
1407
-
1408
- /* runtime schema check */
1409
-
1410
- expect(struct.__schema).toStrictEqual(schema)
1411
- expect(construct.__schema).toStrictEqual(schema)
1412
- expect(construct.__schema === schema).toBe(false)
1413
-
1414
- /* parse result check */
1415
-
1416
- for (const subj of subjects) {
1417
- const schemaParsed = x.parse(schema, subj)
1418
-
1419
- expect(schemaParsed.error).toBe(undefined)
1420
- expect(schemaParsed.data).toStrictEqual(subj)
1421
-
1422
- const constructParsed = construct.parse(subj)
1423
-
1424
- expect(constructParsed.error).toBe(undefined)
1425
- expect(constructParsed.data).toStrictEqual(subj)
1426
-
1427
- const structParsed = struct.parse(subj)
1428
-
1429
- expect(structParsed.error).toBe(undefined)
1430
- expect(structParsed.data).toStrictEqual(subj)
1431
-
1432
- const standardParsed = struct['~standard'].validate(subj)
1433
-
1434
- if (standardParsed instanceof Promise) {
1435
- throw Error('Not expected')
1436
- }
1437
-
1438
- if (standardParsed.issues !== undefined) {
1439
- throw Error('not expected')
1440
- }
1441
-
1442
- expect(standardParsed.value).toStrictEqual(subj)
1443
- }
1444
- }
1445
- })
1446
-
1447
- it('nested compound schema: optional + nullable', () => {
1448
- const schema = {
1449
- type: 'array',
1450
- of: {
1451
- type: 'array',
1452
- of: { type: 'boolean' },
1453
- optional: true,
1454
- nullable: true,
1455
- },
1456
- } as const satisfies x.Schema
1457
-
1458
- const struct = x.array(x.array(x.boolean()).optional().nullable())
1459
-
1460
- type ExpectedSubj = Array<Array<boolean> | undefined | null>
1461
-
1462
- const subjects = [
1463
- [],
1464
- [undefined],
1465
- [null],
1466
- [[]],
1467
- [[true]],
1468
- [[false], undefined, null],
1469
- ] as const satisfies Array<ExpectedSubj>
1470
-
1471
- foldA: {
1472
- const construct = x.makeStruct(schema)
1473
-
1474
- /* ensure that schema/construct/struct/~standard subject types are identical */
1475
-
1476
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
1477
-
1478
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
1479
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
1480
-
1481
- type SchemaSubj = x.Infer<typeof schema>
1482
-
1483
- x.tCh<SchemaSubj, ExpectedSubj>()
1484
- x.tCh<ExpectedSubj, SchemaSubj>()
1485
-
1486
- type StructSubj = x.Infer<typeof struct.__schema>
1487
-
1488
- x.tCh<StructSubj, ExpectedSubj>()
1489
- x.tCh<ExpectedSubj, StructSubj>()
1490
-
1491
- type StandardSubj = NonNullable<
1492
- (typeof struct)['~standard']['types']
1493
- >['output']
1494
-
1495
- x.tCh<StandardSubj, ExpectedSubj>()
1496
- x.tCh<ExpectedSubj, StandardSubj>()
1497
-
1498
- /* parsed either type check */
1499
-
1500
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
1501
-
1502
- const parsed = x.parse(schema, undefined)
1503
-
1504
- type SchemaParsed = typeof parsed
1505
-
1506
- x.tCh<SchemaParsed, ExpectedParsed>()
1507
- x.tCh<ExpectedParsed, SchemaParsed>()
1508
-
1509
- type ConstructParsed = ReturnType<typeof construct.parse>
1510
-
1511
- x.tCh<ConstructParsed, ExpectedParsed>()
1512
- x.tCh<ExpectedParsed, ConstructParsed>()
1513
-
1514
- type StructParsed = ReturnType<typeof struct.parse>
1515
-
1516
- x.tCh<StructParsed, ExpectedParsed>()
1517
- x.tCh<ExpectedParsed, StructParsed>()
1518
-
1519
- type StandardParsed = Extract<
1520
- ReturnType<(typeof struct)['~standard']['validate']>,
1521
- { value: unknown }
1522
- >['value']
1523
-
1524
- x.tCh<StandardParsed, ExpectedSubj>()
1525
- x.tCh<ExpectedSubj, StandardParsed>()
1526
-
1527
- /* runtime schema check */
1528
-
1529
- expect(struct.__schema).toStrictEqual(schema)
1530
- expect(construct.__schema).toStrictEqual(schema)
1531
- expect(construct.__schema === schema).toBe(false)
1532
-
1533
- /* parse result check */
1534
-
1535
- for (const subj of subjects) {
1536
- const schemaParsed = x.parse(schema, subj)
1537
-
1538
- expect(schemaParsed.error).toBe(undefined)
1539
- expect(schemaParsed.data).toStrictEqual(subj)
1540
-
1541
- const constructParsed = construct.parse(subj)
1542
-
1543
- expect(constructParsed.error).toBe(undefined)
1544
- expect(constructParsed.data).toStrictEqual(subj)
1545
-
1546
- const structParsed = struct.parse(subj)
1547
-
1548
- expect(structParsed.error).toBe(undefined)
1549
- expect(structParsed.data).toStrictEqual(subj)
1550
-
1551
- const standardParsed = struct['~standard'].validate(subj)
1552
-
1553
- if (standardParsed instanceof Promise) {
1554
- throw Error('Not expected')
1555
- }
1556
-
1557
- if (standardParsed.issues !== undefined) {
1558
- throw Error('not expected')
1559
- }
1560
-
1561
- expect(standardParsed.value).toStrictEqual(subj)
1562
- }
1563
- }
1564
- })
1565
-
1566
- it('nested by itself (schema depth: 4)', () => {
1567
- const schema = {
1568
- type: 'array',
1569
- of: {
1570
- type: 'array',
1571
- of: { type: 'array', of: { type: 'boolean' } },
1572
- },
1573
- } as const satisfies x.Schema
1574
-
1575
- const struct = x.array(x.array(x.array(x.boolean())))
1576
-
1577
- type ExpectedSubj = Array<Array<Array<boolean>>>
1578
-
1579
- const subjects = [
1580
- [[]],
1581
- [[], []],
1582
- [[[]]],
1583
- [
1584
- [[], []],
1585
- [[], []],
1586
- ],
1587
- [[[true]], [[true, false]]],
1588
- ] as const satisfies Array<ExpectedSubj>
1589
-
1590
- foldA: {
1591
- const construct = x.makeStruct(schema)
1592
-
1593
- /* ensure that schema/construct/struct/~standard subject types are identical */
1594
-
1595
- type ConstructSchemaSubj = x.Infer<typeof construct.__schema>
1596
-
1597
- x.tCh<ConstructSchemaSubj, ExpectedSubj>()
1598
- x.tCh<ExpectedSubj, ConstructSchemaSubj>()
1599
-
1600
- type SchemaSubj = x.Infer<typeof schema>
1601
-
1602
- x.tCh<SchemaSubj, ExpectedSubj>()
1603
- x.tCh<ExpectedSubj, SchemaSubj>()
1604
-
1605
- type StructSubj = x.Infer<typeof struct.__schema>
1606
-
1607
- x.tCh<StructSubj, ExpectedSubj>()
1608
- x.tCh<ExpectedSubj, StructSubj>()
1609
-
1610
- type StandardSubj = NonNullable<
1611
- (typeof struct)['~standard']['types']
1612
- >['output']
1613
-
1614
- x.tCh<StandardSubj, ExpectedSubj>()
1615
- x.tCh<ExpectedSubj, StandardSubj>()
1616
-
1617
- /* parsed either type check */
1618
-
1619
- type ExpectedParsed = x.ParseResult<ExpectedSubj>
1620
-
1621
- const parsed = x.parse(schema, undefined)
1622
-
1623
- type SchemaParsed = typeof parsed
1624
-
1625
- x.tCh<SchemaParsed, ExpectedParsed>()
1626
- x.tCh<ExpectedParsed, SchemaParsed>()
1627
-
1628
- type ConstructParsed = ReturnType<typeof construct.parse>
1629
-
1630
- x.tCh<ConstructParsed, ExpectedParsed>()
1631
- x.tCh<ExpectedParsed, ConstructParsed>()
1632
-
1633
- type StructParsed = ReturnType<typeof struct.parse>
1634
-
1635
- x.tCh<StructParsed, ExpectedParsed>()
1636
- x.tCh<ExpectedParsed, StructParsed>()
1637
-
1638
- type StandardParsed = Extract<
1639
- ReturnType<(typeof struct)['~standard']['validate']>,
1640
- { value: unknown }
1641
- >['value']
1642
-
1643
- x.tCh<StandardParsed, ExpectedSubj>()
1644
- x.tCh<ExpectedSubj, StandardParsed>()
1645
-
1646
- /* runtime schema check */
1647
-
1648
- expect(struct.__schema).toStrictEqual(schema)
1649
- expect(construct.__schema).toStrictEqual(schema)
1650
- expect(construct.__schema === schema).toBe(false)
1651
-
1652
- /* parse result check */
1653
-
1654
- for (const subj of subjects) {
1655
- const schemaParsed = x.parse(schema, subj)
1656
-
1657
- expect(schemaParsed.error).toBe(undefined)
1658
- expect(schemaParsed.data).toStrictEqual(subj)
1659
-
1660
- const constructParsed = construct.parse(subj)
1661
-
1662
- expect(constructParsed.error).toBe(undefined)
1663
- expect(constructParsed.data).toStrictEqual(subj)
1664
-
1665
- const structParsed = struct.parse(subj)
1666
-
1667
- expect(structParsed.error).toBe(undefined)
1668
- expect(structParsed.data).toStrictEqual(subj)
1669
-
1670
- const standardParsed = struct['~standard'].validate(subj)
1671
-
1672
- if (standardParsed instanceof Promise) {
1673
- throw Error('Not expected')
1674
- }
1675
-
1676
- if (standardParsed.issues !== undefined) {
1677
- throw Error('not expected')
1678
- }
1679
-
1680
- expect(standardParsed.value).toStrictEqual(subj)
1681
- }
1682
- }
1683
- })
1684
- })