test(forms): refactor integration tests to improve speed (#13500)

This commit is contained in:
Marc Laval 2016-12-16 02:07:26 +01:00 committed by Chuck Jazdzewski
parent 0fe3cd9a4c
commit 55dfa1b69d
3 changed files with 146 additions and 191 deletions

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Component, Directive, EventEmitter, Input, Output, forwardRef} from '@angular/core'; import {Component, Directive, EventEmitter, Input, Output, Type, forwardRef} from '@angular/core';
import {TestBed, fakeAsync, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {AbstractControl, ControlValueAccessor, FormArray, FormControl, FormGroup, FormGroupDirective, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NG_VALUE_ACCESSOR, NgControl, ReactiveFormsModule, Validator, Validators} from '@angular/forms'; import {AbstractControl, ControlValueAccessor, FormArray, FormControl, FormGroup, FormGroupDirective, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NG_VALUE_ACCESSOR, NgControl, ReactiveFormsModule, Validator, Validators} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
@ -16,38 +16,15 @@ import {dispatchEvent} from '@angular/platform-browser/testing/browser_util';
export function main() { export function main() {
describe('reactive forms integration tests', () => { describe('reactive forms integration tests', () => {
beforeEach(() => { function initTest<T>(component: Type<T>, ...directives: Type<any>[]): ComponentFixture<T> {
TestBed.configureTestingModule({ TestBed.configureTestingModule(
imports: [FormsModule, ReactiveFormsModule], {declarations: [component, ...directives], imports: [FormsModule, ReactiveFormsModule]});
declarations: [ return TestBed.createComponent(component);
FormControlComp, }
FormGroupComp,
FormArrayComp,
FormArrayNestedGroup,
FormControlNameSelect,
FormControlNumberInput,
FormControlRangeInput,
FormControlRadioButtons,
WrappedValue,
WrappedValueForm,
MyInput,
MyInputForm,
FormGroupNgModel,
FormControlNgModel,
LoginIsEmptyValidator,
LoginIsEmptyWrapper,
ValidationBindingsForm,
UniqLoginValidator,
UniqLoginWrapper,
NestedFormGroupComp,
FormControlCheckboxRequiredValidator,
]
});
});
describe('basic functionality', () => { describe('basic functionality', () => {
it('should work with single controls', () => { it('should work with single controls', () => {
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl('old value'); const control = new FormControl('old value');
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -64,7 +41,7 @@ export function main() {
}); });
it('should work with formGroups (model -> view)', () => { it('should work with formGroups (model -> view)', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')});
fixture.detectChanges(); fixture.detectChanges();
@ -73,7 +50,7 @@ export function main() {
}); });
it('should add novalidate by default to form', () => { it('should add novalidate by default to form', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')});
fixture.detectChanges(); fixture.detectChanges();
@ -82,7 +59,7 @@ export function main() {
}); });
it('work with formGroups (view -> model)', () => { it('work with formGroups (view -> model)', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('oldValue')}); const form = new FormGroup({'login': new FormControl('oldValue')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -99,7 +76,7 @@ export function main() {
describe('rebound form groups', () => { describe('rebound form groups', () => {
it('should update DOM elements initially', () => { it('should update DOM elements initially', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('oldValue')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('oldValue')});
fixture.detectChanges(); fixture.detectChanges();
@ -111,7 +88,7 @@ export function main() {
}); });
it('should update model when UI changes', () => { it('should update model when UI changes', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('oldValue')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('oldValue')});
fixture.detectChanges(); fixture.detectChanges();
@ -132,7 +109,7 @@ export function main() {
}); });
it('should work with radio buttons when reusing control', () => { it('should work with radio buttons when reusing control', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const food = new FormControl('chicken'); const food = new FormControl('chicken');
fixture.componentInstance.form = fixture.componentInstance.form =
new FormGroup({'food': food, 'drink': new FormControl('')}); new FormGroup({'food': food, 'drink': new FormControl('')});
@ -150,7 +127,7 @@ export function main() {
}); });
it('should update nested form group model when UI changes', () => { it('should update nested form group model when UI changes', () => {
const fixture = TestBed.createComponent(NestedFormGroupComp); const fixture = initTest(NestedFormGroupComp);
fixture.componentInstance.form = new FormGroup( fixture.componentInstance.form = new FormGroup(
{'signin': new FormGroup({'login': new FormControl(), 'password': new FormControl()})}); {'signin': new FormGroup({'login': new FormControl(), 'password': new FormControl()})});
fixture.detectChanges(); fixture.detectChanges();
@ -178,7 +155,7 @@ export function main() {
}); });
it('should pick up dir validators from form controls', () => { it('should pick up dir validators from form controls', () => {
const fixture = TestBed.createComponent(LoginIsEmptyWrapper); const fixture = initTest(LoginIsEmptyWrapper, LoginIsEmptyValidator);
const form = new FormGroup({ const form = new FormGroup({
'login': new FormControl(''), 'login': new FormControl(''),
'min': new FormControl(''), 'min': new FormControl(''),
@ -202,7 +179,7 @@ export function main() {
}); });
it('should pick up dir validators from nested form groups', () => { it('should pick up dir validators from nested form groups', () => {
const fixture = TestBed.createComponent(NestedFormGroupComp); const fixture = initTest(NestedFormGroupComp, LoginIsEmptyValidator);
const form = new FormGroup({ const form = new FormGroup({
'signin': 'signin':
new FormGroup({'login': new FormControl(''), 'password': new FormControl('')}) new FormGroup({'login': new FormControl(''), 'password': new FormControl('')})
@ -222,7 +199,7 @@ export function main() {
}); });
it('should strip named controls that are not found', () => { it('should strip named controls that are not found', () => {
const fixture = TestBed.createComponent(NestedFormGroupComp); const fixture = initTest(NestedFormGroupComp, LoginIsEmptyValidator);
const form = new FormGroup({ const form = new FormGroup({
'signin': 'signin':
new FormGroup({'login': new FormControl(''), 'password': new FormControl('')}) new FormGroup({'login': new FormControl(''), 'password': new FormControl('')})
@ -248,7 +225,7 @@ export function main() {
}); });
it('should strip array controls that are not found', () => { it('should strip array controls that are not found', () => {
const fixture = TestBed.createComponent(FormArrayComp); const fixture = initTest(FormArrayComp);
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]); const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
const form = new FormGroup({cities: cityArray}); const form = new FormGroup({cities: cityArray});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -277,7 +254,7 @@ export function main() {
it('should attach dir to control when leaf control changes', () => { it('should attach dir to control when leaf control changes', () => {
const form = new FormGroup({'login': new FormControl('oldValue')}); const form = new FormGroup({'login': new FormControl('oldValue')});
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -300,7 +277,7 @@ export function main() {
}); });
it('should attach dirs to all child controls when group control changes', () => { it('should attach dirs to all child controls when group control changes', () => {
const fixture = TestBed.createComponent(NestedFormGroupComp); const fixture = initTest(NestedFormGroupComp, LoginIsEmptyValidator);
const form = new FormGroup({ const form = new FormGroup({
signin: new FormGroup( signin: new FormGroup(
{login: new FormControl('oldLogin'), password: new FormControl('oldPassword')}) {login: new FormControl('oldLogin'), password: new FormControl('oldPassword')})
@ -332,7 +309,7 @@ export function main() {
}); });
it('should attach dirs to all present child controls when array control changes', () => { it('should attach dirs to all present child controls when array control changes', () => {
const fixture = TestBed.createComponent(FormArrayComp); const fixture = initTest(FormArrayComp);
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]); const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
const form = new FormGroup({cities: cityArray}); const form = new FormGroup({cities: cityArray});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -363,7 +340,7 @@ export function main() {
describe('form arrays', () => { describe('form arrays', () => {
it('should support form arrays', () => { it('should support form arrays', () => {
const fixture = TestBed.createComponent(FormArrayComp); const fixture = initTest(FormArrayComp);
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]); const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
const form = new FormGroup({cities: cityArray}); const form = new FormGroup({cities: cityArray});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -386,7 +363,7 @@ export function main() {
}); });
it('should support pushing new controls to form arrays', () => { it('should support pushing new controls to form arrays', () => {
const fixture = TestBed.createComponent(FormArrayComp); const fixture = initTest(FormArrayComp);
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]); const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
const form = new FormGroup({cities: cityArray}); const form = new FormGroup({cities: cityArray});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -402,7 +379,7 @@ export function main() {
}); });
it('should support form groups nested in form arrays', () => { it('should support form groups nested in form arrays', () => {
const fixture = TestBed.createComponent(FormArrayNestedGroup); const fixture = initTest(FormArrayNestedGroup);
const cityArray = new FormArray([ const cityArray = new FormArray([
new FormGroup({town: new FormControl('SF'), state: new FormControl('CA')}), new FormGroup({town: new FormControl('SF'), state: new FormControl('CA')}),
new FormGroup({town: new FormControl('NY'), state: new FormControl('NY')}) new FormGroup({town: new FormControl('NY'), state: new FormControl('NY')})
@ -434,7 +411,7 @@ export function main() {
describe('programmatic changes', () => { describe('programmatic changes', () => {
it('should update the value in the DOM when setValue() is called', () => { it('should update the value in the DOM when setValue() is called', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const login = new FormControl('oldValue'); const login = new FormControl('oldValue');
const form = new FormGroup({'login': login}); const form = new FormGroup({'login': login});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -450,7 +427,7 @@ export function main() {
describe('disabled controls', () => { describe('disabled controls', () => {
it('should add disabled attribute to an individual control when instantiated as disabled', it('should add disabled attribute to an individual control when instantiated as disabled',
() => { () => {
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl({value: 'some value', disabled: true}); const control = new FormControl({value: 'some value', disabled: true});
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -464,7 +441,7 @@ export function main() {
}); });
it('should add disabled attribute to formControlName when instantiated as disabled', () => { it('should add disabled attribute to formControlName when instantiated as disabled', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const control = new FormControl({value: 'some value', disabled: true}); const control = new FormControl({value: 'some value', disabled: true});
fixture.componentInstance.form = new FormGroup({login: control}); fixture.componentInstance.form = new FormGroup({login: control});
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
@ -480,7 +457,7 @@ export function main() {
it('should add disabled attribute to an individual control when disable() is called', it('should add disabled attribute to an individual control when disable() is called',
() => { () => {
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl('some value'); const control = new FormControl('some value');
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -498,7 +475,7 @@ export function main() {
it('should add disabled attribute to child controls when disable() is called on group', it('should add disabled attribute to child controls when disable() is called on group',
() => { () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('login')}); const form = new FormGroup({'login': new FormControl('login')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -516,7 +493,7 @@ export function main() {
it('should not add disabled attribute to custom controls when disable() is called', () => { it('should not add disabled attribute to custom controls when disable() is called', () => {
const fixture = TestBed.createComponent(MyInputForm); const fixture = initTest(MyInputForm, MyInput);
const control = new FormControl('some value'); const control = new FormControl('some value');
fixture.componentInstance.form = new FormGroup({login: control}); fixture.componentInstance.form = new FormGroup({login: control});
fixture.detectChanges(); fixture.detectChanges();
@ -535,7 +512,7 @@ export function main() {
describe('user input', () => { describe('user input', () => {
it('should mark controls as touched after interacting with the DOM control', () => { it('should mark controls as touched after interacting with the DOM control', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const login = new FormControl('oldValue'); const login = new FormControl('oldValue');
const form = new FormGroup({'login': login}); const form = new FormGroup({'login': login});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -553,7 +530,7 @@ export function main() {
describe('submit and reset events', () => { describe('submit and reset events', () => {
it('should emit ngSubmit event with the original submit event on submit', () => { it('should emit ngSubmit event with the original submit event on submit', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')});
fixture.componentInstance.event = null; fixture.componentInstance.event = null;
fixture.detectChanges(); fixture.detectChanges();
@ -566,7 +543,7 @@ export function main() {
}); });
it('should mark formGroup as submitted on submit event', () => { it('should mark formGroup as submitted on submit event', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('loginValue')});
fixture.detectChanges(); fixture.detectChanges();
@ -581,7 +558,7 @@ export function main() {
}); });
it('should set value in UI when form resets to that value programmatically', () => { it('should set value in UI when form resets to that value programmatically', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const login = new FormControl('some value'); const login = new FormControl('some value');
const form = new FormGroup({'login': login}); const form = new FormGroup({'login': login});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -595,7 +572,7 @@ export function main() {
}); });
it('should clear value in UI when form resets programmatically', () => { it('should clear value in UI when form resets programmatically', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const login = new FormControl('some value'); const login = new FormControl('some value');
const form = new FormGroup({'login': login}); const form = new FormGroup({'login': login});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -613,7 +590,7 @@ export function main() {
describe('value changes and status changes', () => { describe('value changes and status changes', () => {
it('should mark controls as dirty before emitting a value change event', () => { it('should mark controls as dirty before emitting a value change event', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const login = new FormControl('oldValue'); const login = new FormControl('oldValue');
fixture.componentInstance.form = new FormGroup({'login': login}); fixture.componentInstance.form = new FormGroup({'login': login});
fixture.detectChanges(); fixture.detectChanges();
@ -628,7 +605,7 @@ export function main() {
it('should mark control as pristine before emitting a value change event when resetting ', it('should mark control as pristine before emitting a value change event when resetting ',
() => { () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const login = new FormControl('oldValue'); const login = new FormControl('oldValue');
const form = new FormGroup({'login': login}); const form = new FormGroup({'login': login});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -649,7 +626,7 @@ export function main() {
describe('setting status classes', () => { describe('setting status classes', () => {
it('should work with single fields', () => { it('should work with single fields', () => {
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl('', Validators.required); const control = new FormControl('', Validators.required);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -670,7 +647,7 @@ export function main() {
}); });
it('should work with single fields and async validators', fakeAsync(() => { it('should work with single fields and async validators', fakeAsync(() => {
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl('', null, uniqLoginAsyncValidator('good')); const control = new FormControl('', null, uniqLoginAsyncValidator('good'));
fixture.debugElement.componentInstance.control = control; fixture.debugElement.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -691,7 +668,7 @@ export function main() {
})); }));
it('should work with single fields that combines async and sync validators', fakeAsync(() => { it('should work with single fields that combines async and sync validators', fakeAsync(() => {
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = const control =
new FormControl('', Validators.required, uniqLoginAsyncValidator('good')); new FormControl('', Validators.required, uniqLoginAsyncValidator('good'));
fixture.debugElement.componentInstance.control = control; fixture.debugElement.componentInstance.control = control;
@ -724,7 +701,7 @@ export function main() {
})); }));
it('should work with single fields in parent forms', () => { it('should work with single fields in parent forms', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('', Validators.required)}); const form = new FormGroup({'login': new FormControl('', Validators.required)});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -745,7 +722,7 @@ export function main() {
}); });
it('should work with formGroup', () => { it('should work with formGroup', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('', Validators.required)}); const form = new FormGroup({'login': new FormControl('', Validators.required)});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -774,7 +751,7 @@ export function main() {
it('should support <input> without type', () => { it('should support <input> without type', () => {
TestBed.overrideComponent( TestBed.overrideComponent(
FormControlComp, {set: {template: `<input [formControl]="control">`}}); FormControlComp, {set: {template: `<input [formControl]="control">`}});
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl('old'); const control = new FormControl('old');
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -791,7 +768,7 @@ export function main() {
}); });
it('should support <input type=text>', () => { it('should support <input type=text>', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('old')}); const form = new FormGroup({'login': new FormControl('old')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -808,7 +785,7 @@ export function main() {
}); });
it('should ignore the change event for <input type=text>', () => { it('should ignore the change event for <input type=text>', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('oldValue')}); const form = new FormGroup({'login': new FormControl('oldValue')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -823,7 +800,7 @@ export function main() {
it('should support <textarea>', () => { it('should support <textarea>', () => {
TestBed.overrideComponent( TestBed.overrideComponent(
FormControlComp, {set: {template: `<textarea [formControl]="control"></textarea>`}}); FormControlComp, {set: {template: `<textarea [formControl]="control"></textarea>`}});
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl('old'); const control = new FormControl('old');
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -842,7 +819,7 @@ export function main() {
it('should support <type=checkbox>', () => { it('should support <type=checkbox>', () => {
TestBed.overrideComponent( TestBed.overrideComponent(
FormControlComp, {set: {template: `<input type="checkbox" [formControl]="control">`}}); FormControlComp, {set: {template: `<input type="checkbox" [formControl]="control">`}});
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
const control = new FormControl(true); const control = new FormControl(true);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -859,7 +836,7 @@ export function main() {
}); });
it('should support <select>', () => { it('should support <select>', () => {
const fixture = TestBed.createComponent(FormControlNameSelect); const fixture = initTest(FormControlNameSelect);
fixture.detectChanges(); fixture.detectChanges();
// model -> view // model -> view
@ -879,7 +856,7 @@ export function main() {
describe('should support <type=number>', () => { describe('should support <type=number>', () => {
it('with basic use case', () => { it('with basic use case', () => {
const fixture = TestBed.createComponent(FormControlNumberInput); const fixture = initTest(FormControlNumberInput);
const control = new FormControl(10); const control = new FormControl(10);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -896,7 +873,7 @@ export function main() {
}); });
it('when value is cleared in the UI', () => { it('when value is cleared in the UI', () => {
const fixture = TestBed.createComponent(FormControlNumberInput); const fixture = initTest(FormControlNumberInput);
const control = new FormControl(10, Validators.required); const control = new FormControl(10, Validators.required);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -916,7 +893,7 @@ export function main() {
}); });
it('when value is cleared programmatically', () => { it('when value is cleared programmatically', () => {
const fixture = TestBed.createComponent(FormControlNumberInput); const fixture = initTest(FormControlNumberInput);
const control = new FormControl(10); const control = new FormControl(10);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -931,7 +908,7 @@ export function main() {
describe('should support <type=radio>', () => { describe('should support <type=radio>', () => {
it('should support basic functionality', () => { it('should support basic functionality', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = const form =
new FormGroup({'food': new FormControl('fish'), 'drink': new FormControl('sprite')}); new FormGroup({'food': new FormControl('fish'), 'drink': new FormControl('sprite')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -958,7 +935,7 @@ export function main() {
}); });
it('should support an initial undefined value', () => { it('should support an initial undefined value', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = new FormGroup({'food': new FormControl(), 'drink': new FormControl()}); const form = new FormGroup({'food': new FormControl(), 'drink': new FormControl()});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -969,7 +946,7 @@ export function main() {
}); });
it('should reset properly', () => { it('should reset properly', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = const form =
new FormGroup({'food': new FormControl('fish'), 'drink': new FormControl('sprite')}); new FormGroup({'food': new FormControl('fish'), 'drink': new FormControl('sprite')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -984,7 +961,7 @@ export function main() {
}); });
it('should set value to null and undefined properly', () => { it('should set value to null and undefined properly', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = new FormGroup( const form = new FormGroup(
{'food': new FormControl('chicken'), 'drink': new FormControl('sprite')}); {'food': new FormControl('chicken'), 'drink': new FormControl('sprite')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -1005,7 +982,7 @@ export function main() {
}); });
it('should use formControlName to group radio buttons when name is absent', () => { it('should use formControlName to group radio buttons when name is absent', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const foodCtrl = new FormControl('fish'); const foodCtrl = new FormControl('fish');
const drinkCtrl = new FormControl('sprite'); const drinkCtrl = new FormControl('sprite');
fixture.componentInstance.form = new FormGroup({'food': foodCtrl, 'drink': drinkCtrl}); fixture.componentInstance.form = new FormGroup({'food': foodCtrl, 'drink': drinkCtrl});
@ -1037,7 +1014,7 @@ export function main() {
}); });
it('should support removing controls from <type=radio>', () => { it('should support removing controls from <type=radio>', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const showRadio = new FormControl('yes'); const showRadio = new FormControl('yes');
const form = const form =
new FormGroup({'food': new FormControl('fish'), 'drink': new FormControl('sprite')}); new FormGroup({'food': new FormControl('fish'), 'drink': new FormControl('sprite')});
@ -1071,7 +1048,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = new FormGroup({ const form = new FormGroup({
food: new FormControl('fish'), food: new FormControl('fish'),
nested: new FormGroup({food: new FormControl('fish')}) nested: new FormGroup({food: new FormControl('fish')})
@ -1100,7 +1077,7 @@ export function main() {
}); });
it('should disable all radio buttons when disable() is called', () => { it('should disable all radio buttons when disable() is called', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = const form =
new FormGroup({food: new FormControl('fish'), drink: new FormControl('cola')}); new FormGroup({food: new FormControl('fish'), drink: new FormControl('cola')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -1132,7 +1109,7 @@ export function main() {
}); });
it('should disable all radio buttons when initially disabled', () => { it('should disable all radio buttons when initially disabled', () => {
const fixture = TestBed.createComponent(FormControlRadioButtons); const fixture = initTest(FormControlRadioButtons);
const form = new FormGroup({ const form = new FormGroup({
food: new FormControl({value: 'fish', disabled: true}), food: new FormControl({value: 'fish', disabled: true}),
drink: new FormControl('cola') drink: new FormControl('cola')
@ -1151,7 +1128,7 @@ export function main() {
describe('should support <type=range>', () => { describe('should support <type=range>', () => {
it('with basic use case', () => { it('with basic use case', () => {
const fixture = TestBed.createComponent(FormControlRangeInput); const fixture = initTest(FormControlRangeInput);
const control = new FormControl(10); const control = new FormControl(10);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -1168,7 +1145,7 @@ export function main() {
}); });
it('when value is cleared in the UI', () => { it('when value is cleared in the UI', () => {
const fixture = TestBed.createComponent(FormControlNumberInput); const fixture = initTest(FormControlNumberInput);
const control = new FormControl(10, Validators.required); const control = new FormControl(10, Validators.required);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -1188,7 +1165,7 @@ export function main() {
}); });
it('when value is cleared programmatically', () => { it('when value is cleared programmatically', () => {
const fixture = TestBed.createComponent(FormControlNumberInput); const fixture = initTest(FormControlNumberInput);
const control = new FormControl(10); const control = new FormControl(10);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -1202,7 +1179,7 @@ export function main() {
describe('custom value accessors', () => { describe('custom value accessors', () => {
it('should support basic functionality', () => { it('should support basic functionality', () => {
const fixture = TestBed.createComponent(WrappedValueForm); const fixture = initTest(WrappedValueForm, WrappedValue);
const form = new FormGroup({'login': new FormControl('aa')}); const form = new FormGroup({'login': new FormControl('aa')});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -1225,7 +1202,7 @@ export function main() {
it('should support non builtin input elements that fire a change event without a \'target\' property', it('should support non builtin input elements that fire a change event without a \'target\' property',
() => { () => {
const fixture = TestBed.createComponent(MyInputForm); const fixture = initTest(MyInputForm, MyInput);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('aa')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('aa')});
fixture.detectChanges(); fixture.detectChanges();
@ -1240,7 +1217,7 @@ export function main() {
}); });
it('should support custom accessors without setDisabledState - formControlName', () => { it('should support custom accessors without setDisabledState - formControlName', () => {
const fixture = TestBed.createComponent(WrappedValueForm); const fixture = initTest(WrappedValueForm, WrappedValue);
fixture.componentInstance.form = new FormGroup({ fixture.componentInstance.form = new FormGroup({
'login': new FormControl({value: 'aa', disabled: true}), 'login': new FormControl({value: 'aa', disabled: true}),
}); });
@ -1254,7 +1231,7 @@ export function main() {
TestBed.overrideComponent( TestBed.overrideComponent(
FormControlComp, FormControlComp,
{set: {template: `<input type="text" [formControl]="control" wrapped-value>`}}); {set: {template: `<input type="text" [formControl]="control" wrapped-value>`}});
const fixture = TestBed.createComponent(FormControlComp); const fixture = initTest(FormControlComp);
fixture.componentInstance.control = new FormControl({value: 'aa', disabled: true}); fixture.componentInstance.control = new FormControl({value: 'aa', disabled: true});
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.componentInstance.control.status).toEqual('DISABLED'); expect(fixture.componentInstance.control.status).toEqual('DISABLED');
@ -1267,7 +1244,7 @@ export function main() {
describe('ngModel interactions', () => { describe('ngModel interactions', () => {
it('should support ngModel for complex forms', fakeAsync(() => { it('should support ngModel for complex forms', fakeAsync(() => {
const fixture = TestBed.createComponent(FormGroupNgModel); const fixture = initTest(FormGroupNgModel);
fixture.componentInstance.form = new FormGroup({'login': new FormControl('')}); fixture.componentInstance.form = new FormGroup({'login': new FormControl('')});
fixture.componentInstance.login = 'oldValue'; fixture.componentInstance.login = 'oldValue';
fixture.detectChanges(); fixture.detectChanges();
@ -1284,7 +1261,7 @@ export function main() {
})); }));
it('should support ngModel for single fields', fakeAsync(() => { it('should support ngModel for single fields', fakeAsync(() => {
const fixture = TestBed.createComponent(FormControlNgModel); const fixture = initTest(FormControlNgModel);
fixture.componentInstance.control = new FormControl(''); fixture.componentInstance.control = new FormControl('');
fixture.componentInstance.login = 'oldValue'; fixture.componentInstance.login = 'oldValue';
fixture.detectChanges(); fixture.detectChanges();
@ -1301,7 +1278,7 @@ export function main() {
})); }));
it('should not update the view when the value initially came from the view', fakeAsync(() => { it('should not update the view when the value initially came from the view', fakeAsync(() => {
const fixture = TestBed.createComponent(FormControlNgModel); const fixture = initTest(FormControlNgModel);
fixture.componentInstance.control = new FormControl(''); fixture.componentInstance.control = new FormControl('');
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -1322,7 +1299,7 @@ export function main() {
describe('validations', () => { describe('validations', () => {
it('required validator should validate checkbox', () => { it('required validator should validate checkbox', () => {
const fixture = TestBed.createComponent(FormControlCheckboxRequiredValidator); const fixture = initTest(FormControlCheckboxRequiredValidator);
const control = new FormControl(false, Validators.requiredTrue); const control = new FormControl(false, Validators.requiredTrue);
fixture.componentInstance.control = control; fixture.componentInstance.control = control;
fixture.detectChanges(); fixture.detectChanges();
@ -1340,7 +1317,7 @@ export function main() {
}); });
it('should use sync validators defined in html', () => { it('should use sync validators defined in html', () => {
const fixture = TestBed.createComponent(LoginIsEmptyWrapper); const fixture = initTest(LoginIsEmptyWrapper, LoginIsEmptyValidator);
const form = new FormGroup({ const form = new FormGroup({
'login': new FormControl(''), 'login': new FormControl(''),
'min': new FormControl(''), 'min': new FormControl(''),
@ -1385,7 +1362,7 @@ export function main() {
}); });
it('should use sync validators using bindings', () => { it('should use sync validators using bindings', () => {
const fixture = TestBed.createComponent(ValidationBindingsForm); const fixture = initTest(ValidationBindingsForm);
const form = new FormGroup({ const form = new FormGroup({
'login': new FormControl(''), 'login': new FormControl(''),
'min': new FormControl(''), 'min': new FormControl(''),
@ -1433,7 +1410,7 @@ export function main() {
}); });
it('changes on bound properties should change the validation state of the form', () => { it('changes on bound properties should change the validation state of the form', () => {
const fixture = TestBed.createComponent(ValidationBindingsForm); const fixture = initTest(ValidationBindingsForm);
const form = new FormGroup({ const form = new FormGroup({
'login': new FormControl(''), 'login': new FormControl(''),
'min': new FormControl(''), 'min': new FormControl(''),
@ -1508,7 +1485,7 @@ export function main() {
}); });
it('should support rebound controls with rebound validators', () => { it('should support rebound controls with rebound validators', () => {
const fixture = TestBed.createComponent(ValidationBindingsForm); const fixture = initTest(ValidationBindingsForm);
const form = new FormGroup({ const form = new FormGroup({
'login': new FormControl(''), 'login': new FormControl(''),
'min': new FormControl(''), 'min': new FormControl(''),
@ -1545,7 +1522,7 @@ export function main() {
}); });
it('should use async validators defined in the html', fakeAsync(() => { it('should use async validators defined in the html', fakeAsync(() => {
const fixture = TestBed.createComponent(UniqLoginWrapper); const fixture = initTest(UniqLoginWrapper, UniqLoginValidator);
const form = new FormGroup({'login': new FormControl('')}); const form = new FormGroup({'login': new FormControl('')});
tick(); tick();
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
@ -1565,7 +1542,7 @@ export function main() {
})); }));
it('should use sync validators defined in the model', () => { it('should use sync validators defined in the model', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const form = new FormGroup({'login': new FormControl('aa', Validators.required)}); const form = new FormGroup({'login': new FormControl('aa', Validators.required)});
fixture.componentInstance.form = form; fixture.componentInstance.form = form;
fixture.detectChanges(); fixture.detectChanges();
@ -1579,7 +1556,7 @@ export function main() {
}); });
it('should use async validators defined in the model', fakeAsync(() => { it('should use async validators defined in the model', fakeAsync(() => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const control = const control =
new FormControl('', Validators.required, uniqLoginAsyncValidator('expected')); new FormControl('', Validators.required, uniqLoginAsyncValidator('expected'));
const form = new FormGroup({'login': control}); const form = new FormGroup({'login': control});
@ -1610,7 +1587,7 @@ export function main() {
describe('errors', () => { describe('errors', () => {
it('should throw if a form isn\'t passed into formGroup', () => { it('should throw if a form isn\'t passed into formGroup', () => {
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError(new RegExp(`formGroup expects a FormGroup instance`)); .toThrowError(new RegExp(`formGroup expects a FormGroup instance`));
@ -1624,7 +1601,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
@ -1641,7 +1618,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
@ -1660,7 +1637,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
@ -1677,7 +1654,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
@ -1696,7 +1673,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
@ -1712,7 +1689,7 @@ export function main() {
</div>` </div>`
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError( .toThrowError(
@ -1729,7 +1706,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.myGroup = new FormGroup({}); fixture.componentInstance.myGroup = new FormGroup({});
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
@ -1747,7 +1724,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.myGroup = new FormGroup({}); fixture.componentInstance.myGroup = new FormGroup({});
expect(() => fixture.detectChanges()).not.toThrowError(); expect(() => fixture.detectChanges()).not.toThrowError();
@ -1765,7 +1742,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
const myGroup = new FormGroup({person: new FormGroup({})}); const myGroup = new FormGroup({person: new FormGroup({})});
fixture.componentInstance.myGroup = new FormGroup({person: new FormGroup({})}); fixture.componentInstance.myGroup = new FormGroup({person: new FormGroup({})});
@ -1786,7 +1763,7 @@ export function main() {
` `
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.myGroup = new FormGroup({}); fixture.componentInstance.myGroup = new FormGroup({});
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
@ -1803,7 +1780,7 @@ export function main() {
</form>` </form>`
} }
}); });
const fixture = TestBed.createComponent(FormGroupComp); const fixture = initTest(FormGroupComp);
fixture.componentInstance.form = new FormGroup({'food': new FormControl('fish')}); fixture.componentInstance.form = new FormGroup({'food': new FormControl('fish')});
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Component, Directive, Input, forwardRef} from '@angular/core'; import {Component, Directive, Input, Type, forwardRef} from '@angular/core';
import {ComponentFixture, TestBed, async, fakeAsync, tick} from '@angular/core/testing'; import {ComponentFixture, TestBed, async, fakeAsync, tick} from '@angular/core/testing';
import {AbstractControl, ControlValueAccessor, FormsModule, NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, NgForm, Validator} from '@angular/forms'; import {AbstractControl, ControlValueAccessor, FormsModule, NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, NgForm, Validator} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by'; import {By} from '@angular/platform-browser/src/dom/debug/by';
@ -16,37 +16,15 @@ import {dispatchEvent} from '@angular/platform-browser/testing/browser_util';
export function main() { export function main() {
describe('template-driven forms integration tests', () => { describe('template-driven forms integration tests', () => {
beforeEach(() => { function initTest<T>(component: Type<T>, ...directives: Type<any>[]): ComponentFixture<T> {
TestBed.configureTestingModule({ TestBed.configureTestingModule(
declarations: [ {declarations: [component, ...directives], imports: [FormsModule]});
StandaloneNgModel, return TestBed.createComponent(component);
NgModelForm, }
NgModelGroupForm,
NgModelValidBinding,
NgModelNgIfForm,
NgModelRadioForm,
NgModelRangeForm,
NgModelSelectForm,
NgNoFormComp,
InvalidNgModelNoName,
NgModelOptionsStandalone,
NgModelCustomComp,
NgModelCustomWrapper,
NgModelValidationBindings,
NgModelMultipleValidators,
NgAsyncValidator,
NgModelAsyncValidation,
NgModelSelectMultipleForm,
NgModelSelectWithNullForm,
NgModelCheckboxRequiredValidator,
],
imports: [FormsModule]
});
});
describe('basic functionality', () => { describe('basic functionality', () => {
it('should support ngModel for standalone fields', fakeAsync(() => { it('should support ngModel for standalone fields', fakeAsync(() => {
const fixture = TestBed.createComponent(StandaloneNgModel); const fixture = initTest(StandaloneNgModel);
fixture.componentInstance.name = 'oldValue'; fixture.componentInstance.name = 'oldValue';
fixture.detectChanges(); fixture.detectChanges();
@ -65,7 +43,7 @@ export function main() {
})); }));
it('should support ngModel registration with a parent form', fakeAsync(() => { it('should support ngModel registration with a parent form', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.componentInstance.name = 'Nancy'; fixture.componentInstance.name = 'Nancy';
fixture.detectChanges(); fixture.detectChanges();
@ -77,7 +55,7 @@ export function main() {
})); }));
it('should add novalidate by default to form element', fakeAsync(() => { it('should add novalidate by default to form element', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -87,7 +65,7 @@ export function main() {
})); }));
it('should support ngModelGroup', fakeAsync(() => { it('should support ngModelGroup', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelGroupForm); const fixture = initTest(NgModelGroupForm);
fixture.componentInstance.first = 'Nancy'; fixture.componentInstance.first = 'Nancy';
fixture.componentInstance.last = 'Drew'; fixture.componentInstance.last = 'Drew';
fixture.componentInstance.email = 'some email'; fixture.componentInstance.email = 'some email';
@ -110,7 +88,7 @@ export function main() {
})); }));
it('should add controls and control groups to form control model', fakeAsync(() => { it('should add controls and control groups to form control model', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelGroupForm); const fixture = initTest(NgModelGroupForm);
fixture.componentInstance.first = 'Nancy'; fixture.componentInstance.first = 'Nancy';
fixture.componentInstance.last = 'Drew'; fixture.componentInstance.last = 'Drew';
fixture.componentInstance.email = 'some email'; fixture.componentInstance.email = 'some email';
@ -125,7 +103,7 @@ export function main() {
})); }));
it('should remove controls and control groups from form control model', fakeAsync(() => { it('should remove controls and control groups from form control model', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelNgIfForm); const fixture = initTest(NgModelNgIfForm);
fixture.componentInstance.emailShowing = true; fixture.componentInstance.emailShowing = true;
fixture.componentInstance.first = 'Nancy'; fixture.componentInstance.first = 'Nancy';
fixture.componentInstance.email = 'some email'; fixture.componentInstance.email = 'some email';
@ -158,7 +136,7 @@ export function main() {
})); }));
it('should set status classes with ngModel', async(() => { it('should set status classes with ngModel', async(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.componentInstance.name = 'aa'; fixture.componentInstance.name = 'aa';
fixture.detectChanges(); fixture.detectChanges();
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
@ -181,7 +159,7 @@ export function main() {
it('should set status classes with ngModel and async validators', fakeAsync(() => { it('should set status classes with ngModel and async validators', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelAsyncValidation); const fixture = initTest(NgModelAsyncValidation, NgAsyncValidator);
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
fixture.detectChanges(); fixture.detectChanges();
@ -203,7 +181,7 @@ export function main() {
})); }));
it('should set status classes with ngModelGroup and ngForm', async(() => { it('should set status classes with ngModelGroup and ngForm', async(() => {
const fixture = TestBed.createComponent(NgModelGroupForm); const fixture = initTest(NgModelGroupForm);
fixture.componentInstance.first = ''; fixture.componentInstance.first = '';
fixture.detectChanges(); fixture.detectChanges();
@ -238,13 +216,13 @@ export function main() {
})); }));
it('should not create a template-driven form when ngNoForm is used', () => { it('should not create a template-driven form when ngNoForm is used', () => {
const fixture = TestBed.createComponent(NgNoFormComp); const fixture = initTest(NgNoFormComp);
fixture.detectChanges(); fixture.detectChanges();
expect(fixture.debugElement.children[0].providerTokens.length).toEqual(0); expect(fixture.debugElement.children[0].providerTokens.length).toEqual(0);
}); });
it('should not add novalidate when ngNoForm is used', () => { it('should not add novalidate when ngNoForm is used', () => {
const fixture = TestBed.createComponent(NgNoFormComp); const fixture = initTest(NgNoFormComp);
fixture.detectChanges(); fixture.detectChanges();
const form = fixture.debugElement.query(By.css('form')); const form = fixture.debugElement.query(By.css('form'));
expect(form.nativeElement.hasAttribute('novalidate')).toBeFalsy(); expect(form.nativeElement.hasAttribute('novalidate')).toBeFalsy();
@ -253,19 +231,19 @@ export function main() {
describe('name and ngModelOptions', () => { describe('name and ngModelOptions', () => {
it('should throw if ngModel has a parent form but no name attr or standalone label', () => { it('should throw if ngModel has a parent form but no name attr or standalone label', () => {
const fixture = TestBed.createComponent(InvalidNgModelNoName); const fixture = initTest(InvalidNgModelNoName);
expect(() => fixture.detectChanges()) expect(() => fixture.detectChanges())
.toThrowError(new RegExp(`name attribute must be set`)); .toThrowError(new RegExp(`name attribute must be set`));
}); });
it('should not throw if ngModel has a parent form, no name attr, and a standalone label', it('should not throw if ngModel has a parent form, no name attr, and a standalone label',
() => { () => {
const fixture = TestBed.createComponent(NgModelOptionsStandalone); const fixture = initTest(NgModelOptionsStandalone);
expect(() => fixture.detectChanges()).not.toThrow(); expect(() => fixture.detectChanges()).not.toThrow();
}); });
it('should not register standalone ngModels with parent form', fakeAsync(() => { it('should not register standalone ngModels with parent form', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelOptionsStandalone); const fixture = initTest(NgModelOptionsStandalone);
fixture.componentInstance.one = 'some data'; fixture.componentInstance.one = 'some data';
fixture.componentInstance.two = 'should not show'; fixture.componentInstance.two = 'should not show';
fixture.detectChanges(); fixture.detectChanges();
@ -280,7 +258,7 @@ export function main() {
})); }));
it('should override name attribute with ngModelOptions name if provided', fakeAsync(() => { it('should override name attribute with ngModelOptions name if provided', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.componentInstance.options = {name: 'override'}; fixture.componentInstance.options = {name: 'override'};
fixture.componentInstance.name = 'some data'; fixture.componentInstance.name = 'some data';
fixture.detectChanges(); fixture.detectChanges();
@ -293,7 +271,7 @@ export function main() {
describe('submit and reset events', () => { describe('submit and reset events', () => {
it('should emit ngSubmit event with the original submit event on submit', fakeAsync(() => { it('should emit ngSubmit event with the original submit event on submit', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.componentInstance.event = null; fixture.componentInstance.event = null;
const form = fixture.debugElement.query(By.css('form')); const form = fixture.debugElement.query(By.css('form'));
@ -304,7 +282,7 @@ export function main() {
})); }));
it('should mark NgForm as submitted on submit event', fakeAsync(() => { it('should mark NgForm as submitted on submit event', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
tick(); tick();
const form = fixture.debugElement.children[0].injector.get(NgForm); const form = fixture.debugElement.children[0].injector.get(NgForm);
@ -318,7 +296,7 @@ export function main() {
})); }));
it('should reset the form to empty when reset event is fired', fakeAsync(() => { it('should reset the form to empty when reset event is fired', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.componentInstance.name = 'should be cleared'; fixture.componentInstance.name = 'should be cleared';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -341,7 +319,7 @@ export function main() {
})); }));
it('should reset the form submit state when reset button is clicked', fakeAsync(() => { it('should reset the form submit state when reset button is clicked', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
const form = fixture.debugElement.children[0].injector.get(NgForm); const form = fixture.debugElement.children[0].injector.get(NgForm);
const formEl = fixture.debugElement.query(By.css('form')); const formEl = fixture.debugElement.query(By.css('form'));
@ -359,7 +337,7 @@ export function main() {
describe('valueChange and statusChange events', () => { describe('valueChange and statusChange events', () => {
it('should emit valueChanges and statusChanges on init', fakeAsync(() => { it('should emit valueChanges and statusChanges on init', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
const form = fixture.debugElement.children[0].injector.get(NgForm); const form = fixture.debugElement.children[0].injector.get(NgForm);
fixture.componentInstance.name = 'aa'; fixture.componentInstance.name = 'aa';
fixture.detectChanges(); fixture.detectChanges();
@ -380,7 +358,7 @@ export function main() {
})); }));
it('should mark controls dirty before emitting the value change event', fakeAsync(() => { it('should mark controls dirty before emitting the value change event', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
const form = fixture.debugElement.children[0].injector.get(NgForm).form; const form = fixture.debugElement.children[0].injector.get(NgForm).form;
fixture.detectChanges(); fixture.detectChanges();
@ -397,7 +375,7 @@ export function main() {
it('should mark controls pristine before emitting the value change event when resetting ', it('should mark controls pristine before emitting the value change event when resetting ',
fakeAsync(() => { fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -419,7 +397,7 @@ export function main() {
describe('disabled controls', () => { describe('disabled controls', () => {
it('should not consider disabled controls in value or validation', fakeAsync(() => { it('should not consider disabled controls in value or validation', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelGroupForm); const fixture = initTest(NgModelGroupForm);
fixture.componentInstance.isDisabled = false; fixture.componentInstance.isDisabled = false;
fixture.componentInstance.first = ''; fixture.componentInstance.first = '';
fixture.componentInstance.last = 'Drew'; fixture.componentInstance.last = 'Drew';
@ -443,7 +421,7 @@ export function main() {
it('should add disabled attribute in the UI if disable() is called programmatically', it('should add disabled attribute in the UI if disable() is called programmatically',
fakeAsync(() => { fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelGroupForm); const fixture = initTest(NgModelGroupForm);
fixture.componentInstance.isDisabled = false; fixture.componentInstance.isDisabled = false;
fixture.componentInstance.first = 'Nancy'; fixture.componentInstance.first = 'Nancy';
fixture.detectChanges(); fixture.detectChanges();
@ -459,7 +437,7 @@ export function main() {
})); }));
it('should disable a custom control if disabled attr is added', async(() => { it('should disable a custom control if disabled attr is added', async(() => {
const fixture = TestBed.createComponent(NgModelCustomWrapper); const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp);
fixture.componentInstance.name = 'Nancy'; fixture.componentInstance.name = 'Nancy';
fixture.componentInstance.isDisabled = true; fixture.componentInstance.isDisabled = true;
fixture.detectChanges(); fixture.detectChanges();
@ -485,7 +463,7 @@ export function main() {
`, `,
} }
}); });
const fixture = TestBed.createComponent(NgModelForm); const fixture = initTest(NgModelForm);
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
const form = fixture.debugElement.children[0].injector.get(NgForm); const form = fixture.debugElement.children[0].injector.get(NgForm);
@ -501,7 +479,7 @@ export function main() {
})); }));
it('should disable radio controls properly with programmatic call', fakeAsync(() => { it('should disable radio controls properly with programmatic call', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRadioForm); const fixture = initTest(NgModelRadioForm);
fixture.componentInstance.food = 'fish'; fixture.componentInstance.food = 'fish';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -537,7 +515,7 @@ export function main() {
describe('range control', () => { describe('range control', () => {
it('should support <type=range>', fakeAsync(() => { it('should support <type=range>', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRangeForm); const fixture = initTest(NgModelRangeForm);
// model -> view // model -> view
fixture.componentInstance.val = 4; fixture.componentInstance.val = 4;
fixture.detectChanges(); fixture.detectChanges();
@ -557,7 +535,7 @@ export function main() {
describe('radio controls', () => { describe('radio controls', () => {
it('should support <type=radio>', fakeAsync(() => { it('should support <type=radio>', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRadioForm); const fixture = initTest(NgModelRadioForm);
fixture.componentInstance.food = 'fish'; fixture.componentInstance.food = 'fish';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -576,7 +554,7 @@ export function main() {
})); }));
it('should support multiple named <type=radio> groups', fakeAsync(() => { it('should support multiple named <type=radio> groups', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRadioForm); const fixture = initTest(NgModelRadioForm);
fixture.componentInstance.food = 'fish'; fixture.componentInstance.food = 'fish';
fixture.componentInstance.drink = 'sprite'; fixture.componentInstance.drink = 'sprite';
fixture.detectChanges(); fixture.detectChanges();
@ -599,7 +577,7 @@ export function main() {
})); }));
it('should support initial undefined value', fakeAsync(() => { it('should support initial undefined value', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRadioForm); const fixture = initTest(NgModelRadioForm);
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -611,7 +589,7 @@ export function main() {
})); }));
it('should support resetting properly', fakeAsync(() => { it('should support resetting properly', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRadioForm); const fixture = initTest(NgModelRadioForm);
fixture.componentInstance.food = 'chicken'; fixture.componentInstance.food = 'chicken';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -627,7 +605,7 @@ export function main() {
})); }));
it('should support setting value to null and undefined', fakeAsync(() => { it('should support setting value to null and undefined', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelRadioForm); const fixture = initTest(NgModelRadioForm);
fixture.componentInstance.food = 'chicken'; fixture.componentInstance.food = 'chicken';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -655,7 +633,7 @@ export function main() {
describe('select controls', () => { describe('select controls', () => {
it('with option values that are objects', fakeAsync(() => { it('with option values that are objects', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelSelectForm); const fixture = initTest(NgModelSelectForm);
const comp = fixture.componentInstance; const comp = fixture.componentInstance;
comp.cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}]; comp.cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}];
comp.selectedCity = comp.cities[1]; comp.selectedCity = comp.cities[1];
@ -679,7 +657,7 @@ export function main() {
})); }));
it('when new options are added', fakeAsync(() => { it('when new options are added', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelSelectForm); const fixture = initTest(NgModelSelectForm);
const comp = fixture.componentInstance; const comp = fixture.componentInstance;
comp.cities = [{'name': 'SF'}, {'name': 'NYC'}]; comp.cities = [{'name': 'SF'}, {'name': 'NYC'}];
comp.selectedCity = comp.cities[1]; comp.selectedCity = comp.cities[1];
@ -698,7 +676,7 @@ export function main() {
})); }));
it('when options are removed', fakeAsync(() => { it('when options are removed', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelSelectForm); const fixture = initTest(NgModelSelectForm);
const comp = fixture.componentInstance; const comp = fixture.componentInstance;
comp.cities = [{'name': 'SF'}, {'name': 'NYC'}]; comp.cities = [{'name': 'SF'}, {'name': 'NYC'}];
comp.selectedCity = comp.cities[1]; comp.selectedCity = comp.cities[1];
@ -716,7 +694,7 @@ export function main() {
})); }));
it('when option values have same content, but different identities', fakeAsync(() => { it('when option values have same content, but different identities', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelSelectForm); const fixture = initTest(NgModelSelectForm);
const comp = fixture.componentInstance; const comp = fixture.componentInstance;
comp.cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'NYC'}]; comp.cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'NYC'}];
comp.selectedCity = comp.cities[0]; comp.selectedCity = comp.cities[0];
@ -733,7 +711,7 @@ export function main() {
})); }));
it('should work with null option', fakeAsync(() => { it('should work with null option', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelSelectWithNullForm); const fixture = initTest(NgModelSelectWithNullForm);
const comp = fixture.componentInstance; const comp = fixture.componentInstance;
comp.cities = [{'name': 'SF'}, {'name': 'NYC'}]; comp.cities = [{'name': 'SF'}, {'name': 'NYC'}];
comp.selectedCity = null; comp.selectedCity = null;
@ -760,7 +738,7 @@ export function main() {
let comp: NgModelSelectMultipleForm; let comp: NgModelSelectMultipleForm;
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(NgModelSelectMultipleForm); fixture = initTest(NgModelSelectMultipleForm);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}]; comp.cities = [{'name': 'SF'}, {'name': 'NYC'}, {'name': 'Buffalo'}];
}); });
@ -821,7 +799,7 @@ export function main() {
describe('custom value accessors', () => { describe('custom value accessors', () => {
it('should support standard writing to view and model', async(() => { it('should support standard writing to view and model', async(() => {
const fixture = TestBed.createComponent(NgModelCustomWrapper); const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp);
fixture.componentInstance.name = 'Nancy'; fixture.componentInstance.name = 'Nancy';
fixture.detectChanges(); fixture.detectChanges();
fixture.whenStable().then(() => { fixture.whenStable().then(() => {
@ -846,7 +824,7 @@ export function main() {
describe('validation directives', () => { describe('validation directives', () => {
it('required validator should validate checkbox', fakeAsync(() => { it('required validator should validate checkbox', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelCheckboxRequiredValidator); const fixture = initTest(NgModelCheckboxRequiredValidator);
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -882,7 +860,7 @@ export function main() {
})); }));
it('should support dir validators using bindings', fakeAsync(() => { it('should support dir validators using bindings', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelValidationBindings); const fixture = initTest(NgModelValidationBindings);
fixture.componentInstance.required = true; fixture.componentInstance.required = true;
fixture.componentInstance.minLen = 3; fixture.componentInstance.minLen = 3;
fixture.componentInstance.maxLen = 3; fixture.componentInstance.maxLen = 3;
@ -926,7 +904,7 @@ export function main() {
})); }));
it('should support optional fields with string pattern validator', fakeAsync(() => { it('should support optional fields with string pattern validator', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelMultipleValidators); const fixture = initTest(NgModelMultipleValidators);
fixture.componentInstance.required = false; fixture.componentInstance.required = false;
fixture.componentInstance.pattern = '[a-z]+'; fixture.componentInstance.pattern = '[a-z]+';
fixture.detectChanges(); fixture.detectChanges();
@ -948,7 +926,7 @@ export function main() {
})); }));
it('should support optional fields with RegExp pattern validator', fakeAsync(() => { it('should support optional fields with RegExp pattern validator', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelMultipleValidators); const fixture = initTest(NgModelMultipleValidators);
fixture.componentInstance.required = false; fixture.componentInstance.required = false;
fixture.componentInstance.pattern = /^[a-z]+$/; fixture.componentInstance.pattern = /^[a-z]+$/;
fixture.detectChanges(); fixture.detectChanges();
@ -970,7 +948,7 @@ export function main() {
})); }));
it('should support optional fields with minlength validator', fakeAsync(() => { it('should support optional fields with minlength validator', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelMultipleValidators); const fixture = initTest(NgModelMultipleValidators);
fixture.componentInstance.required = false; fixture.componentInstance.required = false;
fixture.componentInstance.minLen = 2; fixture.componentInstance.minLen = 2;
fixture.detectChanges(); fixture.detectChanges();
@ -993,7 +971,7 @@ export function main() {
it('changes on bound properties should change the validation state of the form', it('changes on bound properties should change the validation state of the form',
fakeAsync(() => { fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelValidationBindings); const fixture = initTest(NgModelValidationBindings);
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -1067,7 +1045,7 @@ export function main() {
describe('ngModel corner cases', () => { describe('ngModel corner cases', () => {
it('should update the view when the model is set back to what used to be in the view', it('should update the view when the model is set back to what used to be in the view',
fakeAsync(() => { fakeAsync(() => {
const fixture = TestBed.createComponent(StandaloneNgModel); const fixture = initTest(StandaloneNgModel);
fixture.componentInstance.name = ''; fixture.componentInstance.name = '';
fixture.detectChanges(); fixture.detectChanges();
tick(); tick();
@ -1095,7 +1073,7 @@ export function main() {
})); }));
it('should not crash when validity is checked from a binding', fakeAsync(() => { it('should not crash when validity is checked from a binding', fakeAsync(() => {
const fixture = TestBed.createComponent(NgModelValidBinding); const fixture = initTest(NgModelValidBinding);
tick(); tick();
expect(() => fixture.detectChanges()).not.toThrowError(); expect(() => fixture.detectChanges()).not.toThrowError();
})); }));