-
-
Notifications
You must be signed in to change notification settings - Fork 58
/
this.test.ts
112 lines (95 loc) · 3.11 KB
/
this.test.ts
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
104
105
106
107
108
109
110
111
112
import { attest, contextualize } from "@ark/attest"
import { writeUnresolvableMessage } from "@ark/schema"
import { scope, type } from "arktype"
contextualize(() => {
it("resolves from type", () => {
const disappointingGift = type({
label: "string",
"box?": "this"
})
type ExpectedDisappointingGift = {
label: string
box?: ExpectedDisappointingGift
}
attest<ExpectedDisappointingGift>(disappointingGift.infer)
attest(disappointingGift({ label: "foo" })).snap({ label: "foo" })
attest(disappointingGift({ label: "foo", box: { label: "bar" } })).snap({
label: "foo",
box: { label: "bar" }
})
attest(
disappointingGift({
label: "foo",
box: { label: "bar", box: {} }
}).toString()
).snap("box.box.label must be a string (was missing)")
})
it("at nested path", () => {
const t = type({ foo: { bar: "this" } })
attest(t).type.toString.snap("Type<{ foo: { bar: cyclic } }, {}>")
const validData = { foo: { bar: {} } } as typeof t.infer
validData.foo.bar = validData
attest(t(validData)).equals(validData)
const invalidData = { foo: { bar: {} as any } }
invalidData.foo.bar = invalidData.foo
attest(t(invalidData).toString()).snap(
"foo.bar.foo must be an object (was missing)"
)
})
it("this preserved when referencing at path", () => {
const initial = type({
initial: "this"
})
const reference = type({
reference: initial
})
type Initial = {
initial: Initial
}
type Expected = {
reference: Initial
}
attest<Expected>(reference.infer)
const initialData = {} as typeof initial.infer
initialData.initial = initialData
const referenceData = { reference: initialData }
attest(initial(initialData)).equals(initialData)
attest(reference(referenceData)).equals(referenceData)
attest(reference({ reference: {} }).toString()).snap(
"reference.initial must be an object (was missing)"
)
})
it("unresolvable in scope", () => {
attest(() =>
scope({
disappointingGift: {
label: "string",
// @ts-expect-error
"box?": "this"
}
}).export()
).throwsAndHasTypeError(writeUnresolvableMessage("this"))
})
it("tuple expression", () => {
const t = type([{ a: "string" }, "|", { b: "this" }])
attest(t.infer).type.toString.snap(
"{ a: string } | { b: { a: string } | cyclic }"
)
attest(t({ a: "foo" })).snap({ a: "foo" })
attest(t({ b: { a: "bar" } })).snap({ b: { a: "bar" } })
attest(t({ b: { b: {} } }).toString()).snap(
"a must be a string (was missing), b.a must be a string (was missing) or b.b must be b.b.a must be a string (was missing) or b.b.b must be an object (was missing) (was {})"
)
})
it("root expression", () => {
const t = type({ a: "string" }, "|", { b: "this" })
attest(t.infer).type.toString.snap(
"{ a: string } | { b: { a: string } | cyclic }"
)
attest(t({ a: "foo" })).snap({ a: "foo" })
attest(t({ b: { a: "bar" } })).snap({ b: { a: "bar" } })
attest(t({ b: { b: {} } }).toString()).snap(
"a must be a string (was missing), b.a must be a string (was missing) or b.b must be b.b.a must be a string (was missing) or b.b.b must be an object (was missing) (was {})"
)
})
})