Skip to content

Commit c2c4a7b

Browse files
committed
fix(form-field, chips): fix tests & lint (#9767)
1 parent 5efc038 commit c2c4a7b

File tree

7 files changed

+68
-71
lines changed

7 files changed

+68
-71
lines changed

src/lib/autocomplete/autocomplete.spec.ts

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ describe('MatAutocomplete', () => {
102102
let fixture: ComponentFixture<SimpleAutocomplete>;
103103
let input: HTMLInputElement;
104104

105-
beforeEach(() => {
105+
beforeEach(fakeAsync(() => {
106106
fixture = createComponent(SimpleAutocomplete);
107107
fixture.detectChanges();
108108
input = fixture.debugElement.query(By.css('input')).nativeElement;
109-
});
109+
}));
110110

111111
it('should open the panel when the input is focused', () => {
112112
expect(fixture.componentInstance.trigger.panelOpen)
@@ -412,7 +412,7 @@ describe('MatAutocomplete', () => {
412412
}));
413413
});
414414

415-
it('should have the correct text direction in RTL', () => {
415+
it('should have the correct text direction in RTL', fakeAsync(() => {
416416
const rtlFixture = createComponent(SimpleAutocomplete, [
417417
{provide: Directionality, useFactory: () => ({value: 'rtl'})},
418418
]);
@@ -424,18 +424,18 @@ describe('MatAutocomplete', () => {
424424
const overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane')!;
425425
expect(overlayPane.getAttribute('dir')).toEqual('rtl');
426426

427-
});
427+
}));
428428

429429
describe('forms integration', () => {
430430
let fixture: ComponentFixture<SimpleAutocomplete>;
431431
let input: HTMLInputElement;
432432

433-
beforeEach(() => {
433+
beforeEach(fakeAsync(() => {
434434
fixture = createComponent(SimpleAutocomplete);
435435
fixture.detectChanges();
436436

437437
input = fixture.debugElement.query(By.css('input')).nativeElement;
438-
});
438+
}));
439439

440440
it('should update control value as user types with input value', () => {
441441
fixture.componentInstance.trigger.openPanel();
@@ -616,22 +616,23 @@ describe('MatAutocomplete', () => {
616616
.toBe(true, `Expected control to become touched on blur.`);
617617
});
618618

619-
it('should disable the input when used with a value accessor and without `matInput`', () => {
620-
overlayContainer.ngOnDestroy();
621-
fixture.destroy();
622-
TestBed.resetTestingModule();
619+
it('should disable the input when used with a value accessor and without `matInput`',
620+
fakeAsync(() => {
621+
overlayContainer.ngOnDestroy();
622+
fixture.destroy();
623+
TestBed.resetTestingModule();
623624

624-
const plainFixture = createComponent(PlainAutocompleteInputWithFormControl);
625-
plainFixture.detectChanges();
626-
input = plainFixture.nativeElement.querySelector('input');
625+
const plainFixture = createComponent(PlainAutocompleteInputWithFormControl);
626+
plainFixture.detectChanges();
627+
input = plainFixture.nativeElement.querySelector('input');
627628

628-
expect(input.disabled).toBe(false);
629+
expect(input.disabled).toBe(false);
629630

630-
plainFixture.componentInstance.formControl.disable();
631-
plainFixture.detectChanges();
631+
plainFixture.componentInstance.formControl.disable();
632+
plainFixture.detectChanges();
632633

633-
expect(input.disabled).toBe(true);
634-
});
634+
expect(input.disabled).toBe(true);
635+
}));
635636

636637
});
637638

@@ -1115,12 +1116,12 @@ describe('MatAutocomplete', () => {
11151116
let fixture: ComponentFixture<SimpleAutocomplete>;
11161117
let input: HTMLInputElement;
11171118

1118-
beforeEach(() => {
1119+
beforeEach(fakeAsync(() => {
11191120
fixture = createComponent(SimpleAutocomplete);
11201121
fixture.detectChanges();
11211122

11221123
input = fixture.debugElement.query(By.css('input')).nativeElement;
1123-
});
1124+
}));
11241125

11251126
it('should set role of input to combobox', () => {
11261127
expect(input.getAttribute('role'))
@@ -1232,13 +1233,13 @@ describe('MatAutocomplete', () => {
12321233
let input: HTMLInputElement;
12331234
let inputReference: HTMLInputElement;
12341235

1235-
beforeEach(() => {
1236+
beforeEach(fakeAsync(() => {
12361237
fixture = createComponent(SimpleAutocomplete);
12371238
fixture.detectChanges();
12381239

12391240
input = fixture.debugElement.query(By.css('input')).nativeElement;
12401241
inputReference = fixture.debugElement.query(By.css('.mat-input-flex')).nativeElement;
1241-
});
1242+
}));
12421243

12431244
it('should use below positioning by default', fakeAsync(() => {
12441245
fixture.componentInstance.trigger.openPanel();
@@ -1319,10 +1320,10 @@ describe('MatAutocomplete', () => {
13191320
describe('Option selection', () => {
13201321
let fixture: ComponentFixture<SimpleAutocomplete>;
13211322

1322-
beforeEach(() => {
1323+
beforeEach(fakeAsync(() => {
13231324
fixture = createComponent(SimpleAutocomplete);
13241325
fixture.detectChanges();
1325-
});
1326+
}));
13261327

13271328
it('should deselect any other selected option', fakeAsync(() => {
13281329
fixture.componentInstance.trigger.openPanel();
@@ -1512,10 +1513,10 @@ describe('MatAutocomplete', () => {
15121513
describe('without matInput', () => {
15131514
let fixture: ComponentFixture<AutocompleteWithNativeInput>;
15141515

1515-
beforeEach(() => {
1516+
beforeEach(fakeAsync(() => {
15161517
fixture = createComponent(AutocompleteWithNativeInput);
15171518
fixture.detectChanges();
1518-
});
1519+
}));
15191520

15201521
it('should not throw when clicking outside', fakeAsync(() => {
15211522
dispatchFakeEvent(fixture.debugElement.query(By.css('input')).nativeElement, 'focus');
@@ -1528,27 +1529,28 @@ describe('MatAutocomplete', () => {
15281529

15291530
describe('misc', () => {
15301531

1531-
it('should allow basic use without any forms directives', () => {
1532+
it('should allow basic use without any forms directives', fakeAsync(() => {
15321533
expect(() => {
15331534
const fixture = createComponent(AutocompleteWithoutForms);
15341535
fixture.detectChanges();
15351536

15361537
const input = fixture.debugElement.query(By.css('input')).nativeElement;
15371538
typeInElement('d', input);
15381539
fixture.detectChanges();
1540+
tick();
15391541

15401542
const options =
15411543
overlayContainerElement.querySelectorAll('mat-option') as NodeListOf<HTMLElement>;
15421544
expect(options.length).toBe(1);
15431545
}).not.toThrowError();
1544-
});
1546+
}));
15451547

1546-
it('should display an empty input when the value is undefined with ngModel', () => {
1548+
it('should display an empty input when the value is undefined with ngModel', fakeAsync(() => {
15471549
const fixture = createComponent(AutocompleteWithNgModel);
15481550
fixture.detectChanges();
15491551

15501552
expect(fixture.debugElement.query(By.css('input')).nativeElement.value).toBe('');
1551-
});
1553+
}));
15521554

15531555
it('should display the number when the selected option is the number zero', fakeAsync(() => {
15541556
const fixture = createComponent(AutocompleteWithNumbers);
@@ -1560,7 +1562,7 @@ describe('MatAutocomplete', () => {
15601562
expect(fixture.debugElement.query(By.css('input')).nativeElement.value).toBe('0');
15611563
}));
15621564

1563-
it('should work when input is wrapped in ngIf', () => {
1565+
it('should work when input is wrapped in ngIf', fakeAsync(() => {
15641566
const fixture = createComponent(NgIfAutocomplete);
15651567
fixture.detectChanges();
15661568

@@ -1573,9 +1575,9 @@ describe('MatAutocomplete', () => {
15731575
.toContain('One', `Expected panel to display when input is focused.`);
15741576
expect(overlayContainerElement.textContent)
15751577
.toContain('Two', `Expected panel to display when input is focused.`);
1576-
});
1578+
}));
15771579

1578-
it('should filter properly with ngIf after setting the active item', () => {
1580+
it('should filter properly with ngIf after setting the active item', fakeAsync(() => {
15791581
const fixture = createComponent(NgIfAutocomplete);
15801582
fixture.detectChanges();
15811583

@@ -1589,18 +1591,19 @@ describe('MatAutocomplete', () => {
15891591
const input = fixture.debugElement.query(By.css('input')).nativeElement;
15901592
typeInElement('o', input);
15911593
fixture.detectChanges();
1594+
tick();
15921595

15931596
expect(fixture.componentInstance.matOptions.length).toBe(2);
1594-
});
1597+
}));
15951598

1596-
it('should throw if the user attempts to open the panel too early', () => {
1599+
it('should throw if the user attempts to open the panel too early', fakeAsync(() => {
15971600
const fixture = createComponent(AutocompleteWithoutPanel);
15981601
fixture.detectChanges();
15991602

16001603
expect(() => {
16011604
fixture.componentInstance.trigger.openPanel();
16021605
}).toThrow(getMatAutocompleteMissingPanelError());
1603-
});
1606+
}));
16041607

16051608
it('should not throw on init, even if the panel is not defined', fakeAsync(() => {
16061609
expect(() => {
@@ -1679,7 +1682,7 @@ describe('MatAutocomplete', () => {
16791682

16801683
});
16811684

1682-
it('should have correct width when opened', () => {
1685+
it('should have correct width when opened', fakeAsync(() => {
16831686
const widthFixture = createComponent(SimpleAutocomplete);
16841687
widthFixture.componentInstance.width = 300;
16851688
widthFixture.detectChanges();
@@ -1702,9 +1705,9 @@ describe('MatAutocomplete', () => {
17021705

17031706
// Firefox, edge return a decimal value for width, so we need to parse and round it to verify
17041707
expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(500);
1705-
});
1708+
}));
17061709

1707-
it('should update the width while the panel is open', () => {
1710+
it('should update the width while the panel is open', fakeAsync(() => {
17081711
const widthFixture = createComponent(SimpleAutocomplete);
17091712

17101713
widthFixture.componentInstance.width = 300;
@@ -1726,7 +1729,7 @@ describe('MatAutocomplete', () => {
17261729
widthFixture.detectChanges();
17271730

17281731
expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(500);
1729-
});
1732+
}));
17301733

17311734
it('should show the panel when the options are initialized later within a component with ' +
17321735
'OnPush change detection', fakeAsync(() => {

src/lib/chips/chip.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ export class MatChipBase {
6363
constructor(public _elementRef: ElementRef) {}
6464
}
6565

66-
export const _MatChipMixinBase = mixinColor(mixinDisableRipple(mixinDisabled(MatChipBase)), 'primary');
66+
export const _MatChipMixinBase =
67+
mixinColor(mixinDisableRipple(mixinDisabled(MatChipBase)), 'primary');
6768

6869
const CHIP_ATTRIBUTE_NAMES = ['mat-basic-chip'];
6970

src/lib/chips/chips-module.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {PlatformModule} from '@angular/cdk/platform';
910
import {NgModule} from '@angular/core';
1011
import {ErrorStateMatcher} from '@angular/material/core';
11-
import {MatChipList} from './chip-list';
12-
import {MatChip, MatChipRemove, MatChipAvatar, MatChipTrailingIcon} from './chip';
12+
import {MatChip, MatChipAvatar, MatChipRemove, MatChipTrailingIcon} from './chip';
1313
import {MatChipInput} from './chip-input';
14+
import {MatChipList} from './chip-list';
1415

1516
const CHIP_DECLARATIONS = [
1617
MatChipList,
@@ -22,7 +23,7 @@ const CHIP_DECLARATIONS = [
2223
];
2324

2425
@NgModule({
25-
imports: [],
26+
imports: [PlatformModule],
2627
exports: CHIP_DECLARATIONS,
2728
declarations: CHIP_DECLARATIONS,
2829
providers: [ErrorStateMatcher]

src/lib/datepicker/datepicker.spec.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -790,12 +790,6 @@ describe('MatDatepicker', () => {
790790
fixture.detectChanges();
791791
}));
792792

793-
it('should attach popup to mat-form-field underline', () => {
794-
let attachToRef = testComponent.datepickerInput.getConnectedOverlayOrigin();
795-
expect(attachToRef.nativeElement.classList.contains('mat-form-field-underline'))
796-
.toBe(true, 'popup should be attached to mat-form-field underline');
797-
});
798-
799793
it('should float the placeholder when an invalid value is entered', () => {
800794
testComponent.datepickerInput.value = 'totally-not-a-date' as any;
801795
fixture.debugElement.nativeElement.querySelector('input').value = 'totally-not-a-date';
@@ -804,7 +798,6 @@ describe('MatDatepicker', () => {
804798
expect(fixture.debugElement.nativeElement.querySelector('mat-form-field').classList)
805799
.toContain('mat-form-field-should-float');
806800
});
807-
808801
});
809802

810803
describe('datepicker with min and max dates and validation', () => {

src/lib/form-field/form-field.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ export class MatFormField extends _MatFormFieldMixinBase
289289
}
290290

291291
_hasPlaceholder() {
292-
return !!(this._control.placeholder || this._placeholderChild);
292+
return !!(this._control && this._control.placeholder || this._placeholderChild);
293293
}
294294

295295
_hasLabel() {

src/lib/input/autofill.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {
1212
ElementRef,
1313
EventEmitter,
1414
Injectable,
15-
NgZone,
1615
OnDestroy,
16+
OnInit,
1717
Output
1818
} from '@angular/core';
1919
import {Observable} from 'rxjs/Observable';
@@ -50,7 +50,7 @@ const listenerOptions: any = supportsPassiveEventListeners() ? {passive: true} :
5050
export class AutofillMonitor implements OnDestroy {
5151
private _monitoredElements = new Map<Element, MonitoredElementInfo>();
5252

53-
constructor(private _platform: Platform, private _ngZone: NgZone) {}
53+
constructor(private _platform: Platform) {}
5454

5555
/**
5656
* Monitor for changes in the autofill state of the given input element.
@@ -78,9 +78,7 @@ export class AutofillMonitor implements OnDestroy {
7878
}
7979
};
8080

81-
this._ngZone.runOutsideAngular(() => {
82-
element.addEventListener('animationstart', listener, listenerOptions);
83-
});
81+
element.addEventListener('animationstart', listener, listenerOptions);
8482
element.classList.add('mat-input-autofill-monitored');
8583

8684
this._monitoredElements.set(element, {
@@ -120,13 +118,14 @@ export class AutofillMonitor implements OnDestroy {
120118
@Directive({
121119
selector: '[matAutofill]',
122120
})
123-
export class MatAutofill implements OnDestroy {
121+
export class MatAutofill implements OnDestroy, OnInit {
124122
@Output() matAutofill = new EventEmitter<AutofillEvent>();
125123

126-
constructor(private _elementRef: ElementRef, private _autofillMonitor: AutofillMonitor,
127-
ngZone: NgZone) {
124+
constructor(private _elementRef: ElementRef, private _autofillMonitor: AutofillMonitor) {}
125+
126+
ngOnInit() {
128127
this._autofillMonitor.monitor(this._elementRef.nativeElement)
129-
.subscribe(event => ngZone.run(() => this.matAutofill.emit(event)));
128+
.subscribe(event => this.matAutofill.emit(event));
130129
}
131130

132131
ngOnDestroy() {

0 commit comments

Comments
 (0)