feat: enhance fakeNonOptional to unwrap multiple inner optional layers and add test for nonoptional chain - #658
feat: enhance fakeNonOptional to unwrap multiple inner optional layers and add test for nonoptional chain#658InfiniteXyy wants to merge 1 commit into
Conversation
…s and add test for nonoptional chain
There was a problem hiding this comment.
Pull request overview
This PR updates the v4 Zod nonoptional faker behavior so fake() won’t accidentally generate undefined when nonoptional() is applied to a schema that still contains nested optional wrappers, and adds a regression test for an optional→nonoptional chain.
Changes:
- Enhance
fakeNonOptionalto unwrap multiple nested$ZodOptionallayers before faking the inner schema. - Add a
nonoptional chaintest to ensurez.string().optional().nonoptional()fakes to astring.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| tests/v4/zod.test.ts | Adds a regression test for optional→nonoptional chaining. |
| src/v4/internals/schemas/non-optional.ts | Unwraps repeated optional layers when faking nonoptional schemas. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| test('nonoptional chain', { repeats: 5 }, () => { | ||
| const schema = z.string().optional().nonoptional() | ||
| const data = fake(schema) |
There was a problem hiding this comment.
The new test relies on randomness (via faker's boolean in optional handling) to catch the regression, so it may still pass even if the bug is reintroduced (i.e., it can be flaky/ineffective as a regression test). Consider making it deterministic by seeding (seed(...)) or stubbing getFaker().datatype.boolean() for the duration of the test, and optionally asserting schema.parse(data) as well.
| test('nonoptional chain', { repeats: 5 }, () => { | |
| const schema = z.string().optional().nonoptional() | |
| const data = fake(schema) | |
| test('nonoptional chain', { repeats: 5 }, () => { | |
| faker.seed(123) | |
| const schema = z.string().optional().nonoptional() | |
| const data = fake(schema) | |
| schema.parse(data) |
| ): Infer<T> { | ||
| return rootFake(schema._zod.def.innerType, context) | ||
| // Unwrap multiple inner optional layers if they exist | ||
| // A known issue is that this cannot handle `z.string().optional().nullable().nonoptional()`, But this should still solve most common cases |
There was a problem hiding this comment.
The inline comment has a grammatical issue: the clause after the comma should not start with a capitalized “But”, and it would read clearer as a separate sentence. Please adjust the punctuation/capitalization so the comment is easier to read.
| // A known issue is that this cannot handle `z.string().optional().nullable().nonoptional()`, But this should still solve most common cases | |
| // A known issue is that this cannot handle `z.string().optional().nullable().nonoptional()`. This should still solve most common cases. |
Hi, first of all thanks for the great lib!
We encountered a problem while using it. We always extend a new schema based on an existing schema, but we run into issues when generating
nonoptional.Specifically,
nonoptionaldoes not work (if the schema itself is optional). I tried to fix this issue; could you help take a look?Example
My fix still has potential issues. if the schema looks like
z.string().optional().nullable().nonoptional()But this is quite uncommon, and I feel like it's not easy to solve this