|
1 | | -import { expect, html } from '@open-wc/testing'; |
| 1 | +import { elementUpdated, expect, html, nextFrame } from '@open-wc/testing'; |
| 2 | +import { GRID_COLUMN_TAG } from '../src/internal/tags.js'; |
2 | 3 | import type { FilterExpression } from '../src/operations/filter/types.js'; |
3 | 4 | import type { SortingExpression } from '../src/operations/sort/types.js'; |
4 | 5 | import GridTestFixture from './utils/grid-fixture.js'; |
@@ -57,6 +58,42 @@ const TDD = new GridTestFixture(data); |
57 | 58 | const dataStateTDD = new InitialDataStateFixture(data); |
58 | 59 | const autoGenerateTDD = new AutoGenerateFixture(data); |
59 | 60 |
|
| 61 | +/** |
| 62 | + * Fixture covering the edge case where sort/filter expressions are set on the grid |
| 63 | + * before any column elements are slotted. The grid is created without columns, and columns |
| 64 | + * are appended (slotted) dynamically after creation. |
| 65 | + */ |
| 66 | +class LateColumnSlottingFixture<T extends TestData> extends GridTestFixture<T> { |
| 67 | + public sortState: SortingExpression<TestData>[] = [{ key: 'id', direction: 'descending' }]; |
| 68 | + public filterState: FilterExpression<TestData>[] = [ |
| 69 | + { key: 'importance', condition: 'equals', searchTerm: 'high' }, |
| 70 | + ]; |
| 71 | + |
| 72 | + public override setupTemplate() { |
| 73 | + return html` |
| 74 | + <igc-grid-lite |
| 75 | + .data=${this.data} |
| 76 | + .sortingExpressions=${this.sortState} |
| 77 | + .filterExpressions=${this.filterState} |
| 78 | + ></igc-grid-lite> |
| 79 | + `; |
| 80 | + } |
| 81 | + |
| 82 | + public async slotColumns(columnConfig = this.columnConfig) { |
| 83 | + for (const col of columnConfig) { |
| 84 | + const elem = Object.assign(document.createElement(GRID_COLUMN_TAG), { |
| 85 | + field: col.field, |
| 86 | + dataType: col.dataType ?? 'string', |
| 87 | + filterable: col.filterable ?? false, |
| 88 | + sortable: col.sortable ?? false, |
| 89 | + }); |
| 90 | + this.grid.appendChild(elem); |
| 91 | + } |
| 92 | + await Promise.all([elementUpdated(this.grid), nextFrame]); |
| 93 | + await nextFrame(); |
| 94 | + } |
| 95 | +} |
| 96 | + |
60 | 97 | describe('Grid auto-generate column configuration', () => { |
61 | 98 | const keys = new Set(Object.keys(testData[0])); |
62 | 99 | beforeEach(async () => await autoGenerateTDD.setUp()); |
@@ -129,3 +166,46 @@ describe('Grid properties', () => { |
129 | 166 | expect(TDD.grid.filterExpressions).lengthOf(3); |
130 | 167 | }); |
131 | 168 | }); |
| 169 | + |
| 170 | +describe('Grid properties (late column slotting)', () => { |
| 171 | + const lateSlotTDD = new LateColumnSlottingFixture(data); |
| 172 | + |
| 173 | + beforeEach(async () => await lateSlotTDD.setUp()); |
| 174 | + afterEach(() => lateSlotTDD.tearDown()); |
| 175 | + |
| 176 | + it('filterExpressions getter returns stored expressions before columns are slotted', () => { |
| 177 | + expect(lateSlotTDD.grid.filterExpressions).lengthOf(lateSlotTDD.filterState.length); |
| 178 | + }); |
| 179 | + |
| 180 | + it('sortingExpressions getter returns stored expressions before columns are slotted', () => { |
| 181 | + expect(lateSlotTDD.grid.sortingExpressions).lengthOf(lateSlotTDD.sortState.length); |
| 182 | + }); |
| 183 | + |
| 184 | + it('filter is applied to data after columns are slotted', async () => { |
| 185 | + // Data is unfiltered before columns arrive |
| 186 | + expect(lateSlotTDD.grid.totalItems).to.equal(data.length); |
| 187 | + |
| 188 | + await lateSlotTDD.slotColumns([{ field: 'importance', dataType: 'string', filterable: true }]); |
| 189 | + |
| 190 | + // Only 'high' importance rows |
| 191 | + expect(lateSlotTDD.grid.totalItems).to.equal( |
| 192 | + data.filter((d) => d.importance === 'high').length |
| 193 | + ); |
| 194 | + for (const row of lateSlotTDD.grid.rows) { |
| 195 | + expect(row.data!.importance).to.equal('high'); |
| 196 | + } |
| 197 | + }); |
| 198 | + |
| 199 | + it('sort is applied to data after columns are slotted', async () => { |
| 200 | + await lateSlotTDD.slotColumns([{ field: 'id' }]); |
| 201 | + |
| 202 | + // Sorted descending by id — first row should have the highest id |
| 203 | + expect(lateSlotTDD.rows.first.data.id).to.equal(Math.max(...data.map((d) => d.id))); |
| 204 | + }); |
| 205 | + |
| 206 | + it('filterExpressions getter still returns expressions after columns are slotted', async () => { |
| 207 | + await lateSlotTDD.slotColumns([{ field: 'importance', dataType: 'string', filterable: true }]); |
| 208 | + |
| 209 | + expect(lateSlotTDD.grid.filterExpressions).lengthOf(lateSlotTDD.filterState.length); |
| 210 | + }); |
| 211 | +}); |
0 commit comments