Skip to content

fix(form-field, chips): fix tests & lint #9767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 43 additions & 40 deletions src/lib/autocomplete/autocomplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ describe('MatAutocomplete', () => {
let fixture: ComponentFixture<SimpleAutocomplete>;
let input: HTMLInputElement;

beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = createComponent(SimpleAutocomplete);
fixture.detectChanges();
input = fixture.debugElement.query(By.css('input')).nativeElement;
});
}));

it('should open the panel when the input is focused', () => {
expect(fixture.componentInstance.trigger.panelOpen)
Expand Down Expand Up @@ -411,7 +411,7 @@ describe('MatAutocomplete', () => {
}));
});

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

});
}));

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

beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = createComponent(SimpleAutocomplete);
fixture.detectChanges();

input = fixture.debugElement.query(By.css('input')).nativeElement;
});
}));

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

it('should disable the input when used with a value accessor and without `matInput`', () => {
overlayContainer.ngOnDestroy();
fixture.destroy();
TestBed.resetTestingModule();
it('should disable the input when used with a value accessor and without `matInput`',
fakeAsync(() => {
overlayContainer.ngOnDestroy();
fixture.destroy();
TestBed.resetTestingModule();

const plainFixture = createComponent(PlainAutocompleteInputWithFormControl);
plainFixture.detectChanges();
input = plainFixture.nativeElement.querySelector('input');
const plainFixture = createComponent(PlainAutocompleteInputWithFormControl);
plainFixture.detectChanges();
input = plainFixture.nativeElement.querySelector('input');

expect(input.disabled).toBe(false);
expect(input.disabled).toBe(false);

plainFixture.componentInstance.formControl.disable();
plainFixture.detectChanges();
plainFixture.componentInstance.formControl.disable();
plainFixture.detectChanges();

expect(input.disabled).toBe(true);
});
expect(input.disabled).toBe(true);
}));

});

Expand Down Expand Up @@ -1088,12 +1089,12 @@ describe('MatAutocomplete', () => {
let fixture: ComponentFixture<SimpleAutocomplete>;
let input: HTMLInputElement;

beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = createComponent(SimpleAutocomplete);
fixture.detectChanges();

input = fixture.debugElement.query(By.css('input')).nativeElement;
});
}));

it('should set role of input to combobox', () => {
expect(input.getAttribute('role'))
Expand Down Expand Up @@ -1205,13 +1206,13 @@ describe('MatAutocomplete', () => {
let input: HTMLInputElement;
let inputReference: HTMLInputElement;

beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = createComponent(SimpleAutocomplete);
fixture.detectChanges();

input = fixture.debugElement.query(By.css('input')).nativeElement;
inputReference = fixture.debugElement.query(By.css('.mat-input-flex')).nativeElement;
});
}));

it('should use below positioning by default', fakeAsync(() => {
fixture.componentInstance.trigger.openPanel();
Expand Down Expand Up @@ -1292,10 +1293,10 @@ describe('MatAutocomplete', () => {
describe('Option selection', () => {
let fixture: ComponentFixture<SimpleAutocomplete>;

beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = createComponent(SimpleAutocomplete);
fixture.detectChanges();
});
}));

it('should deselect any other selected option', fakeAsync(() => {
fixture.componentInstance.trigger.openPanel();
Expand Down Expand Up @@ -1485,10 +1486,10 @@ describe('MatAutocomplete', () => {
describe('without matInput', () => {
let fixture: ComponentFixture<AutocompleteWithNativeInput>;

beforeEach(() => {
beforeEach(fakeAsync(() => {
fixture = createComponent(AutocompleteWithNativeInput);
fixture.detectChanges();
});
}));

it('should not throw when clicking outside', fakeAsync(() => {
dispatchFakeEvent(fixture.debugElement.query(By.css('input')).nativeElement, 'focus');
Expand All @@ -1501,27 +1502,28 @@ describe('MatAutocomplete', () => {

describe('misc', () => {

it('should allow basic use without any forms directives', () => {
it('should allow basic use without any forms directives', fakeAsync(() => {
expect(() => {
const fixture = createComponent(AutocompleteWithoutForms);
fixture.detectChanges();

const input = fixture.debugElement.query(By.css('input')).nativeElement;
typeInElement('d', input);
fixture.detectChanges();
tick();

const options =
overlayContainerElement.querySelectorAll('mat-option') as NodeListOf<HTMLElement>;
expect(options.length).toBe(1);
}).not.toThrowError();
});
}));

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

expect(fixture.debugElement.query(By.css('input')).nativeElement.value).toBe('');
});
}));

it('should display the number when the selected option is the number zero', fakeAsync(() => {
const fixture = createComponent(AutocompleteWithNumbers);
Expand All @@ -1533,7 +1535,7 @@ describe('MatAutocomplete', () => {
expect(fixture.debugElement.query(By.css('input')).nativeElement.value).toBe('0');
}));

it('should work when input is wrapped in ngIf', () => {
it('should work when input is wrapped in ngIf', fakeAsync(() => {
const fixture = createComponent(NgIfAutocomplete);
fixture.detectChanges();

Expand All @@ -1546,9 +1548,9 @@ describe('MatAutocomplete', () => {
.toContain('One', `Expected panel to display when input is focused.`);
expect(overlayContainerElement.textContent)
.toContain('Two', `Expected panel to display when input is focused.`);
});
}));

it('should filter properly with ngIf after setting the active item', () => {
it('should filter properly with ngIf after setting the active item', fakeAsync(() => {
const fixture = createComponent(NgIfAutocomplete);
fixture.detectChanges();

Expand All @@ -1562,18 +1564,19 @@ describe('MatAutocomplete', () => {
const input = fixture.debugElement.query(By.css('input')).nativeElement;
typeInElement('o', input);
fixture.detectChanges();
tick();

expect(fixture.componentInstance.matOptions.length).toBe(2);
});
}));

it('should throw if the user attempts to open the panel too early', () => {
it('should throw if the user attempts to open the panel too early', fakeAsync(() => {
const fixture = createComponent(AutocompleteWithoutPanel);
fixture.detectChanges();

expect(() => {
fixture.componentInstance.trigger.openPanel();
}).toThrow(getMatAutocompleteMissingPanelError());
});
}));

it('should not throw on init, even if the panel is not defined', fakeAsync(() => {
expect(() => {
Expand Down Expand Up @@ -1652,7 +1655,7 @@ describe('MatAutocomplete', () => {

});

it('should have correct width when opened', () => {
it('should have correct width when opened', fakeAsync(() => {
const widthFixture = createComponent(SimpleAutocomplete);
widthFixture.componentInstance.width = 300;
widthFixture.detectChanges();
Expand All @@ -1675,9 +1678,9 @@ describe('MatAutocomplete', () => {

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

it('should update the width while the panel is open', () => {
it('should update the width while the panel is open', fakeAsync(() => {
const widthFixture = createComponent(SimpleAutocomplete);

widthFixture.componentInstance.width = 300;
Expand All @@ -1699,7 +1702,7 @@ describe('MatAutocomplete', () => {
widthFixture.detectChanges();

expect(Math.ceil(parseFloat(overlayPane.style.width as string))).toBe(500);
});
}));

it('should show the panel when the options are initialized later within a component with ' +
'OnPush change detection', fakeAsync(() => {
Expand Down
3 changes: 2 additions & 1 deletion src/lib/chips/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ export class MatChipBase {
constructor(public _elementRef: ElementRef) {}
}

export const _MatChipMixinBase = mixinColor(mixinDisableRipple(mixinDisabled(MatChipBase)), 'primary');
export const _MatChipMixinBase =
mixinColor(mixinDisableRipple(mixinDisabled(MatChipBase)), 'primary');

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

Expand Down
7 changes: 4 additions & 3 deletions src/lib/chips/chips-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
* found in the LICENSE file at https://angular.io/license
*/

import {PlatformModule} from '@angular/cdk/platform';
import {NgModule} from '@angular/core';
import {ErrorStateMatcher} from '@angular/material/core';
import {MatChipList} from './chip-list';
import {MatChip, MatChipRemove, MatChipAvatar, MatChipTrailingIcon} from './chip';
import {MatChip, MatChipAvatar, MatChipRemove, MatChipTrailingIcon} from './chip';
import {MatChipInput} from './chip-input';
import {MatChipList} from './chip-list';

const CHIP_DECLARATIONS = [
MatChipList,
Expand All @@ -22,7 +23,7 @@ const CHIP_DECLARATIONS = [
];

@NgModule({
imports: [],
imports: [PlatformModule],
exports: CHIP_DECLARATIONS,
declarations: CHIP_DECLARATIONS,
providers: [ErrorStateMatcher]
Expand Down
7 changes: 0 additions & 7 deletions src/lib/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,12 +790,6 @@ describe('MatDatepicker', () => {
fixture.detectChanges();
}));

it('should attach popup to mat-form-field underline', () => {
let attachToRef = testComponent.datepickerInput.getConnectedOverlayOrigin();
expect(attachToRef.nativeElement.classList.contains('mat-form-field-underline'))
.toBe(true, 'popup should be attached to mat-form-field underline');
});

it('should float the placeholder when an invalid value is entered', () => {
testComponent.datepickerInput.value = 'totally-not-a-date' as any;
fixture.debugElement.nativeElement.querySelector('input').value = 'totally-not-a-date';
Expand All @@ -804,7 +798,6 @@ describe('MatDatepicker', () => {
expect(fixture.debugElement.nativeElement.querySelector('mat-form-field').classList)
.toContain('mat-form-field-should-float');
});

});

describe('datepicker with min and max dates and validation', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ export class MatFormField extends _MatFormFieldMixinBase
}

_hasPlaceholder() {
return !!(this._control.placeholder || this._placeholderChild);
return !!(this._control && this._control.placeholder || this._placeholderChild);
}

_hasLabel() {
Expand Down
17 changes: 8 additions & 9 deletions src/lib/input/autofill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
ElementRef,
EventEmitter,
Injectable,
NgZone,
OnDestroy,
OnInit,
Output
} from '@angular/core';
import {Observable} from 'rxjs/Observable';
Expand Down Expand Up @@ -50,7 +50,7 @@ const listenerOptions: any = supportsPassiveEventListeners() ? {passive: true} :
export class AutofillMonitor implements OnDestroy {
private _monitoredElements = new Map<Element, MonitoredElementInfo>();

constructor(private _platform: Platform, private _ngZone: NgZone) {}
constructor(private _platform: Platform) {}

/**
* Monitor for changes in the autofill state of the given input element.
Expand Down Expand Up @@ -78,9 +78,7 @@ export class AutofillMonitor implements OnDestroy {
}
};

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

this._monitoredElements.set(element, {
Expand Down Expand Up @@ -120,13 +118,14 @@ export class AutofillMonitor implements OnDestroy {
@Directive({
selector: '[matAutofill]',
})
export class MatAutofill implements OnDestroy {
export class MatAutofill implements OnDestroy, OnInit {
@Output() matAutofill = new EventEmitter<AutofillEvent>();

constructor(private _elementRef: ElementRef, private _autofillMonitor: AutofillMonitor,
ngZone: NgZone) {
constructor(private _elementRef: ElementRef, private _autofillMonitor: AutofillMonitor) {}

ngOnInit() {
this._autofillMonitor.monitor(this._elementRef.nativeElement)
.subscribe(event => ngZone.run(() => this.matAutofill.emit(event)));
.subscribe(event => this.matAutofill.emit(event));
}

ngOnDestroy() {
Expand Down
Loading