|
| 1 | +/** |
| 2 | + * @license |
| 3 | + * Copyright Google LLC All Rights Reserved. |
| 4 | + * |
| 5 | + * Use of this source code is governed by an MIT-style license that can be |
| 6 | + * found in the LICENSE file at https://angular.io/license |
| 7 | + */ |
| 8 | + |
| 9 | +import {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing'; |
| 10 | +import {ɵTileCoordinator as TileCoordinator} from '@angular/material/grid-list'; |
| 11 | +import {GridListHarnessFilters, GridTileHarnessFilters} from './grid-list-harness-filters'; |
| 12 | +import {MatGridTileHarness} from './grid-tile-harness'; |
| 13 | + |
| 14 | +/** Harness for interacting with a standard `MatGridList` in tests. */ |
| 15 | +export class MatGridListHarness extends ComponentHarness { |
| 16 | + /** The selector for the host element of a `MatGridList` instance. */ |
| 17 | + static hostSelector = '.mat-grid-list'; |
| 18 | + |
| 19 | + /** |
| 20 | + * Gets a `HarnessPredicate` that can be used to search for a `MatGridListHarness` |
| 21 | + * that meets certain criteria. |
| 22 | + * @param options Options for filtering which dialog instances are considered a match. |
| 23 | + * @return a `HarnessPredicate` configured with the given options. |
| 24 | + */ |
| 25 | + static with(options: GridListHarnessFilters = {}): HarnessPredicate<MatGridListHarness> { |
| 26 | + return new HarnessPredicate(MatGridListHarness, options); |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * Tile coordinator that is used by the "MatGridList" for computing |
| 31 | + * positions of tiles. We leverage the coordinator to provide an API |
| 32 | + * for retrieving tiles based on visual tile positions. |
| 33 | + */ |
| 34 | + private _tileCoordinator = new TileCoordinator(); |
| 35 | + |
| 36 | + /** Gets all tiles of the grid-list. */ |
| 37 | + async getTiles(filters: GridTileHarnessFilters = {}): Promise<MatGridTileHarness[]> { |
| 38 | + return await this.locatorForAll(MatGridTileHarness.with(filters))(); |
| 39 | + } |
| 40 | + |
| 41 | + /** Gets the amount of columns of the grid-list. */ |
| 42 | + async getColumns(): Promise<number> { |
| 43 | + return Number(await (await this.host()).getAttribute('cols')); |
| 44 | + } |
| 45 | + |
| 46 | + /** |
| 47 | + * Gets a tile of the grid-list that is located at the given location. |
| 48 | + * @param row Zero-based row index. |
| 49 | + * @param column Zero-based column index. |
| 50 | + */ |
| 51 | + async getTileAtPosition({row, column}: {row: number, column: number}): |
| 52 | + Promise<MatGridTileHarness> { |
| 53 | + const [tileHarnesses, columns] = await Promise.all([this.getTiles(), this.getColumns()]); |
| 54 | + const tileSpans = tileHarnesses.map(t => Promise.all([t.getColspan(), t.getRowspan()])); |
| 55 | + const tiles = (await Promise.all(tileSpans)).map(([colspan, rowspan]) => ({colspan, rowspan})); |
| 56 | + // Update the tile coordinator to reflect the current column amount and |
| 57 | + // rendered tiles. We update upon every call of this method since we do not |
| 58 | + // know if tiles have been added, removed or updated (in terms of rowspan/colspan). |
| 59 | + this._tileCoordinator.update(columns, tiles); |
| 60 | + // The tile coordinator respects the colspan and rowspan for calculating the positions |
| 61 | + // of tiles, but it does not create multiple position entries if a tile spans over multiple |
| 62 | + // columns or rows. We want to provide an API where developers can retrieve a tile based on |
| 63 | + // any position that lies within the visual tile boundaries. For example: If a tile spans |
| 64 | + // over two columns, then the same tile should be returned for either column indices. |
| 65 | + for (let i = 0; i < this._tileCoordinator.positions.length; i++) { |
| 66 | + const position = this._tileCoordinator.positions[i]; |
| 67 | + const {rowspan, colspan} = tiles[i]; |
| 68 | + // Return the tile harness if the given position visually resolves to the tile. |
| 69 | + if (column >= position.col && column <= position.col + colspan - 1 && row >= position.row && |
| 70 | + row <= position.row + rowspan - 1) { |
| 71 | + return tileHarnesses[i]; |
| 72 | + } |
| 73 | + } |
| 74 | + throw Error('Could not find tile at given position.'); |
| 75 | + } |
| 76 | +} |
0 commit comments