Skip to content

Commit f22eb9a

Browse files
maxholmanclaude
andcommitted
test: cover const, nullable type arrays, and enum generation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 064751e commit f22eb9a

9 files changed

Lines changed: 202 additions & 7 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`const values 1`] = `
4+
"export type StringConst = "hello";
5+
export type NumberConst = 42;
6+
export type BooleanConst = true;
7+
export type NullConst = null;
8+
"
9+
`;
10+
11+
exports[`const values 2`] = `
12+
"import * as v from "valibot";
13+
14+
export const stringConstSchema = v.literal("hello");
15+
export const numberConstSchema = v.literal(42);
16+
export const booleanConstSchema = v.literal(true);
17+
export const nullConstSchema = v.null();
18+
"
19+
`;
20+
321
exports[`nullables 1`] = `
422
"export type MySchemaLolOrNullable = "lol" | "kek" | null;
523
"
624
`;
25+
26+
exports[`top-level type array with null 1`] = `
27+
"export type NullableString = string | null;
28+
export type NullableStringEnum = "active" | "inactive" | null;
29+
export type NullableInteger = number | null;
30+
export type MultiType = string | number;
31+
"
32+
`;
33+
34+
exports[`top-level type array with null 2`] = `
35+
"import * as v from "valibot";
36+
37+
export const nullableStringSchema = v.nullable(v.string());
38+
export const nullableStringEnumSchema = v.nullable(v.picklist(["active", "inactive"]));
39+
export const nullableIntegerSchema = v.nullable(v.pipe(v.number(), v.integer()));
40+
export const multiTypeSchema = v.union([v.string(), v.number()]);
41+
"
42+
`;
43+
44+
exports[`top-level type array with null 3`] = `
45+
"export const nullableStringEnum = ["active", "inactive"] as const;
46+
"
47+
`;

__tests__/fixtures/test1.json

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"openapi": "3.0.3",
2+
"openapi": "3.1.0",
33
"info": {
44
"title": "Billing Service REST API",
55
"version": "1.0.0"
@@ -58,6 +58,33 @@
5858
"maxLength": 256,
5959
"pattern": "/^[A-Z0-9]$/"
6060
},
61+
"ApiVersion": {
62+
"type": "string",
63+
"const": "2024-01-01",
64+
"description": "The API version"
65+
},
66+
"MaxRetries": {
67+
"type": "integer",
68+
"const": 3
69+
},
70+
"DefaultEnabled": {
71+
"const": true
72+
},
73+
"NullableNotes": {
74+
"type": ["string", "null"],
75+
"description": "Optional notes field"
76+
},
77+
"NullableDiscount": {
78+
"type": ["number", "null"]
79+
},
80+
"NullableStatus": {
81+
"type": ["string", "null"],
82+
"enum": ["active", "paused", "cancelled"]
83+
},
84+
"AccountTier": {
85+
"type": "string",
86+
"enum": ["free", "pro", "enterprise"]
87+
},
6188
"LongRunningOperationIndeterminate": {
6289
"type": "object",
6390
"additionalProperties": false,

__tests__/fixtures/test1/commands.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* WARN: Do not edit directly.
55
*
6-
* Generated on 2026-03-17T13:15:38.356Z
6+
* Generated on 2026-04-02T04:52:00.193Z
77
*
88
*/
99
/** eslint-disable max-classes */
@@ -40,7 +40,8 @@ import type {
4040
} from "./types.js";
4141

4242
/**
43-
* Tagged template literal that applies encodeURIComponent to all interpolated values, protecting path integrity from characters like `/` and `#`.
43+
* Tagged template literal that applies encodeURIComponent to all interpolated
44+
* values, protecting path integrity from characters like `/` and `#`.
4445
* @example encodePath`/users/${userId}` // "/users/foo%2Fbar"
4546
*/
4647
function encodePath(

__tests__/fixtures/test1/enums.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* This file was auto generated by @block65/openapi-codegen
3+
*
4+
* WARN: Do not edit directly.
5+
*
6+
* Generated on 2026-04-02T04:52:00.193Z
7+
*
8+
*/
9+
export const nullableStatus = ["active", "paused", "cancelled"] as const;
10+
export const accountTier = ["free", "pro", "enterprise"] as const;
11+
export const billingSubscriptionStatus = ["active", "inactive"] as const;
12+
export const billingSubscriptionInterval = ["monthly", "yearly"] as const;
13+
export const planSku = [
14+
"donotuse",
15+
"plasku1",
16+
"plasku2",
17+
"plasku3",
18+
"plasku4",
19+
] as const;
20+
export const paymentMethodBrand = [
21+
"amex",
22+
"diners",
23+
"discover",
24+
"jcb",
25+
"mastercard",
26+
"unionpay",
27+
"visa",
28+
"unknown",
29+
] as const;
30+
export const billingLocale = ["en"] as const;
31+
export const billingAccountType = ["standard", "agency", "reseller"] as const;
32+
export const currency = ["usd", "aud", "sgd", "myr", "gbp"] as const;
33+
export const billingAccountStatus = ["nominal", "delinquent"] as const;
34+
export const billingCountry = ["us", "au", "sg", "my", "gb"] as const;

__tests__/fixtures/test1/hono-valibot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* WARN: Do not edit directly.
55
*
6-
* Generated on 2026-03-17T13:15:38.356Z
6+
* Generated on 2026-04-02T04:52:00.193Z
77
*
88
*/
99

__tests__/fixtures/test1/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* WARN: Do not edit directly.
55
*
6-
* Generated on 2026-03-17T13:15:38.356Z
6+
* Generated on 2026-04-02T04:52:00.193Z
77
*
88
*/
99
import {

__tests__/fixtures/test1/types.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@
33
*
44
* WARN: Do not edit directly.
55
*
6-
* Generated on 2026-03-17T13:15:38.356Z
6+
* Generated on 2026-04-02T04:52:00.193Z
77
*
88
*/
99
import type { Jsonifiable, Jsonify } from "type-fest";
1010

1111
export type PromoCode = string;
12+
/** The API version */
13+
export type ApiVersion = "2024-01-01";
14+
export type MaxRetries = 3;
15+
export type DefaultEnabled = true;
16+
/** Optional notes field */
17+
export type NullableNotes = string | null;
18+
export type NullableDiscount = number | null;
19+
export type NullableStatus = "active" | "paused" | "cancelled" | null;
20+
export type AccountTier = "free" | "pro" | "enterprise";
1221
export type StripeId = string;
1322
export type DateTime = Jsonify<Date>;
1423
export type BillingSubscriptionStatus = "active" | "inactive";

__tests__/fixtures/test1/valibot.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* WARN: Do not edit directly.
55
*
6-
* Generated on 2026-03-17T13:15:38.356Z
6+
* Generated on 2026-04-02T04:52:00.193Z
77
*
88
*/
99
import * as v from "valibot";
@@ -14,6 +14,17 @@ export const promoCodeSchema = v.pipe(
1414
v.maxLength(256),
1515
v.regex(/\/^[A-Z0-9]$\//),
1616
);
17+
/** The API version */
18+
export const apiVersionSchema = v.literal("2024-01-01");
19+
export const maxRetriesSchema = v.literal(3);
20+
export const defaultEnabledSchema = v.literal(true);
21+
/** Optional notes field */
22+
export const nullableNotesSchema = v.nullable(v.string());
23+
export const nullableDiscountSchema = v.nullable(v.number());
24+
export const nullableStatusSchema = v.nullable(
25+
v.picklist(["active", "paused", "cancelled"]),
26+
);
27+
export const accountTierSchema = v.picklist(["free", "pro", "enterprise"]);
1728
export const stripeIdSchema = v.pipe(
1829
v.string(),
1930
v.minLength(11),

__tests__/nullables.test.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,75 @@ test("nullables", async () => {
2929

3030
expect(result.typesFile.getText()).toMatchSnapshot();
3131
});
32+
33+
test("top-level type array with null", async () => {
34+
const result = await processOpenApiDocument(
35+
"/tmp/like-you-know-whatever",
36+
{
37+
openapi: "3.1.0",
38+
info: {
39+
title: "Test",
40+
version: "1.0.0",
41+
},
42+
paths: {},
43+
components: {
44+
schemas: {
45+
NullableString: {
46+
type: ["string", "null"],
47+
},
48+
NullableStringEnum: {
49+
type: ["string", "null"],
50+
enum: ["active", "inactive"],
51+
},
52+
NullableInteger: {
53+
type: ["integer", "null"],
54+
},
55+
MultiType: {
56+
type: ["string", "number"],
57+
},
58+
},
59+
},
60+
},
61+
[],
62+
);
63+
64+
expect(result.typesFile.getText()).toMatchSnapshot();
65+
expect(result.valibotFile?.getText()).toMatchSnapshot();
66+
expect(result.enumsFile.getText()).toMatchSnapshot();
67+
});
68+
69+
test("const values", async () => {
70+
const result = await processOpenApiDocument(
71+
"/tmp/like-you-know-whatever",
72+
{
73+
openapi: "3.1.0",
74+
info: {
75+
title: "Test",
76+
version: "1.0.0",
77+
},
78+
paths: {},
79+
components: {
80+
schemas: {
81+
StringConst: {
82+
type: "string",
83+
const: "hello",
84+
},
85+
NumberConst: {
86+
type: "integer",
87+
const: 42,
88+
},
89+
BooleanConst: {
90+
const: true,
91+
},
92+
NullConst: {
93+
const: null,
94+
},
95+
},
96+
},
97+
},
98+
[],
99+
);
100+
101+
expect(result.typesFile.getText()).toMatchSnapshot();
102+
expect(result.valibotFile?.getText()).toMatchSnapshot();
103+
});

0 commit comments

Comments
 (0)