/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {NgFor, NgIf} from '@angular/common';
import {Component, Directive, EventEmitter, Input, Output, forwardRef} from '@angular/core';
import {ComponentFixture, TestBed, TestComponentBuilder, fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {AsyncTestCompleter, afterEach, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';
import {ControlValueAccessor, FormArray, FormControl, FormGroup, FormsModule, NG_ASYNC_VALIDATORS, NG_VALIDATORS, NgControl, ReactiveFormsModule, Validator, Validators} from '@angular/forms';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {dispatchEvent} from '@angular/platform-browser/testing/browser_util';
import {ListWrapper} from '../src/facade/collection';
export function main() {
describe('reactive forms integration tests', () => {
beforeEach(() => {
TestBed.configureTestingModule({imports: [FormsModule, ReactiveFormsModule]});
});
it('should initialize DOM elements with the given form object',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form =
new FormGroup({'login': new FormControl('loginValue')});
fixture.detectChanges();
var input = fixture.debugElement.query(By.css('input'));
expect(input.nativeElement.value).toEqual('loginValue');
async.done();
});
}));
it('should update the form group values on DOM change',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
var form = new FormGroup({'login': new FormControl('oldValue')});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
var input = fixture.debugElement.query(By.css('input'));
input.nativeElement.value = 'updatedValue';
dispatchEvent(input.nativeElement, 'input');
expect(form.value).toEqual({'login': 'updatedValue'});
async.done();
});
}));
it('should ignore the change event for ',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
var form = new FormGroup({'login': new FormControl('oldValue')});
const t = `
`;
let fixture = tcb.overrideTemplate(MyComp8, t).createFakeAsync(MyComp8);
tick();
fixture.debugElement.componentInstance.form = new FormGroup({});
fixture.debugElement.componentInstance.name = 'old';
tick();
var form = fixture.debugElement.query(By.css('form'));
dispatchEvent(form.nativeElement, 'submit');
tick();
expect(fixture.debugElement.componentInstance.name).toEqual('updated');
})));
it('should mark formGroup as submitted on submit event',
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
const t = `
{{data}}
`;
var fixture: ComponentFixture;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((root) => { fixture = root; });
tick();
fixture.debugElement.componentInstance.form = new FormGroup({});
fixture.debugElement.componentInstance.data = false;
tick();
var form = fixture.debugElement.query(By.css('form'));
dispatchEvent(form.nativeElement, 'submit');
tick();
expect(fixture.debugElement.componentInstance.data).toEqual(true);
})));
it('should work with single controls',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
var control = new FormControl('loginValue');
const t = ``;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = control;
fixture.detectChanges();
var input = fixture.debugElement.query(By.css('input'));
expect(input.nativeElement.value).toEqual('loginValue');
input.nativeElement.value = 'updatedValue';
dispatchEvent(input.nativeElement, 'input');
expect(control.value).toEqual('updatedValue');
async.done();
});
}));
it('should update DOM elements when rebinding the form group',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form =
new FormGroup({'login': new FormControl('oldValue')});
fixture.detectChanges();
fixture.debugElement.componentInstance.form =
new FormGroup({'login': new FormControl('newValue')});
fixture.detectChanges();
var input = fixture.debugElement.query(By.css('input'));
expect(input.nativeElement.value).toEqual('newValue');
async.done();
});
}));
it('should update DOM elements when updating the value of a control',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
var login = new FormControl('oldValue');
var form = new FormGroup({'login': login});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
login.setValue('newValue');
fixture.detectChanges();
var input = fixture.debugElement.query(By.css('input'));
expect(input.nativeElement.value).toEqual('newValue');
async.done();
});
}));
it('should mark controls as touched after interacting with the DOM control',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
var login = new FormControl('oldValue');
var form = new FormGroup({'login': login});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
var loginEl = fixture.debugElement.query(By.css('input'));
expect(login.touched).toBe(false);
dispatchEvent(loginEl.nativeElement, 'blur');
expect(login.touched).toBe(true);
async.done();
});
}));
it('should mark controls as dirty before emitting a value change event',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const login = new FormControl('oldValue');
const form = new FormGroup({'login': login});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
login.valueChanges.subscribe(() => {
expect(login.dirty).toBe(true);
async.done();
});
const loginEl = fixture.debugElement.query(By.css('input')).nativeElement;
loginEl.value = 'newValue';
dispatchEvent(loginEl, 'input');
});
}));
it('should clear value in UI when form resets programmatically',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const login = new FormControl('oldValue');
const form = new FormGroup({'login': login});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
login.setValue('new value');
const loginEl = fixture.debugElement.query(By.css('input')).nativeElement;
expect(loginEl.value).toBe('new value');
form.reset();
expect(loginEl.value).toBe('');
async.done();
});
}));
it('should set value in UI when form resets to that value programmatically',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const login = new FormControl('oldValue');
const form = new FormGroup({'login': login});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
login.setValue('new value');
const loginEl = fixture.debugElement.query(By.css('input')).nativeElement;
expect(loginEl.value).toBe('new value');
form.reset({'login': 'oldValue'});
expect(loginEl.value).toBe('oldValue');
async.done();
});
}));
it('should mark control as pristine before emitting a value change event when resetting ',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const login = new FormControl('oldValue');
const form = new FormGroup({'login': login});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.detectChanges();
const loginEl = fixture.debugElement.query(By.css('input')).nativeElement;
loginEl.value = 'newValue';
dispatchEvent(loginEl, 'input');
expect(login.pristine).toBe(false);
login.valueChanges.subscribe(() => {
expect(login.pristine).toBe(true);
async.done();
});
form.reset();
});
}));
it('should support form arrays',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
const form = new FormGroup({cities: cityArray});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.debugElement.componentInstance.cityArray = cityArray;
fixture.detectChanges();
const inputs = fixture.debugElement.queryAll(By.css('input'));
expect(inputs[0].nativeElement.value).toEqual('SF');
expect(inputs[1].nativeElement.value).toEqual('NY');
expect(fixture.componentInstance.form.value).toEqual({cities: ['SF', 'NY']});
inputs[0].nativeElement.value = 'LA';
dispatchEvent(inputs[0].nativeElement, 'input');
fixture.detectChanges();
expect(fixture.componentInstance.form.value).toEqual({cities: ['LA', 'NY']});
async.done();
});
}));
it('should support form groups nested in form arrays',
inject(
[TestComponentBuilder, AsyncTestCompleter],
(tcb: TestComponentBuilder, async: AsyncTestCompleter) => {
const cityArray = new FormArray([
new FormGroup({town: new FormControl('SF'), state: new FormControl('CA')}),
new FormGroup({town: new FormControl('NY'), state: new FormControl('NY')})
]);
const form = new FormGroup({cities: cityArray});
const t = `
`;
tcb.overrideTemplate(MyComp8, t).createAsync(MyComp8).then((fixture) => {
fixture.debugElement.componentInstance.form = form;
fixture.debugElement.componentInstance.cityArray = cityArray;
fixture.detectChanges();
const inputs = fixture.debugElement.queryAll(By.css('input'));
expect(inputs[0].nativeElement.value).toEqual('SF');
expect(inputs[1].nativeElement.value).toEqual('CA');
expect(inputs[2].nativeElement.value).toEqual('NY');
expect(inputs[3].nativeElement.value).toEqual('NY');
expect(fixture.componentInstance.form.value).toEqual({
cities: [{town: 'SF', state: 'CA'}, {town: 'NY', state: 'NY'}]
});
inputs[0].nativeElement.value = 'LA';
dispatchEvent(inputs[0].nativeElement, 'input');
fixture.detectChanges();
expect(fixture.componentInstance.form.value).toEqual({
cities: [{town: 'LA', state: 'CA'}, {town: 'NY', state: 'NY'}]
});
async.done();
});
}));
it('should support pushing new controls to form arrays',
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
const cityArray = new FormArray([new FormControl('SF'), new FormControl('NY')]);
const form = new FormGroup({cities: cityArray});
const t = `