From 89d9f2ad9fce42399a8b091fd87701ae45700447 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 19:14:56 -0400 Subject: [PATCH] fix(cjson): start enum values at 1 so invalid/missing input is distinguishable (#2357) Co-Authored-By: gpt-5.6-sol via pi --- .../src/language/CJSON/CJSONRenderer.ts | 16 +++++++- test/unit/cjson-enum-default.test.ts | 37 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/unit/cjson-enum-default.test.ts diff --git a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts index c750529c98..442978d9e6 100644 --- a/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts +++ b/packages/quicktype-core/src/language/CJSON/CJSONRenderer.ts @@ -428,6 +428,7 @@ export class CJSONRenderer extends ConvenienceRenderer { const combinedName = allUpperWordStyle( this.sourcelikeToString(enumName), ); + let isFirst = true; this.forEachEnumCase(enumType, "none", (name, jsonName) => { if (enumValues !== undefined) { const [enumValue] = getAccessorName( @@ -444,11 +445,22 @@ export class CJSONRenderer extends ConvenienceRenderer { ",", ); } else { - this.emitLine(combinedName, "_", name, ","); + this.emitLine( + combinedName, + "_", + name, + isFirst ? " = 1," : ",", + ); } } else { - this.emitLine(combinedName, "_", name, ","); + this.emitLine( + combinedName, + "_", + name, + isFirst ? " = 1," : ",", + ); } + isFirst = false; }); }, "", diff --git a/test/unit/cjson-enum-default.test.ts b/test/unit/cjson-enum-default.test.ts new file mode 100644 index 0000000000..b2c02d60ee --- /dev/null +++ b/test/unit/cjson-enum-default.test.ts @@ -0,0 +1,37 @@ +import { InputData, JSONSchemaInput, quicktype } from "quicktype-core"; +import { describe, expect, test } from "vitest"; + +const schema = JSON.stringify({ + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + subscription: { + type: "string", + enum: ["state", "config", "heartbeat"], + }, + }, + required: ["subscription"], +}); + +async function cJSONOutput(): Promise { + const schemaInput = new JSONSchemaInput(undefined); + await schemaInput.addSource({ name: "TopLevel", schema }); + const inputData = new InputData(); + inputData.addInput(schemaInput); + + const result = await quicktype({ inputData, lang: "cjson" }); + return result.lines.join("\n"); +} + +describe("cJSON enum invalid value", () => { + test("does not collide with a real enumerator", async () => { + const output = await cJSONOutput(); + + expect(output).toContain(`enum Subscription { + SUBSCRIPTION_CONFIG = 1, + SUBSCRIPTION_HEARTBEAT, + SUBSCRIPTION_STATE, +};`); + expect(output).toContain("enum Subscription x = 0;"); + }); +});