Skip to content

Commit 3aa8283

Browse files
committed
test: cover File size bounds and regenerate DTS snapshots
1 parent 8414966 commit 3aa8283

8 files changed

Lines changed: 346 additions & 4 deletions

File tree

ark/docs/components/dts/schema.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

ark/docs/components/dts/type.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

ark/docs/components/dts/util.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

ark/schema/__tests__/bounds.test.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
Disjoint,
44
boundKindPairsByLower,
55
rootSchema,
6-
writeInvalidLengthBoundMessage
6+
writeInvalidLengthBoundMessage,
7+
writeInvalidSizeBoundMessage
78
} from "@ark/schema"
89
import { entriesOf, flatMorph } from "@ark/util"
910

@@ -19,6 +20,11 @@ const dateCases = flatMorph(numericCases, (name, v) => [name, new Date(v)])
1920

2021
const lengthCases = flatMorph(numericCases, (name, v) => [name, "1".repeat(v)])
2122

23+
const fileCases = flatMorph(numericCases, (name, v) => [
24+
name,
25+
new File(["x".repeat(v)], "test.txt")
26+
])
27+
2228
contextualize(() => {
2329
it("numeric apply", () => {
2430
const T = rootSchema({
@@ -86,6 +92,45 @@ contextualize(() => {
8692
)
8793
})
8894

95+
it("file apply", () => {
96+
const T = rootSchema({
97+
proto: File,
98+
minSize: { rule: 5, exclusive: true },
99+
maxSize: { rule: 10 }
100+
})
101+
102+
attest(T.traverse(fileCases.lessThanMin)?.toString()).snap(
103+
"must be more than 5 bytes (was 4 bytes)"
104+
)
105+
attest(T.traverse(fileCases.equalToExclusiveMin)?.toString()).snap(
106+
"must be more than 5 bytes (was 5 bytes)"
107+
)
108+
attest(T.traverse(fileCases.between)).equals(fileCases.between)
109+
attest(T.traverse(fileCases.equalToInclusiveMax)).equals(
110+
fileCases.equalToInclusiveMax
111+
)
112+
attest(T.traverse(fileCases.greaterThanMax)?.toString()).snap(
113+
"must be at most 10 bytes (was 11 bytes)"
114+
)
115+
})
116+
117+
it("errors on negative size bound", () => {
118+
attest(() => rootSchema({ proto: File, maxSize: -1 })).throws(
119+
writeInvalidSizeBoundMessage("maxSize", -1)
120+
)
121+
})
122+
123+
it("errors on non-integer size bound", () => {
124+
attest(() => rootSchema({ proto: File, minSize: 1.5 })).throws(
125+
writeInvalidSizeBoundMessage("minSize", 1.5)
126+
)
127+
})
128+
129+
it("minSize 0 reduces to unconstrained", () => {
130+
const T = rootSchema({ proto: File, minSize: 0 })
131+
attest(T.expression).snap("File")
132+
})
133+
89134
it("errors on negative length bound", () => {
90135
attest(() => rootSchema({ domain: "string", maxLength: -1 })).throws(
91136
writeInvalidLengthBoundMessage("maxLength", -1)
@@ -108,10 +153,12 @@ contextualize(() => {
108153
const basis =
109154
min === "min" ? { domain: "number" }
110155
: min === "minLength" ? { domain: "string" }
156+
: min === "minSize" ? { proto: File }
111157
: { proto: Date }
112158
const cases =
113159
min === "min" ? numericCases
114160
: min === "minLength" ? lengthCases
161+
: min === "minSize" ? fileCases
115162
: dateCases
116163

117164
it("allows", () => {
@@ -151,6 +198,12 @@ contextualize(() => {
151198
...basis,
152199
exactLength: 6
153200
} as never)
201+
: min === "minSize" ?
202+
rootSchema({
203+
...basis,
204+
minSize: { rule: 6 },
205+
maxSize: { rule: 6 }
206+
} as never)
154207
: rootSchema({
155208
unit: new Date(6)
156209
})

ark/schema/__tests__/select.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,10 @@ contextualize(() => {
114114
"intersection",
115115
"max",
116116
"maxLength",
117+
"maxSize",
117118
"min",
118119
"minLength",
120+
"minSize",
119121
"morph",
120122
"optional",
121123
"pattern",
@@ -160,8 +162,10 @@ contextualize(() => {
160162
"intersection",
161163
"max",
162164
"maxLength",
165+
"maxSize",
163166
"min",
164167
"minLength",
168+
"minSize",
165169
"morph",
166170
"optional",
167171
"pattern",

ark/type/__tests__/config.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,10 @@ contextualize(() => {
316316
"intersection",
317317
"max",
318318
"maxLength",
319+
"maxSize",
319320
"min",
320321
"minLength",
322+
"minSize",
321323
"morph",
322324
"optional",
323325
"pattern",
@@ -362,8 +364,10 @@ contextualize(() => {
362364
"intersection",
363365
"max",
364366
"maxLength",
367+
"maxSize",
365368
"min",
366369
"minLength",
370+
"minSize",
367371
"morph",
368372
"optional",
369373
"pattern",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { attest, contextualize } from "@ark/attest"
2+
import { type } from "arktype"
3+
4+
contextualize(() => {
5+
it("basic File type", () => {
6+
const T = type("File")
7+
8+
const validFile = new File(["content"], "test.txt")
9+
const anotherFile = new File(["x".repeat(1000)], "data.bin")
10+
const notAFile = "not a file"
11+
const alsoNotAFile = { name: "fake.txt" }
12+
13+
attest(T(validFile)).equals(validFile)
14+
attest(T(anotherFile)).equals(anotherFile)
15+
attest(T(notAFile).toString()).snap("must be a File instance (was string)")
16+
attest(T(alsoNotAFile).toString()).snap(
17+
"must be a File instance (was object)"
18+
)
19+
})
20+
21+
it("File in object schema", () => {
22+
const T = type({
23+
document: "File"
24+
})
25+
26+
const validFile = new File(["content"], "doc.pdf")
27+
const validData = { document: validFile }
28+
const invalidData = { document: "not-a-file.txt" }
29+
30+
attest(T(validData)).equals(validData)
31+
attest(T(invalidData).toString()).snap(
32+
"document must be a File instance (was string)"
33+
)
34+
})
35+
})

0 commit comments

Comments
 (0)