fix(forms): async validator-directives process Observables correctly (#8186)
Closes #/8022
This commit is contained in:
parent
9f00a1b902
commit
eef9512ce6
|
@ -20,7 +20,7 @@ export function normalizeValidator(validator: ValidatorFn | Validator): Validato
|
|||
|
||||
export function normalizeAsyncValidator(validator: AsyncValidatorFn | Validator): AsyncValidatorFn {
|
||||
if ((<Validator>validator).validate !== undefined) {
|
||||
return (c: AbstractControl) => Promise.resolve((<Validator>validator).validate(c));
|
||||
return (c: AbstractControl) => (<Validator>validator).validate(c);
|
||||
} else {
|
||||
return <AsyncValidatorFn>validator;
|
||||
}
|
||||
|
|
|
@ -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); });
|
||||
|
|
|
@ -20,7 +20,7 @@ export function normalizeValidator(validator: ValidatorFn | Validator): Validato
|
|||
|
||||
export function normalizeAsyncValidator(validator: AsyncValidatorFn | Validator): AsyncValidatorFn {
|
||||
if ((<Validator>validator).validate !== undefined) {
|
||||
return (c: AbstractControl) => Promise.resolve((<Validator>validator).validate(c));
|
||||
return (c: AbstractControl) => (<Validator>validator).validate(c);
|
||||
} else {
|
||||
return <AsyncValidatorFn>validator;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
(<Promise<any>>c(new FormControl('expected'))).then(v => value = v);
|
||||
|
||||
tick(1);
|
||||
|
||||
expect(value).toEqual(null);
|
||||
|
|
Loading…
Reference in New Issue