Skip to content

Commit 84442ad

Browse files
committed
test(schema) Add tests
1 parent 3b9af20 commit 84442ad

File tree

2 files changed

+162
-7
lines changed

2 files changed

+162
-7
lines changed

packages/schema/index.test.ts

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { describe, expect, it } from "bun:test";
2+
import {
3+
array,
4+
boolean,
5+
defaulted,
6+
maybe,
7+
number,
8+
object,
9+
SchemaError,
10+
string,
11+
} from ".";
12+
13+
describe("string()", () => {
14+
it("should validate a string input", () => {
15+
const schema = string();
16+
const result = schema.safeParse("hello");
17+
expect(result).toEqual({ value: "hello" });
18+
});
19+
20+
it("should reject non-string inputs", () => {
21+
const schema = string();
22+
const result = schema.safeParse(123);
23+
expect(result.issues).toEqual([{ message: "Expected string" }]);
24+
});
25+
26+
it("should throw SchemaError on invalid input when using parse", () => {
27+
const schema = string();
28+
expect(() => schema.parse(123)).toThrow(SchemaError);
29+
});
30+
});
31+
32+
describe("number()", () => {
33+
it("should validate a number input", () => {
34+
const schema = number();
35+
const result = schema.safeParse(42);
36+
expect(result).toEqual({ value: 42 });
37+
});
38+
39+
it("should reject non-number inputs", () => {
40+
const schema = number();
41+
const result = schema.safeParse("not a number");
42+
expect(result.issues).toEqual([{ message: "Expected number" }]);
43+
});
44+
45+
it("should reject NaN and Infinity", () => {
46+
const schema = number();
47+
expect(schema.safeParse(NaN).issues).toBeDefined();
48+
expect(schema.safeParse(Infinity).issues).toBeDefined();
49+
});
50+
});
51+
52+
describe("boolean()", () => {
53+
it("should validate a boolean input", () => {
54+
const schema = boolean();
55+
const result = schema.safeParse(true);
56+
expect(result).toEqual({ value: true });
57+
});
58+
59+
it("should reject non-boolean inputs", () => {
60+
const schema = boolean();
61+
const result = schema.safeParse("not a boolean");
62+
expect(result.issues).toEqual([{ message: "Expected boolean" }]);
63+
});
64+
});
65+
66+
describe("array()", () => {
67+
it("should validate an array of valid elements", () => {
68+
const schema = array(number());
69+
const result = schema.safeParse([1, 2, 3]);
70+
expect(result).toEqual({ value: [1, 2, 3] });
71+
});
72+
73+
it("should reject non-array inputs", () => {
74+
const schema = array(number());
75+
const result = schema.safeParse("not an array");
76+
expect(result.issues).toEqual([{ message: "Expected array" }]);
77+
});
78+
79+
it("should reject arrays with invalid elements", () => {
80+
const schema = array(number());
81+
const result = schema.safeParse([1, "not a number", 3]);
82+
expect(result.issues).toEqual([{ message: "Expected number", path: [1] }]);
83+
});
84+
});
85+
86+
describe("object()", () => {
87+
it("should validate an object with valid properties", () => {
88+
const schema = object({
89+
name: string(),
90+
age: number(),
91+
});
92+
const result = schema.safeParse({ name: "Alice", age: 30 });
93+
expect(result).toEqual({ value: { name: "Alice", age: 30 } });
94+
});
95+
96+
it("should reject non-object inputs", () => {
97+
const schema = object({});
98+
const result = schema.safeParse("not an object");
99+
expect(result.issues).toEqual([{ message: "Expected object" }]);
100+
});
101+
102+
it("should reject objects with invalid properties", () => {
103+
const schema = object({
104+
name: string(),
105+
age: number(),
106+
});
107+
const result = schema.safeParse({ name: "Alice", age: "not a number" });
108+
expect(result.issues).toEqual([
109+
{ message: "Expected number", path: ["age"] },
110+
]);
111+
});
112+
});
113+
114+
describe("maybe()", () => {
115+
it("should allow null or undefined as valid inputs", () => {
116+
const schema = maybe(number());
117+
expect(schema.safeParse(null)).toEqual({ value: undefined });
118+
expect(schema.safeParse(undefined)).toEqual({ value: undefined });
119+
});
120+
121+
it("should validate non-null/undefined inputs", () => {
122+
const schema = maybe(number());
123+
const result = schema.safeParse(42);
124+
expect(result).toEqual({ value: 42 });
125+
});
126+
127+
it("should reject invalid non-null/undefined inputs", () => {
128+
const schema = maybe(number());
129+
const result = schema.safeParse("not a number");
130+
expect(result.issues).toEqual([{ message: "Expected number" }]);
131+
});
132+
});
133+
134+
describe("defaulted()", () => {
135+
it("should provide a default value for null or undefined inputs", () => {
136+
const schema = defaulted(number(), 42);
137+
expect(schema.safeParse(null)).toEqual({ value: 42 });
138+
expect(schema.safeParse(undefined)).toEqual({ value: 42 });
139+
});
140+
141+
it("should validate non-null/undefined inputs", () => {
142+
const schema = defaulted(number(), 42);
143+
const result = schema.safeParse(100);
144+
expect(result).toEqual({ value: 100 });
145+
});
146+
147+
it("should reject invalid non-null/undefined inputs", () => {
148+
const schema = defaulted(number(), 42);
149+
const result = schema.safeParse("not a number");
150+
expect(result.issues).toEqual([{ message: "Expected number" }]);
151+
});
152+
});

packages/schema/index.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ function prependKeyToIssues(
107107
): Issue[] {
108108
return issues.map((issue) => ({
109109
...issue,
110-
path: Array.isArray(issue.path) ? [key, ...issue.path] : undefined,
110+
path: Array.isArray(issue.path) ? [key, ...issue.path] : [key],
111111
}));
112112
}
113113

@@ -116,7 +116,7 @@ function prependKeyToIssues(
116116
* @param message - The error message to return if validation fails.
117117
* @returns A schema that validates string inputs.
118118
*/
119-
export function str(message = "Expected string") {
119+
export function string(message = "Expected string") {
120120
return createSchema<string>((value) => {
121121
if ("string" === typeof value) return { value };
122122
return { issues: [{ message }] };
@@ -128,7 +128,7 @@ export function str(message = "Expected string") {
128128
* @param message - The error message to return if validation fails.
129129
* @returns A schema that validates number inputs.
130130
*/
131-
export function num(message = "Expected number") {
131+
export function number(message = "Expected number") {
132132
return createSchema<number>((value) => {
133133
if ("number" === typeof value && Number.isFinite(value)) return { value };
134134
return { issues: [{ message }] };
@@ -140,7 +140,7 @@ export function num(message = "Expected number") {
140140
* @param message - The error message to return if validation fails.
141141
* @returns A schema that validates boolean inputs.
142142
*/
143-
export function bool(message = "Expected boolean") {
143+
export function boolean(message = "Expected boolean") {
144144
return createSchema<boolean>((value) => {
145145
if ("boolean" === typeof value) return { value };
146146
return { issues: [{ message }] };
@@ -154,7 +154,7 @@ export function bool(message = "Expected boolean") {
154154
* @param message - The error message to return if validation fails.
155155
* @returns A schema that validates array inputs.
156156
*/
157-
export function list<T extends Schema>(schema: T, message = "Expected array") {
157+
export function array<T extends Schema>(schema: T, message = "Expected array") {
158158
return createSchema<InferOutput<T>[]>((input) => {
159159
if (!Array.isArray(input)) return { issues: [{ message }] };
160160
const len = input.length;
@@ -201,7 +201,7 @@ export interface ObjectSchema<TOutput extends RawShape, TInput = unknown>
201201
* @param message - The error message to return if validation fails.
202202
* @returns A schema that validates object inputs.
203203
*/
204-
export function obj<T extends RawShape>(
204+
export function object<T extends RawShape>(
205205
shape: ObjectShape<T>,
206206
message = "Expected object"
207207
): ObjectSchema<T> {
@@ -242,7 +242,10 @@ export function maybe<T extends Schema>(schema: T) {
242242
* @param defaultValue - The default value to use if the input is `null` or `undefined`.
243243
* @returns A schema that validates inputs and provides a default value if necessary.
244244
*/
245-
export function def<T extends Schema>(schema: T, defaultValue: InferOutput<T>) {
245+
export function defaulted<T extends Schema>(
246+
schema: T,
247+
defaultValue: InferOutput<T>
248+
) {
246249
return createSchema<InferOutput<T>>((value) => {
247250
if (null === value || undefined === value) return { value: defaultValue };
248251
return schema.safeParse(value);

0 commit comments

Comments
 (0)