From eef9512ce6b8b72f8753d2964304745d621cf0d7 Mon Sep 17 00:00:00 2001 From: choeller Date: Mon, 27 Jun 2016 00:52:50 +0200 Subject: [PATCH] fix(forms): async validator-directives process Observables correctly (#8186) Closes #/8022 --- .../directives/normalize_validator.ts | 2 +- .../test/forms-deprecated/validators_spec.ts | 25 ++++++++++++++++++ .../src/directives/normalize_validator.ts | 2 +- .../@angular/forms/test/validators_spec.ts | 26 ++++++++++++++++++- 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/modules/@angular/common/src/forms-deprecated/directives/normalize_validator.ts b/modules/@angular/common/src/forms-deprecated/directives/normalize_validator.ts index 0aad19ef38..1fa9adf3df 100644 --- a/modules/@angular/common/src/forms-deprecated/directives/normalize_validator.ts +++ b/modules/@angular/common/src/forms-deprecated/directives/normalize_validator.ts @@ -20,7 +20,7 @@ export function normalizeValidator(validator: ValidatorFn | Validator): Validato export function normalizeAsyncValidator(validator: AsyncValidatorFn | Validator): AsyncValidatorFn { if ((validator).validate !== undefined) { - return (c: AbstractControl) => Promise.resolve((validator).validate(c)); + return (c: AbstractControl) => (validator).validate(c); } else { return validator; } diff --git a/modules/@angular/common/test/forms-deprecated/validators_spec.ts b/modules/@angular/common/test/forms-deprecated/validators_spec.ts index 4926007b80..0c1404a2af 100644 --- a/modules/@angular/common/test/forms-deprecated/validators_spec.ts +++ b/modules/@angular/common/test/forms-deprecated/validators_spec.ts @@ -9,9 +9,11 @@ import {AbstractControl, Control, ControlArray, ControlGroup, Validators} from '@angular/common/src/forms-deprecated'; import {fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal'; +import {Observable} from 'rxjs/Observable'; import {EventEmitter, ObservableWrapper, TimerWrapper} from '../../src/facade/async'; import {PromiseWrapper} from '../../src/facade/promise'; +import {normalizeAsyncValidator} from '../../src/forms-deprecated/directives/normalize_validator'; export function main() { function validator(key: string, error: any) { @@ -22,6 +24,18 @@ export function main() { } } + class AsyncValidatorDirective { + constructor(private expected: string, private error: any) {} + + validate(c: any): {[key: string]: any;} { + return Observable.create((obs: any) => { + const error = this.expected !== c.value ? this.error : null; + obs.next(error); + obs.complete(); + }); + } + } + describe('Validators', () => { describe('required', () => { it('should error on an empty string', @@ -88,6 +102,17 @@ export function main() { }); }); + it('should normalize and evaluate async validator-directives correctly', fakeAsync(() => { + const c = Validators.composeAsync( + [normalizeAsyncValidator(new AsyncValidatorDirective('expected', {'one': true}))]); + + let value: any = null; + c(new Control()).then((v: any) => value = v); + tick(1); + + expect(value).toEqual({'one': true}); + })); + describe('compose', () => { it('should return null when given null', () => { expect(Validators.compose(null)).toBe(null); }); diff --git a/modules/@angular/forms/src/directives/normalize_validator.ts b/modules/@angular/forms/src/directives/normalize_validator.ts index 0aad19ef38..1fa9adf3df 100644 --- a/modules/@angular/forms/src/directives/normalize_validator.ts +++ b/modules/@angular/forms/src/directives/normalize_validator.ts @@ -20,7 +20,7 @@ export function normalizeValidator(validator: ValidatorFn | Validator): Validato export function normalizeAsyncValidator(validator: AsyncValidatorFn | Validator): AsyncValidatorFn { if ((validator).validate !== undefined) { - return (c: AbstractControl) => Promise.resolve((validator).validate(c)); + return (c: AbstractControl) => (validator).validate(c); } else { return validator; } diff --git a/modules/@angular/forms/test/validators_spec.ts b/modules/@angular/forms/test/validators_spec.ts index 9b341b0ab6..1248de61dc 100644 --- a/modules/@angular/forms/test/validators_spec.ts +++ b/modules/@angular/forms/test/validators_spec.ts @@ -9,7 +9,9 @@ import {fakeAsync, flushMicrotasks, tick} from '@angular/core/testing'; import {afterEach, beforeEach, ddescribe, describe, expect, iit, it, xit} from '@angular/core/testing/testing_internal'; import {AbstractControl, FormControl, Validators} from '@angular/forms'; +import {Observable} from 'rxjs/Observable'; +import {normalizeAsyncValidator} from '../src/directives/normalize_validator'; import {EventEmitter, ObservableWrapper, TimerWrapper} from '../src/facade/async'; import {PromiseWrapper} from '../src/facade/promise'; @@ -22,6 +24,18 @@ export function main() { } } + class AsyncValidatorDirective { + constructor(private expected: string, private error: any) {} + + validate(c: any): {[key: string]: any;} { + return Observable.create((obs: any) => { + const error = this.expected !== c.value ? this.error : null; + obs.next(error); + obs.complete(); + }); + } + } + describe('Validators', () => { describe('required', () => { it('should error on an empty string', @@ -147,12 +161,22 @@ export function main() { expect(value).toEqual({'one': true, 'two': true}); })); + it('should normalize and evaluate async validator-directives correctly', fakeAsync(() => { + const c = Validators.composeAsync( + [normalizeAsyncValidator(new AsyncValidatorDirective('expected', {'one': true}))]); + + let value: any = null; + c(new FormControl()).then((v: any) => value = v); + tick(1); + + expect(value).toEqual({'one': true}); + })); + it('should return null when no errors', fakeAsync(() => { var c = Validators.composeAsync([asyncValidator('expected', {'one': true})]); var value: any /** TODO #9100 */ = null; (>c(new FormControl('expected'))).then(v => value = v); - tick(1); expect(value).toEqual(null);