From 3ca1a57f8111316fcbd6d646cae80a732bebdc9f Mon Sep 17 00:00:00 2001 From: Kara Erickson Date: Tue, 6 Nov 2018 14:02:22 -0800 Subject: [PATCH] test(ivy): run forms tests with ivy on ci (#26968) PR Close #26968 --- packages/forms/test/BUILD.bazel | 7 +- .../forms/test/reactive_integration_spec.ts | 310 +++++++------- .../forms/test/template_integration_spec.ts | 395 +++++++++--------- .../test/value_accessor_integration_spec.ts | 38 +- 4 files changed, 388 insertions(+), 362 deletions(-) diff --git a/packages/forms/test/BUILD.bazel b/packages/forms/test/BUILD.bazel index 5f8e90e682..d0fceb4806 100644 --- a/packages/forms/test/BUILD.bazel +++ b/packages/forms/test/BUILD.bazel @@ -10,6 +10,7 @@ ts_library( "//packages/forms", "//packages/platform-browser", "//packages/platform-browser/testing", + "//packages/private/testing", "@rxjs", "@rxjs//operators", ], @@ -18,9 +19,6 @@ ts_library( jasmine_node_test( name = "test", bootstrap = ["angular/tools/testing/init_node_spec.js"], - tags = [ - "fixme-ivy-aot", - ], deps = [ ":test_lib", "//tools/testing:node", @@ -29,9 +27,6 @@ jasmine_node_test( ts_web_test_suite( name = "test_web", - tags = [ - "fixme-ivy-aot", - ], deps = [ ":test_lib", ], diff --git a/packages/forms/test/reactive_integration_spec.ts b/packages/forms/test/reactive_integration_spec.ts index 22a1c16191..49f456bf2a 100644 --- a/packages/forms/test/reactive_integration_spec.ts +++ b/packages/forms/test/reactive_integration_spec.ts @@ -12,6 +12,7 @@ import {AbstractControl, AsyncValidator, AsyncValidatorFn, COMPOSITION_BUFFER_MO 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/src/browser_util'; +import {fixmeIvy} from '@angular/private/testing'; import {merge, timer} from 'rxjs'; import {tap} from 'rxjs/operators'; @@ -712,127 +713,133 @@ import {MyInput, MyInputForm} from './value_accessor_integration_spec'; }); - describe('setting status classes', () => { - it('should work with single fields', () => { - const fixture = initTest(FormControlComp); - const control = new FormControl('', Validators.required); - fixture.componentInstance.control = control; - fixture.detectChanges(); + fixmeIvy('Host bindings to styles do not yet work') && + describe('setting status classes', () => { + it('should work with single fields', () => { + const fixture = initTest(FormControlComp); + const control = new FormControl('', Validators.required); + fixture.componentInstance.control = control; + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); + const input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); + expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - }); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + }); - it('should work with single fields and async validators', fakeAsync(() => { - const fixture = initTest(FormControlComp); - const control = new FormControl('', null !, uniqLoginAsyncValidator('good')); - fixture.debugElement.componentInstance.control = control; - fixture.detectChanges(); + it('should work with single fields and async validators', fakeAsync(() => { + const fixture = initTest(FormControlComp); + const control = new FormControl('', null !, uniqLoginAsyncValidator('good')); + fixture.debugElement.componentInstance.control = control; + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual(['ng-pending', 'ng-pristine', 'ng-untouched']); + const input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-pending', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-pending', 'ng-pristine', 'ng-touched']); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); + expect(sortedClassList(input)).toEqual(['ng-pending', 'ng-pristine', 'ng-touched']); - input.value = 'good'; - dispatchEvent(input, 'input'); - tick(); - fixture.detectChanges(); + input.value = 'good'; + dispatchEvent(input, 'input'); + tick(); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - })); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + })); - it('should work with single fields that combines async and sync validators', fakeAsync(() => { - const fixture = initTest(FormControlComp); - const control = - new FormControl('', Validators.required, uniqLoginAsyncValidator('good')); - fixture.debugElement.componentInstance.control = control; - fixture.detectChanges(); + it('should work with single fields that combines async and sync validators', + fakeAsync(() => { + const fixture = initTest(FormControlComp); + const control = + new FormControl('', Validators.required, uniqLoginAsyncValidator('good')); + fixture.debugElement.componentInstance.control = control; + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); + const input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); + expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); - input.value = 'bad'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'bad'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-pending', 'ng-touched']); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-pending', 'ng-touched']); - tick(); - fixture.detectChanges(); + tick(); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-invalid', 'ng-touched']); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-invalid', 'ng-touched']); - input.value = 'good'; - dispatchEvent(input, 'input'); - tick(); - fixture.detectChanges(); + input.value = 'good'; + dispatchEvent(input, 'input'); + tick(); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - })); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + })); - it('should work with single fields in parent forms', () => { - const fixture = initTest(FormGroupComp); - const form = new FormGroup({'login': new FormControl('', Validators.required)}); - fixture.componentInstance.form = form; - fixture.detectChanges(); + it('should work with single fields in parent forms', () => { + const fixture = initTest(FormGroupComp); + const form = new FormGroup({'login': new FormControl('', Validators.required)}); + fixture.componentInstance.form = form; + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); + const input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); + expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - }); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + }); - it('should work with formGroup', () => { - const fixture = initTest(FormGroupComp); - const form = new FormGroup({'login': new FormControl('', Validators.required)}); - fixture.componentInstance.form = form; - fixture.detectChanges(); + it('should work with formGroup', () => { + const fixture = initTest(FormGroupComp); + const form = new FormGroup({'login': new FormControl('', Validators.required)}); + fixture.componentInstance.form = form; + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - const formEl = fixture.debugElement.query(By.css('form')).nativeElement; + const input = fixture.debugElement.query(By.css('input')).nativeElement; + const formEl = fixture.debugElement.query(By.css('form')).nativeElement; - expect(sortedClassList(formEl)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); + expect(sortedClassList(formEl)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(formEl)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); + expect(sortedClassList(formEl)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(formEl)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - }); + expect(sortedClassList(formEl)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + }); - }); + }); describe('updateOn options', () => { @@ -1911,80 +1918,81 @@ import {MyInput, MyInputForm} from './value_accessor_integration_spec'; expect(form.valid).toEqual(true); }); - it('changes on bound properties should change the validation state of the form', () => { - const fixture = initTest(ValidationBindingsForm); - const form = new FormGroup({ - 'login': new FormControl(''), - 'min': new FormControl(''), - 'max': new FormControl(''), - 'pattern': new FormControl('') - }); - fixture.componentInstance.form = form; - fixture.detectChanges(); + fixmeIvy('host attribute instructions are not generated properly') && + it('changes on bound properties should change the validation state of the form', () => { + const fixture = initTest(ValidationBindingsForm); + const form = new FormGroup({ + 'login': new FormControl(''), + 'min': new FormControl(''), + 'max': new FormControl(''), + 'pattern': new FormControl('') + }); + fixture.componentInstance.form = form; + fixture.detectChanges(); - const required = fixture.debugElement.query(By.css('[name=required]')); - const minLength = fixture.debugElement.query(By.css('[name=minlength]')); - const maxLength = fixture.debugElement.query(By.css('[name=maxlength]')); - const pattern = fixture.debugElement.query(By.css('[name=pattern]')); + const required = fixture.debugElement.query(By.css('[name=required]')); + const minLength = fixture.debugElement.query(By.css('[name=minlength]')); + const maxLength = fixture.debugElement.query(By.css('[name=maxlength]')); + const pattern = fixture.debugElement.query(By.css('[name=pattern]')); - required.nativeElement.value = ''; - minLength.nativeElement.value = '1'; - maxLength.nativeElement.value = '1234'; - pattern.nativeElement.value = '12'; + required.nativeElement.value = ''; + minLength.nativeElement.value = '1'; + maxLength.nativeElement.value = '1234'; + pattern.nativeElement.value = '12'; - dispatchEvent(required.nativeElement, 'input'); - dispatchEvent(minLength.nativeElement, 'input'); - dispatchEvent(maxLength.nativeElement, 'input'); - dispatchEvent(pattern.nativeElement, 'input'); + dispatchEvent(required.nativeElement, 'input'); + dispatchEvent(minLength.nativeElement, 'input'); + dispatchEvent(maxLength.nativeElement, 'input'); + dispatchEvent(pattern.nativeElement, 'input'); - expect(form.hasError('required', ['login'])).toEqual(false); - expect(form.hasError('minlength', ['min'])).toEqual(false); - expect(form.hasError('maxlength', ['max'])).toEqual(false); - expect(form.hasError('pattern', ['pattern'])).toEqual(false); - expect(form.valid).toEqual(true); + expect(form.hasError('required', ['login'])).toEqual(false); + expect(form.hasError('minlength', ['min'])).toEqual(false); + expect(form.hasError('maxlength', ['max'])).toEqual(false); + expect(form.hasError('pattern', ['pattern'])).toEqual(false); + expect(form.valid).toEqual(true); - fixture.componentInstance.required = true; - fixture.componentInstance.minLen = 3; - fixture.componentInstance.maxLen = 3; - fixture.componentInstance.pattern = '.{3,}'; - fixture.detectChanges(); + fixture.componentInstance.required = true; + fixture.componentInstance.minLen = 3; + fixture.componentInstance.maxLen = 3; + fixture.componentInstance.pattern = '.{3,}'; + fixture.detectChanges(); - dispatchEvent(required.nativeElement, 'input'); - dispatchEvent(minLength.nativeElement, 'input'); - dispatchEvent(maxLength.nativeElement, 'input'); - dispatchEvent(pattern.nativeElement, 'input'); + dispatchEvent(required.nativeElement, 'input'); + dispatchEvent(minLength.nativeElement, 'input'); + dispatchEvent(maxLength.nativeElement, 'input'); + dispatchEvent(pattern.nativeElement, 'input'); - expect(form.hasError('required', ['login'])).toEqual(true); - expect(form.hasError('minlength', ['min'])).toEqual(true); - expect(form.hasError('maxlength', ['max'])).toEqual(true); - expect(form.hasError('pattern', ['pattern'])).toEqual(true); - expect(form.valid).toEqual(false); + expect(form.hasError('required', ['login'])).toEqual(true); + expect(form.hasError('minlength', ['min'])).toEqual(true); + expect(form.hasError('maxlength', ['max'])).toEqual(true); + expect(form.hasError('pattern', ['pattern'])).toEqual(true); + expect(form.valid).toEqual(false); - expect(required.nativeElement.getAttribute('required')).toEqual(''); - expect(fixture.componentInstance.minLen.toString()) - .toEqual(minLength.nativeElement.getAttribute('minlength')); - expect(fixture.componentInstance.maxLen.toString()) - .toEqual(maxLength.nativeElement.getAttribute('maxlength')); - expect(fixture.componentInstance.pattern.toString()) - .toEqual(pattern.nativeElement.getAttribute('pattern')); + expect(required.nativeElement.getAttribute('required')).toEqual(''); + expect(fixture.componentInstance.minLen.toString()) + .toEqual(minLength.nativeElement.getAttribute('minlength')); + expect(fixture.componentInstance.maxLen.toString()) + .toEqual(maxLength.nativeElement.getAttribute('maxlength')); + expect(fixture.componentInstance.pattern.toString()) + .toEqual(pattern.nativeElement.getAttribute('pattern')); - fixture.componentInstance.required = false; - fixture.componentInstance.minLen = null !; - fixture.componentInstance.maxLen = null !; - fixture.componentInstance.pattern = null !; - fixture.detectChanges(); + fixture.componentInstance.required = false; + fixture.componentInstance.minLen = null !; + fixture.componentInstance.maxLen = null !; + fixture.componentInstance.pattern = null !; + fixture.detectChanges(); - expect(form.hasError('required', ['login'])).toEqual(false); - expect(form.hasError('minlength', ['min'])).toEqual(false); - expect(form.hasError('maxlength', ['max'])).toEqual(false); - expect(form.hasError('pattern', ['pattern'])).toEqual(false); - expect(form.valid).toEqual(true); + expect(form.hasError('required', ['login'])).toEqual(false); + expect(form.hasError('minlength', ['min'])).toEqual(false); + expect(form.hasError('maxlength', ['max'])).toEqual(false); + expect(form.hasError('pattern', ['pattern'])).toEqual(false); + expect(form.valid).toEqual(true); - expect(required.nativeElement.getAttribute('required')).toEqual(null); - expect(required.nativeElement.getAttribute('minlength')).toEqual(null); - expect(required.nativeElement.getAttribute('maxlength')).toEqual(null); - expect(required.nativeElement.getAttribute('pattern')).toEqual(null); - }); + expect(required.nativeElement.getAttribute('required')).toEqual(null); + expect(required.nativeElement.getAttribute('minlength')).toEqual(null); + expect(required.nativeElement.getAttribute('maxlength')).toEqual(null); + expect(required.nativeElement.getAttribute('pattern')).toEqual(null); + }); it('should support rebound controls with rebound validators', () => { const fixture = initTest(ValidationBindingsForm); diff --git a/packages/forms/test/template_integration_spec.ts b/packages/forms/test/template_integration_spec.ts index ed487c032e..bd1515c203 100644 --- a/packages/forms/test/template_integration_spec.ts +++ b/packages/forms/test/template_integration_spec.ts @@ -12,6 +12,7 @@ import {AbstractControl, AsyncValidator, COMPOSITION_BUFFER_MODE, FormControl, F 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/src/browser_util'; +import {fixmeIvy} from '@angular/private/testing'; import {merge} from 'rxjs'; import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integration_spec'; @@ -148,85 +149,101 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat expect(form.value).toEqual({}); })); - it('should set status classes with ngModel', async(() => { - const fixture = initTest(NgModelForm); - fixture.componentInstance.name = 'aa'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); + fixmeIvy('whenStable not working') && + it('should set status classes with ngModel', async(() => { + const fixture = initTest(NgModelForm); + fixture.componentInstance.name = 'aa'; + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); + const input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); + expect(sortedClassList(input)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-touched' + ]); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - }); - })); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + }); + })); - it('should set status classes with ngModel and async validators', fakeAsync(() => { + fixmeIvy('whenStable not working') && + it('should set status classes with ngModel and async validators', fakeAsync(() => { - const fixture = initTest(NgModelAsyncValidation, NgAsyncValidator); - fixture.whenStable().then(() => { - fixture.detectChanges(); + const fixture = initTest(NgModelAsyncValidation, NgAsyncValidator); + fixture.whenStable().then(() => { + fixture.detectChanges(); - const input = fixture.debugElement.query(By.css('input')).nativeElement; - expect(sortedClassList(input)).toEqual(['ng-pending', 'ng-pristine', 'ng-untouched']); + const input = fixture.debugElement.query(By.css('input')).nativeElement; + expect(sortedClassList(input)).toEqual([ + 'ng-pending', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-pending', 'ng-pristine', 'ng-touched']); + expect(sortedClassList(input)).toEqual([ + 'ng-pending', 'ng-pristine', 'ng-touched' + ]); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - tick(); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + tick(); + fixture.detectChanges(); - expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - }); - })); + expect(sortedClassList(input)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + }); + })); - it('should set status classes with ngModelGroup and ngForm', async(() => { - const fixture = initTest(NgModelGroupForm); - fixture.componentInstance.first = ''; - fixture.detectChanges(); + fixmeIvy('whenStable not working') && + it('should set status classes with ngModelGroup and ngForm', async(() => { + const fixture = initTest(NgModelGroupForm); + fixture.componentInstance.first = ''; + fixture.detectChanges(); - const form = fixture.debugElement.query(By.css('form')).nativeElement; - const modelGroup = fixture.debugElement.query(By.css('[ngModelGroup]')).nativeElement; - const input = fixture.debugElement.query(By.css('input')).nativeElement; + const form = fixture.debugElement.query(By.css('form')).nativeElement; + const modelGroup = + fixture.debugElement.query(By.css('[ngModelGroup]')).nativeElement; + const input = fixture.debugElement.query(By.css('input')).nativeElement; - // ngModelGroup creates its control asynchronously - fixture.whenStable().then(() => { - fixture.detectChanges(); - expect(sortedClassList(modelGroup)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-untouched' - ]); + // ngModelGroup creates its control asynchronously + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(sortedClassList(modelGroup)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - expect(sortedClassList(form)).toEqual(['ng-invalid', 'ng-pristine', 'ng-untouched']); + expect(sortedClassList(form)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-untouched' + ]); - dispatchEvent(input, 'blur'); - fixture.detectChanges(); + dispatchEvent(input, 'blur'); + fixture.detectChanges(); - expect(sortedClassList(modelGroup)).toEqual([ - 'ng-invalid', 'ng-pristine', 'ng-touched' - ]); - expect(sortedClassList(form)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); + expect(sortedClassList(modelGroup)).toEqual([ + 'ng-invalid', 'ng-pristine', 'ng-touched' + ]); + expect(sortedClassList(form)).toEqual(['ng-invalid', 'ng-pristine', 'ng-touched']); - input.value = 'updatedValue'; - dispatchEvent(input, 'input'); - fixture.detectChanges(); + input.value = 'updatedValue'; + dispatchEvent(input, 'input'); + fixture.detectChanges(); - expect(sortedClassList(modelGroup)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - expect(sortedClassList(form)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); - }); - })); + expect(sortedClassList(modelGroup)).toEqual([ + 'ng-dirty', 'ng-touched', 'ng-valid' + ]); + expect(sortedClassList(form)).toEqual(['ng-dirty', 'ng-touched', 'ng-valid']); + }); + })); it('should not create a template-driven form when ngNoForm is used', () => { const fixture = initTest(NgNoFormComp); @@ -1167,22 +1184,23 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat expect(input.nativeElement.disabled).toBe(true); })); - it('should disable a custom control if disabled attr is added', async(() => { - const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp); - fixture.componentInstance.name = 'Nancy'; - fixture.componentInstance.isDisabled = true; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - const form = fixture.debugElement.children[0].injector.get(NgForm); - expect(form.control.get('name') !.disabled).toBe(true); + fixmeIvy('whenStable not working') && + it('should disable a custom control if disabled attr is added', async(() => { + const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp); + fixture.componentInstance.name = 'Nancy'; + fixture.componentInstance.isDisabled = true; + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + const form = fixture.debugElement.children[0].injector.get(NgForm); + expect(form.control.get('name') !.disabled).toBe(true); - const customInput = fixture.debugElement.query(By.css('[name="custom"]')); - expect(customInput.nativeElement.disabled).toEqual(true); - }); - }); - })); + const customInput = fixture.debugElement.query(By.css('[name="custom"]')); + expect(customInput.nativeElement.disabled).toEqual(true); + }); + }); + })); it('should disable a control with unbound disabled attr', fakeAsync(() => { TestBed.overrideComponent(NgModelForm, { @@ -1213,41 +1231,42 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat describe('validation directives', () => { - it('required validator should validate checkbox', fakeAsync(() => { - const fixture = initTest(NgModelCheckboxRequiredValidator); - fixture.detectChanges(); - tick(); + fixmeIvy('RequiredValidator provided instead of CheckboxRequiredValidator') && + it('required validator should validate checkbox', fakeAsync(() => { + const fixture = initTest(NgModelCheckboxRequiredValidator); + fixture.detectChanges(); + tick(); - const control = - fixture.debugElement.children[0].injector.get(NgForm).control.get('checkbox') !; + const control = + fixture.debugElement.children[0].injector.get(NgForm).control.get('checkbox') !; - const input = fixture.debugElement.query(By.css('input')); - expect(input.nativeElement.checked).toBe(false); - expect(control.hasError('required')).toBe(false); + const input = fixture.debugElement.query(By.css('input')); + expect(input.nativeElement.checked).toBe(false); + expect(control.hasError('required')).toBe(false); - fixture.componentInstance.required = true; - fixture.detectChanges(); - tick(); + fixture.componentInstance.required = true; + fixture.detectChanges(); + tick(); - expect(input.nativeElement.checked).toBe(false); - expect(control.hasError('required')).toBe(true); + expect(input.nativeElement.checked).toBe(false); + expect(control.hasError('required')).toBe(true); - input.nativeElement.checked = true; - dispatchEvent(input.nativeElement, 'change'); - fixture.detectChanges(); - tick(); + input.nativeElement.checked = true; + dispatchEvent(input.nativeElement, 'change'); + fixture.detectChanges(); + tick(); - expect(input.nativeElement.checked).toBe(true); - expect(control.hasError('required')).toBe(false); + expect(input.nativeElement.checked).toBe(true); + expect(control.hasError('required')).toBe(false); - input.nativeElement.checked = false; - dispatchEvent(input.nativeElement, 'change'); - fixture.detectChanges(); - tick(); + input.nativeElement.checked = false; + dispatchEvent(input.nativeElement, 'change'); + fixture.detectChanges(); + tick(); - expect(input.nativeElement.checked).toBe(false); - expect(control.hasError('required')).toBe(true); - })); + expect(input.nativeElement.checked).toBe(false); + expect(control.hasError('required')).toBe(true); + })); it('should validate email', fakeAsync(() => { const fixture = initTest(NgModelEmailValidator); @@ -1401,106 +1420,108 @@ import {NgModelCustomComp, NgModelCustomWrapper} from './value_accessor_integrat expect(form.control.hasError('minlength', ['tovalidate'])).toBeTruthy(); })); - it('changes on bound properties should change the validation state of the form', - fakeAsync(() => { - const fixture = initTest(NgModelValidationBindings); - fixture.detectChanges(); - tick(); + fixmeIvy('host attribute instructions are not generated properly') && + it('changes on bound properties should change the validation state of the form', + fakeAsync(() => { + const fixture = initTest(NgModelValidationBindings); + fixture.detectChanges(); + tick(); - const required = fixture.debugElement.query(By.css('[name=required]')); - const minLength = fixture.debugElement.query(By.css('[name=minlength]')); - const maxLength = fixture.debugElement.query(By.css('[name=maxlength]')); - const pattern = fixture.debugElement.query(By.css('[name=pattern]')); + const required = fixture.debugElement.query(By.css('[name=required]')); + const minLength = fixture.debugElement.query(By.css('[name=minlength]')); + const maxLength = fixture.debugElement.query(By.css('[name=maxlength]')); + const pattern = fixture.debugElement.query(By.css('[name=pattern]')); - required.nativeElement.value = ''; - minLength.nativeElement.value = '1'; - maxLength.nativeElement.value = '1234'; - pattern.nativeElement.value = '12'; + required.nativeElement.value = ''; + minLength.nativeElement.value = '1'; + maxLength.nativeElement.value = '1234'; + pattern.nativeElement.value = '12'; - dispatchEvent(required.nativeElement, 'input'); - dispatchEvent(minLength.nativeElement, 'input'); - dispatchEvent(maxLength.nativeElement, 'input'); - dispatchEvent(pattern.nativeElement, 'input'); + dispatchEvent(required.nativeElement, 'input'); + dispatchEvent(minLength.nativeElement, 'input'); + dispatchEvent(maxLength.nativeElement, 'input'); + dispatchEvent(pattern.nativeElement, 'input'); - const form = fixture.debugElement.children[0].injector.get(NgForm); - expect(form.control.hasError('required', ['required'])).toEqual(false); - expect(form.control.hasError('minlength', ['minlength'])).toEqual(false); - expect(form.control.hasError('maxlength', ['maxlength'])).toEqual(false); - expect(form.control.hasError('pattern', ['pattern'])).toEqual(false); - expect(form.valid).toEqual(true); + const form = fixture.debugElement.children[0].injector.get(NgForm); + expect(form.control.hasError('required', ['required'])).toEqual(false); + expect(form.control.hasError('minlength', ['minlength'])).toEqual(false); + expect(form.control.hasError('maxlength', ['maxlength'])).toEqual(false); + expect(form.control.hasError('pattern', ['pattern'])).toEqual(false); + expect(form.valid).toEqual(true); - fixture.componentInstance.required = true; - fixture.componentInstance.minLen = 3; - fixture.componentInstance.maxLen = 3; - fixture.componentInstance.pattern = '.{3,}'; - fixture.detectChanges(); + fixture.componentInstance.required = true; + fixture.componentInstance.minLen = 3; + fixture.componentInstance.maxLen = 3; + fixture.componentInstance.pattern = '.{3,}'; + fixture.detectChanges(); - dispatchEvent(required.nativeElement, 'input'); - dispatchEvent(minLength.nativeElement, 'input'); - dispatchEvent(maxLength.nativeElement, 'input'); - dispatchEvent(pattern.nativeElement, 'input'); + dispatchEvent(required.nativeElement, 'input'); + dispatchEvent(minLength.nativeElement, 'input'); + dispatchEvent(maxLength.nativeElement, 'input'); + dispatchEvent(pattern.nativeElement, 'input'); - expect(form.control.hasError('required', ['required'])).toEqual(true); - expect(form.control.hasError('minlength', ['minlength'])).toEqual(true); - expect(form.control.hasError('maxlength', ['maxlength'])).toEqual(true); - expect(form.control.hasError('pattern', ['pattern'])).toEqual(true); - expect(form.valid).toEqual(false); + expect(form.control.hasError('required', ['required'])).toEqual(true); + expect(form.control.hasError('minlength', ['minlength'])).toEqual(true); + expect(form.control.hasError('maxlength', ['maxlength'])).toEqual(true); + expect(form.control.hasError('pattern', ['pattern'])).toEqual(true); + expect(form.valid).toEqual(false); - expect(required.nativeElement.getAttribute('required')).toEqual(''); - expect(fixture.componentInstance.minLen.toString()) - .toEqual(minLength.nativeElement.getAttribute('minlength')); - expect(fixture.componentInstance.maxLen.toString()) - .toEqual(maxLength.nativeElement.getAttribute('maxlength')); - expect(fixture.componentInstance.pattern.toString()) - .toEqual(pattern.nativeElement.getAttribute('pattern')); + expect(required.nativeElement.getAttribute('required')).toEqual(''); + expect(fixture.componentInstance.minLen.toString()) + .toEqual(minLength.nativeElement.getAttribute('minlength')); + expect(fixture.componentInstance.maxLen.toString()) + .toEqual(maxLength.nativeElement.getAttribute('maxlength')); + expect(fixture.componentInstance.pattern.toString()) + .toEqual(pattern.nativeElement.getAttribute('pattern')); - fixture.componentInstance.required = false; - fixture.componentInstance.minLen = null !; - fixture.componentInstance.maxLen = null !; - fixture.componentInstance.pattern = null !; - fixture.detectChanges(); + fixture.componentInstance.required = false; + fixture.componentInstance.minLen = null !; + fixture.componentInstance.maxLen = null !; + fixture.componentInstance.pattern = null !; + fixture.detectChanges(); - expect(form.control.hasError('required', ['required'])).toEqual(false); - expect(form.control.hasError('minlength', ['minlength'])).toEqual(false); - expect(form.control.hasError('maxlength', ['maxlength'])).toEqual(false); - expect(form.control.hasError('pattern', ['pattern'])).toEqual(false); - expect(form.valid).toEqual(true); + expect(form.control.hasError('required', ['required'])).toEqual(false); + expect(form.control.hasError('minlength', ['minlength'])).toEqual(false); + expect(form.control.hasError('maxlength', ['maxlength'])).toEqual(false); + expect(form.control.hasError('pattern', ['pattern'])).toEqual(false); + expect(form.valid).toEqual(true); - expect(required.nativeElement.getAttribute('required')).toEqual(null); - expect(required.nativeElement.getAttribute('minlength')).toEqual(null); - expect(required.nativeElement.getAttribute('maxlength')).toEqual(null); - expect(required.nativeElement.getAttribute('pattern')).toEqual(null); - })); + expect(required.nativeElement.getAttribute('required')).toEqual(null); + expect(required.nativeElement.getAttribute('minlength')).toEqual(null); + expect(required.nativeElement.getAttribute('maxlength')).toEqual(null); + expect(required.nativeElement.getAttribute('pattern')).toEqual(null); + })); - it('should update control status', fakeAsync(() => { - const fixture = initTest(NgModelChangeState); - const inputEl = fixture.debugElement.query(By.css('input')); - const inputNativeEl = inputEl.nativeElement; - const onNgModelChange = jasmine.createSpy('onNgModelChange'); - fixture.componentInstance.onNgModelChange = onNgModelChange; - fixture.detectChanges(); - tick(); + fixmeIvy('ngModelChange callback never called') && + it('should update control status', fakeAsync(() => { + const fixture = initTest(NgModelChangeState); + const inputEl = fixture.debugElement.query(By.css('input')); + const inputNativeEl = inputEl.nativeElement; + const onNgModelChange = jasmine.createSpy('onNgModelChange'); + fixture.componentInstance.onNgModelChange = onNgModelChange; + fixture.detectChanges(); + tick(); - expect(onNgModelChange).not.toHaveBeenCalled(); + expect(onNgModelChange).not.toHaveBeenCalled(); - inputNativeEl.value = 'updated'; - onNgModelChange.and.callFake((ngModel: NgModel) => { - expect(ngModel.invalid).toBe(true); - expect(ngModel.value).toBe('updated'); - }); - dispatchEvent(inputNativeEl, 'input'); - expect(onNgModelChange).toHaveBeenCalled(); - tick(); + inputNativeEl.value = 'updated'; + onNgModelChange.and.callFake((ngModel: NgModel) => { + expect(ngModel.invalid).toBe(true); + expect(ngModel.value).toBe('updated'); + }); + dispatchEvent(inputNativeEl, 'input'); + expect(onNgModelChange).toHaveBeenCalled(); + tick(); - inputNativeEl.value = '333'; - onNgModelChange.and.callFake((ngModel: NgModel) => { - expect(ngModel.invalid).toBe(false); - expect(ngModel.value).toBe('333'); - }); - dispatchEvent(inputNativeEl, 'input'); - expect(onNgModelChange).toHaveBeenCalledTimes(2); - tick(); - })); + inputNativeEl.value = '333'; + onNgModelChange.and.callFake((ngModel: NgModel) => { + expect(ngModel.invalid).toBe(false); + expect(ngModel.value).toBe('333'); + }); + dispatchEvent(inputNativeEl, 'input'); + expect(onNgModelChange).toHaveBeenCalledTimes(2); + tick(); + })); }); diff --git a/packages/forms/test/value_accessor_integration_spec.ts b/packages/forms/test/value_accessor_integration_spec.ts index 3a9c8317cd..a10a531808 100644 --- a/packages/forms/test/value_accessor_integration_spec.ts +++ b/packages/forms/test/value_accessor_integration_spec.ts @@ -11,6 +11,7 @@ import {ComponentFixture, TestBed, async, fakeAsync, tick} from '@angular/core/t import {AbstractControl, ControlValueAccessor, FormControl, FormGroup, FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, NgControl, NgForm, NgModel, ReactiveFormsModule, Validators} from '@angular/forms'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util'; +import {fixmeIvy} from '@angular/private/testing'; { describe('value accessors', () => { @@ -1058,26 +1059,27 @@ import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util' }); describe('in template-driven forms', () => { - it('should support standard writing to view and model', async(() => { - const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp); - fixture.componentInstance.name = 'Nancy'; - fixture.detectChanges(); - fixture.whenStable().then(() => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - // model -> view - const customInput = fixture.debugElement.query(By.css('[name="custom"]')); - expect(customInput.nativeElement.value).toEqual('Nancy'); - - customInput.nativeElement.value = 'Carson'; - dispatchEvent(customInput.nativeElement, 'input'); + fixmeIvy('whenStable not working') && + it('should support standard writing to view and model', async(() => { + const fixture = initTest(NgModelCustomWrapper, NgModelCustomComp); + fixture.componentInstance.name = 'Nancy'; fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + // model -> view + const customInput = fixture.debugElement.query(By.css('[name="custom"]')); + expect(customInput.nativeElement.value).toEqual('Nancy'); - // view -> model - expect(fixture.componentInstance.name).toEqual('Carson'); - }); - }); - })); + customInput.nativeElement.value = 'Carson'; + dispatchEvent(customInput.nativeElement, 'input'); + fixture.detectChanges(); + + // view -> model + expect(fixture.componentInstance.name).toEqual('Carson'); + }); + }); + })); });