@svgrid/grid 1.1.2 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SvGrid.svelte +3 -1
- package/dist/SvGridDropdown.svelte +7 -3
- package/dist/cdn/svgrid.js +13504 -0
- package/dist/cdn/svgrid.svelte-external.js +11188 -0
- package/package.json +12 -2
- package/src/SvGrid.svelte +3 -1
- package/src/SvGridDropdown.svelte +7 -3
- package/dist/SvGrid.helpers.test.d.ts +0 -1
- package/dist/SvGrid.helpers.test.js +0 -298
- package/dist/SvGridChart.test.d.ts +0 -1
- package/dist/SvGridChart.test.js +0 -62
- package/dist/a11y.contract.test.d.ts +0 -1
- package/dist/a11y.contract.test.js +0 -39
- package/dist/a11y.test.d.ts +0 -1
- package/dist/a11y.test.js +0 -44
- package/dist/aligned-grids.test.d.ts +0 -1
- package/dist/aligned-grids.test.js +0 -75
- package/dist/build-api.coverage.test.d.ts +0 -20
- package/dist/build-api.coverage.test.js +0 -505
- package/dist/cell-formatting.test.d.ts +0 -1
- package/dist/cell-formatting.test.js +0 -234
- package/dist/cell-render.test.d.ts +0 -1
- package/dist/cell-render.test.js +0 -338
- package/dist/chart-export.test.d.ts +0 -1
- package/dist/chart-export.test.js +0 -302
- package/dist/chart.coverage.test.d.ts +0 -1
- package/dist/chart.coverage.test.js +0 -748
- package/dist/chart.test.d.ts +0 -1
- package/dist/chart.test.js +0 -289
- package/dist/clipboard.test.d.ts +0 -1
- package/dist/clipboard.test.js +0 -700
- package/dist/collaboration.coverage.test.d.ts +0 -1
- package/dist/collaboration.coverage.test.js +0 -200
- package/dist/collaboration.test.d.ts +0 -1
- package/dist/collaboration.test.js +0 -65
- package/dist/column-groups.test.d.ts +0 -1
- package/dist/column-groups.test.js +0 -56
- package/dist/column-types.test.d.ts +0 -1
- package/dist/column-types.test.js +0 -62
- package/dist/columns.test.d.ts +0 -1
- package/dist/columns.test.js +0 -625
- package/dist/conditional-formatting.test.d.ts +0 -1
- package/dist/conditional-formatting.test.js +0 -87
- package/dist/core.coverage.test.d.ts +0 -1
- package/dist/core.coverage.test.js +0 -186
- package/dist/core.performance.test.d.ts +0 -1
- package/dist/core.performance.test.js +0 -29
- package/dist/createGrid.test.d.ts +0 -1
- package/dist/createGrid.test.js +0 -9
- package/dist/editing.test.d.ts +0 -1
- package/dist/editing.test.js +0 -732
- package/dist/editors/cell-editors.coverage.test.d.ts +0 -1
- package/dist/editors/cell-editors.coverage.test.js +0 -139
- package/dist/editors/cell-editors.test.d.ts +0 -1
- package/dist/editors/cell-editors.test.js +0 -75
- package/dist/facet-buckets.test.d.ts +0 -1
- package/dist/facet-buckets.test.js +0 -296
- package/dist/fill-patterns.test.d.ts +0 -1
- package/dist/fill-patterns.test.js +0 -81
- package/dist/filter-operators.test.d.ts +0 -1
- package/dist/filter-operators.test.js +0 -135
- package/dist/filtering/excel-filters.test.d.ts +0 -1
- package/dist/filtering/excel-filters.test.js +0 -116
- package/dist/filtering/locale-filter.test.d.ts +0 -13
- package/dist/filtering/locale-filter.test.js +0 -189
- package/dist/flex-render.test.d.ts +0 -1
- package/dist/flex-render.test.js +0 -142
- package/dist/group-aggregate.test.d.ts +0 -1
- package/dist/group-aggregate.test.js +0 -32
- package/dist/hyperformula-adapter.test.d.ts +0 -1
- package/dist/hyperformula-adapter.test.js +0 -205
- package/dist/keyboard-handlers.coverage.test.d.ts +0 -1
- package/dist/keyboard-handlers.coverage.test.js +0 -495
- package/dist/keyboard.test.d.ts +0 -1
- package/dist/keyboard.test.js +0 -27
- package/dist/menus.test.d.ts +0 -1
- package/dist/menus.test.js +0 -560
- package/dist/named-views.coverage.test.d.ts +0 -1
- package/dist/named-views.coverage.test.js +0 -180
- package/dist/named-views.test.d.ts +0 -1
- package/dist/named-views.test.js +0 -57
- package/dist/new-features.test.d.ts +0 -1
- package/dist/new-features.test.js +0 -183
- package/dist/render-component.test.d.ts +0 -1
- package/dist/render-component.test.js +0 -41
- package/dist/row-drag.test.d.ts +0 -1
- package/dist/row-drag.test.js +0 -142
- package/dist/row-resize.test.d.ts +0 -1
- package/dist/row-resize.test.js +0 -329
- package/dist/scroll-sync.test.d.ts +0 -1
- package/dist/scroll-sync.test.js +0 -290
- package/dist/selection.multi-range.test.d.ts +0 -1
- package/dist/selection.multi-range.test.js +0 -55
- package/dist/selection.test.d.ts +0 -1
- package/dist/selection.test.js +0 -647
- package/dist/server-data-source.coverage.test.d.ts +0 -1
- package/dist/server-data-source.coverage.test.js +0 -154
- package/dist/server-data-source.test.d.ts +0 -1
- package/dist/server-data-source.test.js +0 -81
- package/dist/sparkline.test.d.ts +0 -1
- package/dist/sparkline.test.js +0 -52
- package/dist/spreadsheet.test.d.ts +0 -1
- package/dist/spreadsheet.test.js +0 -446
- package/dist/subscribe.test.d.ts +0 -1
- package/dist/subscribe.test.js +0 -93
- package/dist/svgrid.api-extensions.test.d.ts +0 -14
- package/dist/svgrid.api-extensions.test.js +0 -334
- package/dist/svgrid.api.test.d.ts +0 -15
- package/dist/svgrid.api.test.js +0 -169
- package/dist/svgrid.behavior.test.d.ts +0 -15
- package/dist/svgrid.behavior.test.js +0 -625
- package/dist/svgrid.column-reorder.test.d.ts +0 -15
- package/dist/svgrid.column-reorder.test.js +0 -224
- package/dist/svgrid.comments-autocomplete.test.d.ts +0 -1
- package/dist/svgrid.comments-autocomplete.test.js +0 -96
- package/dist/svgrid.context-menu.test.d.ts +0 -1
- package/dist/svgrid.context-menu.test.js +0 -102
- package/dist/svgrid.features.test.d.ts +0 -1
- package/dist/svgrid.features.test.js +0 -129
- package/dist/svgrid.interaction.test.d.ts +0 -9
- package/dist/svgrid.interaction.test.js +0 -349
- package/dist/svgrid.locale-filtering.test.d.ts +0 -15
- package/dist/svgrid.locale-filtering.test.js +0 -261
- package/dist/svgrid.new-features.wrapper.test.d.ts +0 -1
- package/dist/svgrid.new-features.wrapper.test.js +0 -194
- package/dist/svgrid.row-pinning.test.d.ts +0 -14
- package/dist/svgrid.row-pinning.test.js +0 -250
- package/dist/svgrid.set-filter.test.d.ts +0 -17
- package/dist/svgrid.set-filter.test.js +0 -268
- package/dist/svgrid.wrapper.test.d.ts +0 -1
- package/dist/svgrid.wrapper.test.js +0 -59
- package/dist/test-setup.d.ts +0 -1
- package/dist/test-setup.js +0 -35
- package/dist/transaction.test.d.ts +0 -1
- package/dist/transaction.test.js +0 -89
- package/dist/virtualization/column-virtualizer.test.d.ts +0 -1
- package/dist/virtualization/column-virtualizer.test.js +0 -25
- package/dist/virtualization/scroll-scaling.test.d.ts +0 -1
- package/dist/virtualization/scroll-scaling.test.js +0 -127
- package/dist/virtualization/virtualizer.test.d.ts +0 -1
- package/dist/virtualization/virtualizer.test.js +0 -41
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Behavioral tests for the SvGridApi extensions inspired by the jqxGrid API:
|
|
3
|
-
* - Row selection read/write (getSelectedRows / getSelectedRowIds /
|
|
4
|
-
* selectRows / selectAllRows / toggleRowSelected)
|
|
5
|
-
* - Pagination control (getPageInfo / setPage / next/prev/first/last /
|
|
6
|
-
* setPageSize)
|
|
7
|
-
* - Navigation (scrollToRow / getActiveCell / setActiveCell)
|
|
8
|
-
* - View state (getState / setState / refresh)
|
|
9
|
-
* - Click / double-click / scroll-bottom events
|
|
10
|
-
*
|
|
11
|
-
* They mount the real <SvGrid /> in jsdom and exercise the api object handed
|
|
12
|
-
* back from onApiReady.
|
|
13
|
-
*/
|
|
14
|
-
import { describe, expect, it } from 'vitest';
|
|
15
|
-
import { mount, unmount } from 'svelte';
|
|
16
|
-
import SvGrid from './SvGrid.svelte';
|
|
17
|
-
import { columnFilteringFeature, getGridCellDomId, rowPaginationFeature, rowSelectionFeature, rowSortingFeature, tableFeatures, } from './index';
|
|
18
|
-
const sampleRows = [
|
|
19
|
-
{ id: 1, name: 'Ada Lovelace', team: 'Research', salary: 142000 },
|
|
20
|
-
{ id: 2, name: 'Grace Hopper', team: 'Compilers', salary: 158000 },
|
|
21
|
-
{ id: 3, name: 'Alan Turing', team: 'Research', salary: 138000 },
|
|
22
|
-
{ id: 4, name: 'Margaret Hamilton', team: 'Apollo', salary: 165000 },
|
|
23
|
-
{ id: 5, name: 'Linus Torvalds', team: 'Kernel', salary: 175000 },
|
|
24
|
-
];
|
|
25
|
-
const sampleColumns = [
|
|
26
|
-
{ field: 'name', header: 'Name', width: 200 },
|
|
27
|
-
{ field: 'team', header: 'Team', width: 160 },
|
|
28
|
-
{ field: 'salary', header: 'Salary', width: 140 },
|
|
29
|
-
];
|
|
30
|
-
// One microtask is enough for the grid's derived state (gridStateVersion) to
|
|
31
|
-
// re-run after an imperative mutation - mirrors the existing api test.
|
|
32
|
-
const flush = () => Promise.resolve();
|
|
33
|
-
function mountGrid(extraProps = {}, features = tableFeatures({
|
|
34
|
-
columnFilteringFeature,
|
|
35
|
-
rowSortingFeature,
|
|
36
|
-
rowSelectionFeature,
|
|
37
|
-
})) {
|
|
38
|
-
return new Promise((resolveApi, rejectApi) => {
|
|
39
|
-
const target = document.createElement('div');
|
|
40
|
-
document.body.appendChild(target);
|
|
41
|
-
let captured = null;
|
|
42
|
-
const app = mount(SvGrid, {
|
|
43
|
-
target,
|
|
44
|
-
props: {
|
|
45
|
-
data: sampleRows,
|
|
46
|
-
columns: sampleColumns,
|
|
47
|
-
features,
|
|
48
|
-
rowHeight: 36,
|
|
49
|
-
containerHeight: 480,
|
|
50
|
-
virtualization: false,
|
|
51
|
-
onApiReady(api) {
|
|
52
|
-
captured = api;
|
|
53
|
-
resolveApi({
|
|
54
|
-
api,
|
|
55
|
-
target,
|
|
56
|
-
destroy: () => {
|
|
57
|
-
unmount(app);
|
|
58
|
-
target.remove();
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
...extraProps,
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
queueMicrotask(() => {
|
|
66
|
-
if (!captured)
|
|
67
|
-
rejectApi(new Error('onApiReady never fired'));
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
describe('SvGridApi - row selection', () => {
|
|
72
|
-
it('selectAllRows selects every row; getSelectedRows / Ids reflect it', async () => {
|
|
73
|
-
const { api, destroy } = await mountGrid();
|
|
74
|
-
try {
|
|
75
|
-
api.selectAllRows();
|
|
76
|
-
await flush();
|
|
77
|
-
expect(api.getSelectedRows().length).toBe(5);
|
|
78
|
-
expect(api.getSelectedRowIds().length).toBe(5);
|
|
79
|
-
}
|
|
80
|
-
finally {
|
|
81
|
-
destroy();
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
it('selectRows replaces the selection by default and adds with additive', async () => {
|
|
85
|
-
const { api, destroy } = await mountGrid();
|
|
86
|
-
try {
|
|
87
|
-
api.selectAllRows();
|
|
88
|
-
await flush();
|
|
89
|
-
const ids = api.getSelectedRowIds();
|
|
90
|
-
expect(ids.length).toBe(5);
|
|
91
|
-
api.selectRows([ids[0]]);
|
|
92
|
-
await flush();
|
|
93
|
-
expect(api.getSelectedRowIds()).toEqual([ids[0]]);
|
|
94
|
-
api.selectRows([ids[1]], true);
|
|
95
|
-
await flush();
|
|
96
|
-
expect(new Set(api.getSelectedRowIds())).toEqual(new Set([ids[0], ids[1]]));
|
|
97
|
-
}
|
|
98
|
-
finally {
|
|
99
|
-
destroy();
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
it('toggleRowSelected flips one row; clearRowSelection wipes all', async () => {
|
|
103
|
-
const { api, destroy } = await mountGrid();
|
|
104
|
-
try {
|
|
105
|
-
api.selectAllRows();
|
|
106
|
-
await flush();
|
|
107
|
-
const id = api.getSelectedRowIds()[0];
|
|
108
|
-
api.toggleRowSelected(id);
|
|
109
|
-
await flush();
|
|
110
|
-
expect(api.getSelectedRowIds()).not.toContain(id);
|
|
111
|
-
api.clearRowSelection();
|
|
112
|
-
await flush();
|
|
113
|
-
expect(api.getSelectedRowIds().length).toBe(0);
|
|
114
|
-
}
|
|
115
|
-
finally {
|
|
116
|
-
destroy();
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
describe('SvGridApi - pagination', () => {
|
|
121
|
-
const paged = () => mountGrid({ showPagination: true, pageSize: 2 }, tableFeatures({ rowPaginationFeature }));
|
|
122
|
-
it('getPageInfo derives pageCount from the filtered total', async () => {
|
|
123
|
-
const { api, destroy } = await paged();
|
|
124
|
-
try {
|
|
125
|
-
const info = api.getPageInfo();
|
|
126
|
-
expect(info.total).toBe(5);
|
|
127
|
-
expect(info.pageSize).toBe(2);
|
|
128
|
-
expect(info.pageCount).toBe(3); // ceil(5 / 2)
|
|
129
|
-
expect(info.pageIndex).toBe(0);
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
destroy();
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
it('setPage clamps to [0, pageCount - 1]', async () => {
|
|
136
|
-
const { api, destroy } = await paged();
|
|
137
|
-
try {
|
|
138
|
-
api.setPage(99);
|
|
139
|
-
await flush();
|
|
140
|
-
expect(api.getPageInfo().pageIndex).toBe(2);
|
|
141
|
-
api.setPage(-5);
|
|
142
|
-
await flush();
|
|
143
|
-
expect(api.getPageInfo().pageIndex).toBe(0);
|
|
144
|
-
}
|
|
145
|
-
finally {
|
|
146
|
-
destroy();
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
it('next/prev/first/last move through the pages', async () => {
|
|
150
|
-
const { api, destroy } = await paged();
|
|
151
|
-
try {
|
|
152
|
-
api.nextPage();
|
|
153
|
-
await flush();
|
|
154
|
-
expect(api.getPageInfo().pageIndex).toBe(1);
|
|
155
|
-
api.lastPage();
|
|
156
|
-
await flush();
|
|
157
|
-
expect(api.getPageInfo().pageIndex).toBe(2);
|
|
158
|
-
api.prevPage();
|
|
159
|
-
await flush();
|
|
160
|
-
expect(api.getPageInfo().pageIndex).toBe(1);
|
|
161
|
-
api.firstPage();
|
|
162
|
-
await flush();
|
|
163
|
-
expect(api.getPageInfo().pageIndex).toBe(0);
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
destroy();
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
it('setPageSize updates the page size and recomputes pageCount', async () => {
|
|
170
|
-
const { api, destroy } = await paged();
|
|
171
|
-
try {
|
|
172
|
-
api.setPageSize(5);
|
|
173
|
-
await flush();
|
|
174
|
-
const info = api.getPageInfo();
|
|
175
|
-
expect(info.pageSize).toBe(5);
|
|
176
|
-
expect(info.pageCount).toBe(1);
|
|
177
|
-
}
|
|
178
|
-
finally {
|
|
179
|
-
destroy();
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
describe('SvGridApi - navigation', () => {
|
|
184
|
-
it('setActiveCell + getActiveCell round-trip with the column id', async () => {
|
|
185
|
-
const { api, destroy } = await mountGrid();
|
|
186
|
-
try {
|
|
187
|
-
api.setActiveCell(2, 1);
|
|
188
|
-
await flush();
|
|
189
|
-
expect(api.getActiveCell()).toEqual({
|
|
190
|
-
rowIndex: 2,
|
|
191
|
-
colIndex: 1,
|
|
192
|
-
columnId: 'team',
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
finally {
|
|
196
|
-
destroy();
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
it('setActiveCell clamps out-of-range coordinates', async () => {
|
|
200
|
-
const { api, destroy } = await mountGrid();
|
|
201
|
-
try {
|
|
202
|
-
api.setActiveCell(999, 999);
|
|
203
|
-
await flush();
|
|
204
|
-
const cell = api.getActiveCell();
|
|
205
|
-
expect(cell?.rowIndex).toBe(4); // last row
|
|
206
|
-
expect(cell?.colIndex).toBe(2); // last column
|
|
207
|
-
}
|
|
208
|
-
finally {
|
|
209
|
-
destroy();
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
it('scrollToRow does not throw for valid or out-of-range indices', async () => {
|
|
213
|
-
const { api, destroy } = await mountGrid();
|
|
214
|
-
try {
|
|
215
|
-
expect(() => api.scrollToRow(3)).not.toThrow();
|
|
216
|
-
expect(() => api.scrollToRow(9999)).not.toThrow();
|
|
217
|
-
}
|
|
218
|
-
finally {
|
|
219
|
-
destroy();
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
describe('SvGridApi - view state (getState / setState)', () => {
|
|
224
|
-
it('getState captures sort + filters; setState restores them', async () => {
|
|
225
|
-
const { api, destroy } = await mountGrid();
|
|
226
|
-
try {
|
|
227
|
-
api.setSort('salary', 'desc');
|
|
228
|
-
api.setFilter('team', { operator: 'equals', value: 'Research' });
|
|
229
|
-
await flush();
|
|
230
|
-
const snapshot = api.getState();
|
|
231
|
-
expect(snapshot.sorting).toEqual([{ id: 'salary', desc: true }]);
|
|
232
|
-
expect(snapshot.columnFilters.team).toEqual({
|
|
233
|
-
operator: 'equals',
|
|
234
|
-
value: 'Research',
|
|
235
|
-
});
|
|
236
|
-
// Wipe, then restore from the snapshot.
|
|
237
|
-
api.clearSort();
|
|
238
|
-
api.clearAllFilters();
|
|
239
|
-
await flush();
|
|
240
|
-
expect(api.getState().sorting).toEqual([]);
|
|
241
|
-
expect(api.getFilters()).toEqual({});
|
|
242
|
-
api.setState(snapshot);
|
|
243
|
-
await flush();
|
|
244
|
-
expect(api.getState().sorting).toEqual([{ id: 'salary', desc: true }]);
|
|
245
|
-
expect(api.getFilters().team).toEqual({
|
|
246
|
-
operator: 'equals',
|
|
247
|
-
value: 'Research',
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
finally {
|
|
251
|
-
destroy();
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
it('setState restores column width + visibility', async () => {
|
|
255
|
-
const { api, destroy } = await mountGrid();
|
|
256
|
-
try {
|
|
257
|
-
api.setState({ columnWidths: { name: 320 }, hiddenColumns: ['team'] });
|
|
258
|
-
await flush();
|
|
259
|
-
expect(api.getColumnWidths().name).toBe(320);
|
|
260
|
-
expect(api.isColumnVisible('team')).toBe(false);
|
|
261
|
-
expect(api.getState().hiddenColumns).toContain('team');
|
|
262
|
-
}
|
|
263
|
-
finally {
|
|
264
|
-
destroy();
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
it('partial setState only touches the keys present', async () => {
|
|
268
|
-
const { api, destroy } = await mountGrid();
|
|
269
|
-
try {
|
|
270
|
-
api.setSort('name', 'asc');
|
|
271
|
-
await flush();
|
|
272
|
-
// Restoring only filters must not clear the existing sort.
|
|
273
|
-
api.setState({ globalFilter: '' });
|
|
274
|
-
await flush();
|
|
275
|
-
expect(api.getState().sorting).toEqual([{ id: 'name', desc: false }]);
|
|
276
|
-
}
|
|
277
|
-
finally {
|
|
278
|
-
destroy();
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
describe('SvGridApi - click / double-click / scroll events', () => {
|
|
283
|
-
function clickCell(_target, rowIndex, colIndex, type) {
|
|
284
|
-
const id = getGridCellDomId('svgrid', rowIndex, colIndex);
|
|
285
|
-
const el = document.getElementById(id);
|
|
286
|
-
if (!el)
|
|
287
|
-
throw new Error(`cell ${id} not found`);
|
|
288
|
-
el.dispatchEvent(new MouseEvent(type, { bubbles: true }));
|
|
289
|
-
}
|
|
290
|
-
it('onCellClick + onRowClick fire with the expected payload', async () => {
|
|
291
|
-
const cellEvents = [];
|
|
292
|
-
const rowEvents = [];
|
|
293
|
-
const { target, destroy } = await mountGrid({
|
|
294
|
-
onCellClick: (e) => cellEvents.push(e),
|
|
295
|
-
onRowClick: (e) => rowEvents.push(e),
|
|
296
|
-
});
|
|
297
|
-
try {
|
|
298
|
-
clickCell(target, 0, 0, 'click');
|
|
299
|
-
await flush();
|
|
300
|
-
expect(cellEvents.length).toBe(1);
|
|
301
|
-
expect(cellEvents[0]).toMatchObject({
|
|
302
|
-
rowIndex: 0,
|
|
303
|
-
colIndex: 0,
|
|
304
|
-
columnId: 'name',
|
|
305
|
-
value: 'Ada Lovelace',
|
|
306
|
-
});
|
|
307
|
-
expect(cellEvents[0].row.id).toBe(1);
|
|
308
|
-
expect(rowEvents.length).toBe(1);
|
|
309
|
-
expect(rowEvents[0]).toMatchObject({ rowIndex: 0, columnId: 'name' });
|
|
310
|
-
}
|
|
311
|
-
finally {
|
|
312
|
-
destroy();
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
it('onCellDoubleClick + onRowDoubleClick fire on dblclick', async () => {
|
|
316
|
-
const cellEvents = [];
|
|
317
|
-
const rowEvents = [];
|
|
318
|
-
const { target, destroy } = await mountGrid({
|
|
319
|
-
enableInlineEditing: false,
|
|
320
|
-
onCellDoubleClick: (e) => cellEvents.push(e),
|
|
321
|
-
onRowDoubleClick: (e) => rowEvents.push(e),
|
|
322
|
-
});
|
|
323
|
-
try {
|
|
324
|
-
clickCell(target, 1, 1, 'dblclick');
|
|
325
|
-
await flush();
|
|
326
|
-
expect(cellEvents.length).toBe(1);
|
|
327
|
-
expect(cellEvents[0]).toMatchObject({ rowIndex: 1, colIndex: 1, columnId: 'team' });
|
|
328
|
-
expect(rowEvents.length).toBe(1);
|
|
329
|
-
}
|
|
330
|
-
finally {
|
|
331
|
-
destroy();
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Behavioral tests for the imperative SvGridApi exposed via `onApiReady`.
|
|
3
|
-
*
|
|
4
|
-
* These mount the real <SvGrid /> render component in jsdom, capture the api
|
|
5
|
-
* object on mount, and exercise:
|
|
6
|
-
* - clearAllFilters (new)
|
|
7
|
-
* - getFilters (new)
|
|
8
|
-
* - getDisplayedRows (new)
|
|
9
|
-
* - setFilter (regression)
|
|
10
|
-
* - getData (regression)
|
|
11
|
-
*
|
|
12
|
-
* Bare-bones DOM env is enough; we never assert on rendered HTML, just on
|
|
13
|
-
* the object the component hands back.
|
|
14
|
-
*/
|
|
15
|
-
export {};
|
package/dist/svgrid.api.test.js
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Behavioral tests for the imperative SvGridApi exposed via `onApiReady`.
|
|
3
|
-
*
|
|
4
|
-
* These mount the real <SvGrid /> render component in jsdom, capture the api
|
|
5
|
-
* object on mount, and exercise:
|
|
6
|
-
* - clearAllFilters (new)
|
|
7
|
-
* - getFilters (new)
|
|
8
|
-
* - getDisplayedRows (new)
|
|
9
|
-
* - setFilter (regression)
|
|
10
|
-
* - getData (regression)
|
|
11
|
-
*
|
|
12
|
-
* Bare-bones DOM env is enough; we never assert on rendered HTML, just on
|
|
13
|
-
* the object the component hands back.
|
|
14
|
-
*/
|
|
15
|
-
import { describe, expect, it } from 'vitest';
|
|
16
|
-
import { mount, unmount } from 'svelte';
|
|
17
|
-
import SvGrid from './SvGrid.svelte';
|
|
18
|
-
import { columnFilteringFeature, createCoreRowModel, createFilteredRowModel, createSortedRowModel, rowSortingFeature, sortFns, tableFeatures, } from './index';
|
|
19
|
-
const features = tableFeatures({
|
|
20
|
-
columnFilteringFeature,
|
|
21
|
-
rowSortingFeature,
|
|
22
|
-
});
|
|
23
|
-
const sampleRows = [
|
|
24
|
-
{ id: 1, name: 'Ada Lovelace', team: 'Research', salary: 142000 },
|
|
25
|
-
{ id: 2, name: 'Grace Hopper', team: 'Compilers', salary: 158000 },
|
|
26
|
-
{ id: 3, name: 'Alan Turing', team: 'Research', salary: 138000 },
|
|
27
|
-
{ id: 4, name: 'Margaret Hamilton', team: 'Apollo', salary: 165000 },
|
|
28
|
-
{ id: 5, name: 'Linus Torvalds', team: 'Kernel', salary: 175000 },
|
|
29
|
-
];
|
|
30
|
-
const sampleColumns = [
|
|
31
|
-
{ field: 'name', header: 'Name', width: 200 },
|
|
32
|
-
{ field: 'team', header: 'Team', width: 160 },
|
|
33
|
-
{ field: 'salary', header: 'Salary', width: 140 },
|
|
34
|
-
];
|
|
35
|
-
function mountGrid() {
|
|
36
|
-
return new Promise((resolveApi, rejectApi) => {
|
|
37
|
-
const target = document.createElement('div');
|
|
38
|
-
document.body.appendChild(target);
|
|
39
|
-
let capturedApi = null;
|
|
40
|
-
const app = mount(SvGrid, {
|
|
41
|
-
target,
|
|
42
|
-
props: {
|
|
43
|
-
data: sampleRows,
|
|
44
|
-
columns: sampleColumns,
|
|
45
|
-
features,
|
|
46
|
-
_rowModels: {
|
|
47
|
-
coreRowModel: createCoreRowModel(),
|
|
48
|
-
filteredRowModel: createFilteredRowModel(),
|
|
49
|
-
sortedRowModel: createSortedRowModel(sortFns),
|
|
50
|
-
},
|
|
51
|
-
rowHeight: 36,
|
|
52
|
-
containerHeight: 480,
|
|
53
|
-
virtualization: false,
|
|
54
|
-
onApiReady(api) {
|
|
55
|
-
capturedApi = api;
|
|
56
|
-
resolveApi({
|
|
57
|
-
api,
|
|
58
|
-
destroy: () => {
|
|
59
|
-
unmount(app);
|
|
60
|
-
target.remove();
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
// Safety net: if onApiReady doesn't fire within a turn, fail loudly.
|
|
67
|
-
queueMicrotask(() => {
|
|
68
|
-
if (!capturedApi)
|
|
69
|
-
rejectApi(new Error('onApiReady never fired'));
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
describe('SvGridApi - getData / getDisplayedRows', () => {
|
|
74
|
-
it('getData returns the full row set', async () => {
|
|
75
|
-
const { api, destroy } = await mountGrid();
|
|
76
|
-
try {
|
|
77
|
-
const data = api.getData();
|
|
78
|
-
expect(data.length).toBe(sampleRows.length);
|
|
79
|
-
expect(data.map((r) => r.id)).toEqual([1, 2, 3, 4, 5]);
|
|
80
|
-
}
|
|
81
|
-
finally {
|
|
82
|
-
destroy();
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
it('getDisplayedRows returns the post-pipeline visible rows', async () => {
|
|
86
|
-
const { api, destroy } = await mountGrid();
|
|
87
|
-
try {
|
|
88
|
-
// With no filters / sort, displayed rows match full data (no group rows).
|
|
89
|
-
const displayed = api.getDisplayedRows();
|
|
90
|
-
expect(displayed.length).toBe(sampleRows.length);
|
|
91
|
-
}
|
|
92
|
-
finally {
|
|
93
|
-
destroy();
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
it('getDisplayedRows updates after setFilter narrows the set', async () => {
|
|
97
|
-
const { api, destroy } = await mountGrid();
|
|
98
|
-
try {
|
|
99
|
-
api.setFilter('team', { operator: 'contains', value: 'Research' });
|
|
100
|
-
// Wait one microtask so the derived row pipeline re-runs.
|
|
101
|
-
await Promise.resolve();
|
|
102
|
-
const displayed = api.getDisplayedRows();
|
|
103
|
-
// 2 rows have team === 'Research'
|
|
104
|
-
expect(displayed.length).toBe(2);
|
|
105
|
-
for (const r of displayed) {
|
|
106
|
-
expect(r.team).toBe('Research');
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
destroy();
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
describe('SvGridApi - getFilters / clearAllFilters', () => {
|
|
115
|
-
it('getFilters returns an empty object when nothing is filtered', async () => {
|
|
116
|
-
const { api, destroy } = await mountGrid();
|
|
117
|
-
try {
|
|
118
|
-
expect(api.getFilters()).toEqual({});
|
|
119
|
-
}
|
|
120
|
-
finally {
|
|
121
|
-
destroy();
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
it('getFilters reflects the last setFilter call', async () => {
|
|
125
|
-
const { api, destroy } = await mountGrid();
|
|
126
|
-
try {
|
|
127
|
-
api.setFilter('team', { operator: 'equals', value: 'Apollo' });
|
|
128
|
-
await Promise.resolve();
|
|
129
|
-
const filters = api.getFilters();
|
|
130
|
-
expect(filters.team).toEqual({ operator: 'equals', value: 'Apollo' });
|
|
131
|
-
}
|
|
132
|
-
finally {
|
|
133
|
-
destroy();
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
it('clearAllFilters wipes every column filter at once', async () => {
|
|
137
|
-
const { api, destroy } = await mountGrid();
|
|
138
|
-
try {
|
|
139
|
-
api.setFilter('team', { operator: 'contains', value: 'Research' });
|
|
140
|
-
api.setFilter('name', { operator: 'contains', value: 'Ada' });
|
|
141
|
-
await Promise.resolve();
|
|
142
|
-
expect(Object.keys(api.getFilters()).length).toBe(2);
|
|
143
|
-
api.clearAllFilters();
|
|
144
|
-
await Promise.resolve();
|
|
145
|
-
expect(api.getFilters()).toEqual({});
|
|
146
|
-
// The full row set is back.
|
|
147
|
-
const displayed = api.getDisplayedRows();
|
|
148
|
-
expect(displayed.length).toBe(sampleRows.length);
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
destroy();
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
it('clearAllFilters returns a snapshot that is safe to mutate', async () => {
|
|
155
|
-
const { api, destroy } = await mountGrid();
|
|
156
|
-
try {
|
|
157
|
-
api.setFilter('team', { operator: 'contains', value: 'X' });
|
|
158
|
-
await Promise.resolve();
|
|
159
|
-
const snapshot = api.getFilters();
|
|
160
|
-
// Mutate the snapshot - internal state must not be affected.
|
|
161
|
-
snapshot.team.value = 'mutated externally';
|
|
162
|
-
const fresh = api.getFilters();
|
|
163
|
-
expect(fresh.team.value).toBe('X');
|
|
164
|
-
}
|
|
165
|
-
finally {
|
|
166
|
-
destroy();
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Broad behavioral test suite for the <SvGrid /> render component.
|
|
3
|
-
*
|
|
4
|
-
* The intent is wide coverage on a single file - SvGrid.svelte is ~3000
|
|
5
|
-
* lines and most of its branches are reachable only when the component is
|
|
6
|
-
* mounted with a particular prop combination. Each test below exercises a
|
|
7
|
-
* different feature set so the whole file's effect graph is traversed.
|
|
8
|
-
*
|
|
9
|
-
* Pattern (re-used across files):
|
|
10
|
-
* 1. mount SvGrid in jsdom with the props that trigger the feature
|
|
11
|
-
* 2. wait one microtask for $effects to flush
|
|
12
|
-
* 3. assert on the api object delivered via onApiReady, or on visible DOM
|
|
13
|
-
* 4. unmount
|
|
14
|
-
*/
|
|
15
|
-
export {};
|