diff --git a/packages/forms/signals/test/web/field_directive.spec.ts b/packages/forms/signals/test/web/field_directive.spec.ts
index 14dc8eef6c3..1d38f5abe9f 100644
--- a/packages/forms/signals/test/web/field_directive.spec.ts
+++ b/packages/forms/signals/test/web/field_directive.spec.ts
@@ -44,6 +44,7 @@ import {
provideSignalFormsConfig,
readonly,
required,
+ requiredError,
validateAsync,
type DisabledReason,
type FieldTree,
@@ -352,6 +353,67 @@ describe('field directive', () => {
});
});
+ describe('errors', () => {
+ it('should bind to custom control', () => {
+ @Component({
+ selector: 'custom-control',
+ template: '',
+ })
+ class CustomControl implements FormValueControl {
+ readonly value = model.required();
+ readonly errors = input.required[]>();
+ }
+
+ @Component({
+ template: ` `,
+ imports: [CustomControl, Field],
+ })
+ class TestCmp {
+ readonly data = signal('');
+ readonly f = form(this.data, (p) => {
+ required(p);
+ });
+ readonly customControl = viewChild.required(CustomControl);
+ }
+
+ const comp = act(() => TestBed.createComponent(TestCmp)).componentInstance;
+ expect(comp.customControl().errors()).toEqual([requiredError({fieldTree: comp.f})]);
+
+ act(() => comp.f().value.set('valid'));
+ expect(comp.customControl().errors()).toEqual([]);
+ });
+
+ it('should be reset when field changes on custom control', () => {
+ @Component({selector: 'custom-control', template: ``})
+ class CustomControl implements FormValueControl {
+ readonly value = model.required();
+ readonly errors = input.required[]>();
+ }
+
+ @Component({
+ imports: [Field, CustomControl],
+ template: ``,
+ })
+ class TestCmp {
+ readonly f = form(signal({x: '', y: ''}), (p) => {
+ required(p.x);
+ });
+ readonly field = signal(this.f.x);
+ readonly customControl = viewChild.required(CustomControl);
+ }
+
+ const fixture = act(() => TestBed.createComponent(TestCmp));
+ const component = fixture.componentInstance;
+
+ expect(component.customControl().errors()).toEqual([
+ requiredError({fieldTree: component.f.x}),
+ ]);
+
+ act(() => component.field.set(component.f.y));
+ expect(component.customControl().errors()).toEqual([]);
+ });
+ });
+
describe('hidden', () => {
it('should bind to a custom control', () => {
@Component({selector: 'custom-control', template: ``})