From 5181d57bbdd1af0388c208fdf284ab33530298c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20K=C3=BCsgen?= Date: Wed, 22 Apr 2026 09:15:37 +0000 Subject: [PATCH] test: replaceFieldValue should clear onMount errors --- packages/form-core/tests/FormApi.spec.ts | 86 +++++++++++++++++++ .../tests/standardSchemaValidator.spec.ts | 51 +++++++++++ 2 files changed, 137 insertions(+) diff --git a/packages/form-core/tests/FormApi.spec.ts b/packages/form-core/tests/FormApi.spec.ts index eccd2e544..4e75e9733 100644 --- a/packages/form-core/tests/FormApi.spec.ts +++ b/packages/form-core/tests/FormApi.spec.ts @@ -366,6 +366,92 @@ describe('form api', () => { expect(form.getFieldValue('names')).toStrictEqual(['one', 'two', 'three']) }) + it("should clean onMount errors when replacing an array field's value", async () => { + const form = new FormApi({ + defaultValues: { + people: [ + { + firstName: '', + lastName: '', + }, + ], + }, + validators: { + onMount: ({ value }) => { + let fieldErrors: Record = {} + + value.people.map((x, index) => { + if (x.firstName.length < 3) { + fieldErrors[`people[${index}].firstName`] = + 'First name is too short' + } + + if (x.lastName.length < 3) { + fieldErrors[`people[${index}].lastName`] = + 'Last name is too short' + } + }) + + if (Object.keys(fieldErrors).length > 0) { + return { + fields: { ...fieldErrors }, + } + } + + return fieldErrors + }, + onChange: ({ value }) => { + let fieldErrors: Record = {} + + value.people.map((x, index) => { + if (x.firstName.length < 3) { + fieldErrors[`people[${index}].firstName`] = + 'First name is too short' + } + + if (x.lastName.length < 3) { + fieldErrors[`people[${index}].lastName`] = + 'Last name is too short' + } + }) + + if (Object.keys(fieldErrors).length > 0) { + return { + fields: { ...fieldErrors }, + } + } + + return fieldErrors + }, + }, + }) + form.mount() + + // Since validation runs through the field, a field must be mounted for that array + new FieldApi({ form, name: 'people' }).mount() + + await form.replaceFieldValue('people', 0, { + firstName: 'Chuck', + lastName: 'Norris', + }) + + expect(form.state.values).toStrictEqual({ + people: [ + { + firstName: 'Chuck', + lastName: 'Norris', + }, + ], + }) + expect.soft(form.state.fieldMetaBase['people']!.errorMap).toStrictEqual({}) + expect + .soft(form.state.fieldMetaBase['people[0].firstName']!.errorMap) + .toStrictEqual({}) + expect + .soft(form.state.fieldMetaBase['people[0].firstName']!.errorSourceMap) + .toStrictEqual({}) + }) + it("should run onChange validation when inserting an array field's value", () => { const form = new FormApi({ defaultValues: { diff --git a/packages/form-core/tests/standardSchemaValidator.spec.ts b/packages/form-core/tests/standardSchemaValidator.spec.ts index 463dac173..f1b668a4d 100644 --- a/packages/form-core/tests/standardSchemaValidator.spec.ts +++ b/packages/form-core/tests/standardSchemaValidator.spec.ts @@ -608,4 +608,55 @@ describe('standard schema validator', () => { ]) }) }) + + it("should clean onMount errors when replacing an array field's value", async () => { + const schema = z.object({ + people: z.array( + z.object({ + firstName: z.string().min(3), + lastName: z.string().min(3), + }), + ), + }) + + const form = new FormApi({ + defaultValues: { + people: [ + { + firstName: '', + lastName: '', + }, + ], + }, + validators: { + onMount: schema, + onChange: schema, + }, + }) + form.mount() + + // Since validation runs through the field, a field must be mounted for that array + new FieldApi({ form, name: 'people' }).mount() + + await form.replaceFieldValue('people', 0, { + firstName: 'Chuck', + lastName: 'Norris', + }) + + expect(form.state.values).toStrictEqual({ + people: [ + { + firstName: 'Chuck', + lastName: 'Norris', + }, + ], + }) + expect.soft(form.state.fieldMetaBase['people']!.errorMap).toStrictEqual({}) + expect + .soft(form.state.fieldMetaBase['people[0].firstName']!.errorMap) + .toStrictEqual({}) + expect + .soft(form.state.fieldMetaBase['people[0].firstName']!.errorSourceMap) + .toStrictEqual({}) + }) })