From 245ca3d843d61b32e752de13229b099c7158a777 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 18:16:11 -0400 Subject: [PATCH 1/5] fix(naming): preserve word-initial acronyms in pascal-upper-acronyms style (#1363) Co-Authored-By: gpt-5.6-sol via pi --- .../quicktype-core/src/support/Strings.ts | 5 ++- test/fixtures.ts | 23 +++++++++++++ test/fixtures/cplusplus/acronym_names.cpp | 6 ++++ test/inputs/schema/upper-acronym-names.1.json | 13 ++++++++ test/inputs/schema/upper-acronym-names.schema | 32 +++++++++++++++++++ test/languages.ts | 10 ++++++ 6 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/cplusplus/acronym_names.cpp create mode 100644 test/inputs/schema/upper-acronym-names.1.json create mode 100644 test/inputs/schema/upper-acronym-names.schema diff --git a/packages/quicktype-core/src/support/Strings.ts b/packages/quicktype-core/src/support/Strings.ts index e9d9a82ed4..080b151e40 100644 --- a/packages/quicktype-core/src/support/Strings.ts +++ b/packages/quicktype-core/src/support/Strings.ts @@ -619,10 +619,13 @@ export function makeNameStyle( switch (namingStyle) { case "pascal": - case "pascal-upper-acronyms": firstWordAcronymStyle = firstUpperWordStyle; firstWordStyle = firstWordAcronymStyle; break; + case "pascal-upper-acronyms": + firstWordStyle = firstUpperWordStyle; + firstWordAcronymStyle = allUpperWordStyle; + break; case "camel": case "camel-upper-acronyms": firstWordAcronymStyle = allLowerWordStyle; diff --git a/test/fixtures.ts b/test/fixtures.ts index dece181ef6..e3fdc7fed0 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -823,6 +823,28 @@ class JSONSchemaFixture extends LanguageFixture { } } +class CPlusPlusUpperAcronymsFixture extends JSONSchemaFixture { + constructor() { + super( + languages.CPlusPlusUpperAcronymsLanguage, + "schema-cplusplus-upper-acronyms", + ); + } + + runForName(name: string): boolean { + return this.name === name; + } + + getSamples(sources: string[]): { priority: Sample[]; others: Sample[] } { + return samplesFromSources( + sources, + ["test/inputs/schema/upper-acronym-names.schema"], + [], + "schema", + ); + } +} + type TreeSitterTarget = { displayName: string; language: languages.Language; @@ -1604,6 +1626,7 @@ export const allFixtures: Fixture[] = [ new JSONSchemaFixture(languages.GoLanguage), new JSONSchemaFixture(languages.CJSONLanguage), new JSONSchemaFixture(languages.CPlusPlusLanguage), + new CPlusPlusUpperAcronymsFixture(), new JSONSchemaFixture(languages.RustLanguage), new JSONSchemaFixture(languages.RubyLanguage), new JSONSchemaFixture(languages.PythonLanguage), diff --git a/test/fixtures/cplusplus/acronym_names.cpp b/test/fixtures/cplusplus/acronym_names.cpp new file mode 100644 index 0000000000..6a8c61e995 --- /dev/null +++ b/test/fixtures/cplusplus/acronym_names.cpp @@ -0,0 +1,6 @@ +#include "TopLevel.hpp" + +void use_upper_acronym_names( + quicktype::SCUBAWaypoint *, + quicktype::SCUBAManeuver *, + quicktype::IDCardHTTP *) {} diff --git a/test/inputs/schema/upper-acronym-names.1.json b/test/inputs/schema/upper-acronym-names.1.json new file mode 100644 index 0000000000..81f8a054b2 --- /dev/null +++ b/test/inputs/schema/upper-acronym-names.1.json @@ -0,0 +1,13 @@ +[ + { + "location": { + "latitude": 43.0, + "longitude": 16.0 + }, + "depth": 12.5, + "maneuver": "LEVEL", + "idCard": { + "value": "HTTP" + } + } +] diff --git a/test/inputs/schema/upper-acronym-names.schema b/test/inputs/schema/upper-acronym-names.schema new file mode 100644 index 0000000000..32e0f771e0 --- /dev/null +++ b/test/inputs/schema/upper-acronym-names.schema @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "description": "An array of SCUBA waypoints", + "type": "array", + "items": { + "title": "SCUBAWaypoint", + "type": "object", + "properties": { + "location": { + "title": "Point", + "type": "object", + "properties": { + "latitude": { "type": "number" }, + "longitude": { "type": "number" } + } + }, + "depth": { "type": "number" }, + "maneuver": { + "title": "SCUBAManeuver", + "type": "string", + "enum": ["ASCENT", "DESCENT", "LEVEL"] + }, + "idCard": { + "title": "IDCardHTTP", + "type": "object", + "properties": { + "value": { "type": "string" } + } + } + } + } +} diff --git a/test/languages.ts b/test/languages.ts index 6bcfd43611..acc43eb389 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -753,6 +753,16 @@ export const CPlusPlusLanguage: Language = { sourceFiles: ["src/language/CPlusPlus/index.ts"], }; +export const CPlusPlusUpperAcronymsLanguage: Language = { + ...CPlusPlusLanguage, + compileCommand: + "g++ -O0 -o quicktype -std=c++17 main.cpp acronym_names.cpp", + rendererOptions: { + "type-style": "pascal-case-upper-acronyms", + "member-style": "camel-case-upper-acronyms", + }, +}; + export const ElmLanguage: Language = { name: "elm", base: "test/fixtures/elm", From a23f3fd31d12dca39676532941219b92579f68a4 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 19:38:00 -0400 Subject: [PATCH 2/5] test: add missing fixture cases for upper-acronym-names.schema (#3036) Co-Authored-By: Claude --- .../schema/upper-acronym-names.1.fail.enum.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 test/inputs/schema/upper-acronym-names.1.fail.enum.json diff --git a/test/inputs/schema/upper-acronym-names.1.fail.enum.json b/test/inputs/schema/upper-acronym-names.1.fail.enum.json new file mode 100644 index 0000000000..42ea1fb4ab --- /dev/null +++ b/test/inputs/schema/upper-acronym-names.1.fail.enum.json @@ -0,0 +1,13 @@ +[ + { + "location": { + "latitude": 43.0, + "longitude": 16.0 + }, + "depth": 12.5, + "maneuver": "BACKFLIP", + "idCard": { + "value": "HTTP" + } + } +] From b15c7baa5b4198fab1e8737f94f4a6ba2eeb93aa Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 20:09:01 -0400 Subject: [PATCH 3/5] test: make upper-acronym-names schema a top-level object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upper-acronym-names.schema fixture was a top-level array, which several language drivers can't handle: kotlinx renders top-level arrays as `typealias TopLevel = JsonArray` (doesn't compile), and the typescript-zod driver can't locate the top-level schema when the array's titled item type is named `SCUBAWaypointSchema` instead of `TopLevelElementSchema` ("No schema found"). The CI failure surfaced on kotlinx first; fail-fast hid the rest. The top-level array is incidental to the acronym-naming bug being tested (word-initial acronyms in type names). Wrapping the waypoints in a top-level object exercises the identical naming path — C++ still emits `SCUBAWaypoint`/`SCUBAManeuver`/`IDCardHTTP` with the fix and downcases them without it — while working across all language drivers. Co-Authored-By: Claude --- .../upper-acronym-names.1.fail.enum.json | 26 +++++----- test/inputs/schema/upper-acronym-names.1.json | 26 +++++----- test/inputs/schema/upper-acronym-names.schema | 51 ++++++++++--------- 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/test/inputs/schema/upper-acronym-names.1.fail.enum.json b/test/inputs/schema/upper-acronym-names.1.fail.enum.json index 42ea1fb4ab..711ae90282 100644 --- a/test/inputs/schema/upper-acronym-names.1.fail.enum.json +++ b/test/inputs/schema/upper-acronym-names.1.fail.enum.json @@ -1,13 +1,15 @@ -[ - { - "location": { - "latitude": 43.0, - "longitude": 16.0 - }, - "depth": 12.5, - "maneuver": "BACKFLIP", - "idCard": { - "value": "HTTP" +{ + "waypoints": [ + { + "location": { + "latitude": 43.0, + "longitude": 16.0 + }, + "depth": 12.5, + "maneuver": "BACKFLIP", + "idCard": { + "value": "HTTP" + } } - } -] + ] +} diff --git a/test/inputs/schema/upper-acronym-names.1.json b/test/inputs/schema/upper-acronym-names.1.json index 81f8a054b2..52372eed94 100644 --- a/test/inputs/schema/upper-acronym-names.1.json +++ b/test/inputs/schema/upper-acronym-names.1.json @@ -1,13 +1,15 @@ -[ - { - "location": { - "latitude": 43.0, - "longitude": 16.0 - }, - "depth": 12.5, - "maneuver": "LEVEL", - "idCard": { - "value": "HTTP" +{ + "waypoints": [ + { + "location": { + "latitude": 43.0, + "longitude": 16.0 + }, + "depth": 12.5, + "maneuver": "LEVEL", + "idCard": { + "value": "HTTP" + } } - } -] + ] +} diff --git a/test/inputs/schema/upper-acronym-names.schema b/test/inputs/schema/upper-acronym-names.schema index 32e0f771e0..03210c4557 100644 --- a/test/inputs/schema/upper-acronym-names.schema +++ b/test/inputs/schema/upper-acronym-names.schema @@ -1,30 +1,35 @@ { "$schema": "http://json-schema.org/draft-06/schema#", - "description": "An array of SCUBA waypoints", - "type": "array", - "items": { - "title": "SCUBAWaypoint", - "type": "object", - "properties": { - "location": { - "title": "Point", + "description": "A SCUBA dive log with waypoints", + "type": "object", + "properties": { + "waypoints": { + "type": "array", + "items": { + "title": "SCUBAWaypoint", "type": "object", "properties": { - "latitude": { "type": "number" }, - "longitude": { "type": "number" } - } - }, - "depth": { "type": "number" }, - "maneuver": { - "title": "SCUBAManeuver", - "type": "string", - "enum": ["ASCENT", "DESCENT", "LEVEL"] - }, - "idCard": { - "title": "IDCardHTTP", - "type": "object", - "properties": { - "value": { "type": "string" } + "location": { + "title": "Point", + "type": "object", + "properties": { + "latitude": { "type": "number" }, + "longitude": { "type": "number" } + } + }, + "depth": { "type": "number" }, + "maneuver": { + "title": "SCUBAManeuver", + "type": "string", + "enum": ["ASCENT", "DESCENT", "LEVEL"] + }, + "idCard": { + "title": "IDCardHTTP", + "type": "object", + "properties": { + "value": { "type": "string" } + } + } } } } From c0b8c24b437f7bbc099be4ecd3c7dae59c81a43e Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Mon, 20 Jul 2026 20:54:29 -0400 Subject: [PATCH 4/5] fix CI: skip enum-value fail sample for upper-acronym-names schema (#1363) cjson's generated deserializer does not validate enum values (a known, already-documented limitation shared with enum.schema, enum-large.schema, etc.), so the new upper-acronym-names.schema's .1.fail.enum.json sample round-trips instead of being rejected. Add it to the shared skipsEnumValueValidation list, matching the identical precedent in commit 349bc781 for all-of-additional-properties-false.schema. Co-Authored-By: gpt-5.6-sol via pi --- test/languages.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/languages.ts b/test/languages.ts index acc43eb389..18cb0713a9 100644 --- a/test/languages.ts +++ b/test/languages.ts @@ -25,6 +25,7 @@ const skipsEnumValueValidation = [ "enum-large.schema", "optional-enum.schema", "const-non-string.schema", + "upper-acronym-names.schema", ]; // The language makes no int/double distinction in unions (e.g. an integer is From 23cfa4af755d4712dd9e70e1a32f86c1a99f2c55 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Tue, 21 Jul 2026 11:28:02 -0400 Subject: [PATCH 5/5] fix(test): wire up and repair C++ upper-acronyms fixture The schema-cplusplus-upper-acronyms fixture was never listed in the CI matrix, so it never ran, and acronym_names.cpp included the multi-source header TopLevel.hpp while the fixture generates single-source output (quicktype.hpp), causing a compile failure when the fixture is actually executed. Include the generated single-source header and add the fixture to the cplusplus CI matrix entry so the acronym-preservation check runs. Co-Authored-By: Claude --- .github/workflows/test-pr.yaml | 2 +- test/fixtures/cplusplus/acronym_names.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 7001f80230..09c28329dd 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -40,7 +40,7 @@ jobs: - golang,schema-golang - cjson,schema-cjson - cjson-default,cjson-multi-header,cjson-multi-split - - cplusplus,schema-cplusplus + - cplusplus,schema-cplusplus,schema-cplusplus-upper-acronyms - flow,schema-flow - java,schema-java - python,schema-python diff --git a/test/fixtures/cplusplus/acronym_names.cpp b/test/fixtures/cplusplus/acronym_names.cpp index 6a8c61e995..613aef98e6 100644 --- a/test/fixtures/cplusplus/acronym_names.cpp +++ b/test/fixtures/cplusplus/acronym_names.cpp @@ -1,4 +1,4 @@ -#include "TopLevel.hpp" +#include "quicktype.hpp" void use_upper_acronym_names( quicktype::SCUBAWaypoint *,