Skip to content
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
1 change: 1 addition & 0 deletions src/material/list/selection-list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,7 @@ describe('MatSelectionList with forms', () => {
.toBe(false);
});

// TODO: this seems tricky to switch away from `fakeAsync` for some reason.
it('should remove a selected option from the value on destroy', fakeAsync(() => {
listOptions[1].selected = true;
listOptions[2].selected = true;
Expand Down
48 changes: 28 additions & 20 deletions src/material/menu/context-menu-trigger.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, signal, ViewChild, ChangeDetectionStrategy} from '@angular/core';
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MATERIAL_ANIMATIONS} from '../core';
import {MatContextMenuTrigger} from './context-menu-trigger';
import {MatMenu} from './menu';
import {MatMenuItem} from './menu-item';
Expand All @@ -8,6 +9,10 @@ import {dispatchFakeEvent, dispatchMouseEvent} from '@angular/cdk/testing/privat
describe('context menu trigger', () => {
let fixture: ComponentFixture<ContextMenuTest>;

function wait(milliseconds: number) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}

function getTrigger(): HTMLElement {
return fixture.nativeElement.querySelector('.area');
}
Expand All @@ -21,6 +26,9 @@ describe('context menu trigger', () => {
}

beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}],
});
fixture = TestBed.createComponent(ContextMenuTest);
fixture.detectChanges();
});
Expand All @@ -32,16 +40,16 @@ describe('context menu trigger', () => {
expect(getMenu()).toBeTruthy();
});

it('should close the menu when clicking outside the trigger', fakeAsync(() => {
it('should close the menu when clicking outside the trigger', async () => {
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
fixture.detectChanges();
expect(getMenu()).toBeTruthy();

document.body.click();
fixture.detectChanges();
flush();
await wait(50);
expect(getMenu()).toBe(null);
}));
});

it('should reposition the menu when right-clicking within the area', () => {
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
Expand All @@ -57,43 +65,43 @@ describe('context menu trigger', () => {
expect(menuRect.left).toBe(50);
});

it('should ignore the first auxclick after opening', fakeAsync(() => {
it('should ignore the first auxclick after opening', async () => {
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
fixture.detectChanges();
expect(getMenu()).toBeTruthy();

dispatchMouseEvent(document.body, 'auxclick');
fixture.detectChanges();
flush();
await wait(50);
expect(getMenu()).toBeTruthy();

dispatchMouseEvent(document.body, 'auxclick');
fixture.detectChanges();
flush();
await wait(50);
expect(getMenu()).toBe(null);
}));
});

it('should close on `contextmenu` events outside the trigger', fakeAsync(() => {
it('should close on `contextmenu` events outside the trigger', async () => {
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
fixture.detectChanges();
expect(getMenu()).toBeTruthy();

dispatchMouseEvent(document.body, 'contextmenu');
fixture.detectChanges();
flush();
await wait(50);
expect(getMenu()).toBe(null);
}));
});

it('should not close on `contextmenu` events from inside the menu', fakeAsync(() => {
it('should not close on `contextmenu` events from inside the menu', async () => {
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
fixture.detectChanges();
expect(getMenu()).toBeTruthy();

dispatchMouseEvent(getMenu()!, 'contextmenu');
fixture.detectChanges();
flush();
await wait(50);
expect(getMenu()).toBeTruthy();
}));
});

it('should set aria-controls on the trigger while the menu is open', () => {
expect(getTrigger().getAttribute('aria-controls')).toBe(null);
Expand Down Expand Up @@ -124,7 +132,7 @@ describe('context menu trigger', () => {
scroller.remove();
});

it('should emit events when the menu is opened and closed', fakeAsync(() => {
it('should emit events when the menu is opened and closed', async () => {
const {opened, closed} = fixture.componentInstance;
expect(opened).toHaveBeenCalledTimes(0);
expect(closed).toHaveBeenCalledTimes(0);
Expand All @@ -136,21 +144,21 @@ describe('context menu trigger', () => {

document.body.click();
fixture.detectChanges();
flush();
await wait(50);
expect(opened).toHaveBeenCalledTimes(1);
expect(closed).toHaveBeenCalledTimes(1);
}));
});

it('should close the menu if the trigger is destroyed', fakeAsync(() => {
it('should close the menu if the trigger is destroyed', async () => {
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
fixture.detectChanges();
expect(getMenu()).toBeTruthy();

fixture.componentInstance.showTrigger.set(false);
fixture.detectChanges();
flush();
await wait(50);
expect(getMenu()).toBe(null);
}));
});

it('should not open when clicking on a disabled context menu trigger', () => {
fixture.componentInstance.disabled.set(true);
Expand Down
7 changes: 3 additions & 4 deletions src/material/paginator/paginator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
inject,
ChangeDetectionStrategy,
} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {ThemePalette} from '../core';
import {MatSelect} from '../select';
import {By} from '@angular/platform-browser';
Expand Down Expand Up @@ -205,16 +205,15 @@ describe('MatPaginator', () => {
expect(getLastButton(fixture)).withContext('Expected last button to be rendered.').toBeTruthy();
});

it('should mark itself as initialized', fakeAsync(() => {
it('should mark itself as initialized', () => {
const fixture = createComponent(MatPaginatorApp);
const component = fixture.componentInstance;
const paginator = component.paginator;
let isMarkedInitialized = false;
paginator.initialized.subscribe(() => (isMarkedInitialized = true));

tick();
expect(isMarkedInitialized).toBeTruthy();
}));
});

it('should not allow a negative pageSize', () => {
const fixture = createComponent(MatPaginatorApp);
Expand Down
12 changes: 6 additions & 6 deletions src/material/radio/radio.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {dispatchFakeEvent} from '@angular/cdk/testing/private';
import {Component, DebugElement, ViewChild, ChangeDetectionStrategy} from '@angular/core';
import {ComponentFixture, TestBed, fakeAsync, tick, waitForAsync} from '@angular/core/testing';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';
import {
Expand Down Expand Up @@ -442,8 +442,8 @@ describe('MatRadio', () => {
});

it('should have a focus indicator', () => {
const radioRippleNativeElements = radioNativeElements.map(
element => element.querySelector('.mat-radio-ripple')!,
const radioRippleNativeElements = radioNativeElements.map(element =>
element.querySelector('.mat-radio-ripple')!,
);

expect(
Expand Down Expand Up @@ -610,17 +610,17 @@ describe('MatRadio', () => {
expect(groupNgModel.touched).toBe(true);
});

it('should write to the radio button based on ngModel', fakeAsync(() => {
it('should write to the radio button based on ngModel', async () => {
testComponent.modelValue = 'chocolate';
fixture.changeDetectorRef.markForCheck();

fixture.detectChanges();
tick();
await fixture.whenStable();
fixture.detectChanges();

expect(innerRadios[1].nativeElement.checked).toBe(true);
expect(radioInstances[1].checked).toBe(true);
}));
});

it('should update the ngModel value when selecting a radio button', () => {
dispatchFakeEvent(innerRadios[1].nativeElement, 'change');
Expand Down
32 changes: 15 additions & 17 deletions src/material/table/table-data-source.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {MatTableDataSource} from './table-data-source';
import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MatSort, MatSortModule} from '@angular/material/sort';
import {Component, ViewChild, ChangeDetectionStrategy} from '@angular/core';

describe('MatTableDataSource', () => {
describe('sort', () => {
let dataSource: MatTableDataSource<{'prop': string | number}>;
let dataSource: MatTableDataSource<{prop: string | number}>;
let fixture: ComponentFixture<MatSortApp>;
let sort: MatSort;

Expand All @@ -23,7 +23,7 @@ describe('MatTableDataSource', () => {
// the sort should be performed over a particular key.
// Map the values into an array of objects where each value is keyed by "prop"
// e.g. [0, 1, 2] -> [{prop: 0}, {prop: 1}, {prop: 2}]
const data = values.map(v => ({'prop': v}));
const data = values.map(v => ({prop: v}));

// Set the active sort to be on the "prop" key
sort.active = 'prop';
Expand Down Expand Up @@ -73,45 +73,43 @@ describe('MatTableDataSource', () => {
});

it('should update filteredData even if the data source is disconnected', () => {
dataSource.data = [{'prop': 1}, {'prop': 2}, {'prop': 3}];
expect(dataSource.filteredData).toEqual([{'prop': 1}, {'prop': 2}, {'prop': 3}]);
dataSource.data = [{prop: 1}, {prop: 2}, {prop: 3}];
expect(dataSource.filteredData).toEqual([{prop: 1}, {prop: 2}, {prop: 3}]);

dataSource.disconnect();
dataSource.data = [{'prop': 3}, {'prop': 2}, {'prop': 1}];
expect(dataSource.filteredData).toEqual([{'prop': 3}, {'prop': 2}, {'prop': 1}]);
dataSource.data = [{prop: 3}, {prop: 2}, {prop: 1}];
expect(dataSource.filteredData).toEqual([{prop: 3}, {prop: 2}, {prop: 1}]);
});

it('should filter data', () => {
dataSource.data = [{'prop': 1}, {'prop': 'foo'}, {'prop': 'banana'}];
dataSource.data = [{prop: 1}, {prop: 'foo'}, {prop: 'banana'}];
dataSource.filter = 'b';
expect(dataSource.filteredData).toEqual([{'prop': 'banana'}]);
expect(dataSource.filteredData).toEqual([{prop: 'banana'}]);
});

it('does not warn in non-dev mode when filtering non-object data', fakeAsync(() => {
it('does not warn in non-dev mode when filtering non-object data', () => {
const warnSpy = spyOn(console, 'warn');
(window as any).ngDevMode = null;
dataSource.data = [1, 2, 3, 4, 5] as unknown as {'prop': number}[];
dataSource.data = [1, 2, 3, 4, 5] as unknown as {prop: number}[];

dataSource.filter = '1';
tick();

expect(warnSpy).not.toHaveBeenCalled();
expect(dataSource.filteredData).toEqual([]);
}));
});

it('displays the warning in dev mode when filtering non-object data', fakeAsync(() => {
it('displays the warning in dev mode when filtering non-object data', () => {
const warnSpy = spyOn(console, 'warn');
(window as any).ngDevMode = {};
dataSource.data = [1, 2, 3, 4, 5] as unknown as {'prop': number}[];
dataSource.data = [1, 2, 3, 4, 5] as unknown as {prop: number}[];

dataSource.filter = '1';
tick();

expect(warnSpy).toHaveBeenCalledWith(
jasmine.stringContaining('requires data to be a non-null object'),
);
expect(dataSource.filteredData).toEqual([]);
}));
});
});
});

Expand Down
Loading
Loading