169 lines
5.7 KiB
TypeScript
169 lines
5.7 KiB
TypeScript
|
|
import {Component, signal} from '@angular/core';
|
||
|
|
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||
|
|
import {HarnessLoader, parallel} from '@angular/cdk/testing';
|
||
|
|
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
|
||
|
|
import {MatSortModule, Sort} from '@angular/material/sort';
|
||
|
|
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||
|
|
import {MatSortHarness} from './sort-harness';
|
||
|
|
|
||
|
|
describe('MatSortHarness', () => {
|
||
|
|
let fixture: ComponentFixture<SortHarnessTest>;
|
||
|
|
let loader: HarnessLoader;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
TestBed.configureTestingModule({
|
||
|
|
imports: [MatSortModule, NoopAnimationsModule, SortHarnessTest],
|
||
|
|
});
|
||
|
|
|
||
|
|
fixture = TestBed.createComponent(SortHarnessTest);
|
||
|
|
fixture.detectChanges();
|
||
|
|
loader = TestbedHarnessEnvironment.loader(fixture);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should load harness for mat-sort', async () => {
|
||
|
|
const sorts = await loader.getAllHarnesses(MatSortHarness);
|
||
|
|
expect(sorts.length).toBe(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should load the harnesses for all the headers in a mat-sort', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const headers = await sort.getSortHeaders();
|
||
|
|
expect(headers.length).toBe(5);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should be able to filter headers by their label text', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const headers = await sort.getSortHeaders({label: 'Carbs'});
|
||
|
|
expect(headers.length).toBe(1);
|
||
|
|
expect(await headers[0].getLabel()).toBe('Carbs');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should be able to filter headers by their labels via a regex', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const headers = await sort.getSortHeaders({label: /^C/});
|
||
|
|
const labels = await parallel(() => headers.map(header => header.getLabel()));
|
||
|
|
expect(headers.length).toBe(2);
|
||
|
|
expect(labels).toEqual(['Calories', 'Carbs']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should be able to filter headers by their sorted state', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
let headers = await sort.getSortHeaders({sortDirection: ''});
|
||
|
|
expect(headers.length).toBe(5);
|
||
|
|
|
||
|
|
await headers[0].click();
|
||
|
|
|
||
|
|
headers = await sort.getSortHeaders({sortDirection: 'asc'});
|
||
|
|
|
||
|
|
expect(headers.length).toBe(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should be able to get the label of a header', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const headers = await sort.getSortHeaders();
|
||
|
|
const labels = await parallel(() => headers.map(header => header.getLabel()));
|
||
|
|
expect(labels).toEqual(['Dessert', 'Calories', 'Fat', 'Carbs', 'Protein']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get the disabled state of a header', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const thirdHeader = (await sort.getSortHeaders())[2];
|
||
|
|
|
||
|
|
expect(await thirdHeader.isDisabled()).toBe(false);
|
||
|
|
|
||
|
|
fixture.componentInstance.disableThirdHeader.set(true);
|
||
|
|
fixture.detectChanges();
|
||
|
|
|
||
|
|
expect(await thirdHeader.isDisabled()).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get the active state of a header', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const secondHeader = (await sort.getSortHeaders())[1];
|
||
|
|
|
||
|
|
expect(await secondHeader.isActive()).toBe(false);
|
||
|
|
|
||
|
|
await secondHeader.click();
|
||
|
|
|
||
|
|
expect(await secondHeader.isActive()).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get the sorte direction of a header', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const secondHeader = (await sort.getSortHeaders())[1];
|
||
|
|
|
||
|
|
expect(await secondHeader.getSortDirection()).toBe('');
|
||
|
|
|
||
|
|
await secondHeader.click();
|
||
|
|
expect(await secondHeader.getSortDirection()).toBe('asc');
|
||
|
|
|
||
|
|
await secondHeader.click();
|
||
|
|
expect(await secondHeader.getSortDirection()).toBe('desc');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get the active header', async () => {
|
||
|
|
const sort = await loader.getHarness(MatSortHarness);
|
||
|
|
const fifthHeader = (await sort.getSortHeaders())[4];
|
||
|
|
|
||
|
|
expect(await sort.getActiveHeader()).toBeNull();
|
||
|
|
|
||
|
|
await fifthHeader.click();
|
||
|
|
|
||
|
|
const activeHeader = await sort.getActiveHeader();
|
||
|
|
expect(activeHeader).toBeTruthy();
|
||
|
|
expect(await activeHeader!.getLabel()).toBe('Protein');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
@Component({
|
||
|
|
template: `
|
||
|
|
<table matSort (matSortChange)="sortData($event)">
|
||
|
|
<tr>
|
||
|
|
<th mat-sort-header="name">Dessert</th>
|
||
|
|
<th mat-sort-header="calories">Calories</th>
|
||
|
|
<th mat-sort-header="fat" [disabled]="disableThirdHeader()">Fat</th>
|
||
|
|
<th mat-sort-header="carbs">Carbs</th>
|
||
|
|
<th mat-sort-header="protein">Protein</th>
|
||
|
|
</tr>
|
||
|
|
|
||
|
|
@for (dessert of sortedData; track dessert) {
|
||
|
|
<tr>
|
||
|
|
<td>{{dessert.name}}</td>
|
||
|
|
<td>{{dessert.calories}}</td>
|
||
|
|
<td>{{dessert.fat}}</td>
|
||
|
|
<td>{{dessert.carbs}}</td>
|
||
|
|
<td>{{dessert.protein}}</td>
|
||
|
|
</tr>
|
||
|
|
}
|
||
|
|
</table>
|
||
|
|
`,
|
||
|
|
standalone: true,
|
||
|
|
imports: [MatSortModule],
|
||
|
|
})
|
||
|
|
class SortHarnessTest {
|
||
|
|
disableThirdHeader = signal(false);
|
||
|
|
desserts = [
|
||
|
|
{name: 'Frozen yogurt', calories: 159, fat: 6, carbs: 24, protein: 4},
|
||
|
|
{name: 'Ice cream sandwich', calories: 237, fat: 9, carbs: 37, protein: 4},
|
||
|
|
{name: 'Eclair', calories: 262, fat: 16, carbs: 24, protein: 6},
|
||
|
|
{name: 'Cupcake', calories: 305, fat: 4, carbs: 67, protein: 4},
|
||
|
|
{name: 'Gingerbread', calories: 356, fat: 16, carbs: 49, protein: 4},
|
||
|
|
];
|
||
|
|
|
||
|
|
sortedData = this.desserts.slice();
|
||
|
|
|
||
|
|
sortData(sort: Sort) {
|
||
|
|
const data = this.desserts.slice();
|
||
|
|
|
||
|
|
if (!sort.active || sort.direction === '') {
|
||
|
|
this.sortedData = data;
|
||
|
|
} else {
|
||
|
|
this.sortedData = data.sort((a, b) => {
|
||
|
|
const aValue = (a as any)[sort.active];
|
||
|
|
const bValue = (b as any)[sort.active];
|
||
|
|
return (aValue < bValue ? -1 : 1) * (sort.direction === 'asc' ? 1 : -1);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|