From a12dc7d75aa0483efe1c503f696f564cf6746cc9 Mon Sep 17 00:00:00 2001 From: vsavkin Date: Thu, 19 Mar 2015 14:21:40 -0700 Subject: [PATCH] refactor(forms): wrapped all validators into the Validator class --- modules/angular2/src/forms/directives.js | 6 +- modules/angular2/src/forms/model.js | 8 +-- .../src/forms/validator_directives.js | 5 +- modules/angular2/src/forms/validators.js | 56 ++++++++++--------- .../angular2/test/forms/form_builder_spec.js | 19 +++---- .../angular2/test/forms/integration_spec.js | 6 +- modules/angular2/test/forms/model_spec.js | 21 ++++--- .../angular2/test/forms/validators_spec.js | 20 +++---- 8 files changed, 69 insertions(+), 72 deletions(-) diff --git a/modules/angular2/src/forms/directives.js b/modules/angular2/src/forms/directives.js index 9eddae29f3..e3d848d33e 100644 --- a/modules/angular2/src/forms/directives.js +++ b/modules/angular2/src/forms/directives.js @@ -4,7 +4,7 @@ import {DOM} from 'angular2/src/dom/dom_adapter'; import {isBlank, isPresent, isString, CONST} from 'angular2/src/facade/lang'; import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection'; import {ControlGroup, Control} from './model'; -import * as validators from './validators'; +import {Validators} from './validators'; @CONST() export class ControlValueAccessor { @@ -79,7 +79,7 @@ export class ControlDirective { this._el = el; this.controlName = null; this.type = null; - this.validator = validators.nullValidator; + this.validator = Validators.nullValidator; } // TODO: vsavkin this should be moved into the constructor once static bindings @@ -92,7 +92,7 @@ export class ControlDirective { this._groupDirective.addDirective(this); var c = this._control(); - c.validator = validators.compose([c.validator, this.validator]); + c.validator = Validators.compose([c.validator, this.validator]); if (isBlank(this.valueAccessor)) { this.valueAccessor = controlValueAccessorFor(this.type); diff --git a/modules/angular2/src/forms/model.js b/modules/angular2/src/forms/model.js index d8130710ad..ae63afd135 100644 --- a/modules/angular2/src/forms/model.js +++ b/modules/angular2/src/forms/model.js @@ -1,6 +1,6 @@ import {isPresent} from 'angular2/src/facade/lang'; import {StringMap, StringMapWrapper} from 'angular2/src/facade/collection'; -import {nullValidator, controlGroupValidator} from './validators'; +import {Validators} from './validators'; export const VALID = "VALID"; export const INVALID = "INVALID"; @@ -26,7 +26,7 @@ export class AbstractControl { _parent:ControlGroup; validator:Function; - constructor(validator:Function = nullValidator) { + constructor(validator:Function) { this.validator = validator; this._updateNeeded = true; this._pristine = true; @@ -76,7 +76,7 @@ export class AbstractControl { } export class Control extends AbstractControl { - constructor(value:any, validator:Function = nullValidator) { + constructor(value:any, validator:Function = Validators.nullValidator) { super(validator); this._value = value; } @@ -101,7 +101,7 @@ export class ControlGroup extends AbstractControl { controls; optionals; - constructor(controls, optionals = null, validator:Function = controlGroupValidator) { + constructor(controls, optionals = null, validator:Function = Validators.group) { super(validator); this.controls = controls; this.optionals = isPresent(optionals) ? optionals : {}; diff --git a/modules/angular2/src/forms/validator_directives.js b/modules/angular2/src/forms/validator_directives.js index 0adfaccb05..e592d65f8d 100644 --- a/modules/angular2/src/forms/validator_directives.js +++ b/modules/angular2/src/forms/validator_directives.js @@ -1,13 +1,12 @@ import {Decorator} from 'angular2/angular2'; -import {ControlDirective} from 'angular2/forms'; -import * as validators from 'angular2/forms'; +import {ControlDirective, Validators} from 'angular2/forms'; @Decorator({ selector: '[required]' }) export class RequiredValidatorDirective { constructor(c:ControlDirective) { - c.validator = validators.compose([c.validator, validators.required]); + c.validator = Validators.compose([c.validator, Validators.required]); } } \ No newline at end of file diff --git a/modules/angular2/src/forms/validators.js b/modules/angular2/src/forms/validators.js index 773ac8ba34..fd5e3ccbe0 100644 --- a/modules/angular2/src/forms/validators.js +++ b/modules/angular2/src/forms/validators.js @@ -3,35 +3,37 @@ import {List, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collectio import * as modelModule from './model'; -export function required(c:modelModule.Control) { - return isBlank(c.value) || c.value == "" ? {"required" : true} : null; -} +export class Validators { + static required(c:modelModule.Control) { + return isBlank(c.value) || c.value == "" ? {"required": true} : null; + } -export function nullValidator(c:modelModule.Control) { - return null; -} + static nullValidator(c:modelModule.Control) { + return null; + } -export function compose(validators:List):Function { - return function(c:modelModule.Control) { - var res = ListWrapper.reduce(validators, (res, validator) => { - var errors = validator(c); - return isPresent(errors) ? StringMapWrapper.merge(res, errors) : res; - }, {}); + static compose(validators:List):Function { + return function (c:modelModule.Control) { + var res = ListWrapper.reduce(validators, (res, validator) => { + var errors = validator(c); + return isPresent(errors) ? StringMapWrapper.merge(res, errors) : res; + }, {}); + return StringMapWrapper.isEmpty(res) ? null : res; + } + } + + static group(c:modelModule.ControlGroup) { + var res = {}; + StringMapWrapper.forEach(c.controls, (control, name) => { + if (c.contains(name) && isPresent(control.errors)) { + StringMapWrapper.forEach(control.errors, (value, error) => { + if (!StringMapWrapper.contains(res, error)) { + res[error] = []; + } + ListWrapper.push(res[error], control); + }); + } + }); return StringMapWrapper.isEmpty(res) ? null : res; } } - -export function controlGroupValidator(c:modelModule.ControlGroup) { - var res = {}; - StringMapWrapper.forEach(c.controls, (control, name) => { - if (c.contains(name) && isPresent(control.errors)) { - StringMapWrapper.forEach(control.errors, (value, error) => { - if (! StringMapWrapper.contains(res, error)) { - res[error] = []; - } - ListWrapper.push(res[error], control); - }); - } - }); - return StringMapWrapper.isEmpty(res) ? null : res; -} diff --git a/modules/angular2/test/forms/form_builder_spec.js b/modules/angular2/test/forms/form_builder_spec.js index 94fda5f4b5..083f9c3250 100644 --- a/modules/angular2/test/forms/form_builder_spec.js +++ b/modules/angular2/test/forms/form_builder_spec.js @@ -1,6 +1,5 @@ import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el} from 'angular2/test_lib'; -import {Control, FormBuilder} from 'angular2/forms'; -import * as validations from 'angular2/forms'; +import {Control, FormBuilder, Validators} from 'angular2/forms'; export function main() { describe("Form Builder", () => { @@ -21,21 +20,21 @@ export function main() { it("should create controls from an array", () => { var g = b.group({ "login": ["some value"], - "password": ["some value", validations.required] + "password": ["some value", Validators.required] }); expect(g.controls["login"].value).toEqual("some value"); expect(g.controls["password"].value).toEqual("some value"); - expect(g.controls["password"].validator).toEqual(validations.required); + expect(g.controls["password"].validator).toEqual(Validators.required); }); it("should use controls", () => { var g = b.group({ - "login": b.control("some value", validations.required) + "login": b.control("some value", Validators.required) }); expect(g.controls["login"].value).toEqual("some value"); - expect(g.controls["login"].validator).toBe(validations.required); + expect(g.controls["login"].validator).toBe(Validators.required); }); it("should create groups with optional controls", () => { @@ -49,17 +48,17 @@ export function main() { it("should create groups with a custom validator", () => { var g = b.group({ "login": "some value" - }, {"validator": validations.nullValidator}); + }, {"validator": Validators.nullValidator}); - expect(g.validator).toBe(validations.nullValidator); + expect(g.validator).toBe(Validators.nullValidator); }); it("should use default validators when no validators are provided", () => { var g = b.group({ "login": "some value" }); - expect(g.controls["login"].validator).toBe(validations.nullValidator); - expect(g.validator).toBe(validations.controlGroupValidator); + expect(g.controls["login"].validator).toBe(Validators.nullValidator); + expect(g.validator).toBe(Validators.group); }); }); } \ No newline at end of file diff --git a/modules/angular2/test/forms/integration_spec.js b/modules/angular2/test/forms/integration_spec.js index bdf816fa96..826525e033 100644 --- a/modules/angular2/test/forms/integration_spec.js +++ b/modules/angular2/test/forms/integration_spec.js @@ -31,9 +31,7 @@ import {Injector} from 'angular2/di'; import {Component, Decorator, Template} from 'angular2/angular2'; import {ControlGroupDirective, ControlDirective, Control, ControlGroup, OptionalControl, - ControlValueAccessor, RequiredValidatorDirective} from 'angular2/forms'; - -import * as validators from 'angular2/src/forms/validators'; + ControlValueAccessor, RequiredValidatorDirective, Validators} from 'angular2/forms'; export function main() { function detectChanges(view) { @@ -261,7 +259,7 @@ export function main() { })); it("should use validators defined in the model", inject([AsyncTestCompleter], (async) => { - var form = new ControlGroup({"login": new Control("aa", validators.required)}); + var form = new ControlGroup({"login": new Control("aa", Validators.required)}); var ctx = new MyComp(form); var t = `
diff --git a/modules/angular2/test/forms/model_spec.js b/modules/angular2/test/forms/model_spec.js index 70f2e16b4f..69a732c3b8 100644 --- a/modules/angular2/test/forms/model_spec.js +++ b/modules/angular2/test/forms/model_spec.js @@ -1,24 +1,23 @@ import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el} from 'angular2/test_lib'; -import {ControlGroup, Control, OptionalControl} from 'angular2/forms'; -import * as validations from 'angular2/forms'; +import {ControlGroup, Control, OptionalControl, Validators} from 'angular2/forms'; export function main() { describe("Form Model", () => { describe("Control", () => { describe("validator", () => { it("should run validator with the initial value", () => { - var c = new Control("value", validations.required); + var c = new Control("value", Validators.required); expect(c.valid).toEqual(true); }); it("should rerun the validator when the value changes", () => { - var c = new Control("value", validations.required); + var c = new Control("value", Validators.required); c.updateValue(null); expect(c.valid).toEqual(false); }); it("should return errors", () => { - var c = new Control(null, validations.required); + var c = new Control(null, Validators.required); expect(c.errors).toEqual({"required" : true}); }); }); @@ -83,7 +82,7 @@ export function main() { describe("validator", () => { it("should run the validator with the initial value (valid)", () => { var g = new ControlGroup({ - "one": new Control('value', validations.required) + "one": new Control('value', Validators.required) }); expect(g.valid).toEqual(true); @@ -92,7 +91,7 @@ export function main() { }); it("should run the validator with the initial value (invalid)", () => { - var one = new Control(null, validations.required); + var one = new Control(null, Validators.required); var g = new ControlGroup({"one": one}); expect(g.valid).toEqual(false); @@ -101,7 +100,7 @@ export function main() { }); it("should run the validator with the value changes", () => { - var c = new Control(null, validations.required); + var c = new Control(null, Validators.required); var g = new ControlGroup({"one": c}); c.updateValue("some value"); @@ -174,10 +173,10 @@ export function main() { expect(group.value).toEqual({"required" : "requiredValue", "optional" : "optionalValue"}); }); - it("should not run validations on an inactive component", () => { + it("should not run Validators on an inactive component", () => { var group = new ControlGroup({ - "required": new Control("requiredValue", validations.required), - "optional": new Control("", validations.required) + "required": new Control("requiredValue", Validators.required), + "optional": new Control("", Validators.required) }, { "optional": false }); diff --git a/modules/angular2/test/forms/validators_spec.js b/modules/angular2/test/forms/validators_spec.js index 5300ff4dce..8293093424 100644 --- a/modules/angular2/test/forms/validators_spec.js +++ b/modules/angular2/test/forms/validators_spec.js @@ -1,5 +1,5 @@ import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el} from 'angular2/test_lib'; -import {ControlGroup, Control, required, compose, controlGroupValidator, nullValidator} from 'angular2/forms'; +import {ControlGroup, Control, Validators} from 'angular2/forms'; export function main() { function validator(key:string, error:any){ @@ -13,31 +13,31 @@ export function main() { describe("Validators", () => { describe("required", () => { it("should error on an empty string", () => { - expect(required(new Control(""))).toEqual({"required" : true}); + expect(Validators.required(new Control(""))).toEqual({"required" : true}); }); it("should error on null", () => { - expect(required(new Control(null))).toEqual({"required" : true}); + expect(Validators.required(new Control(null))).toEqual({"required" : true}); }); it("should not error on a non-empty string", () => { - expect(required(new Control("not empty"))).toEqual(null); + expect(Validators.required(new Control("not empty"))).toEqual(null); }); }); describe("compose", () => { it("should collect errors from all the validators", () => { - var c = compose([validator("a", true), validator("b", true)]); + var c = Validators.compose([validator("a", true), validator("b", true)]); expect(c(new Control(""))).toEqual({"a" : true, "b" : true}); }); it("should run validators left to right", () => { - var c = compose([validator("a", 1), validator("a", 2)]); + var c = Validators.compose([validator("a", 1), validator("a", 2)]); expect(c(new Control(""))).toEqual({"a" : 2}); }); it("should return null when no errors", () => { - var c = compose([nullValidator, nullValidator]); + var c = Validators.compose([Validators.nullValidator, Validators.nullValidator]); expect(c(new Control(""))).toEqual(null); }); }); @@ -48,7 +48,7 @@ export function main() { var two = new Control("one", validator("b", true)); var g = new ControlGroup({"one" : one, "two" : two}); - expect(controlGroupValidator(g)).toEqual({ + expect(Validators.group(g)).toEqual({ "a" : [one], "b" : [two] }); @@ -59,7 +59,7 @@ export function main() { var two = new Control("two"); var g = new ControlGroup({"one" : one, "two" : two}); - expect(controlGroupValidator(g)).toEqual({ + expect(Validators.group(g)).toEqual({ "a": [one] }); }); @@ -69,7 +69,7 @@ export function main() { "one" : new Control("one") }); - expect(controlGroupValidator(g)).toEqual(null); + expect(Validators.group(g)).toEqual(null); }); }); });