1import assert from "node:assert/strict"
2import * as v from "valibot"
3import { invalidData, validData } from "./data.ts"
4
5// Extracted from open-circle/schema-benchmarks at
6// 11fab2a741cef95a1374910276023c51218c0683.
7
8const makeSchema = () => {
9 const image = v.object({
10 id: v.number(),
11 created: v.date(),
12 title: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),
13 type: v.picklist(["jpg", "png"]),
14 size: v.number(),
15 url: v.pipe(v.string(), v.url())
16 })
17 const rating = v.object({
18 id: v.number(),
19 stars: v.pipe(v.number(), v.minValue(0), v.maxValue(5)),
20 title: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),
21 text: v.pipe(v.string(), v.minLength(1), v.maxLength(1000)),
22 images: v.array(image)
23 })
24 return v.object({
25 id: v.number(),
26 created: v.date(),
27 title: v.pipe(v.string(), v.minLength(1), v.maxLength(100)),
28 brand: v.pipe(v.string(), v.minLength(1), v.maxLength(30)),
29 description: v.pipe(v.string(), v.minLength(1), v.maxLength(500)),
30 price: v.pipe(v.number(), v.minValue(1), v.maxValue(10000)),
31 discount: v.nullable(v.pipe(v.number(), v.minValue(1), v.maxValue(100))),
32 quantity: v.pipe(v.number(), v.minValue(1), v.maxValue(10)),
33 tags: v.array(v.pipe(v.string(), v.minLength(1), v.maxLength(30))),
34 images: v.array(image),
35 ratings: v.array(rating)
36 })
37}
38
39export const initializationSchema = () => ({
40 run: makeSchema,
41 validate: (schema) => assert.equal(schema.type, "object")
42})
43
44const validationCase = (input, expected) => () => {
45 const schema = makeSchema()
46 return {
47 run: () => v.is(schema, input),
48 validate: (result) => assert.equal(result, expected)
49 }
50}
51
52export const validationValid = validationCase(validData, true)
53export const validationInvalid = validationCase(invalidData, false)
54
55const parsingCase = (input, options, success) => () => {
56 const schema = makeSchema()
57 return {
58 run: () => v.safeParse(schema, input, options),
59 validate: (result) => {
60 assert.equal(result.success, success)
61 if (success) assert.deepEqual(result.output, validData)
62 }
63 }
64}
65
66export const parsingAllValid = parsingCase(validData, undefined, true)
67export const parsingAllInvalid = parsingCase(invalidData, undefined, false)
68export const parsingFirstValid = parsingCase(validData, { abortEarly: true }, true)
69export const parsingFirstInvalid = parsingCase(invalidData, { abortEarly: true }, false)
70
71const standardCase = (input, success) => () => {
72 const schema = makeSchema()
73 return {
74 run: () => schema["~standard"].validate(input),
75 validate: (result) => {
76 assert.equal(typeof result?.then, "undefined")
77 assert.equal(result.issues === undefined, success)
78 if (success) assert.deepEqual(result.value, validData)
79 }
80 }
81}
82
83export const standardAllValid = standardCase(validData, true)
84export const standardAllInvalid = standardCase(invalidData, false)