chore(forms): moved tests/forms to typescript

This commit is contained in:
vsavkin 2015-05-22 12:32:49 -07:00
parent 05774f6c8a
commit 3525c9c074
6 changed files with 619 additions and 650 deletions

View File

@ -1,5 +1,16 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el, import {
AsyncTestCompleter, inject} from 'angular2/test_lib'; ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
el,
AsyncTestCompleter,
inject
} from 'angular2/test_lib';
import {ControlGroup, ControlDirective, ControlGroupDirective} from 'angular2/forms'; import {ControlGroup, ControlDirective, ControlGroupDirective} from 'angular2/forms';
export function main() { export function main() {
@ -7,9 +18,8 @@ export function main() {
describe("Control", () => { describe("Control", () => {
it("should throw when the group is not found and the control is not set", () => { it("should throw when the group is not found and the control is not set", () => {
var c = new ControlDirective(null); var c = new ControlDirective(null);
expect(() => { expect(() => { c.controlOrName = 'login'; })
c.controlOrName = 'login'; .toThrowError(new RegExp('No control group found for "login"'));
}).toThrowError(new RegExp('No control group found for "login"'));
}); });
it("should throw when cannot find the control in the group", () => { it("should throw when cannot find the control in the group", () => {
@ -17,9 +27,8 @@ export function main() {
emptyGroup.controlOrName = new ControlGroup({}); emptyGroup.controlOrName = new ControlGroup({});
var c = new ControlDirective(emptyGroup); var c = new ControlDirective(emptyGroup);
expect(() => { expect(() => { c.controlOrName = 'login'; })
c.controlOrName = 'login'; .toThrowError(new RegExp('Cannot find control "login"'));
}).toThrowError(new RegExp('Cannot find control "login"'));
}); });
}); });
}); });

View File

@ -1,27 +1,30 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el} from 'angular2/test_lib'; import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
el
} from 'angular2/test_lib';
import {Control, FormBuilder, Validators} from 'angular2/forms'; import {Control, FormBuilder, Validators} from 'angular2/forms';
export function main() { export function main() {
describe("Form Builder", () => { describe("Form Builder", () => {
var b; var b;
beforeEach(() => { beforeEach(() => { b = new FormBuilder(); });
b = new FormBuilder();
});
it("should create controls from a value", () => { it("should create controls from a value", () => {
var g = b.group({ var g = b.group({"login": "some value"});
"login": "some value"
});
expect(g.controls["login"].value).toEqual("some value"); expect(g.controls["login"].value).toEqual("some value");
}); });
it("should create controls from an array", () => { it("should create controls from an array", () => {
var g = b.group({ var g = b.group({"login": ["some value"], "password": ["some value", Validators.required]});
"login": ["some value"],
"password": ["some value", Validators.required]
});
expect(g.controls["login"].value).toEqual("some value"); expect(g.controls["login"].value).toEqual("some value");
expect(g.controls["password"].value).toEqual("some value"); expect(g.controls["password"].value).toEqual("some value");
@ -29,49 +32,35 @@ export function main() {
}); });
it("should use controls", () => { it("should use controls", () => {
var g = b.group({ var g = b.group({"login": b.control("some value", Validators.required)});
"login": b.control("some value", Validators.required)
});
expect(g.controls["login"].value).toEqual("some value"); expect(g.controls["login"].value).toEqual("some value");
expect(g.controls["login"].validator).toBe(Validators.required); expect(g.controls["login"].validator).toBe(Validators.required);
}); });
it("should create groups with optional controls", () => { it("should create groups with optional controls", () => {
var g = b.group({ var g = b.group({"login": "some value"}, {"optionals": {"login": false}});
"login": "some value"
}, {"optionals": {"login" : false}});
expect(g.contains("login")).toEqual(false); expect(g.contains("login")).toEqual(false);
}); });
it("should create groups with a custom validator", () => { it("should create groups with a custom validator", () => {
var g = b.group({ var g = b.group({"login": "some value"}, {"validator": Validators.nullValidator});
"login": "some value"
}, {"validator": Validators.nullValidator});
expect(g.validator).toBe(Validators.nullValidator); expect(g.validator).toBe(Validators.nullValidator);
}); });
it("should use default validators when no validators are provided", () => { it("should use default validators when no validators are provided", () => {
var g = b.group({ var g = b.group({"login": "some value"});
"login": "some value"
});
expect(g.controls["login"].validator).toBe(Validators.nullValidator); expect(g.controls["login"].validator).toBe(Validators.nullValidator);
expect(g.validator).toBe(Validators.group); expect(g.validator).toBe(Validators.group);
}); });
it("should create control arrays", () => { it("should create control arrays", () => {
var c = b.control("three"); var c = b.control("three");
var a = b.array([ var a = b.array(["one", ["two", Validators.required], c, b.array(['four'])]);
"one",
["two", Validators.required],
c,
b.array(['four'])
]);
expect(a.value).toEqual(['one', 'two', 'three', ['four']]); expect(a.value).toEqual(['one', 'two', 'three', ['four']]);
}); });
}); });
} }

View File

@ -1,429 +0,0 @@
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
dispatchEvent,
el,
expect,
iit,
inject,
it,
xit
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {Inject} from 'angular2/src/di/annotations_impl';
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
import {View} from 'angular2/src/core/annotations_impl/view';
import {TestBed} from 'angular2/src/test_lib/test_bed';
import {ControlGroupDirective, ControlDirective, Control, ControlGroup, RequiredValidatorDirective, CheckboxControlValueAccessor, DefaultValueAccessor, SelectControlValueAccessor, Validators} from 'angular2/forms';
export function main() {
describe("integration tests", () => {
it("should initialize DOM elements with the given form object",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({
"login": new Control("loginValue")
}));
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("loginValue");
async.done();
});
}));
it("should update the control group values on DOM change",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({
"login": new Control("oldValue")
});
var ctx = new MyComp(form);
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input");
input.value = "updatedValue";
dispatchEvent(input, "change");
expect(form.value).toEqual({"login": "updatedValue"});
async.done();
});
}));
it("should work with single controls", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var control = new Control("loginValue");
var ctx = new MyComp(control);
var t = `<div><input type="text" [control]="form"></div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("loginValue");
input.value = "updatedValue";
dispatchEvent(input, "change");
expect(control.value).toEqual("updatedValue");
async.done();
});
}));
it("should update DOM elements when rebinding the control group",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({
"login": new Control("oldValue")
});
var ctx = new MyComp(form);
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
ctx.form = new ControlGroup({
"login": new Control("newValue")
});
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("newValue");
async.done();
});
}));
it("should update DOM element when rebinding the control name",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({
"one": new Control("one"),
"two": new Control("two")
}), "one");
var t = `<div [control-group]="form">
<input type="text" [control]="name">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("one");
ctx.name = "two";
view.detectChanges();
expect(input.value).toEqual("two");
async.done();
});
}));
describe("different control types", () => {
it("should support <input type=text>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"text": new Control("old")}));
var t = `<div [control-group]="form">
<input type="text" control="text">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("old");
input.value = "new";
dispatchEvent(input, "input");
expect(ctx.form.value).toEqual({"text": "new"});
async.done();
});
}));
it("should support <input> without type", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"text": new Control("old")}));
var t = `<div [control-group]="form">
<input control="text">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("old");
input.value = "new";
dispatchEvent(input, "input");
expect(ctx.form.value).toEqual({"text": "new"});
async.done();
});
}));
it("should support <textarea>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"text": new Control('old')}));
var t = `<div [control-group]="form">
<textarea control="text"></textarea>
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var textarea = view.querySelector("textarea")
expect(textarea.value).toEqual("old");
textarea.value = "new";
dispatchEvent(textarea, "input");
expect(ctx.form.value).toEqual({"text": 'new'});
async.done();
});
}));
it("should support <type=checkbox>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"checkbox": new Control(true)}));
var t = `<div [control-group]="form">
<input type="checkbox" control="checkbox">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.checked).toBe(true);
input.checked = false;
dispatchEvent(input, "change");
expect(ctx.form.value).toEqual({"checkbox": false});
async.done();
});
}));
it("should support <select>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"city": new Control("SF")}));
var t = `<div [control-group]="form">
<select control="city">
<option value="SF"></option>
<option value="NYC"></option>
</select>
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var select = view.querySelector("select")
var sfOption = view.querySelector("option")
expect(select.value).toEqual('SF');
if (DOM.supportsDOMEvents()) {
expect(sfOption.selected).toBe(true);
}
select.value = 'NYC';
dispatchEvent(select, "change");
expect(ctx.form.value).toEqual({"city": 'NYC'});
if (DOM.supportsDOMEvents()) {
expect(sfOption.selected).toBe(false);
}
async.done();
});
}));
it("should support custom value accessors", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"name": new Control("aa")}));
var t = `<div [control-group]="form">
<input type="text" control="name" wrapped-value>
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("!aa!");
input.value = "!bb!";
dispatchEvent(input, "change");
expect(ctx.form.value).toEqual({"name": "bb"});
async.done();
});
}));
it("should throw when cannot find a value accessor", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = new MyComp(new ControlGroup({"name": new Control("aa")}));
var t = `<div [control-group]="form">
<div control="name">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
expect(() => view.detectChanges()).toThrowError(new RegExp("Cannot find value accessor"))
async.done();
});
}));
});
describe("validations", () => {
it("should use validators defined in html",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({"login": new Control("aa")});
var ctx = new MyComp(form);
var t = `<div [control-group]="form">
<input type="text" control="login" required>
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
expect(form.valid).toEqual(true);
var input = view.querySelector("input");
input.value = "";
dispatchEvent(input, "change");
expect(form.valid).toEqual(false);
async.done();
});
}));
it("should use validators defined in the model",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({"login": new Control("aa", Validators.required)});
var ctx = new MyComp(form);
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
expect(form.valid).toEqual(true);
var input = view.querySelector("input");
input.value = "";
dispatchEvent(input, "change");
expect(form.valid).toEqual(false);
async.done();
});
}));
});
describe("nested forms", () => {
it("should init DOM with the given form object",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({
"nested": new ControlGroup({
"login": new Control("value")
})
});
var ctx = new MyComp(form);
var t = `<div [control-group]="form">
<div control-group="nested">
<input type="text" control="login">
</div>
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
expect(input.value).toEqual("value");
async.done();
});
}));
it("should update the control group values on DOM change",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({
"nested": new ControlGroup({
"login": new Control("value")
})
});
var ctx = new MyComp(form);
var t = `<div [control-group]="form">
<div control-group="nested">
<input type="text" control="login">
</div>
</div>`;
tb.createView(MyComp, {context: ctx, html: t}).then((view) => {
view.detectChanges();
var input = view.querySelector("input")
input.value = "updatedValue";
dispatchEvent(input, "change");
expect(form.value).toEqual({"nested": {"login": "updatedValue"}});
async.done();
});
}));
});
});
}
@Component({selector: "my-comp"})
@View({directives: [
ControlGroupDirective,
ControlDirective,
WrappedValue,
RequiredValidatorDirective,
DefaultValueAccessor,
CheckboxControlValueAccessor,
SelectControlValueAccessor
]})
class MyComp {
form:any;
name:string;
constructor(@Inject('form') form = null, @Inject('name') name = null) {
this.form = form;
this.name = name;
}
}
@Directive({
selector:'[wrapped-value]',
hostListeners: {
'change' : 'handleOnChange($event.target.value)'
},
hostProperties: {
'value' : 'value'
}
})
class WrappedValue {
value;
onChange:Function;
constructor(cd:ControlDirective) {
cd.valueAccessor = this;
}
writeValue(value) {
this.value = `!${value}!`;
}
handleOnChange(value) {
this.onChange(value.substring(1, value.length - 1));
}
}

View File

@ -0,0 +1,402 @@
import {
afterEach,
AsyncTestCompleter,
beforeEach,
ddescribe,
describe,
dispatchEvent,
el,
expect,
iit,
inject,
it,
xit
} from 'angular2/test_lib';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {Component, Directive, View} from 'angular2/angular2';
import {TestBed} from 'angular2/src/test_lib/test_bed';
import {
Control,
ControlGroup,
ControlDirective,
RequiredValidatorDirective,
Validators,
formDirectives
} from 'angular2/forms';
export function main() {
describe("integration tests", () => {
it("should initialize DOM elements with the given form object",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"login": new Control("loginValue")})});
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("loginValue");
async.done();
});
}));
it("should update the control group values on DOM change",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({"login": new Control("oldValue")});
var ctx = MyComp.create({form: form});
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
input.value = "updatedValue";
dispatchEvent(input, "change");
expect(form.value).toEqual({"login": "updatedValue"});
async.done();
});
}));
it("should work with single controls", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var control = new Control("loginValue");
var ctx = MyComp.create({form: control});
var t = `<div><input type="text" [control]="form"></div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("loginValue");
input.value = "updatedValue";
dispatchEvent(input, "change");
expect(control.value).toEqual("updatedValue");
async.done();
});
}));
it("should update DOM elements when rebinding the control group",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({"login": new Control("oldValue")});
var ctx = MyComp.create({form: form});
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
ctx.form = new ControlGroup({"login": new Control("newValue")});
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("newValue");
async.done();
});
}));
it("should update DOM element when rebinding the control name",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({
form: new ControlGroup({"one": new Control("one"), "two": new Control("two")}),
name: "one"
});
var t = `<div [control-group]="form">
<input type="text" [control]="name">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("one");
ctx.name = "two";
view.detectChanges();
expect(input.value).toEqual("two");
async.done();
});
}));
describe("different control types", () => {
it("should support <input type=text>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"text": new Control("old")})});
var t = `<div [control-group]="form">
<input type="text" control="text">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("old");
input.value = "new";
dispatchEvent(input, "input");
expect(ctx.form.value).toEqual({"text": "new"});
async.done();
});
}));
it("should support <input> without type",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"text": new Control("old")})});
var t = `<div [control-group]="form">
<input control="text">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("old");
input.value = "new";
dispatchEvent(input, "input");
expect(ctx.form.value).toEqual({"text": "new"});
async.done();
});
}));
it("should support <textarea>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"text": new Control('old')})});
var t = `<div [control-group]="form">
<textarea control="text"></textarea>
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var textarea = view.querySelector("textarea");
expect(textarea.value).toEqual("old");
textarea.value = "new";
dispatchEvent(textarea, "input");
expect(ctx.form.value).toEqual({"text": 'new'});
async.done();
});
}));
it("should support <type=checkbox>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"checkbox": new Control(true)})});
var t = `<div [control-group]="form">
<input type="checkbox" control="checkbox">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.checked).toBe(true);
input.checked = false;
dispatchEvent(input, "change");
expect(ctx.form.value).toEqual({"checkbox": false});
async.done();
});
}));
it("should support <select>", inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"city": new Control("SF")})});
var t = `<div [control-group]="form">
<select control="city">
<option value="SF"></option>
<option value="NYC"></option>
</select>
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var select = view.querySelector("select");
var sfOption = view.querySelector("option");
expect(select.value).toEqual('SF');
if (DOM.supportsDOMEvents()) {
expect(sfOption.selected).toBe(true);
}
select.value = 'NYC';
dispatchEvent(select, "change");
expect(ctx.form.value).toEqual({"city": 'NYC'});
if (DOM.supportsDOMEvents()) {
expect(sfOption.selected).toBe(false);
}
async.done();
});
}));
it("should support custom value accessors",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var ctx = MyComp.create({form: new ControlGroup({"name": new Control("aa")})});
var t = `<div [control-group]="form">
<input type="text" control="name" wrapped-value>
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("!aa!");
input.value = "!bb!";
dispatchEvent(input, "change");
expect(ctx.form.value).toEqual({"name": "bb"});
async.done();
});
}));
});
describe("validations", () => {
it("should use validators defined in html",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({"login": new Control("aa")});
var ctx = MyComp.create({form: form});
var t = `<div [control-group]="form">
<input type="text" control="login" required>
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
expect(form.valid).toEqual(true);
var input = view.querySelector("input");
input.value = "";
dispatchEvent(input, "change");
expect(form.valid).toEqual(false);
async.done();
});
}));
it("should use validators defined in the model",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form = new ControlGroup({"login": new Control("aa", Validators.required)});
var ctx = MyComp.create({form: form});
var t = `<div [control-group]="form">
<input type="text" control="login">
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
expect(form.valid).toEqual(true);
var input = view.querySelector("input");
input.value = "";
dispatchEvent(input, "change");
expect(form.valid).toEqual(false);
async.done();
});
}));
});
describe("nested forms", () => {
it("should init DOM with the given form object",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form =
new ControlGroup({"nested": new ControlGroup({"login": new Control("value")})});
var ctx = MyComp.create({form: form});
var t = `<div [control-group]="form">
<div control-group="nested">
<input type="text" control="login">
</div>
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input");
expect(input.value).toEqual("value");
async.done();
});
}));
it("should update the control group values on DOM change",
inject([TestBed, AsyncTestCompleter], (tb, async) => {
var form =
new ControlGroup({"nested": new ControlGroup({"login": new Control("value")})});
var ctx = MyComp.create({form: form});
var t = `<div [control-group]="form">
<div control-group="nested">
<input type="text" control="login">
</div>
</div>`;
tb.createView(MyComp, {context: ctx, html: t})
.then((view) => {
view.detectChanges();
var input = view.querySelector("input")
input.value = "updatedValue";
dispatchEvent(input, "change");
expect(form.value).toEqual({"nested": {"login": "updatedValue"}});
async.done();
});
}));
});
});
}
@Directive({
selector: '[wrapped-value]',
hostListeners: {'change': 'handleOnChange($event.target.value)'},
hostProperties: {'value': 'value'}
})
class WrappedValue {
value;
onChange: Function;
constructor(cd: ControlDirective) { cd.valueAccessor = this; }
writeValue(value) { this.value = `!${value}!`; }
handleOnChange(value) { this.onChange(value.substring(1, value.length - 1)); }
}
@Component({selector: "my-comp"})
@View({directives: [WrappedValue, formDirectives, RequiredValidatorDirective]})
class MyComp {
form: any;
name: string;
static create({form, name}: {form?, name?}) {
var mc = new MyComp();
mc.form = form;
mc.name = name;
return mc;
}
}

View File

@ -1,5 +1,16 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el, import {
AsyncTestCompleter, inject} from 'angular2/test_lib'; ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
el,
AsyncTestCompleter,
inject
} from 'angular2/test_lib';
import {ControlGroup, Control, ControlArray, Validators} from 'angular2/forms'; import {ControlGroup, Control, ControlArray, Validators} from 'angular2/forms';
import {ObservableWrapper} from 'angular2/src/facade/async'; import {ObservableWrapper} from 'angular2/src/facade/async';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
@ -21,7 +32,7 @@ export function main() {
it("should return errors", () => { it("should return errors", () => {
var c = new Control(null, Validators.required); var c = new Control(null, Validators.required);
expect(c.errors).toEqual({"required" : true}); expect(c.errors).toEqual({"required": true});
}); });
}); });
@ -54,37 +65,33 @@ export function main() {
describe("valueChanges", () => { describe("valueChanges", () => {
var c; var c;
beforeEach(() => { beforeEach(() => { c = new Control("old"); });
c = new Control("old");
});
it("should fire an event after the value has been updated", inject([AsyncTestCompleter], (async) => { it("should fire an event after the value has been updated",
ObservableWrapper.subscribe(c.valueChanges, (value) => { inject([AsyncTestCompleter], (async) => {
expect(c.value).toEqual('new'); ObservableWrapper.subscribe(c.valueChanges, (value) => {
expect(value).toEqual('new'); expect(c.value).toEqual('new');
async.done(); expect(value).toEqual('new');
}); async.done();
c.updateValue("new"); });
})); c.updateValue("new");
}));
it("should return a cold observable", inject([AsyncTestCompleter], (async) => { it("should return a cold observable", inject([AsyncTestCompleter], (async) => {
c.updateValue("will be ignored"); c.updateValue("will be ignored");
ObservableWrapper.subscribe(c.valueChanges, (value) => { ObservableWrapper.subscribe(c.valueChanges, (value) => {
expect(value).toEqual('new'); expect(value).toEqual('new');
async.done(); async.done();
}); });
c.updateValue("new"); c.updateValue("new");
})); }));
}); });
}); });
describe("ControlGroup", () => { describe("ControlGroup", () => {
describe("value", () => { describe("value", () => {
it("should be the reduced value of the child controls", () => { it("should be the reduced value of the child controls", () => {
var g = new ControlGroup({ var g = new ControlGroup({"one": new Control("111"), "two": new Control("222")});
"one": new Control("111"),
"two": new Control("222")
});
expect(g.value).toEqual({"one": "111", "two": "222"}); expect(g.value).toEqual({"one": "111", "two": "222"});
}); });
@ -96,23 +103,19 @@ export function main() {
it("should support nested groups", () => { it("should support nested groups", () => {
var g = new ControlGroup({ var g = new ControlGroup({
"one": new Control("111"), "one": new Control("111"),
"nested": new ControlGroup({ "nested": new ControlGroup({"two": new Control("222")})
"two" : new Control("222")
})
}); });
expect(g.value).toEqual({"one": "111", "nested" : {"two": "222"}}); expect(g.value).toEqual({"one": "111", "nested": {"two": "222"}});
g.controls["nested"].controls["two"].updateValue("333"); g.controls["nested"].controls["two"].updateValue("333");
expect(g.value).toEqual({"one": "111", "nested" : {"two": "333"}}); expect(g.value).toEqual({"one": "111", "nested": {"two": "333"}});
}); });
}); });
describe("validator", () => { describe("validator", () => {
it("should run the validator with the initial value (valid)", () => { it("should run the validator with the initial value (valid)", () => {
var g = new ControlGroup({ var g = new ControlGroup({"one": new Control('value', Validators.required)});
"one": new Control('value', Validators.required)
});
expect(g.valid).toEqual(true); expect(g.valid).toEqual(true);
@ -161,22 +164,20 @@ export function main() {
var group; var group;
beforeEach(() => { beforeEach(() => {
group = new ControlGroup({ group = new ControlGroup(
"required": new Control("requiredValue"), {
"optional": new Control("optionalValue") "required": new Control("requiredValue"),
}, { "optional": new Control("optionalValue")
"optional": false },
}); {"optional": false});
}); });
// rename contains into has // rename contains into has
it("should return false when the component is not included", () => { it("should return false when the component is not included",
expect(group.contains("optional")).toEqual(false); () => { expect(group.contains("optional")).toEqual(false); })
})
it("should return false when there is no component with the given name", () => { it("should return false when there is no component with the given name",
expect(group.contains("something else")).toEqual(false); () => { expect(group.contains("something else")).toEqual(false); });
});
it("should return true when the component is included", () => { it("should return true when the component is included", () => {
expect(group.contains("required")).toEqual(true); expect(group.contains("required")).toEqual(true);
@ -188,27 +189,24 @@ export function main() {
}); });
it("should not include an inactive component into the group value", () => { it("should not include an inactive component into the group value", () => {
var group = new ControlGroup({ var group = new ControlGroup(
"required": new Control("requiredValue"), {"required": new Control("requiredValue"), "optional": new Control("optionalValue")},
"optional": new Control("optionalValue") {"optional": false});
}, {
"optional": false
});
expect(group.value).toEqual({"required" : "requiredValue"}); expect(group.value).toEqual({"required": "requiredValue"});
group.include("optional"); group.include("optional");
expect(group.value).toEqual({"required" : "requiredValue", "optional" : "optionalValue"}); expect(group.value).toEqual({"required": "requiredValue", "optional": "optionalValue"});
}); });
it("should not run Validators on an inactive component", () => { it("should not run Validators on an inactive component", () => {
var group = new ControlGroup({ var group = new ControlGroup(
"required": new Control("requiredValue", Validators.required), {
"optional": new Control("", Validators.required) "required": new Control("requiredValue", Validators.required),
}, { "optional": new Control("", Validators.required)
"optional": false },
}); {"optional": false});
expect(group.valid).toEqual(true); expect(group.valid).toEqual(true);
@ -222,80 +220,79 @@ export function main() {
beforeEach(() => { beforeEach(() => {
c1 = new Control("old1"); c1 = new Control("old1");
c2 = new Control("old2") c2 = new Control("old2");
g = new ControlGroup({ g = new ControlGroup({"one": c1, "two": c2}, {"two": true});
"one" : c1, "two" : c2
}, {
"two" : true
});
}); });
it("should fire an event after the value has been updated", inject([AsyncTestCompleter], (async) => { it("should fire an event after the value has been updated",
ObservableWrapper.subscribe(g.valueChanges, (value) => { inject([AsyncTestCompleter], (async) => {
expect(g.value).toEqual({'one' : 'new1', 'two' : 'old2'}); ObservableWrapper.subscribe(g.valueChanges, (value) => {
expect(value).toEqual({'one' : 'new1', 'two' : 'old2'}); expect(g.value).toEqual({'one': 'new1', 'two': 'old2'});
async.done(); expect(value).toEqual({'one': 'new1', 'two': 'old2'});
}); async.done();
c1.updateValue("new1"); });
})); c1.updateValue("new1");
}));
it("should fire an event after the control's observable fired an event", inject([AsyncTestCompleter], (async) => { it("should fire an event after the control's observable fired an event",
var controlCallbackIsCalled = false; inject([AsyncTestCompleter], (async) => {
var controlCallbackIsCalled = false;
ObservableWrapper.subscribe(c1.valueChanges, (value) => { ObservableWrapper.subscribe(c1.valueChanges,
controlCallbackIsCalled = true; (value) => { controlCallbackIsCalled = true; });
});
ObservableWrapper.subscribe(g.valueChanges, (value) => { ObservableWrapper.subscribe(g.valueChanges, (value) => {
expect(controlCallbackIsCalled).toBe(true); expect(controlCallbackIsCalled).toBe(true);
async.done(); async.done();
}); });
c1.updateValue("new1"); c1.updateValue("new1");
})); }));
it("should fire an event when a control is excluded", inject([AsyncTestCompleter], (async) => { it("should fire an event when a control is excluded",
ObservableWrapper.subscribe(g.valueChanges, (value) => { inject([AsyncTestCompleter], (async) => {
expect(value).toEqual({'one' : 'old1'}); ObservableWrapper.subscribe(g.valueChanges, (value) => {
async.done(); expect(value).toEqual({'one': 'old1'});
}); async.done();
});
g.exclude("two"); g.exclude("two");
})); }));
it("should fire an event when a control is included", inject([AsyncTestCompleter], (async) => { it("should fire an event when a control is included",
g.exclude("two"); inject([AsyncTestCompleter], (async) => {
g.exclude("two");
ObservableWrapper.subscribe(g.valueChanges, (value) => { ObservableWrapper.subscribe(g.valueChanges, (value) => {
expect(value).toEqual({'one' : 'old1', 'two' : 'old2'}); expect(value).toEqual({'one': 'old1', 'two': 'old2'});
async.done(); async.done();
}); });
g.include("two"); g.include("two");
})); }));
it("should fire an event every time a control is updated", inject([AsyncTestCompleter], (async) => { it("should fire an event every time a control is updated",
var loggedValues = []; inject([AsyncTestCompleter], (async) => {
var loggedValues = [];
ObservableWrapper.subscribe(g.valueChanges, (value) => { ObservableWrapper.subscribe(g.valueChanges, (value) => {
ListWrapper.push(loggedValues, value); ListWrapper.push(loggedValues, value);
if (loggedValues.length == 2) { if (loggedValues.length == 2) {
expect(loggedValues).toEqual([ expect(loggedValues)
{"one" : "new1", "two" : "old2"}, .toEqual([{"one": "new1", "two": "old2"}, {"one": "new1", "two": "new2"}])
{"one" : "new1", "two" : "new2"} async.done();
]) }
async.done(); });
}
});
c1.updateValue("new1"); c1.updateValue("new1");
c2.updateValue("new2"); c2.updateValue("new2");
})); }));
xit("should not fire an event when an excluded control is updated", inject([AsyncTestCompleter], (async) => { xit("should not fire an event when an excluded control is updated",
// hard to test without hacking zones inject([AsyncTestCompleter], (async) => {
})); // hard to test without hacking zones
}));
}); });
}); });
@ -351,10 +348,8 @@ export function main() {
describe("validator", () => { describe("validator", () => {
it("should run the validator with the initial value (valid)", () => { it("should run the validator with the initial value (valid)", () => {
var a = new ControlArray([ var a = new ControlArray(
new Control(1, Validators.required), [new Control(1, Validators.required), new Control(2, Validators.required)]);
new Control(2, Validators.required)
]);
expect(a.valid).toBe(true); expect(a.valid).toBe(true);
expect(a.errors).toBe(null); expect(a.errors).toBe(null);
@ -405,53 +400,56 @@ export function main() {
beforeEach(() => { beforeEach(() => {
c1 = new Control("old1"); c1 = new Control("old1");
c2 = new Control("old2") c2 = new Control("old2");
a = new ControlArray([c1, c2]); a = new ControlArray([c1, c2]);
}); });
it("should fire an event after the value has been updated", inject([AsyncTestCompleter], (async) => { it("should fire an event after the value has been updated",
ObservableWrapper.subscribe(a.valueChanges, (value) => { inject([AsyncTestCompleter], (async) => {
expect(a.value).toEqual(['new1', 'old2']); ObservableWrapper.subscribe(a.valueChanges, (value) => {
expect(value).toEqual(['new1', 'old2']); expect(a.value).toEqual(['new1', 'old2']);
async.done(); expect(value).toEqual(['new1', 'old2']);
}); async.done();
c1.updateValue("new1"); });
})); c1.updateValue("new1");
}));
it("should fire an event after the control's observable fired an event", inject([AsyncTestCompleter], (async) => { it("should fire an event after the control's observable fired an event",
var controlCallbackIsCalled = false; inject([AsyncTestCompleter], (async) => {
var controlCallbackIsCalled = false;
ObservableWrapper.subscribe(c1.valueChanges, (value) => { ObservableWrapper.subscribe(c1.valueChanges,
controlCallbackIsCalled = true; (value) => { controlCallbackIsCalled = true; });
});
ObservableWrapper.subscribe(a.valueChanges, (value) => { ObservableWrapper.subscribe(a.valueChanges, (value) => {
expect(controlCallbackIsCalled).toBe(true); expect(controlCallbackIsCalled).toBe(true);
async.done(); async.done();
}); });
c1.updateValue("new1"); c1.updateValue("new1");
})); }));
it("should fire an event when a control is removed", inject([AsyncTestCompleter], (async) => { it("should fire an event when a control is removed",
ObservableWrapper.subscribe(a.valueChanges, (value) => { inject([AsyncTestCompleter], (async) => {
expect(value).toEqual(['old1']); ObservableWrapper.subscribe(a.valueChanges, (value) => {
async.done(); expect(value).toEqual(['old1']);
}); async.done();
});
a.removeAt(1); a.removeAt(1);
})); }));
it("should fire an event when a control is added", inject([AsyncTestCompleter], (async) => { it("should fire an event when a control is added",
a.removeAt(1); inject([AsyncTestCompleter], (async) => {
a.removeAt(1);
ObservableWrapper.subscribe(a.valueChanges, (value) => { ObservableWrapper.subscribe(a.valueChanges, (value) => {
expect(value).toEqual(['old1', 'old2']); expect(value).toEqual(['old1', 'old2']);
async.done(); async.done();
}); });
a.push(c2); a.push(c2);
})); }));
}); });
}); });
}); });

View File

@ -1,9 +1,19 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, el} from 'angular2/test_lib'; import {
ddescribe,
describe,
it,
iit,
xit,
expect,
beforeEach,
afterEach,
el
} from 'angular2/test_lib';
import {ControlGroup, Control, Validators} from 'angular2/forms'; import {ControlGroup, Control, Validators} from 'angular2/forms';
export function main() { export function main() {
function validator(key:string, error:any){ function validator(key: string, error: any) {
return function(c:Control) { return function(c: Control) {
var r = {}; var r = {};
r[key] = error; r[key] = error;
return r; return r;
@ -12,28 +22,25 @@ export function main() {
describe("Validators", () => { describe("Validators", () => {
describe("required", () => { describe("required", () => {
it("should error on an empty string", () => { it("should error on an empty string",
expect(Validators.required(new Control(""))).toEqual({"required" : true}); () => { expect(Validators.required(new Control(""))).toEqual({"required": true}); });
});
it("should error on null", () => { it("should error on null",
expect(Validators.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", () => { it("should not error on a non-empty string",
expect(Validators.required(new Control("not empty"))).toEqual(null); () => { expect(Validators.required(new Control("not empty"))).toEqual(null); });
});
}); });
describe("compose", () => { describe("compose", () => {
it("should collect errors from all the validators", () => { it("should collect errors from all the validators", () => {
var c = Validators.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}); expect(c(new Control(""))).toEqual({"a": true, "b": true});
}); });
it("should run validators left to right", () => { it("should run validators left to right", () => {
var c = Validators.compose([validator("a", 1), validator("a", 2)]); var c = Validators.compose([validator("a", 1), validator("a", 2)]);
expect(c(new Control(""))).toEqual({"a" : 2}); expect(c(new Control(""))).toEqual({"a": 2});
}); });
it("should return null when no errors", () => { it("should return null when no errors", () => {
@ -46,28 +53,21 @@ export function main() {
it("should collect errors from the child controls", () => { it("should collect errors from the child controls", () => {
var one = new Control("one", validator("a", true)); var one = new Control("one", validator("a", true));
var two = new Control("one", validator("b", true)); var two = new Control("one", validator("b", true));
var g = new ControlGroup({"one" : one, "two" : two}); var g = new ControlGroup({"one": one, "two": two});
expect(Validators.group(g)).toEqual({ expect(Validators.group(g)).toEqual({"a": [one], "b": [two]});
"a" : [one],
"b" : [two]
});
}); });
it("should not include controls that have no errors", () => { it("should not include controls that have no errors", () => {
var one = new Control("one", validator("a", true)); var one = new Control("one", validator("a", true));
var two = new Control("two"); var two = new Control("two");
var g = new ControlGroup({"one" : one, "two" : two}); var g = new ControlGroup({"one": one, "two": two});
expect(Validators.group(g)).toEqual({ expect(Validators.group(g)).toEqual({"a": [one]});
"a": [one]
});
}); });
it("should return null when no errors", () => { it("should return null when no errors", () => {
var g = new ControlGroup({ var g = new ControlGroup({"one": new Control("one")});
"one" : new Control("one")
});
expect(Validators.group(g)).toEqual(null); expect(Validators.group(g)).toEqual(null);
}); });