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