Skip to content

feat(generator/golang): fold 3.1 const-based scalar oneOf/anyOf into enums - #617

Open
sloudel wants to merge 4 commits into
pb33f:mainfrom
sloudel:fix/const-scalar-enum
Open

sloudel wants to merge 4 commits into
pb33f:mainfrom
sloudel:fix/const-scalar-enum

Conversation

@sloudel

@sloudel sloudel commented Aug 14, 2026

Copy link
Copy Markdown

Problem

OpenAPI 3.1 expresses string/number/boolean enums as oneOf of scalar
const values, e.g.

PetStatus:
  oneOf:
    - const: available
      title: Available
    - const: pending
    - const: sold

The go model generator routes this through populateUnion and emits a
raw XXXXUnion{Raw json.RawMessage}; the enum values and names are lost,
and WithEnumConstants can generate nothing.

Fix

In populateUnion, before settling KindUnion, fold the union into a
KindEnum when every non-null variant is a scalar const (new helper
constScalarEnumFromVariants). Null-valued variants become Nullable,
object/array/union/disambiguation variants are left as unions.

Effects

before after
XXXXUnion{Raw json.RawMessage} type PetStatus string + typed constants

Tests

  • TestJSONSchema202012ConstScalarEnumVariants — const enum, string/int,
    anyOf, nullable, mixed->any, compile-check.
  • TestJSONSchemaSchemaObjectUnionNotEnum — object variants stay unions.

Verified: go build ./generator/..., go vet ./generator/golang/,
go test ./generator/golang/ — all green.

…enums

OpenAPI 3.1 expresses string/number/boolean enums as `oneOf` of scalar
`const` values (e.g. oneOf: [ {const: available}, {const: pending} ]).
The model generator treated those as raw json.RawMessage unions,
discarding the values, so enum constants were never emitted.

Recognize a union whose non-null variants are all scalar consts and build
it as a KindEnum instead (honouring null-of variants as nullable and mixed
value types as `any`), so `WithEnumConstants` can render typed aliases and
constants. Object/array/union/disambiguation variants that carry consts as
properties are left as unions.

Adds coverage for const enums, anyOf const, integer const enums, nullable
const enums, mixed const types, and guards the object union from being
collapsed into an enum.
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.87%. Comparing base (ca6ca73) to head (b14892b).
⚠️ Report is 14 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #617      +/-   ##
==========================================
+ Coverage   99.78%   99.87%   +0.09%     
==========================================
  Files         283      296      +13     
  Lines       34456    37221    +2765     
==========================================
+ Hits        34382    37175    +2793     
+ Misses         46       27      -19     
+ Partials       28       19       -9     
Flag Coverage Δ
unittests 99.87% <100.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…aths

Add a table-driven unit test that hits every veto branch of
constScalarEnumFromVariants: nil/empty variant lists, a nil member, a
variant without a const, declared object/array types, , nested
composition keywords, explicit enum, properties/patternProperties, items,
prefixItems, and a null-only list. Raises the function to 100% coverage so
the codecov patch gate stays green.
nullable = true
continue
}
if v.Const == nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: constScalarEnumFromVariants must reject non-scalar const nodes. Untyped mapping and sequence constants pass these guards and become string enums with empty constants, so valid object/array JSON cannot unmarshal. Check v.Const.Kind == yaml.ScalarNode (and supported scalar tags) after null handling, with public render regressions for untyped object and array constants.

@daveshanley

Copy link
Copy Markdown
Member

Follow-up: restrict folding to scalar const nodes and add untyped object/array regression coverage. Once updated, rerun go test ./generator/golang and go test ./....

Andrey Sorochinskiy added 2 commits September 22, 2026 15:51
…olding

P1: constScalarEnumFromVariants folded untyped object/array consts into a
KindEnum as an empty string enum, producing a type that cannot unmarshal
the declared object/array JSON. Reject any const that is not a scalar node
and not one of the enum-emittable scalar families (str/int/float/bool)
after null handling.

Adds public render regressions for untyped object and array constants and
unit coverage for the mapping/sequence guard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants