@scalar/validation 0.3.0 → 0.3.1
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.
- package/CHANGELOG.md +6 -0
- package/package.json +6 -2
- package/.turbo/turbo-build.log +0 -4
- package/src/coerce.test.ts +0 -1158
- package/src/coerce.ts +0 -224
- package/src/helpers/is-object.test.ts +0 -168
- package/src/helpers/is-object.ts +0 -31
- package/src/index.ts +0 -37
- package/src/schema.ts +0 -250
- package/src/typegen.test.ts +0 -214
- package/src/typegen.ts +0 -268
- package/src/types.ts +0 -110
- package/src/validate.test.ts +0 -833
- package/src/validate.ts +0 -106
- package/tsconfig.build.json +0 -11
- package/tsconfig.json +0 -10
- package/vite.config.ts +0 -13
package/src/validate.test.ts
DELETED
|
@@ -1,833 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
any,
|
|
5
|
-
array,
|
|
6
|
-
boolean,
|
|
7
|
-
evaluate,
|
|
8
|
-
intersection,
|
|
9
|
-
lazy,
|
|
10
|
-
literal,
|
|
11
|
-
notDefined,
|
|
12
|
-
nullable,
|
|
13
|
-
number,
|
|
14
|
-
object,
|
|
15
|
-
optional,
|
|
16
|
-
record,
|
|
17
|
-
string,
|
|
18
|
-
union,
|
|
19
|
-
} from '@/schema'
|
|
20
|
-
import { validate } from '@/validate'
|
|
21
|
-
|
|
22
|
-
describe('any', () => {
|
|
23
|
-
const T = any()
|
|
24
|
-
it('Should pass string', () => {
|
|
25
|
-
const value = 'hello'
|
|
26
|
-
const result = validate(T, value)
|
|
27
|
-
expect(result).toBe(true)
|
|
28
|
-
})
|
|
29
|
-
it('Should pass number', () => {
|
|
30
|
-
const value = 1
|
|
31
|
-
const result = validate(T, value)
|
|
32
|
-
expect(result).toBe(true)
|
|
33
|
-
})
|
|
34
|
-
it('Should pass boolean', () => {
|
|
35
|
-
const value = true
|
|
36
|
-
const result = validate(T, value)
|
|
37
|
-
expect(result).toBe(true)
|
|
38
|
-
})
|
|
39
|
-
it('Should pass null', () => {
|
|
40
|
-
const value = null
|
|
41
|
-
const result = validate(T, value)
|
|
42
|
-
expect(result).toBe(true)
|
|
43
|
-
})
|
|
44
|
-
it('Should pass undefined', () => {
|
|
45
|
-
const value = undefined
|
|
46
|
-
const result = validate(T, value)
|
|
47
|
-
expect(result).toBe(true)
|
|
48
|
-
})
|
|
49
|
-
it('Should pass object', () => {
|
|
50
|
-
const value = { a: 1 }
|
|
51
|
-
const result = validate(T, value)
|
|
52
|
-
expect(result).toBe(true)
|
|
53
|
-
})
|
|
54
|
-
it('Should pass array', () => {
|
|
55
|
-
const value = [1, 2]
|
|
56
|
-
const result = validate(T, value)
|
|
57
|
-
expect(result).toBe(true)
|
|
58
|
-
})
|
|
59
|
-
it('Should pass Date', () => {
|
|
60
|
-
const value = new Date()
|
|
61
|
-
const result = validate(T, value)
|
|
62
|
-
expect(result).toBe(true)
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
describe('array', () => {
|
|
67
|
-
it('Should pass number array', () => {
|
|
68
|
-
const T = array(number())
|
|
69
|
-
const value = [1, 2, 3]
|
|
70
|
-
const result = validate(T, value)
|
|
71
|
-
expect(result).toBe(true)
|
|
72
|
-
})
|
|
73
|
-
it('Should fail number array', () => {
|
|
74
|
-
const T = array(number())
|
|
75
|
-
const value = ['a', 'b', 'c']
|
|
76
|
-
const result = validate(T, value)
|
|
77
|
-
expect(result).toBe(false)
|
|
78
|
-
})
|
|
79
|
-
it('Should pass object array', () => {
|
|
80
|
-
const T = array(object({ x: number() }))
|
|
81
|
-
const value = [{ x: 1 }, { x: 1 }, { x: 1 }]
|
|
82
|
-
const result = validate(T, value)
|
|
83
|
-
expect(result).toBe(true)
|
|
84
|
-
})
|
|
85
|
-
it('Should fail object array', () => {
|
|
86
|
-
const T = array(object({ x: number() }))
|
|
87
|
-
const value = [{ x: 1 }, { x: 1 }, 1]
|
|
88
|
-
const result = validate(T, value)
|
|
89
|
-
expect(result).toBe(false)
|
|
90
|
-
})
|
|
91
|
-
it('Should fail Date', () => {
|
|
92
|
-
const value = new Date()
|
|
93
|
-
const result = validate(array(any()), value)
|
|
94
|
-
expect(result).toBe(false)
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
describe('boolean', () => {
|
|
99
|
-
const T = boolean()
|
|
100
|
-
it('Should fail string', () => {
|
|
101
|
-
const value = 'hello'
|
|
102
|
-
const result = validate(T, value)
|
|
103
|
-
expect(result).toBe(false)
|
|
104
|
-
})
|
|
105
|
-
it('Should fail number', () => {
|
|
106
|
-
const value = 1
|
|
107
|
-
const result = validate(T, value)
|
|
108
|
-
expect(result).toBe(false)
|
|
109
|
-
})
|
|
110
|
-
it('Should pass boolean', () => {
|
|
111
|
-
const value = true
|
|
112
|
-
const result = validate(T, value)
|
|
113
|
-
expect(result).toBe(true)
|
|
114
|
-
})
|
|
115
|
-
it('Should fail null', () => {
|
|
116
|
-
const value = null
|
|
117
|
-
const result = validate(T, value)
|
|
118
|
-
expect(result).toBe(false)
|
|
119
|
-
})
|
|
120
|
-
it('Should fail undefined', () => {
|
|
121
|
-
const value = undefined
|
|
122
|
-
const result = validate(T, value)
|
|
123
|
-
expect(result).toBe(false)
|
|
124
|
-
})
|
|
125
|
-
it('Should fail object', () => {
|
|
126
|
-
const value = { a: 1 }
|
|
127
|
-
const result = validate(T, value)
|
|
128
|
-
expect(result).toBe(false)
|
|
129
|
-
})
|
|
130
|
-
it('Should fail array', () => {
|
|
131
|
-
const value = [1, 2]
|
|
132
|
-
const result = validate(T, value)
|
|
133
|
-
expect(result).toBe(false)
|
|
134
|
-
})
|
|
135
|
-
it('Should fail Date', () => {
|
|
136
|
-
const value = new Date()
|
|
137
|
-
const result = validate(T, value)
|
|
138
|
-
expect(result).toBe(false)
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
describe('literal', () => {
|
|
143
|
-
const T = literal('hello')
|
|
144
|
-
it('Should pass literal', () => {
|
|
145
|
-
const value = 'hello'
|
|
146
|
-
const result = validate(T, value)
|
|
147
|
-
expect(result).toBe(true)
|
|
148
|
-
})
|
|
149
|
-
it('Should fail literal', () => {
|
|
150
|
-
const value = 1
|
|
151
|
-
const result = validate(T, value)
|
|
152
|
-
expect(result).toBe(false)
|
|
153
|
-
})
|
|
154
|
-
it('Should fail literal with undefined', () => {
|
|
155
|
-
const value = undefined
|
|
156
|
-
const result = validate(T, value)
|
|
157
|
-
expect(result).toBe(false)
|
|
158
|
-
})
|
|
159
|
-
it('Should fail literal with null', () => {
|
|
160
|
-
const value = null
|
|
161
|
-
const result = validate(T, value)
|
|
162
|
-
expect(result).toBe(false)
|
|
163
|
-
})
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
describe('null', () => {
|
|
167
|
-
const T = nullable()
|
|
168
|
-
it('Should fail string', () => {
|
|
169
|
-
const value = 'hello'
|
|
170
|
-
const result = validate(T, value)
|
|
171
|
-
expect(result).toBe(false)
|
|
172
|
-
})
|
|
173
|
-
it('Should fail number', () => {
|
|
174
|
-
const value = 1
|
|
175
|
-
const result = validate(T, value)
|
|
176
|
-
expect(result).toBe(false)
|
|
177
|
-
})
|
|
178
|
-
it('Should fail boolean', () => {
|
|
179
|
-
const value = true
|
|
180
|
-
const result = validate(T, value)
|
|
181
|
-
expect(result).toBe(false)
|
|
182
|
-
})
|
|
183
|
-
it('Should pass null', () => {
|
|
184
|
-
const value = null
|
|
185
|
-
const result = validate(T, value)
|
|
186
|
-
expect(result).toBe(true)
|
|
187
|
-
})
|
|
188
|
-
it('Should fail undefined', () => {
|
|
189
|
-
const value = undefined
|
|
190
|
-
const result = validate(T, value)
|
|
191
|
-
expect(result).toBe(false)
|
|
192
|
-
})
|
|
193
|
-
it('Should fail object', () => {
|
|
194
|
-
const value = { a: 1 }
|
|
195
|
-
const result = validate(T, value)
|
|
196
|
-
expect(result).toBe(false)
|
|
197
|
-
})
|
|
198
|
-
it('Should fail array', () => {
|
|
199
|
-
const value = [1, 2]
|
|
200
|
-
const result = validate(T, value)
|
|
201
|
-
expect(result).toBe(false)
|
|
202
|
-
})
|
|
203
|
-
it('Should fail Date', () => {
|
|
204
|
-
const value = new Date()
|
|
205
|
-
const result = validate(T, value)
|
|
206
|
-
expect(result).toBe(false)
|
|
207
|
-
})
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
describe('number', () => {
|
|
211
|
-
const T = number()
|
|
212
|
-
it('Should not validate NaN', () => {
|
|
213
|
-
const result = validate(T, Number.NaN)
|
|
214
|
-
expect(result).toBe(false)
|
|
215
|
-
})
|
|
216
|
-
it('Should not validate +Infinity', () => {
|
|
217
|
-
const result = validate(T, Number.POSITIVE_INFINITY)
|
|
218
|
-
expect(result).toBe(false)
|
|
219
|
-
})
|
|
220
|
-
it('Should not validate -Infinity', () => {
|
|
221
|
-
const result = validate(T, Number.NEGATIVE_INFINITY)
|
|
222
|
-
expect(result).toBe(false)
|
|
223
|
-
})
|
|
224
|
-
it('Should fail string', () => {
|
|
225
|
-
const value = 'hello'
|
|
226
|
-
const result = validate(T, value)
|
|
227
|
-
expect(result).toBe(false)
|
|
228
|
-
})
|
|
229
|
-
it('Should pass number', () => {
|
|
230
|
-
const value = 1
|
|
231
|
-
const result = validate(T, value)
|
|
232
|
-
expect(result).toBe(true)
|
|
233
|
-
})
|
|
234
|
-
it('Should fail boolean', () => {
|
|
235
|
-
const value = true
|
|
236
|
-
const result = validate(T, value)
|
|
237
|
-
expect(result).toBe(false)
|
|
238
|
-
})
|
|
239
|
-
it('Should fail null', () => {
|
|
240
|
-
const value = null
|
|
241
|
-
const result = validate(T, value)
|
|
242
|
-
expect(result).toBe(false)
|
|
243
|
-
})
|
|
244
|
-
it('Should fail undefined', () => {
|
|
245
|
-
const value = undefined
|
|
246
|
-
const result = validate(T, value)
|
|
247
|
-
expect(result).toBe(false)
|
|
248
|
-
})
|
|
249
|
-
it('Should fail object', () => {
|
|
250
|
-
const value = { a: 1 }
|
|
251
|
-
const result = validate(T, value)
|
|
252
|
-
expect(result).toBe(false)
|
|
253
|
-
})
|
|
254
|
-
it('Should fail array', () => {
|
|
255
|
-
const value = [1, 2]
|
|
256
|
-
const result = validate(T, value)
|
|
257
|
-
expect(result).toBe(false)
|
|
258
|
-
})
|
|
259
|
-
it('Should fail Date', () => {
|
|
260
|
-
const value = new Date()
|
|
261
|
-
const result = validate(T, value)
|
|
262
|
-
expect(result).toBe(false)
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
it('Should fail NaN', () => {
|
|
266
|
-
const result = validate(T, Number.NaN)
|
|
267
|
-
expect(result).toBe(false)
|
|
268
|
-
})
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
describe('object', () => {
|
|
272
|
-
const T = object({
|
|
273
|
-
x: number(),
|
|
274
|
-
y: number(),
|
|
275
|
-
z: number(),
|
|
276
|
-
a: string(),
|
|
277
|
-
b: string(),
|
|
278
|
-
c: string(),
|
|
279
|
-
})
|
|
280
|
-
it('Should pass object', () => {
|
|
281
|
-
const value = {
|
|
282
|
-
x: 1,
|
|
283
|
-
y: 1,
|
|
284
|
-
z: 1,
|
|
285
|
-
a: '1',
|
|
286
|
-
b: '1',
|
|
287
|
-
c: '1',
|
|
288
|
-
}
|
|
289
|
-
const result = validate(T, value)
|
|
290
|
-
expect(result).toBe(true)
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
it('Should fail object with invalid property', () => {
|
|
294
|
-
const value = {
|
|
295
|
-
x: true,
|
|
296
|
-
y: 1,
|
|
297
|
-
z: 1,
|
|
298
|
-
a: '1',
|
|
299
|
-
b: '1',
|
|
300
|
-
c: '1',
|
|
301
|
-
}
|
|
302
|
-
const result = validate(T, value)
|
|
303
|
-
expect(result).toBe(false)
|
|
304
|
-
})
|
|
305
|
-
it('Should fail object with missing property', () => {
|
|
306
|
-
const value = {
|
|
307
|
-
y: 1,
|
|
308
|
-
z: 1,
|
|
309
|
-
a: '1',
|
|
310
|
-
b: '1',
|
|
311
|
-
c: '1',
|
|
312
|
-
}
|
|
313
|
-
const result = validate(T, value)
|
|
314
|
-
expect(result).toBe(false)
|
|
315
|
-
})
|
|
316
|
-
it('Should pass object with optional properties', () => {
|
|
317
|
-
const T = object({
|
|
318
|
-
x: optional(number()),
|
|
319
|
-
y: optional(number()),
|
|
320
|
-
z: optional(number()),
|
|
321
|
-
a: string(),
|
|
322
|
-
b: string(),
|
|
323
|
-
c: string(),
|
|
324
|
-
})
|
|
325
|
-
const value = {
|
|
326
|
-
a: '1',
|
|
327
|
-
b: '1',
|
|
328
|
-
c: '1',
|
|
329
|
-
}
|
|
330
|
-
const result = validate(T, value)
|
|
331
|
-
expect(result).toBe(true)
|
|
332
|
-
})
|
|
333
|
-
it('Should fail object with null', () => {
|
|
334
|
-
const value = null
|
|
335
|
-
const result = validate(T, value)
|
|
336
|
-
expect(result).toBe(false)
|
|
337
|
-
})
|
|
338
|
-
it('Should fail object with undefined', () => {
|
|
339
|
-
const value = undefined
|
|
340
|
-
const result = validate(T, value)
|
|
341
|
-
expect(result).toBe(false)
|
|
342
|
-
})
|
|
343
|
-
|
|
344
|
-
it('Should check for property key if property type is undefined', () => {
|
|
345
|
-
const T = object({ x: notDefined() })
|
|
346
|
-
expect(validate(T, { x: undefined })).toBe(true)
|
|
347
|
-
expect(validate(T, {})).toBe(true)
|
|
348
|
-
})
|
|
349
|
-
it('Should check for property key if property type extends undefined', () => {
|
|
350
|
-
const T = object({ x: union([number(), notDefined()]) })
|
|
351
|
-
expect(validate(T, { x: 1 })).toBe(true)
|
|
352
|
-
expect(validate(T, { x: undefined })).toBe(true)
|
|
353
|
-
expect(validate(T, {})).toBe(true)
|
|
354
|
-
})
|
|
355
|
-
it('Should not check for property key if property type is undefined and optional', () => {
|
|
356
|
-
const T = object({ x: optional(notDefined()) })
|
|
357
|
-
expect(validate(T, { x: undefined })).toBe(true)
|
|
358
|
-
expect(validate(T, {})).toBe(true)
|
|
359
|
-
})
|
|
360
|
-
it('Should not check for property key if property type extends undefined and optional', () => {
|
|
361
|
-
const T = object({ x: optional(union([number(), notDefined()])) })
|
|
362
|
-
expect(validate(T, { x: 1 })).toBe(true)
|
|
363
|
-
expect(validate(T, { x: undefined })).toBe(true)
|
|
364
|
-
expect(validate(T, {})).toBe(true)
|
|
365
|
-
})
|
|
366
|
-
it('Should check undefined for optional property of number', () => {
|
|
367
|
-
const T = object({ x: optional(number()) })
|
|
368
|
-
expect(validate(T, { x: 1 })).toBe(true)
|
|
369
|
-
expect(validate(T, { x: undefined })).toBe(true) // allowed by default
|
|
370
|
-
expect(validate(T, {})).toBe(true)
|
|
371
|
-
})
|
|
372
|
-
it('Should check undefined for optional property of undefined', () => {
|
|
373
|
-
const T = object({ x: optional(notDefined()) })
|
|
374
|
-
expect(validate(T, { x: 1 })).toBe(false)
|
|
375
|
-
expect(validate(T, {})).toBe(true)
|
|
376
|
-
expect(validate(T, { x: undefined })).toBe(true)
|
|
377
|
-
})
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
describe('record', () => {
|
|
381
|
-
it('Should pass record', () => {
|
|
382
|
-
const T = record(
|
|
383
|
-
string(),
|
|
384
|
-
object({
|
|
385
|
-
x: number(),
|
|
386
|
-
y: number(),
|
|
387
|
-
z: number(),
|
|
388
|
-
}),
|
|
389
|
-
)
|
|
390
|
-
const value = {
|
|
391
|
-
position: {
|
|
392
|
-
x: 1,
|
|
393
|
-
y: 2,
|
|
394
|
-
z: 3,
|
|
395
|
-
},
|
|
396
|
-
}
|
|
397
|
-
const result = validate(T, value)
|
|
398
|
-
expect(result).toBe(true)
|
|
399
|
-
})
|
|
400
|
-
it('Should fail record with Date', () => {
|
|
401
|
-
const T = record(string(), string())
|
|
402
|
-
const result = validate(T, new Date())
|
|
403
|
-
expect(result).toBe(false)
|
|
404
|
-
})
|
|
405
|
-
it('Should fail record with Uint8Array', () => {
|
|
406
|
-
const T = record(string(), string())
|
|
407
|
-
const result = validate(T, new Uint8Array())
|
|
408
|
-
expect(result).toBe(false)
|
|
409
|
-
})
|
|
410
|
-
it('Should fail record with missing property', () => {
|
|
411
|
-
const T = record(
|
|
412
|
-
string(),
|
|
413
|
-
object({
|
|
414
|
-
x: number(),
|
|
415
|
-
y: number(),
|
|
416
|
-
z: number(),
|
|
417
|
-
}),
|
|
418
|
-
)
|
|
419
|
-
const value = {
|
|
420
|
-
position: {
|
|
421
|
-
x: 1,
|
|
422
|
-
y: 2,
|
|
423
|
-
},
|
|
424
|
-
}
|
|
425
|
-
const result = validate(T, value)
|
|
426
|
-
expect(result).toBe(false)
|
|
427
|
-
})
|
|
428
|
-
it('Should fail record with invalid property', () => {
|
|
429
|
-
const T = record(
|
|
430
|
-
string(),
|
|
431
|
-
object({
|
|
432
|
-
x: number(),
|
|
433
|
-
y: number(),
|
|
434
|
-
z: number(),
|
|
435
|
-
}),
|
|
436
|
-
)
|
|
437
|
-
const value = {
|
|
438
|
-
position: {
|
|
439
|
-
x: 1,
|
|
440
|
-
y: 2,
|
|
441
|
-
z: '3',
|
|
442
|
-
},
|
|
443
|
-
}
|
|
444
|
-
const result = validate(T, value)
|
|
445
|
-
expect(result).toBe(false)
|
|
446
|
-
})
|
|
447
|
-
it('Should pass record with optional property', () => {
|
|
448
|
-
const T = record(
|
|
449
|
-
string(),
|
|
450
|
-
object({
|
|
451
|
-
x: number(),
|
|
452
|
-
y: number(),
|
|
453
|
-
z: optional(number()),
|
|
454
|
-
}),
|
|
455
|
-
)
|
|
456
|
-
const value = {
|
|
457
|
-
position: {
|
|
458
|
-
x: 1,
|
|
459
|
-
y: 2,
|
|
460
|
-
},
|
|
461
|
-
}
|
|
462
|
-
const result = validate(T, value)
|
|
463
|
-
expect(result).toBe(true)
|
|
464
|
-
})
|
|
465
|
-
it('Should pass record with optional property', () => {
|
|
466
|
-
const T = record(
|
|
467
|
-
string(),
|
|
468
|
-
object({
|
|
469
|
-
x: number(),
|
|
470
|
-
y: number(),
|
|
471
|
-
z: optional(number()),
|
|
472
|
-
}),
|
|
473
|
-
)
|
|
474
|
-
const value = {
|
|
475
|
-
position: {
|
|
476
|
-
x: 1,
|
|
477
|
-
y: 2,
|
|
478
|
-
},
|
|
479
|
-
}
|
|
480
|
-
const result = validate(T, value)
|
|
481
|
-
expect(result).toBe(true)
|
|
482
|
-
})
|
|
483
|
-
|
|
484
|
-
it('Should validate for any keys', () => {
|
|
485
|
-
const T = record(any(), nullable())
|
|
486
|
-
const R = validate(T, {
|
|
487
|
-
a: null,
|
|
488
|
-
b: null,
|
|
489
|
-
0: null,
|
|
490
|
-
1: null,
|
|
491
|
-
})
|
|
492
|
-
expect(R).toBe(true)
|
|
493
|
-
})
|
|
494
|
-
|
|
495
|
-
// TODO: implement this
|
|
496
|
-
it.skip('Should pass record with number key', () => {
|
|
497
|
-
// @ts-expect-error - number key is not supported yet
|
|
498
|
-
const T = record(number(), string())
|
|
499
|
-
const value = {
|
|
500
|
-
0: 'a',
|
|
501
|
-
1: 'a',
|
|
502
|
-
2: 'a',
|
|
503
|
-
}
|
|
504
|
-
const result = validate(T, value)
|
|
505
|
-
expect(result).toBe(true)
|
|
506
|
-
})
|
|
507
|
-
|
|
508
|
-
it.skip('Should not pass record with invalid number key', () => {
|
|
509
|
-
// @ts-expect-error - number key is not supported yet
|
|
510
|
-
const T = record(number(), string())
|
|
511
|
-
const value = {
|
|
512
|
-
a: 'a',
|
|
513
|
-
1: 'a',
|
|
514
|
-
2: 'a',
|
|
515
|
-
}
|
|
516
|
-
const result = validate(T, value)
|
|
517
|
-
expect(result).toBe(false)
|
|
518
|
-
})
|
|
519
|
-
|
|
520
|
-
it.skip('Should validate for number keys', () => {
|
|
521
|
-
// @ts-expect-error - number key is not supported yet
|
|
522
|
-
const T = record(number(), nullable())
|
|
523
|
-
const R1 = validate(T, {
|
|
524
|
-
a: null,
|
|
525
|
-
b: null,
|
|
526
|
-
0: null,
|
|
527
|
-
1: null,
|
|
528
|
-
})
|
|
529
|
-
const R2 = validate(T, {
|
|
530
|
-
0: null,
|
|
531
|
-
1: null,
|
|
532
|
-
})
|
|
533
|
-
expect(R1).toBe(false)
|
|
534
|
-
expect(R2).toBe(true)
|
|
535
|
-
})
|
|
536
|
-
})
|
|
537
|
-
|
|
538
|
-
describe('string', () => {
|
|
539
|
-
const T = string()
|
|
540
|
-
it('Should pass string', () => {
|
|
541
|
-
const value = 'hello'
|
|
542
|
-
const result = validate(T, value)
|
|
543
|
-
expect(result).toBe(true)
|
|
544
|
-
})
|
|
545
|
-
it('Should fail number', () => {
|
|
546
|
-
const value = 1
|
|
547
|
-
const result = validate(T, value)
|
|
548
|
-
expect(result).toBe(false)
|
|
549
|
-
})
|
|
550
|
-
it('Should fail boolean', () => {
|
|
551
|
-
const value = true
|
|
552
|
-
const result = validate(T, value)
|
|
553
|
-
expect(result).toBe(false)
|
|
554
|
-
})
|
|
555
|
-
it('Should fail null', () => {
|
|
556
|
-
const value = null
|
|
557
|
-
const result = validate(T, value)
|
|
558
|
-
expect(result).toBe(false)
|
|
559
|
-
})
|
|
560
|
-
it('Should fail undefined', () => {
|
|
561
|
-
const value = undefined
|
|
562
|
-
const result = validate(T, value)
|
|
563
|
-
expect(result).toBe(false)
|
|
564
|
-
})
|
|
565
|
-
it('Should fail object', () => {
|
|
566
|
-
const value = { a: 1 }
|
|
567
|
-
const result = validate(T, value)
|
|
568
|
-
expect(result).toBe(false)
|
|
569
|
-
})
|
|
570
|
-
it('Should fail array', () => {
|
|
571
|
-
const value = [1, 2]
|
|
572
|
-
const result = validate(T, value)
|
|
573
|
-
expect(result).toBe(false)
|
|
574
|
-
})
|
|
575
|
-
it('Should fail Date', () => {
|
|
576
|
-
const value = new Date()
|
|
577
|
-
const result = validate(T, value)
|
|
578
|
-
expect(result).toBe(false)
|
|
579
|
-
})
|
|
580
|
-
})
|
|
581
|
-
|
|
582
|
-
describe('union', () => {
|
|
583
|
-
const A = object({
|
|
584
|
-
type: literal('A'),
|
|
585
|
-
x: number(),
|
|
586
|
-
y: number(),
|
|
587
|
-
})
|
|
588
|
-
|
|
589
|
-
const B = object({
|
|
590
|
-
type: literal('B'),
|
|
591
|
-
x: boolean(),
|
|
592
|
-
y: boolean(),
|
|
593
|
-
})
|
|
594
|
-
|
|
595
|
-
const T = union([A, B])
|
|
596
|
-
|
|
597
|
-
it('Should pass union A', () => {
|
|
598
|
-
const value = { type: 'A', x: 1, y: 1 }
|
|
599
|
-
const result = validate(T, value)
|
|
600
|
-
expect(result).toBe(true)
|
|
601
|
-
})
|
|
602
|
-
|
|
603
|
-
it('Should pass union B', () => {
|
|
604
|
-
const value = { type: 'B', x: true, y: false }
|
|
605
|
-
const result = validate(T, value)
|
|
606
|
-
expect(result).toBe(true)
|
|
607
|
-
})
|
|
608
|
-
|
|
609
|
-
it('Should fail union A', () => {
|
|
610
|
-
const value = { type: 'A', x: true, y: false }
|
|
611
|
-
const result = validate(T, value)
|
|
612
|
-
expect(result).toBe(false)
|
|
613
|
-
})
|
|
614
|
-
|
|
615
|
-
it('Should fail union B', () => {
|
|
616
|
-
const value = { type: 'B', x: 1, y: 1 }
|
|
617
|
-
const result = validate(T, value)
|
|
618
|
-
expect(result).toBe(false)
|
|
619
|
-
})
|
|
620
|
-
|
|
621
|
-
it('Should pass union A with optional properties', () => {
|
|
622
|
-
const A = object({
|
|
623
|
-
type: literal('A'),
|
|
624
|
-
x: optional(number()),
|
|
625
|
-
y: optional(number()),
|
|
626
|
-
})
|
|
627
|
-
const B = object({
|
|
628
|
-
type: literal('B'),
|
|
629
|
-
x: boolean(),
|
|
630
|
-
y: boolean(),
|
|
631
|
-
})
|
|
632
|
-
const T = union([A, B])
|
|
633
|
-
const value = { type: 'A' }
|
|
634
|
-
const result = validate(T, value)
|
|
635
|
-
expect(result).toBe(true)
|
|
636
|
-
})
|
|
637
|
-
|
|
638
|
-
it('Should fail union A with invalid optional properties', () => {
|
|
639
|
-
const A = object({
|
|
640
|
-
type: literal('A'),
|
|
641
|
-
x: optional(number()),
|
|
642
|
-
y: optional(number()),
|
|
643
|
-
})
|
|
644
|
-
const B = object({
|
|
645
|
-
type: literal('B'),
|
|
646
|
-
x: boolean(),
|
|
647
|
-
y: boolean(),
|
|
648
|
-
})
|
|
649
|
-
const T = union([A, B])
|
|
650
|
-
const value = { type: 'A', x: true, y: false }
|
|
651
|
-
const result = validate(T, value)
|
|
652
|
-
expect(result).toBe(false)
|
|
653
|
-
})
|
|
654
|
-
})
|
|
655
|
-
|
|
656
|
-
describe('intersection', () => {
|
|
657
|
-
it('passes when the value satisfies every member object schema', () => {
|
|
658
|
-
const T = intersection([object({ a: number(), b: number() }), object({ c: string(), d: string() })])
|
|
659
|
-
expect(validate(T, { a: 1, b: 2, c: 'x', d: 'y' })).toBe(true)
|
|
660
|
-
})
|
|
661
|
-
|
|
662
|
-
it('fails when one member object schema fails', () => {
|
|
663
|
-
const T = intersection([object({ a: number(), b: number() }), object({ c: string(), d: string() })])
|
|
664
|
-
expect(validate(T, { a: 1, b: 2, c: 'x', d: 3 })).toBe(false)
|
|
665
|
-
})
|
|
666
|
-
|
|
667
|
-
it('fails when the first member fails even if later members would pass', () => {
|
|
668
|
-
const T = intersection([object({ x: literal(1) }), object({ y: string() })])
|
|
669
|
-
expect(validate(T, { x: 2, y: 'ok' })).toBe(false)
|
|
670
|
-
})
|
|
671
|
-
|
|
672
|
-
it('requires overlapping keys to satisfy every arm that declares them', () => {
|
|
673
|
-
const T = intersection([object({ id: number() }), object({ id: string() })])
|
|
674
|
-
expect(validate(T, { id: 1 })).toBe(false)
|
|
675
|
-
expect(validate(T, { id: '1' })).toBe(false)
|
|
676
|
-
})
|
|
677
|
-
|
|
678
|
-
it('rejects non-plain objects before member checks', () => {
|
|
679
|
-
const T = intersection([object({ x: number() }), object({ y: number() })])
|
|
680
|
-
expect(validate(T, null)).toBe(false)
|
|
681
|
-
expect(validate(T, undefined)).toBe(false)
|
|
682
|
-
expect(validate(T, 0)).toBe(false)
|
|
683
|
-
expect(validate(T, [])).toBe(false)
|
|
684
|
-
expect(validate(T, new Date())).toBe(false)
|
|
685
|
-
})
|
|
686
|
-
|
|
687
|
-
it('treats an empty intersection as vacuously valid', () => {
|
|
688
|
-
const T = intersection([])
|
|
689
|
-
expect(validate(T, null)).toBe(true)
|
|
690
|
-
expect(validate(T, { a: 1 })).toBe(true)
|
|
691
|
-
})
|
|
692
|
-
|
|
693
|
-
it('matches a single member the same as that object schema alone', () => {
|
|
694
|
-
const O = object({ x: number() })
|
|
695
|
-
const T = intersection([O])
|
|
696
|
-
expect(validate(T, { x: 1 })).toBe(true)
|
|
697
|
-
expect(validate(T, {})).toBe(false)
|
|
698
|
-
expect(validate(O, { x: 1 })).toBe(validate(T, { x: 1 }))
|
|
699
|
-
})
|
|
700
|
-
|
|
701
|
-
it('validates members that use lazy schemas', () => {
|
|
702
|
-
const T = intersection([object({ a: number() }), object({ nested: lazy(() => object({ z: string() })) })])
|
|
703
|
-
expect(validate(T, { a: 1, nested: { z: 'ok' } })).toBe(true)
|
|
704
|
-
expect(validate(T, { a: 1, nested: { z: 1 } })).toBe(false)
|
|
705
|
-
})
|
|
706
|
-
})
|
|
707
|
-
|
|
708
|
-
describe('notDefined', () => {
|
|
709
|
-
const T = notDefined()
|
|
710
|
-
it('Should fail string', () => {
|
|
711
|
-
const value = 'hello'
|
|
712
|
-
const result = validate(T, value)
|
|
713
|
-
expect(result).toBe(false)
|
|
714
|
-
})
|
|
715
|
-
it('Should fail number', () => {
|
|
716
|
-
const value = 1
|
|
717
|
-
const result = validate(T, value)
|
|
718
|
-
expect(result).toBe(false)
|
|
719
|
-
})
|
|
720
|
-
it('Should fail boolean', () => {
|
|
721
|
-
const value = true
|
|
722
|
-
const result = validate(T, value)
|
|
723
|
-
expect(result).toBe(false)
|
|
724
|
-
})
|
|
725
|
-
it('Should fail null', () => {
|
|
726
|
-
const value = null
|
|
727
|
-
const result = validate(T, value)
|
|
728
|
-
expect(result).toBe(false)
|
|
729
|
-
})
|
|
730
|
-
it('Should pass undefined', () => {
|
|
731
|
-
const value = undefined
|
|
732
|
-
const result = validate(T, value)
|
|
733
|
-
expect(result).toBe(true)
|
|
734
|
-
})
|
|
735
|
-
it('Should fail object', () => {
|
|
736
|
-
const value = { a: 1 }
|
|
737
|
-
const result = validate(T, value)
|
|
738
|
-
expect(result).toBe(false)
|
|
739
|
-
})
|
|
740
|
-
it('Should fail array', () => {
|
|
741
|
-
const value = [1, 2]
|
|
742
|
-
const result = validate(T, value)
|
|
743
|
-
expect(result).toBe(false)
|
|
744
|
-
})
|
|
745
|
-
it('Should fail Date', () => {
|
|
746
|
-
const value = new Date()
|
|
747
|
-
const result = validate(T, value)
|
|
748
|
-
expect(result).toBe(false)
|
|
749
|
-
})
|
|
750
|
-
})
|
|
751
|
-
|
|
752
|
-
describe('evaluate', () => {
|
|
753
|
-
const T = evaluate((value) => value, number())
|
|
754
|
-
it('Should pass number', () => {
|
|
755
|
-
const value = 1
|
|
756
|
-
const result = validate(T, value)
|
|
757
|
-
expect(result).toBe(true)
|
|
758
|
-
})
|
|
759
|
-
it('Should fail string', () => {
|
|
760
|
-
const value = 'hello'
|
|
761
|
-
const result = validate(T, value)
|
|
762
|
-
expect(result).toBe(false)
|
|
763
|
-
})
|
|
764
|
-
it('Should fail boolean', () => {
|
|
765
|
-
const value = true
|
|
766
|
-
const result = validate(T, value)
|
|
767
|
-
expect(result).toBe(false)
|
|
768
|
-
})
|
|
769
|
-
it('Should fail null', () => {
|
|
770
|
-
const value = null
|
|
771
|
-
const result = validate(T, value)
|
|
772
|
-
expect(result).toBe(false)
|
|
773
|
-
})
|
|
774
|
-
it('Should fail undefined', () => {
|
|
775
|
-
const value = undefined
|
|
776
|
-
const result = validate(T, value)
|
|
777
|
-
expect(result).toBe(false)
|
|
778
|
-
})
|
|
779
|
-
it('Should fail object', () => {
|
|
780
|
-
const value = { a: 1 }
|
|
781
|
-
const result = validate(T, value)
|
|
782
|
-
expect(result).toBe(false)
|
|
783
|
-
})
|
|
784
|
-
it('Should fail array', () => {
|
|
785
|
-
const value = [1, 2]
|
|
786
|
-
const result = validate(T, value)
|
|
787
|
-
expect(result).toBe(false)
|
|
788
|
-
})
|
|
789
|
-
it('Should fail Date', () => {
|
|
790
|
-
const value = new Date()
|
|
791
|
-
const result = validate(T, value)
|
|
792
|
-
expect(result).toBe(false)
|
|
793
|
-
})
|
|
794
|
-
})
|
|
795
|
-
|
|
796
|
-
describe('lazy', () => {
|
|
797
|
-
const T = lazy(() => object({ x: number() }))
|
|
798
|
-
it('Should pass object', () => {
|
|
799
|
-
const value = { x: 1 }
|
|
800
|
-
const result = validate(T, value)
|
|
801
|
-
expect(result).toBe(true)
|
|
802
|
-
})
|
|
803
|
-
it('Should fail string', () => {
|
|
804
|
-
const value = 'hello'
|
|
805
|
-
const result = validate(T, value)
|
|
806
|
-
expect(result).toBe(false)
|
|
807
|
-
})
|
|
808
|
-
it('Should fail boolean', () => {
|
|
809
|
-
const value = true
|
|
810
|
-
const result = validate(T, value)
|
|
811
|
-
expect(result).toBe(false)
|
|
812
|
-
})
|
|
813
|
-
it('Should fail null', () => {
|
|
814
|
-
const value = null
|
|
815
|
-
const result = validate(T, value)
|
|
816
|
-
expect(result).toBe(false)
|
|
817
|
-
})
|
|
818
|
-
it('Should fail undefined', () => {
|
|
819
|
-
const value = undefined
|
|
820
|
-
const result = validate(T, value)
|
|
821
|
-
expect(result).toBe(false)
|
|
822
|
-
})
|
|
823
|
-
it('Should fail array', () => {
|
|
824
|
-
const value = [1, 2]
|
|
825
|
-
const result = validate(T, value)
|
|
826
|
-
expect(result).toBe(false)
|
|
827
|
-
})
|
|
828
|
-
it('Should fail Date', () => {
|
|
829
|
-
const value = new Date()
|
|
830
|
-
const result = validate(T, value)
|
|
831
|
-
expect(result).toBe(false)
|
|
832
|
-
})
|
|
833
|
-
})
|