|
1 | 1 | import { describe, expect, expectTypeOf, it } from "vitest"; |
2 | 2 | import { |
3 | 3 | FnError, |
| 4 | + getErrors, |
4 | 5 | memoryAdapter, |
5 | 6 | UnexpectedError, |
6 | 7 | ValidationError, |
@@ -1149,3 +1150,41 @@ describe("multi-issue validation", () => { |
1149 | 1150 | } |
1150 | 1151 | }); |
1151 | 1152 | }); |
| 1153 | + |
| 1154 | +describe("getErrors", () => { |
| 1155 | + it("returns undefined when fn declares no errors", () => { |
| 1156 | + const f = v.fn( |
| 1157 | + "ge.no_errors", |
| 1158 | + { input: { n: v.number() } }, |
| 1159 | + (c) => c.input.n, |
| 1160 | + ); |
| 1161 | + expect(getErrors(f)).toBeUndefined(); |
| 1162 | + }); |
| 1163 | + |
| 1164 | + it("returns the declared error map at runtime", () => { |
| 1165 | + const f = v.fn( |
| 1166 | + "ge.with_errors", |
| 1167 | + { errors: { not_found: v.object({ id: v.string() }), forbidden: {} } }, |
| 1168 | + () => "ok", |
| 1169 | + ); |
| 1170 | + const errs = getErrors(f); |
| 1171 | + expect(errs).toBeDefined(); |
| 1172 | + expect(errs).toHaveProperty("not_found"); |
| 1173 | + expect(errs).toHaveProperty("forbidden"); |
| 1174 | + }); |
| 1175 | + |
| 1176 | + it("infers the error-map type from the generic parameter", () => { |
| 1177 | + const conflict = v.object({ email: v.string() }); |
| 1178 | + const f = v.fn("ge.typed", { errors: { conflict } }, () => "ok"); |
| 1179 | + // Type-level: getErrors should return the declared map or undefined. |
| 1180 | + expectTypeOf(getErrors(f)).toMatchTypeOf< |
| 1181 | + { conflict: typeof conflict } | undefined |
| 1182 | + >(); |
| 1183 | + }); |
| 1184 | + |
| 1185 | + it("returns undefined for a fn that omitted the errors key", () => { |
| 1186 | + const bare = v.fn(() => "bare"); |
| 1187 | + // $schema is always present from defineFn, but without an errors key. |
| 1188 | + expect(getErrors(bare)).toBeUndefined(); |
| 1189 | + }); |
| 1190 | +}); |
0 commit comments