From 7bce4ac16ac8b4f9ead806c89e51af4ab01a48fd Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 21 Oct 2022 12:57:07 +0200 Subject: [PATCH] fix(forms): don't mutate validators array Fixes that the `AbstractControl` was mutating the validators arrays being passed into the constructor an helper methods like `setValidators`. Fixes #47827. --- packages/forms/src/model/abstract_model.ts | 22 +++++------ packages/forms/test/form_control_spec.ts | 44 ++++++++++++++++++++++ 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/packages/forms/src/model/abstract_model.ts b/packages/forms/src/model/abstract_model.ts index 015cb39ba54b0e..40383efbde1a10 100644 --- a/packages/forms/src/model/abstract_model.ts +++ b/packages/forms/src/model/abstract_model.ts @@ -372,7 +372,7 @@ export abstract class AbstractControl { expect(c.valid).toEqual(true); }); + it('should not mutate the validators array when overriding using setValidators', () => { + const control = new FormControl(''); + const originalValidators = [Validators.required]; + + control.setValidators(originalValidators); + control.addValidators(Validators.minLength(10)); + + expect(originalValidators.length).toBe(1); + }); + it('should override validators by setting `control.validator` field value', () => { const c = new FormControl(''); expect(c.valid).toEqual(true); @@ -357,6 +367,30 @@ describe('FormControl', () => { expect(c.hasValidator(Validators.required)).toEqual(false); }); + it('should not mutate the validators array when adding/removing sync validators', () => { + const originalValidators = [Validators.required]; + const control = new FormControl('', originalValidators); + + control.addValidators(Validators.min(10)); + expect(originalValidators.length).toBe(1); + + control.removeValidators(Validators.required); + expect(originalValidators.length).toBe(1); + }); + + it('should not mutate the validators array when adding/removing async validators', () => { + const firstValidator = asyncValidator('one'); + const secondValidator = asyncValidator('two'); + const originalValidators = [firstValidator]; + const control = new FormControl('', null, originalValidators); + + control.addAsyncValidators(secondValidator); + expect(originalValidators.length).toBe(1); + + control.removeAsyncValidators(firstValidator); + expect(originalValidators.length).toBe(1); + }); + it('should return false when checking presence of a validator not identical by reference', () => { const minValidator = Validators.min(5); @@ -518,6 +552,16 @@ describe('FormControl', () => { expect(c.valid).toEqual(true); })); + it('should not mutate the validators array when overriding using setValidators', () => { + const control = new FormControl(''); + const originalValidators = [asyncValidator('one')]; + + control.setAsyncValidators(originalValidators); + control.addAsyncValidators(asyncValidator('two')); + + expect(originalValidators.length).toBe(1); + }); + it('should override validators by setting `control.asyncValidator` field value', fakeAsync(() => { const c = new FormControl('');