refactor(input): switch to fakeAsync tests (#8490)

Moves all of the input tests away from the `async` zone either to the default one or to `fakeAsync`.
This commit is contained in:
Kristiyan Kostadinov
2017-11-20 20:03:22 +01:00
committed by Jeremy Elbourn
parent 192e6b3e4c
commit 05084e97c9
+170 -176
View File
@@ -1,7 +1,7 @@
import {Platform, PlatformModule} from '@angular/cdk/platform';
import {createFakeEvent, dispatchFakeEvent, wrappedErrorMessage} from '@angular/cdk/testing';
import {ChangeDetectionStrategy, Component, ViewChild} from '@angular/core';
import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing';
import {ComponentFixture, inject, TestBed, fakeAsync, flush} from '@angular/core/testing';
import {
FormControl,
FormGroup,
@@ -29,7 +29,7 @@ import {MatInputModule} from './index';
import {MatInput} from './input';
describe('MatInput without forms', function () {
beforeEach(async(() => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
@@ -74,7 +74,7 @@ describe('MatInput without forms', function () {
TestBed.compileComponents();
}));
it('should default to floating placeholders', () => {
it('should default to floating placeholders', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithId);
fixture.detectChanges();
@@ -82,9 +82,9 @@ describe('MatInput without forms', function () {
.componentInstance as MatFormField;
expect(formField.floatPlaceholder).toBe('auto',
'Expected MatInput to set floatingLabel to auto by default.');
});
}));
it('should default to global floating placeholder type', () => {
it('should default to global floating placeholder type', fakeAsync(() => {
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [
@@ -106,10 +106,10 @@ describe('MatInput without forms', function () {
.componentInstance as MatFormField;
expect(formField.floatPlaceholder).toBe('always',
'Expected MatInput to set floatingLabel to always from global option.');
});
}));
it('should not be treated as empty if type is date',
inject([Platform], (platform: Platform) => {
fakeAsync(inject([Platform], (platform: Platform) => {
if (!(platform.TRIDENT || (platform.SAFARI && !platform.IOS))) {
let fixture = TestBed.createComponent(MatInputDateTestController);
fixture.detectChanges();
@@ -118,11 +118,11 @@ describe('MatInput without forms', function () {
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(false);
}
}));
})));
// Safari Desktop and IE don't support type="date" and fallback to type="text".
it('should be treated as empty if type is date in Safari Desktop or IE',
inject([Platform], (platform: Platform) => {
fakeAsync(inject([Platform], (platform: Platform) => {
if (platform.TRIDENT || (platform.SAFARI && !platform.IOS)) {
let fixture = TestBed.createComponent(MatInputDateTestController);
fixture.detectChanges();
@@ -131,36 +131,36 @@ describe('MatInput without forms', function () {
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(true);
}
}));
})));
it('should treat text input type as empty at init', () => {
it('should treat text input type as empty at init', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(true);
});
}));
it('should treat password input type as empty at init', () => {
it('should treat password input type as empty at init', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputPasswordTestController);
fixture.detectChanges();
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(true);
});
}));
it('should treat number input type as empty at init', () => {
it('should treat number input type as empty at init', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputNumberTestController);
fixture.detectChanges();
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(true);
});
}));
it('should not be empty after input entered', async(() => {
it('should not be empty after input entered', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
@@ -178,7 +178,7 @@ describe('MatInput without forms', function () {
expect(el.classList.contains('mat-form-field-empty')).toBe(false, 'should not be empty');
}));
it('should update the placeholder when input entered', async(() => {
it('should update the placeholder when input entered', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithStaticPlaceholder);
fixture.detectChanges();
@@ -198,7 +198,7 @@ describe('MatInput without forms', function () {
expect(labelEl.classList).not.toContain('mat-form-field-float');
}));
it('should not be empty when the value set before view init', async(() => {
it('should not be empty when the value set before view init', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithValueBinding);
fixture.detectChanges();
@@ -213,7 +213,7 @@ describe('MatInput without forms', function () {
expect(placeholderEl.classList).toContain('mat-form-field-empty');
}));
it('should add id', () => {
it('should add id', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
@@ -224,9 +224,9 @@ describe('MatInput without forms', function () {
expect(inputElement.id).toBeTruthy();
expect(inputElement.id).toEqual(labelElement.getAttribute('for')!);
});
}));
it('should add aria-owns to the label for the associated control', () => {
it('should add aria-owns to the label for the associated control', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
@@ -236,9 +236,9 @@ describe('MatInput without forms', function () {
fixture.debugElement.query(By.css('label')).nativeElement;
expect(labelElement.getAttribute('aria-owns')).toBe(inputElement.id);
});
}));
it('should add aria-required reflecting the required state', () => {
it('should add aria-required reflecting the required state', fakeAsync(() => {
const fixture = TestBed.createComponent(MatInputWithRequired);
fixture.detectChanges();
@@ -253,9 +253,9 @@ describe('MatInput without forms', function () {
expect(inputElement.getAttribute('aria-required'))
.toBe('true', 'Expected aria-required to reflect required state of true');
});
}));
it('should not overwrite existing id', () => {
it('should not overwrite existing id', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithId);
fixture.detectChanges();
@@ -266,37 +266,37 @@ describe('MatInput without forms', function () {
expect(inputElement.id).toBe('test-id');
expect(labelElement.getAttribute('for')).toBe('test-id');
});
}));
it('validates there\'s only one hint label per side', () => {
it('validates there\'s only one hint label per side', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputInvalidHintTestController);
expect(() => fixture.detectChanges()).toThrowError(
wrappedErrorMessage(getMatFormFieldDuplicatedHintError('start')));
});
}));
it('validates there\'s only one hint label per side (attribute)', () => {
it('validates there\'s only one hint label per side (attribute)', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputInvalidHint2TestController);
expect(() => fixture.detectChanges()).toThrowError(
wrappedErrorMessage(getMatFormFieldDuplicatedHintError('start')));
});
}));
it('validates there\'s only one placeholder', () => {
it('validates there\'s only one placeholder', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputInvalidPlaceholderTestController);
expect(() => fixture.detectChanges()).toThrowError(
wrappedErrorMessage(getMatFormFieldPlaceholderConflictError()));
});
}));
it('validates that matInput child is present', () => {
it('validates that matInput child is present', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputMissingMatInputTestController);
expect(() => fixture.detectChanges()).toThrowError(
wrappedErrorMessage(getMatFormFieldMissingControlError()));
});
}));
it('validates that matInput child is present after initialization', async(() => {
it('validates that matInput child is present after initialization', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithNgIf);
expect(() => fixture.detectChanges()).not.toThrowError(
@@ -308,7 +308,7 @@ describe('MatInput without forms', function () {
wrappedErrorMessage(getMatFormFieldMissingControlError()));
}));
it('validates the type', () => {
it('validates the type', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputInvalidTypeTestController);
// Technically this throws during the OnChanges detection phase,
@@ -317,9 +317,9 @@ describe('MatInput without forms', function () {
// We just check for any exception in this case.
expect(() => fixture.detectChanges()).toThrow(
/* new MatInputUnsupportedTypeError('file') */);
});
}));
it('supports hint labels attribute', () => {
it('supports hint labels attribute', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputHintLabelTestController);
fixture.detectChanges();
@@ -329,9 +329,9 @@ describe('MatInput without forms', function () {
fixture.componentInstance.label = 'label';
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('.mat-hint'))).not.toBeNull();
});
}));
it('sets an id on hint labels', () => {
it('sets an id on hint labels', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputHintLabelTestController);
fixture.componentInstance.label = 'label';
@@ -340,9 +340,9 @@ describe('MatInput without forms', function () {
let hint = fixture.debugElement.query(By.css('.mat-hint')).nativeElement;
expect(hint.getAttribute('id')).toBeTruthy();
});
}));
it('supports hint labels elements', () => {
it('supports hint labels elements', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputHintLabel2TestController);
fixture.detectChanges();
@@ -354,9 +354,9 @@ describe('MatInput without forms', function () {
fixture.detectChanges();
el = fixture.debugElement.query(By.css('mat-hint')).nativeElement;
expect(el.textContent).toBe('label');
});
}));
it('sets an id on the hint element', () => {
it('sets an id on the hint element', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputHintLabel2TestController);
fixture.componentInstance.label = 'label';
@@ -365,9 +365,9 @@ describe('MatInput without forms', function () {
let hint = fixture.debugElement.query(By.css('mat-hint')).nativeElement;
expect(hint.getAttribute('id')).toBeTruthy();
});
}));
it('supports placeholder attribute', async(() => {
it('supports placeholder attribute', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputPlaceholderAttrTestComponent);
fixture.detectChanges();
@@ -387,7 +387,7 @@ describe('MatInput without forms', function () {
expect(labelEl.nativeElement.textContent).not.toMatch(/\*/g);
}));
it('supports placeholder element', async(() => {
it('supports placeholder element', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputPlaceholderElementTestComponent);
fixture.detectChanges();
@@ -404,25 +404,25 @@ describe('MatInput without forms', function () {
expect(el.nativeElement.textContent).not.toMatch(/\*/g);
}));
it('supports placeholder required star', () => {
it('supports placeholder required star', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputPlaceholderRequiredTestComponent);
fixture.detectChanges();
let el = fixture.debugElement.query(By.css('label'));
expect(el).not.toBeNull();
expect(el.nativeElement.textContent).toMatch(/hello\s+\*/g);
});
}));
it('should hide the required star from screen readers', () => {
it('should hide the required star from screen readers', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputPlaceholderRequiredTestComponent);
fixture.detectChanges();
let el = fixture.debugElement.query(By.css('.mat-form-field-required-marker')).nativeElement;
expect(el.getAttribute('aria-hidden')).toBe('true');
});
}));
it('hide placeholder required star when set to hide the required marker', () => {
it('hide placeholder required star when set to hide the required marker', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputPlaceholderRequiredTestComponent);
fixture.detectChanges();
@@ -434,9 +434,9 @@ describe('MatInput without forms', function () {
fixture.detectChanges();
expect(el.nativeElement.textContent).toMatch(/hello/g);
});
}));
it('supports the disabled attribute as binding', async(() => {
it('supports the disabled attribute as binding', fakeAsync(() => {
const fixture = TestBed.createComponent(MatInputWithDisabled);
fixture.detectChanges();
@@ -456,7 +456,7 @@ describe('MatInput without forms', function () {
expect(inputEl.disabled).toBe(true);
}));
it('supports the required attribute as binding', async(() => {
it('supports the required attribute as binding', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithRequired);
fixture.detectChanges();
@@ -470,7 +470,7 @@ describe('MatInput without forms', function () {
expect(inputEl.required).toBe(true);
}));
it('supports the type attribute as binding', async(() => {
it('supports the type attribute as binding', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithType);
fixture.detectChanges();
@@ -484,15 +484,15 @@ describe('MatInput without forms', function () {
expect(inputEl.type).toBe('password');
}));
it('supports textarea', () => {
it('supports textarea', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextareaWithBindings);
fixture.detectChanges();
const textarea: HTMLTextAreaElement = fixture.nativeElement.querySelector('textarea');
expect(textarea).not.toBeNull();
});
}));
it('sets the aria-describedby when a hintLabel is set', () => {
it('sets the aria-describedby when a hintLabel is set', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputHintLabelTestController);
fixture.componentInstance.label = 'label';
@@ -502,9 +502,9 @@ describe('MatInput without forms', function () {
let input = fixture.debugElement.query(By.css('input')).nativeElement;
expect(input.getAttribute('aria-describedby')).toBe(hint.getAttribute('id'));
});
}));
it('sets the aria-describedby to the id of the mat-hint', () => {
it('sets the aria-describedby to the id of the mat-hint', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputHintLabel2TestController);
fixture.componentInstance.label = 'label';
@@ -514,9 +514,9 @@ describe('MatInput without forms', function () {
let input = fixture.debugElement.query(By.css('input')).nativeElement;
expect(input.getAttribute('aria-describedby')).toBe(hint.getAttribute('id'));
});
}));
it('sets the aria-describedby with multiple mat-hint instances', () => {
it('sets the aria-describedby with multiple mat-hint instances', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputMultipleHintTestController);
fixture.componentInstance.startId = 'start';
@@ -526,22 +526,23 @@ describe('MatInput without forms', function () {
let input = fixture.debugElement.query(By.css('input')).nativeElement;
expect(input.getAttribute('aria-describedby')).toBe('start end');
});
}));
it('sets the aria-describedby when a hintLabel is set, in addition to a mat-hint', () => {
let fixture = TestBed.createComponent(MatInputMultipleHintMixedTestController);
it('sets the aria-describedby when a hintLabel is set, in addition to a mat-hint',
fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputMultipleHintMixedTestController);
fixture.detectChanges();
fixture.detectChanges();
let hintLabel = fixture.debugElement.query(By.css('.mat-hint:not(.mat-right)')).nativeElement;
let endLabel = fixture.debugElement.query(By.css('.mat-hint.mat-right')).nativeElement;
let input = fixture.debugElement.query(By.css('input')).nativeElement;
let ariaValue = input.getAttribute('aria-describedby');
let hintLabel = fixture.debugElement.query(By.css('.mat-hint:not(.mat-right)')).nativeElement;
let endLabel = fixture.debugElement.query(By.css('.mat-hint.mat-right')).nativeElement;
let input = fixture.debugElement.query(By.css('input')).nativeElement;
let ariaValue = input.getAttribute('aria-describedby');
expect(ariaValue).toBe(`${hintLabel.getAttribute('id')} ${endLabel.getAttribute('id')}`);
});
expect(ariaValue).toBe(`${hintLabel.getAttribute('id')} ${endLabel.getAttribute('id')}`);
}));
it('should float when floatPlaceholder is set to default and text is entered', () => {
it('should float when floatPlaceholder is set to default and text is entered', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithDynamicPlaceholder);
fixture.detectChanges();
@@ -565,9 +566,9 @@ describe('MatInput without forms', function () {
expect(formFieldEl.classList).toContain('mat-form-field-can-float');
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
});
}));
it('should always float the placeholder when floatPlaceholder is set to true', () => {
it('should always float the placeholder when floatPlaceholder is set to true', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithDynamicPlaceholder);
fixture.detectChanges();
@@ -587,10 +588,10 @@ describe('MatInput without forms', function () {
expect(formFieldEl.classList).toContain('mat-form-field-can-float');
expect(formFieldEl.classList).toContain('mat-form-field-should-float');
});
}));
it('should never float the placeholder when floatPlaceholder is set to false', () => {
it('should never float the placeholder when floatPlaceholder is set to false', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithDynamicPlaceholder);
fixture.componentInstance.shouldFloat = 'never';
@@ -610,9 +611,9 @@ describe('MatInput without forms', function () {
expect(labelEl.classList).not.toContain('mat-form-field-empty');
expect(labelEl.classList).not.toContain('mat-form-field-float');
});
}));
it('should be able to toggle the floating placeholder programmatically', () => {
it('should be able to toggle the floating placeholder programmatically', fakeAsync(() => {
const fixture = TestBed.createComponent(MatInputWithId);
fixture.detectChanges();
@@ -630,9 +631,9 @@ describe('MatInput without forms', function () {
expect(placeholder.classList)
.not.toContain('mat-form-field-empty', 'Expected input to be considered not empty.');
});
}));
it('should not have prefix and suffix elements when none are specified', () => {
it('should not have prefix and suffix elements when none are specified', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithId);
fixture.detectChanges();
@@ -641,22 +642,22 @@ describe('MatInput without forms', function () {
expect(prefixEl).toBeNull();
expect(suffixEl).toBeNull();
});
}));
it('should add prefix and suffix elements when specified', () => {
let fixture = TestBed.createComponent(MatInputWithPrefixAndSuffix);
it('should add prefix and suffix elements when specified', fakeAsync(() => {
const fixture = TestBed.createComponent(MatInputWithPrefixAndSuffix);
fixture.detectChanges();
let prefixEl = fixture.debugElement.query(By.css('.mat-form-field-prefix'));
let suffixEl = fixture.debugElement.query(By.css('.mat-form-field-suffix'));
const prefixEl = fixture.debugElement.query(By.css('.mat-form-field-prefix'));
const suffixEl = fixture.debugElement.query(By.css('.mat-form-field-suffix'));
expect(prefixEl).not.toBeNull();
expect(suffixEl).not.toBeNull();
expect(prefixEl.nativeElement.innerText.trim()).toEqual('Prefix');
expect(suffixEl.nativeElement.innerText.trim()).toEqual('Suffix');
});
}));
it('should update empty class when value changes programmatically and OnPush', () => {
it('should update empty class when value changes programmatically and OnPush', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputOnPush);
fixture.detectChanges();
@@ -670,9 +671,9 @@ describe('MatInput without forms', function () {
fixture.detectChanges();
expect(placeholder.classList).not.toContain('mat-form-field-empty', 'Input no longer empty');
});
}));
it('should set the focused class when the input is focused', () => {
it('should set the focused class when the input is focused', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
@@ -686,9 +687,9 @@ describe('MatInput without forms', function () {
fixture.detectChanges();
expect(container.classList).toContain('mat-focused');
});
}));
it('should be able to animate the placeholder up and lock it in position', () => {
it('should be able to animate the placeholder up and lock it in position', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputTextTestController);
fixture.detectChanges();
@@ -713,9 +714,9 @@ describe('MatInput without forms', function () {
expect(inputContainer._shouldAlwaysFloat).toBe(true);
expect(inputContainer.floatPlaceholder).toBe('always');
});
}));
it('should not highlight when focusing a readonly input', () => {
it('should not highlight when focusing a readonly input', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithReadonlyInput);
fixture.detectChanges();
@@ -729,12 +730,12 @@ describe('MatInput without forms', function () {
expect(input.focused).toBe(false);
expect(container.classList).not.toContain('mat-focused');
});
}));
});
describe('MatInput with forms', () => {
beforeEach(async(() => {
beforeEach(fakeAsync(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
@@ -762,58 +763,56 @@ describe('MatInput with forms', () => {
let containerEl: HTMLElement;
let inputEl: HTMLElement;
beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(MatInputWithFormErrorMessages);
fixture.detectChanges();
testComponent = fixture.componentInstance;
containerEl = fixture.debugElement.query(By.css('mat-form-field')).nativeElement;
inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
});
}));
it('should not show any errors if the user has not interacted', () => {
it('should not show any errors if the user has not interacted', fakeAsync(() => {
expect(testComponent.formControl.untouched).toBe(true, 'Expected untouched form control');
expect(containerEl.querySelectorAll('mat-error').length).toBe(0, 'Expected no error message');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('false', 'Expected aria-invalid to be set to "false".');
});
}));
it('should display an error message when the input is touched and invalid', async(() => {
it('should display an error message when the input is touched and invalid', fakeAsync(() => {
expect(testComponent.formControl.invalid).toBe(true, 'Expected form control to be invalid');
expect(containerEl.querySelectorAll('mat-error').length).toBe(0, 'Expected no error message');
testComponent.formControl.markAsTouched();
fixture.detectChanges();
flush();
fixture.whenStable().then(() => {
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('true', 'Expected aria-invalid to be set to "true".');
});
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('true', 'Expected aria-invalid to be set to "true".');
}));
it('should display an error message when the parent form is submitted', async(() => {
it('should display an error message when the parent form is submitted', fakeAsync(() => {
expect(testComponent.form.submitted).toBe(false, 'Expected form not to have been submitted');
expect(testComponent.formControl.invalid).toBe(true, 'Expected form control to be invalid');
expect(containerEl.querySelectorAll('mat-error').length).toBe(0, 'Expected no error message');
dispatchFakeEvent(fixture.debugElement.query(By.css('form')).nativeElement, 'submit');
fixture.detectChanges();
flush();
fixture.whenStable().then(() => {
expect(testComponent.form.submitted).toBe(true, 'Expected form to have been submitted');
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('true', 'Expected aria-invalid to be set to "true".');
});
expect(testComponent.form.submitted).toBe(true, 'Expected form to have been submitted');
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('true', 'Expected aria-invalid to be set to "true".');
}));
it('should display an error message when the parent form group is submitted', async(() => {
it('should display an error message when the parent form group is submitted', fakeAsync(() => {
fixture.destroy();
let groupFixture = TestBed.createComponent(MatInputWithFormGroupErrorMessages);
@@ -833,46 +832,43 @@ describe('MatInput with forms', () => {
dispatchFakeEvent(groupFixture.debugElement.query(By.css('form')).nativeElement, 'submit');
groupFixture.detectChanges();
flush();
groupFixture.whenStable().then(() => {
expect(component.formGroupDirective.submitted)
.toBe(true, 'Expected form to have been submitted');
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('true', 'Expected aria-invalid to be set to "true".');
});
expect(component.formGroupDirective.submitted)
.toBe(true, 'Expected form to have been submitted');
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(inputEl.getAttribute('aria-invalid'))
.toBe('true', 'Expected aria-invalid to be set to "true".');
}));
it('should hide the errors and show the hints once the input becomes valid', async(() => {
it('should hide the errors and show the hints once the input becomes valid', fakeAsync(() => {
testComponent.formControl.markAsTouched();
fixture.detectChanges();
flush();
fixture.whenStable().then(() => {
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(containerEl.querySelectorAll('mat-hint').length)
.toBe(0, 'Expected no hints to be shown.');
expect(containerEl.classList)
.toContain('mat-form-field-invalid', 'Expected container to have the invalid CSS class.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error message to have been rendered.');
expect(containerEl.querySelectorAll('mat-hint').length)
.toBe(0, 'Expected no hints to be shown.');
testComponent.formControl.setValue('something');
fixture.detectChanges();
testComponent.formControl.setValue('something');
fixture.detectChanges();
flush();
fixture.whenStable().then(() => {
expect(containerEl.classList).not.toContain('mat-form-field-invalid',
'Expected container not to have the invalid class when valid.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(0, 'Expected no error messages when the input is valid.');
expect(containerEl.querySelectorAll('mat-hint').length)
.toBe(1, 'Expected one hint to be shown once the input is valid.');
});
});
expect(containerEl.classList).not.toContain('mat-form-field-invalid',
'Expected container not to have the invalid class when valid.');
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(0, 'Expected no error messages when the input is valid.');
expect(containerEl.querySelectorAll('mat-hint').length)
.toBe(1, 'Expected one hint to be shown once the input is valid.');
}));
it('should not hide the hint if there are no error messages', async(() => {
it('should not hide the hint if there are no error messages', fakeAsync(() => {
testComponent.renderError = false;
fixture.detectChanges();
@@ -881,21 +877,20 @@ describe('MatInput with forms', () => {
testComponent.formControl.markAsTouched();
fixture.detectChanges();
flush();
fixture.whenStable().then(() => {
expect(containerEl.querySelectorAll('mat-hint').length)
.toBe(1, 'Expected one hint to still be shown.');
});
expect(containerEl.querySelectorAll('mat-hint').length)
.toBe(1, 'Expected one hint to still be shown.');
}));
it('should set the proper role on the error messages', () => {
it('should set the proper role on the error messages', fakeAsync(() => {
testComponent.formControl.markAsTouched();
fixture.detectChanges();
expect(containerEl.querySelector('mat-error')!.getAttribute('role')).toBe('alert');
});
}));
it('sets the aria-describedby to reference errors when in error state', () => {
it('sets the aria-describedby to reference errors when in error state', fakeAsync(() => {
let hintId = fixture.debugElement.query(By.css('.mat-hint')).nativeElement.getAttribute('id');
let describedBy = inputEl.getAttribute('aria-describedby');
@@ -911,12 +906,12 @@ describe('MatInput with forms', () => {
expect(errorIds).toBeTruthy('errors should be shown');
expect(describedBy).toBe(errorIds);
});
}));
});
describe('custom error behavior', () => {
it('should display an error message when a custom error matcher returns true', () => {
it('should display an error message when a custom error matcher returns true', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithCustomErrorStateMatcher);
fixture.detectChanges();
@@ -940,9 +935,9 @@ describe('MatInput with forms', () => {
expect(containerEl.querySelectorAll('mat-error').length)
.toBe(1, 'Expected one error messages to have been rendered.');
});
}));
it('should display an error message when global error matcher returns true', () => {
it('should display an error message when global error matcher returns true', fakeAsync(() => {
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [
@@ -968,9 +963,9 @@ describe('MatInput with forms', () => {
// Expect the control to still be untouched but the error to show due to the global setting
expect(testComponent.formControl.untouched).toBe(true, 'Expected untouched form control');
expect(containerEl.querySelectorAll('mat-error').length).toBe(1, 'Expected an error message');
});
}));
it('should display an error message when using ShowOnDirtyErrorStateMatcher', async(() => {
it('should display an error message when using ShowOnDirtyErrorStateMatcher', fakeAsync(() => {
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [
@@ -1009,7 +1004,7 @@ describe('MatInput with forms', () => {
}));
});
it('should update the value when using FormControl.setValue', () => {
it('should update the value when using FormControl.setValue', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputWithFormControl);
fixture.detectChanges();
@@ -1021,9 +1016,9 @@ describe('MatInput with forms', () => {
fixture.componentInstance.formControl.setValue('something');
expect(input.value).toBe('something');
});
}));
it('should display disabled styles when using FormControl.disable()', () => {
it('should display disabled styles when using FormControl.disable()', fakeAsync(() => {
const fixture = TestBed.createComponent(MatInputWithFormControl);
fixture.detectChanges();
@@ -1041,19 +1036,18 @@ describe('MatInput with forms', () => {
expect(formFieldEl.classList).toContain('mat-form-field-disabled',
`Expected form field to look disabled after disable() is called.`);
expect(inputEl.disabled).toBe(true);
});
}));
it('should not treat the number 0 as empty', async(() => {
it('should not treat the number 0 as empty', fakeAsync(() => {
let fixture = TestBed.createComponent(MatInputZeroTestController);
fixture.detectChanges();
flush();
fixture.whenStable().then(() => {
fixture.detectChanges();
fixture.detectChanges();
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(false);
});
let el = fixture.debugElement.query(By.css('label')).nativeElement;
expect(el).not.toBeNull();
expect(el.classList.contains('mat-form-field-empty')).toBe(false);
}));
});