-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidation.as
More file actions
103 lines (103 loc) · 6.09 KB
/
validation.as
File metadata and controls
103 lines (103 loc) · 6.09 KB
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
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import * as schema from "std/schema"
import * as json from "std/json"
import * as string from "std/string"
fn looksLikeEmail(s) {
return string.contains(s, "@")
}
let addressSchema = schema.object({ city: schema.minLength(schema.string(), 1), zip: schema.pattern(schema.string(), "^[0-9]{5}$") })
let userSchema = schema.object({ name: schema.minLength(schema.string(), 1), age: schema.min(schema.number(), 0), email: schema.refine(schema.string(), looksLikeEmail, "must look like an email"), tags: schema.array(schema.string()), nickname: schema.optional(schema.string()), address: addressSchema })
let validUser = { name: "Ada Lovelace", age: 36, email: "ada@example.com", tags: ["pioneer", "mathematician"], nickname: nil, address: { city: "London", zip: "12345" } }
let [u, e1] = schema.parse(userSchema, validUser)
assert(e1 == nil, "valid user: err should be nil")
assert(u.name == "Ada Lovelace", "valid user: name ok")
assert(u.age == 36, "valid user: age ok")
assert(u.nickname == nil, "valid user: optional nil ok")
assert(u.address.city == "London", "valid user: nested city ok")
let badUser = { name: "Ada", age: -5, email: "ada@example.com", tags: [], address: { city: "London", zip: "12345" } }
let [bad, e2] = schema.parse(userSchema, badUser)
assert(bad == nil, "bad user: nil value on failure")
assert(e2 != nil, "bad user: err set")
assert(e2.path != nil, "bad user: err.path set")
assert(e2.message != nil, "bad user: err.message set")
print(`validation error path="${e2.path}" message="${e2.message}"`)
let badEmail = { name: "Bob", age: 25, email: "not-an-email", tags: [], address: { city: "Paris", zip: "75001" } }
let [bad2, e3] = schema.parse(userSchema, badEmail)
assert(bad2 == nil, "bad email: nil value")
assert(e3 != nil, "bad email: err set")
assert(e3.message == "must look like an email", `refine message mismatch: ${e3.message}`)
print(`refine error path="${e3.path}" message="${e3.message}"`)
let addrJsonSchema = schema.object({ city: schema.minLength(schema.string(), 1), zip: schema.any() })
let userJsonSchema = schema.object({ name: schema.minLength(schema.string(), 1), age: schema.min(schema.number(), 0), email: schema.refine(schema.string(), looksLikeEmail, "must look like an email"), tags: schema.array(schema.string()), address: addrJsonSchema })
let validJson = "{\"name\":\"Grace Hopper\",\"age\":85,\"email\":\"grace@navy.mil\",\"tags\":[\"compiler\"],\"address\":{\"city\":\"Arlington\",\"zip\":22201}}"
let [ju, je1] = json.parse(validJson, userJsonSchema)
assert(je1 == nil, "json.parse ok: err nil")
assert(ju.name == "Grace Hopper", "json.parse ok: name matches")
assert(ju.age == 85, "json.parse ok: age matches")
assert(ju.address.city == "Arlington", "json.parse ok: nested city")
let [bad3, je2] = json.parse("{not json", userJsonSchema)
assert(bad3 == nil, "malformed json: nil value")
assert(je2 != nil, "malformed json: err set")
print(`fused error (bad JSON): "${je2.message}"`)
let [bad4, je3] = json.parse("{\"name\":\"\",\"age\":30,\"email\":\"x@y.com\",\"tags\":[],\"address\":{\"city\":\"Rome\",\"zip\":0}}", userJsonSchema)
assert(bad4 == nil, "json schema mismatch: nil value")
assert(je3 != nil, "json schema mismatch: err set")
print(`fused error (schema mismatch) path="${je3.path}" msg="${je3.message}"`)
let [coerced, ce] = schema.parse(schema.number(), "42", { coerce: true })
assert(ce == nil, "coerce string->number: err nil")
assert(coerced == 42, "coerce string->number: value is 42")
let [coerced2, ce2] = schema.parse(schema.bool(), "true", { coerce: true })
assert(ce2 == nil, "coerce string->bool: err nil")
assert(coerced2 == true, "coerce 'true'->bool")
let [coerced3, ce3] = schema.parse(schema.string(), 99, { coerce: true })
assert(ce3 == nil, "coerce number->string: err nil")
assert(coerced3 == "99", "coerce number->string: value is '99'")
class Point {
x: number
y: number
label: string?
}
let pointSchema = schema.fromClass(Point)
let [pt, pe1] = schema.parse(pointSchema, { x: 3, y: 4 })
assert(pe1 == nil, "fromClass ok: err nil")
assert(pt.x == 3, "fromClass ok: x == 3")
assert(pt.y == 4, "fromClass ok: y == 4")
let [pt2, pe2] = schema.parse(pointSchema, { x: "not-a-number", y: 4 })
assert(pt2 == nil, "fromClass mismatch: nil value")
assert(pe2 != nil, "fromClass mismatch: err set")
print(`fromClass error path="${pe2.path}" message="${pe2.message}"`)
let roleSchema = schema.oneOf(["admin", "editor", "viewer"])
let [r1, re1] = schema.parse(roleSchema, "admin")
assert(re1 == nil, "oneOf: valid value accepted")
assert(r1 == "admin", "oneOf: value preserved")
let [r2, re2] = schema.parse(roleSchema, "superuser")
assert(r2 == nil, "oneOf: invalid value rejected")
assert(re2 != nil, "oneOf: err set")
let numOrStr = schema.union([schema.number(), schema.string()])
let [ns1, nse1] = schema.parse(numOrStr, 42)
assert(nse1 == nil, "union: number accepted")
let [ns2, nse2] = schema.parse(numOrStr, "hello")
assert(nse2 == nil, "union: string accepted")
let [ns3, nse3] = schema.parse(numOrStr, true)
assert(ns3 == nil, "union: bool rejected")
assert(nse3 != nil, "union: err set for bool")
let withDefault = schema.default(schema.string(), "anonymous")
let [d1, de1] = schema.parse(withDefault, nil)
assert(de1 == nil, "default: nil gets default")
assert(d1 == "anonymous", "default: value is 'anonymous'")
let [d2, de2] = schema.parse(withDefault, "Ada")
assert(de2 == nil, "default: non-nil passes through")
assert(d2 == "Ada", "default: non-nil value preserved")
let username = schema.string().minLength(3).maxLength(12).pattern("^[a-z0-9_]+$")
let [fu, fe1] = username.parse("ada_lovelace")
assert(fe1 == nil, "fluent: valid username err nil")
assert(fu == "ada_lovelace", "fluent: value preserved")
let [fu2, fe2] = username.parse("ab")
assert(fu2 == nil, "fluent: too-short value nil")
assert(fe2 != nil, "fluent: too-short err set")
let [free, freeErr] = schema.parse(username, "ab")
assert(freeErr.message == fe2.message, "fluent: method parse == free-fn parse")
let maybeAge = schema.number().min(0).optional()
let [ma, mae] = maybeAge.parse(nil)
assert(mae == nil && ma == nil, "fluent: optional accepts nil")
print(`fluent username error message="${fe2.message}"`)
print("validation: all assertions passed")