Skip to content

Commit 6043957

Browse files
authored
refactor(material-experimental/mdc-table): de-duplicate test harness logic (#22451)
The logic for all the MDC table harnesses was identical. These changes pull it out into base classes in order to avoid repeating it.
1 parent 032feef commit 6043957

File tree

12 files changed

+196
-349
lines changed

12 files changed

+196
-349
lines changed

scripts/check-mdc-exports-config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ export const config = {
9797
'_MatTableDataSource',
9898
'_MAT_TEXT_COLUMN_TEMPLATE'
9999
],
100+
'mdc-table/testing': [
101+
// Private symbols that are only exported for MDC.
102+
'_MatTableHarnessBase',
103+
'_MatRowHarnessBase'
104+
],
100105
'mdc-tooltip': [
101106
// Private symbols that are only exported for MDC.
102107
'_MatTooltipBase',

src/material-experimental/mdc-table/testing/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ ts_library(
1111
module_name = "@angular/material-experimental/mdc-table/testing",
1212
deps = [
1313
"//src/cdk/testing",
14+
"//src/material/table/testing",
1415
],
1516
)
1617

src/material-experimental/mdc-table/testing/cell-harness.ts

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

9+
import {HarnessPredicate} from '@angular/cdk/testing';
910
import {
10-
HarnessPredicate,
11-
ComponentHarnessConstructor,
12-
ContentContainerComponentHarness,
13-
} from '@angular/cdk/testing';
14-
import {CellHarnessFilters} from './table-harness-filters';
11+
MatCellHarness as BaseMatCellHarness,
12+
MatHeaderCellHarness as BaseMatHeaderCellHarness,
13+
MatFooterCellHarness as BaseMatFooterCellHarness,
14+
CellHarnessFilters
15+
} from '@angular/material/table/testing';
1516

1617
/** Harness for interacting with an MDC-based Angular Material table cell. */
17-
export class MatCellHarness extends ContentContainerComponentHarness {
18+
export class MatCellHarness extends BaseMatCellHarness {
1819
/** The selector for the host element of a `MatCellHarness` instance. */
1920
static hostSelector = '.mat-mdc-cell';
2021

@@ -24,34 +25,12 @@ export class MatCellHarness extends ContentContainerComponentHarness {
2425
* @return a `HarnessPredicate` configured with the given options.
2526
*/
2627
static with(options: CellHarnessFilters = {}): HarnessPredicate<MatCellHarness> {
27-
return getCellPredicate(MatCellHarness, options);
28-
}
29-
30-
/** Gets the cell's text. */
31-
async getText(): Promise<string> {
32-
return (await this.host()).text();
33-
}
34-
35-
/** Gets the name of the column that the cell belongs to. */
36-
async getColumnName(): Promise<string> {
37-
const host = await this.host();
38-
const classAttribute = await host.getAttribute('class');
39-
40-
if (classAttribute) {
41-
const prefix = 'mat-column-';
42-
const name = classAttribute.split(' ').map(c => c.trim()).find(c => c.startsWith(prefix));
43-
44-
if (name) {
45-
return name.split(prefix)[1];
46-
}
47-
}
48-
49-
throw Error('Could not determine column name of cell.');
28+
return BaseMatCellHarness._getCellPredicate(MatCellHarness, options);
5029
}
5130
}
5231

5332
/** Harness for interacting with an MDC-based Angular Material table header cell. */
54-
export class MatHeaderCellHarness extends MatCellHarness {
33+
export class MatHeaderCellHarness extends BaseMatHeaderCellHarness {
5534
/** The selector for the host element of a `MatHeaderCellHarness` instance. */
5635
static hostSelector = '.mat-mdc-header-cell';
5736

@@ -62,12 +41,12 @@ export class MatHeaderCellHarness extends MatCellHarness {
6241
* @return a `HarnessPredicate` configured with the given options.
6342
*/
6443
static with(options: CellHarnessFilters = {}): HarnessPredicate<MatHeaderCellHarness> {
65-
return getCellPredicate(MatHeaderCellHarness, options);
44+
return BaseMatHeaderCellHarness._getCellPredicate(MatHeaderCellHarness, options);
6645
}
6746
}
6847

6948
/** Harness for interacting with an MDC-based Angular Material table footer cell. */
70-
export class MatFooterCellHarness extends MatCellHarness {
49+
export class MatFooterCellHarness extends BaseMatFooterCellHarness {
7150
/** The selector for the host element of a `MatFooterCellHarness` instance. */
7251
static hostSelector = '.mat-mdc-footer-cell';
7352

@@ -78,17 +57,6 @@ export class MatFooterCellHarness extends MatCellHarness {
7857
* @return a `HarnessPredicate` configured with the given options.
7958
*/
8059
static with(options: CellHarnessFilters = {}): HarnessPredicate<MatFooterCellHarness> {
81-
return getCellPredicate(MatFooterCellHarness, options);
60+
return BaseMatFooterCellHarness._getCellPredicate(MatFooterCellHarness, options);
8261
}
8362
}
84-
85-
86-
function getCellPredicate<T extends MatCellHarness>(
87-
type: ComponentHarnessConstructor<T>,
88-
options: CellHarnessFilters): HarnessPredicate<T> {
89-
return new HarnessPredicate(type, options)
90-
.addOption('text', options.text,
91-
(harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))
92-
.addOption('columnName', options.columnName,
93-
(harness, name) => HarnessPredicate.stringMatches(harness.getColumnName(), name));
94-
}

src/material-experimental/mdc-table/testing/public-api.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
export {
10+
CellHarnessFilters,
11+
RowHarnessFilters,
12+
TableHarnessFilters,
13+
MatRowHarnessColumnsText,
14+
MatTableHarnessColumnsText,
15+
} from '@angular/material/table/testing';
916
export * from './table-harness';
1017
export * from './row-harness';
1118
export * from './cell-harness';
12-
export * from './table-harness-filters';

src/material-experimental/mdc-table/testing/row-harness.ts

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,15 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ComponentHarness, HarnessPredicate, parallel} from '@angular/cdk/testing';
10-
import {RowHarnessFilters, CellHarnessFilters} from './table-harness-filters';
9+
import {HarnessPredicate} from '@angular/cdk/testing';
10+
import {_MatRowHarnessBase, RowHarnessFilters} from '@angular/material/table/testing';
1111
import {MatCellHarness, MatHeaderCellHarness, MatFooterCellHarness} from './cell-harness';
1212

13-
/** Text extracted from a table row organized by columns. */
14-
export interface MatRowHarnessColumnsText {
15-
[columnName: string]: string;
16-
}
17-
1813
/** Harness for interacting with an MDC-based Angular Material table row. */
19-
export class MatRowHarness extends ComponentHarness {
14+
export class MatRowHarness extends _MatRowHarnessBase<typeof MatCellHarness, MatCellHarness> {
2015
/** The selector for the host element of a `MatRowHarness` instance. */
2116
static hostSelector = '.mat-mdc-row';
17+
protected _cellHarness = MatCellHarness;
2218

2319
/**
2420
* Gets a `HarnessPredicate` that can be used to search for a table row with specific attributes.
@@ -28,27 +24,14 @@ export class MatRowHarness extends ComponentHarness {
2824
static with(options: RowHarnessFilters = {}): HarnessPredicate<MatRowHarness> {
2925
return new HarnessPredicate(MatRowHarness, options);
3026
}
31-
32-
/** Gets a list of `MatCellHarness` for all cells in the row. */
33-
async getCells(filter: CellHarnessFilters = {}): Promise<MatCellHarness[]> {
34-
return this.locatorForAll(MatCellHarness.with(filter))();
35-
}
36-
37-
/** Gets the text of the cells in the row. */
38-
async getCellTextByIndex(filter: CellHarnessFilters = {}): Promise<string[]> {
39-
return getCellTextByIndex(this, filter);
40-
}
41-
42-
/** Gets the text inside the row organized by columns. */
43-
async getCellTextByColumnName(): Promise<MatRowHarnessColumnsText> {
44-
return getCellTextByColumnName(this);
45-
}
4627
}
4728

4829
/** Harness for interacting with an MDC-based Angular Material table header row. */
49-
export class MatHeaderRowHarness extends ComponentHarness {
30+
export class MatHeaderRowHarness extends _MatRowHarnessBase<
31+
typeof MatHeaderCellHarness, MatHeaderCellHarness> {
5032
/** The selector for the host element of a `MatHeaderRowHarness` instance. */
5133
static hostSelector = '.mat-mdc-header-row';
34+
protected _cellHarness = MatHeaderCellHarness;
5235

5336
/**
5437
* Gets a `HarnessPredicate` that can be used to search for
@@ -59,28 +42,15 @@ export class MatHeaderRowHarness extends ComponentHarness {
5942
static with(options: RowHarnessFilters = {}): HarnessPredicate<MatHeaderRowHarness> {
6043
return new HarnessPredicate(MatHeaderRowHarness, options);
6144
}
62-
63-
/** Gets a list of `MatHeaderCellHarness` for all cells in the row. */
64-
async getCells(filter: CellHarnessFilters = {}): Promise<MatHeaderCellHarness[]> {
65-
return this.locatorForAll(MatHeaderCellHarness.with(filter))();
66-
}
67-
68-
/** Gets the text of the cells in the header row. */
69-
async getCellTextByIndex(filter: CellHarnessFilters = {}): Promise<string[]> {
70-
return getCellTextByIndex(this, filter);
71-
}
72-
73-
/** Gets the text inside the header row organized by columns. */
74-
async getCellTextByColumnName(): Promise<MatRowHarnessColumnsText> {
75-
return getCellTextByColumnName(this);
76-
}
7745
}
7846

7947

8048
/** Harness for interacting with an MDC-based Angular Material table footer row. */
81-
export class MatFooterRowHarness extends ComponentHarness {
49+
export class MatFooterRowHarness extends _MatRowHarnessBase<
50+
typeof MatFooterCellHarness, MatFooterCellHarness> {
8251
/** The selector for the host element of a `MatFooterRowHarness` instance. */
8352
static hostSelector = '.mat-mdc-footer-row';
53+
protected _cellHarness = MatFooterCellHarness;
8454

8555
/**
8656
* Gets a `HarnessPredicate` that can be used to search for
@@ -91,39 +61,4 @@ export class MatFooterRowHarness extends ComponentHarness {
9161
static with(options: RowHarnessFilters = {}): HarnessPredicate<MatFooterRowHarness> {
9262
return new HarnessPredicate(MatFooterRowHarness, options);
9363
}
94-
95-
/** Gets a list of `MatFooterCellHarness` for all cells in the row. */
96-
async getCells(filter: CellHarnessFilters = {}): Promise<MatFooterCellHarness[]> {
97-
return this.locatorForAll(MatFooterCellHarness.with(filter))();
98-
}
99-
100-
/** Gets the text of the cells in the footer row. */
101-
async getCellTextByIndex(filter: CellHarnessFilters = {}): Promise<string[]> {
102-
return getCellTextByIndex(this, filter);
103-
}
104-
105-
/** Gets the text inside the footer row organized by columns. */
106-
async getCellTextByColumnName(): Promise<MatRowHarnessColumnsText> {
107-
return getCellTextByColumnName(this);
108-
}
109-
}
110-
111-
112-
async function getCellTextByIndex(harness: {
113-
getCells: (filter?: CellHarnessFilters) => Promise<MatCellHarness[]>
114-
}, filter: CellHarnessFilters): Promise<string[]> {
115-
const cells = await harness.getCells(filter);
116-
return parallel(() => cells.map(cell => cell.getText()));
117-
}
118-
119-
async function getCellTextByColumnName(harness: {
120-
getCells: () => Promise<MatCellHarness[]>
121-
}): Promise<MatRowHarnessColumnsText> {
122-
const output: MatRowHarnessColumnsText = {};
123-
const cells = await harness.getCells();
124-
const cellsData = await parallel(() => cells.map(cell => {
125-
return parallel(() => [cell.getColumnName(), cell.getText()]);
126-
}));
127-
cellsData.forEach(([columnName, text]) => output[columnName] = text);
128-
return output;
12964
}

src/material-experimental/mdc-table/testing/table-harness-filters.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/material-experimental/mdc-table/testing/table-harness.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import {runHarnessTests} from '@angular/material/table/testing/shared.spec';
33
import {MatTableHarness} from './table-harness';
44

55
describe('MDC-based MatTableHarness', () => {
6-
runHarnessTests(MatTableModule, MatTableHarness);
6+
runHarnessTests(MatTableModule, MatTableHarness as any);
77
});

0 commit comments

Comments
 (0)