fix(mock): emit boolean enum literals instead of random datatype.boolean() - #3428
Conversation
…ean()
The MSW mock generator's boolean branch in scalar.ts ignored `item.enum`
and unconditionally emitted `faker.datatype.boolean()`. For schemas like
`oneOf [{ success: enum [true] }, { success: enum [false], failReason }]`
this broke the discriminator: the randomly-picked union variant set
`success` to a random boolean, so the mock no longer matched the
TypeScript literal type its branch enforced (`success: true` /
`success: false`).
Route boolean through the same `getEnum` helper as number/string so
`enum: [true]` emits `faker.helpers.arrayElement([true] as const)` and
`enum: [false]` likewise, keeping the mock value pinned to the chosen
branch's literal.
The type-generation half of orval-labs#1775 was already addressed by orval-labs#3159's
boolean-enum branch in `packages/core/src/getters/scalar.ts`; this
change closes the mock-side gap and adds a focused regression covering
the exact orval-labs#1775 shape.
Closes orval-labs#1775
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThis PR fixes boolean enum mock generation in MSW. The scalar Faker getter now detects and emits boolean enums via the widened ChangesBoolean Enum Discriminator Fix
Sequence DiagramsequenceDiagram
participant getMockScalar
participant getEnum
participant Faker
participant MSWHandler
participant TypeOutput
getMockScalar->>getMockScalar: Detect item.enum on boolean
getMockScalar->>getEnum: Call with type='boolean'
getEnum->>getEnum: Generate enum import expression
getEnum-->>getMockScalar: Return enum import list
getMockScalar-->>TypeOutput: Return enums + imports
MSWHandler->>Faker: faker.helpers.arrayElement
Faker-->>MSWHandler: Select [true, false] as const
MSWHandler-->>MSWHandler: Preserve literal boolean in mock
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a regression test + fixtures for issue-1775 and updates the mock faker scalar generation so boolean enum values are preserved (rather than random booleans), including for allOf + oneOf compositions.
Changes:
- Introduces a new OpenAPI spec fixture for issue-1775 and wires it into the default test config.
- Adds a generation test asserting boolean enum literal preservation in both models and mocks.
- Updates mock scalar generation to route boolean enums through
getEnum, updating snapshots accordingly.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/specifications/issue-1775.yaml | Adds a spec reproducing the allOf + oneOf boolean-enum case. |
| tests/configs/default.config.ts | Registers the new issue-1775 fixture for generation. |
| tests/api-generation.spec.ts | Adds a regression test asserting model + mock output for issue-1775. |
| tests/snapshots/default/nullable-oneof-enums/endpoints.ts | Updates snapshot reflecting boolean enums generated via arrayElement([...]). |
| tests/snapshots/default/issue-1775/model/putApiOrderLimit200Item.ts | Adds snapshot for the generated model type for issue-1775. |
| tests/snapshots/default/issue-1775/model/index.ts | Adds snapshot index for the new model folder. |
| tests/snapshots/default/issue-1775/endpoints.ts | Adds snapshot for generated endpoint + mock handler for issue-1775. |
| packages/mock/src/faker/getters/scalar.ts | Changes boolean scalar mock generation to honor enum via getEnum. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| case 'boolean': { | ||
| let value = 'faker.datatype.boolean()'; | ||
| if ('const' in item) { | ||
| const booleanImports: GeneratorImport[] = []; | ||
| if (item.enum) { | ||
| value = getEnum( | ||
| item, | ||
| booleanImports, | ||
| context, | ||
| existingReferencedProperties, | ||
| 'boolean', | ||
| ); | ||
| } else if ('const' in item) { | ||
| value = JSON.stringify(item.const); | ||
| } | ||
| return { | ||
| value, | ||
| imports: [], | ||
| enums: item.enum, | ||
| imports: booleanImports, | ||
| name: item.name, | ||
| }; | ||
| } |
There was a problem hiding this comment.
This boolean branch deliberately mirrors the sibling number/integer (L221) and string (L362) cases, which also check item.enum before 'const' in item. So in the (very unusual) shape enum + const together, all primitive types behave the same way today — the change here doesn't introduce asymmetry, it preserves it.
If const should take precedence, that's a repo-wide invariant that belongs in a dedicated PR touching all three primitive branches at once (with snapshot churn across many specs), not a one-off flip on the boolean case. Marking out of scope for #1775 — keeping consistency with the established pattern.
| let value = 'faker.datatype.boolean()'; | ||
| if ('const' in item) { | ||
| const booleanImports: GeneratorImport[] = []; | ||
| if (item.enum) { |
There was a problem hiding this comment.
The sibling number/integer (L221) and string (L362) branches both use the same if (item.enum) truthiness check (not item.enum?.length), and getEnum itself has if (!item.enum) return '' rather than a length guard. So an enum: [] would degrade identically across all primitives today — boolean isn't a new outlier. (enum: [] is also a malformed schema that the OpenAPI validator should reject before reaching this getter.)
If empty-enum handling should fall back to the default generator, that belongs in getEnum (or as a coordinated change across all primitive branches), not as a one-off boolean tweak. Keeping the boolean branch symmetric with its siblings for #1775's scope.
The MSW mock generator's
booleanbranch inpackages/mock/src/faker/getters/scalar.tsignoreditem.enumand unconditionally emittedfaker.datatype.boolean(). For a schema shaped likethe generated mock picked a
oneOfbranch withfaker.helpers.arrayElementand then setsuccessto a random boolean inside that branch — so the value no longer matched the discriminated-union literal (success: true/success: false) its branch enforced.Routing
booleanthrough the samegetEnumhelper asnumber/stringproducesso each branch's
successstays pinned to its literal regardless of which onearrayElementselects.Notes
success: booleaninstead ofsuccess: false) was already addressed by fix(core): boolean discriminated unions generate literal true/false instead of boolean #3159's boolean-enum branch inpackages/core/src/getters/scalar.ts. The original report's third symptom —{ … }, { … }bare object literals in the mock body — was likewise fixed in the meantime bycombine.ts's spread handling. This PR closes the remaining mock-side gap.tests/__snapshots__/default/nullable-oneof-enums/endpoints.ts):enum: [true, false]→arrayElement([true, false] as const)(cosmetic; semantically identical tofaker.datatype.boolean()).enum: [true]→arrayElement([true] as const)(real fix; previously emitted a random boolean despite the single-value enum).tests/specifications/issue-1775.yaml+ a focusedtest()intests/api-generation.spec.tsthat fails with a targeted message on regression rather than via a full-file snapshot diff (matching the style of the recentissue-1879/issue-1935regression tests).Closes #1775
Summary by CodeRabbit
Bug Fixes
Tests