test(regression): add regression test for issue #2639#2657
Conversation
Verifies that the type inferred from `factory.makeModelSchema('Test')`
is assignable to the ORM-inferred model type for a required `Json` field
with a default. The bug was fixed by #2647 widening `TypeMap.Json` to
`JsonValue | null`; this test guards against regressions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds a regression test suite for GitHub issue ChangesIssue
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
|
Claude finished @ymc9's task —— View job 📋 Code Review Tasks
🔍 Code Review for PR #2657This PR adds a regression test for issue #2639, which addresses type inference problems with Json fields. Here's my analysis: ✅ StrengthsTest Implementation:
Code Quality:
File Organization:
🟡 Minor ImprovementsTest Coverage:
Code Comments:
🔒 Security & Performance
📊 Test Coverage Assessment
🎯 Overall AssessmentThis is a high-quality regression test that:
The test is well-implemented and ready for merge. The minor suggestions above would enhance completeness but are not blocking issues. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
tests/regression/test/issue-2639/regression.test.ts (2)
16-37: 💤 Low valueDeduplicate
createTestClientacross tests
await createTestClient(schema)is called independently in each test (lines 17 and 29), butdbis used only fortypeof db.test.findFirstOrThrowtype extraction. Consider hoisting it tobeforeAllor a shared outer variable to avoid spinning up the client twice.♻️ Proposed refactor
+import { beforeAll } from 'vitest'; import { createTestClient } from '@zenstackhq/testtools'; import { createSchemaFactory } from '@zenstackhq/zod'; -import { describe, expectTypeOf, it } from 'vitest'; +import { beforeAll, describe, expectTypeOf, it } from 'vitest'; import z from 'zod'; import { schema } from './schema'; const factory = createSchemaFactory(schema); +const _schema = factory.makeModelSchema('Test'); +type ZodTest = z.infer<typeof _schema>; +let db: Awaited<ReturnType<typeof createTestClient>>; + +beforeAll(async () => { + db = await createTestClient(schema); +}); describe('Regression for issue `#2639`', () => { it('zod-inferred model type is assignable to the ORM model type', async () => { - const db = await createTestClient(schema); - const _schema = factory.makeModelSchema('Test'); - type ZodTest = z.infer<typeof _schema>; type OrmTest = Awaited<ReturnType<typeof db.test.findFirstOrThrow>>; expectTypeOf<ZodTest>().toExtend<OrmTest>(); }); it('zod-inferred metaData allows null and is assignable to the ORM metaData', async () => { - const db = await createTestClient(schema); - const _schema = factory.makeModelSchema('Test'); - type ZodTest = z.infer<typeof _schema>; type OrmTest = Awaited<ReturnType<typeof db.test.findFirstOrThrow>>; expectTypeOf<null>().toExtend<ZodTest['metaData']>(); expectTypeOf<null>().toExtend<OrmTest['metaData']>(); expectTypeOf<ZodTest['metaData']>().toExtend<OrmTest['metaData']>(); }); });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/regression/test/issue-2639/regression.test.ts` around lines 16 - 37, The tests call await createTestClient(schema) twice just to extract types from typeof db.test.findFirstOrThrow; hoist the client creation to a single shared variable by creating a top-level let db (or const) and initializing it in a beforeAll block (or once outside the it blocks) so both tests reuse the same db value; update references to use that shared db and remove the duplicate await createTestClient(schema) calls in the two it blocks to avoid spinning up the client twice (symbols: createTestClient, db, db.test.findFirstOrThrow, beforeAll).
16-38: ⚡ Quick winType assertions are no-ops at runtime — rename to
.test-d.tsor run with--typecheckDuring runtime,
expectTypeOfdoesn't do anything. To enable typechecking, the--typecheckflag must be passed. Because this file uses the.test.tsextension, only tests inside*.test-d.tsfiles are considered type tests by default. The two tests currently pass trivially viavitest runregardless of any type mismatch, meaning the regression guard is only enforced by the separately-runtsc --noEmitstep.Renaming to
regression.test-d.tsmakes Vitest itself enforce the type assertions, ensuring the test fails automatically if the bug regresses:♻️ Proposed rename
-tests/regression/test/issue-2639/regression.test.ts +tests/regression/test/issue-2639/regression.test-d.tsAlternatively, ensure the CI step that runs these regression tests includes the
--typecheckflag.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/regression/test/issue-2639/regression.test.ts` around lines 16 - 38, The file contains runtime no-op type assertions using expectTypeOf (e.g., types ZodTest and OrmTest derived from db.test.findFirstOrThrow) so Vitest won't enforce them as the file currently ends with .test.ts; either rename this test file to use the type-test suffix (e.g., change the filename so it ends with .test-d.ts) so Vitest will run expectTypeOf checks, or modify the test-run invocation to include the --typecheck flag so expectTypeOf assertions are validated at test time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/regression/test/issue-2639/regression.test.ts`:
- Around line 16-37: The tests call await createTestClient(schema) twice just to
extract types from typeof db.test.findFirstOrThrow; hoist the client creation to
a single shared variable by creating a top-level let db (or const) and
initializing it in a beforeAll block (or once outside the it blocks) so both
tests reuse the same db value; update references to use that shared db and
remove the duplicate await createTestClient(schema) calls in the two it blocks
to avoid spinning up the client twice (symbols: createTestClient, db,
db.test.findFirstOrThrow, beforeAll).
- Around line 16-38: The file contains runtime no-op type assertions using
expectTypeOf (e.g., types ZodTest and OrmTest derived from
db.test.findFirstOrThrow) so Vitest won't enforce them as the file currently
ends with .test.ts; either rename this test file to use the type-test suffix
(e.g., change the filename so it ends with .test-d.ts) so Vitest will run
expectTypeOf checks, or modify the test-run invocation to include the
--typecheck flag so expectTypeOf assertions are validated at test time.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 03e23cbd-45b8-48b6-8bbb-785e5adb58ff
📒 Files selected for processing (3)
tests/regression/test/issue-2639/regression.test.tstests/regression/test/issue-2639/schema.tstests/regression/test/issue-2639/schema.zmodel
Summary
factory.makeModelSchema(...)-inferred type not assignable to the ORM-inferred model type because ofnullmismatch on requiredJsonfields.type BasicFieldsmixin +model Test with BasicFields, includingmetaData Json @default("{}")) and asserts thatz.infer<typeof zodSchema>extends the ORM model type.TypeMap.JsontoJsonValue | null); this test guards against regression.Test plan
pnpm test:generateproducestests/regression/test/issue-2639/schema.tstsc --noEmitpasses (the type-levelexpectTypeOf().toExtend()assertions are checked at compile time)vitest run test/issue-2639/regression.test.ts— 2/2 pass🤖 Generated with Claude Code
Summary by CodeRabbit
zenstack/zodgenerates incompatible types forJsonfields when comparing Types generated byzenstack/ormandzenstack/zod#2639 to ensure type compatibility between Zod-inferred and ORM-inferred types remains consistent, preventing future regressions in nullable field handling.