mirror of
https://github.com/gosticks/react-table.git
synced 2025-10-16 11:55:36 +00:00
test: snapshots for useFilters, useGroupBy, useSortBy
This commit is contained in:
parent
bcefe5d6e8
commit
12e7b3220d
@ -58,26 +58,17 @@ function Table({ columns, data }) {
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(
|
||||
column =>
|
||||
console.log(column) || (
|
||||
// Add the sorting props to control sorting. For this example
|
||||
// we can add them into the header props
|
||||
<th
|
||||
{...column.getHeaderProps(column.getSortByToggleProps())}
|
||||
>
|
||||
{column.render('Header')}
|
||||
{/* Add a sort direction indicator */}
|
||||
<span>
|
||||
{column.sorted
|
||||
? column.sortedDesc
|
||||
? ' 🔽'
|
||||
: ' 🔼'
|
||||
: ''}
|
||||
</span>
|
||||
</th>
|
||||
)
|
||||
)}
|
||||
{headerGroup.headers.map(column => (
|
||||
// Add the sorting props to control sorting. For this example
|
||||
// we can add them into the header props
|
||||
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
|
||||
{column.render('Header')}
|
||||
{/* Add a sort direction indicator */}
|
||||
<span>
|
||||
{column.sorted ? (column.sortedDesc ? ' 🔽' : ' 🔼') : ''}
|
||||
</span>
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
export const text = (rows, id, filterValue) => {
|
||||
return rows.filter(row => {
|
||||
rows = rows.filter(row => {
|
||||
const rowValue = row.values[id]
|
||||
return rowValue !== undefined
|
||||
? String(rowValue)
|
||||
.toLowerCase()
|
||||
.includes(String(filterValue).toLowerCase())
|
||||
: true
|
||||
return String(rowValue)
|
||||
.toLowerCase()
|
||||
.includes(String(filterValue).toLowerCase())
|
||||
})
|
||||
return rows
|
||||
}
|
||||
|
||||
text.autoRemove = val => !val
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import '@testing-library/react/cleanup-after-each'
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
// NOTE: jest-dom adds handy assertions to Jest and is recommended, but not required
|
||||
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
@ -63,6 +63,7 @@ export const useTable = (props, ...plugins) => {
|
||||
plugins,
|
||||
hooks: {
|
||||
columnsBeforeHeaderGroups: [],
|
||||
columnsBeforeHeaderGroupsDeps: [],
|
||||
useMain: [],
|
||||
useColumns: [],
|
||||
useHeaders: [],
|
||||
@ -84,45 +85,57 @@ export const useTable = (props, ...plugins) => {
|
||||
})
|
||||
if (debug) console.timeEnd('plugins')
|
||||
|
||||
// Compute columns, headerGroups and headers
|
||||
const columnInfo = React.useMemo(
|
||||
if (debug) console.info('buildColumns/headerGroup/headers')
|
||||
// Decorate All the columns
|
||||
let columnTree = React.useMemo(
|
||||
() => decorateColumnTree(userColumns, defaultColumn),
|
||||
[defaultColumn, userColumns]
|
||||
)
|
||||
|
||||
// Get the flat list of all columns
|
||||
let columns = React.useMemo(() => flattenBy(columnTree, 'columns'), [
|
||||
columnTree,
|
||||
])
|
||||
|
||||
// Allow hooks to decorate columns (and trigger this memoization via deps)
|
||||
columns = React.useMemo(
|
||||
() => {
|
||||
if (debug) console.info('buildColumns/headerGroup/headers')
|
||||
// Decorate All the columns
|
||||
let columnTree = decorateColumnTree(userColumns, defaultColumn)
|
||||
|
||||
// Get the flat list of all columns
|
||||
let columns = flattenBy(columnTree, 'columns')
|
||||
|
||||
// Allow hooks to decorate columns
|
||||
if (debug) console.time('hooks.columnsBeforeHeaderGroups')
|
||||
columns = applyHooks(
|
||||
const newColumns = applyHooks(
|
||||
instanceRef.current.hooks.columnsBeforeHeaderGroups,
|
||||
columns,
|
||||
instanceRef.current
|
||||
)
|
||||
if (debug) console.timeEnd('hooks.columnsBeforeHeaderGroups')
|
||||
|
||||
// Make the headerGroups
|
||||
const headerGroups = makeHeaderGroups(
|
||||
columns,
|
||||
findMaxDepth(columnTree),
|
||||
defaultColumn
|
||||
)
|
||||
|
||||
const headers = flattenBy(headerGroups, 'headers')
|
||||
|
||||
return {
|
||||
columns,
|
||||
headerGroups,
|
||||
headers,
|
||||
}
|
||||
return newColumns
|
||||
},
|
||||
[debug, defaultColumn, userColumns]
|
||||
[
|
||||
columns,
|
||||
debug,
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
...applyHooks(
|
||||
instanceRef.current.hooks.columnsBeforeHeaderGroupsDeps,
|
||||
[],
|
||||
instanceRef.current
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
// Place the columns, headerGroups and headers on the api
|
||||
Object.assign(instanceRef.current, columnInfo)
|
||||
// Make the headerGroups
|
||||
const headerGroups = React.useMemo(
|
||||
() => makeHeaderGroups(columns, findMaxDepth(columnTree), defaultColumn),
|
||||
[columnTree, columns, defaultColumn]
|
||||
)
|
||||
|
||||
const headers = React.useMemo(() => flattenBy(headerGroups, 'headers'), [
|
||||
headerGroups,
|
||||
])
|
||||
|
||||
Object.assign(instanceRef.current, {
|
||||
columns,
|
||||
headerGroups,
|
||||
headers,
|
||||
})
|
||||
|
||||
// Access the row model
|
||||
instanceRef.current.rows = React.useMemo(
|
||||
|
||||
@ -1,11 +1,203 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders a sortable table 1`] = `
|
||||
exports[`renders a filterable table 1`] = `
|
||||
"Snapshot Diff:
|
||||
Compared values have no visual difference."
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
Last Name
|
||||
<input
|
||||
placeholder=\\"Search...\\"
|
||||
- value=\\"\\"
|
||||
+ value=\\"l\\"
|
||||
/>
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
@@ -115,78 +115,10 @@
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
progress: 50
|
||||
- </td>
|
||||
- </tr>
|
||||
- <tr
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- firstName: derek
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- lastName: perkins
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- age: 40
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- visits: 40
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- status: Single
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- progress: 80
|
||||
- </td>
|
||||
- </tr>
|
||||
- <tr
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- firstName: joe
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- lastName: bergevin
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- age: 45
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- visits: 20
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- status: Complicated
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- progress: 10
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=\\"\\"
|
||||
>"
|
||||
`;
|
||||
|
||||
exports[`renders a sortable table 2`] = `
|
||||
exports[`renders a filterable table 2`] = `
|
||||
"Snapshot Diff:
|
||||
Compared values have no visual difference."
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
Last Name
|
||||
<input
|
||||
placeholder=\\"Search...\\"
|
||||
- value=\\"l\\"
|
||||
+ value=\\"er\\"
|
||||
/>
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
@@ -89,70 +89,70 @@
|
||||
class=\\"\\"
|
||||
>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- firstName: tanner
|
||||
+ firstName: derek
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- lastName: linsley
|
||||
+ lastName: perkins
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- age: 29
|
||||
+ age: 40
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- visits: 100
|
||||
+ visits: 40
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- status: In Relationship
|
||||
+ status: Single
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- progress: 50
|
||||
+ progress: 80
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=\\"\\"
|
||||
>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- firstName: jaylen
|
||||
+ firstName: joe
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- lastName: linsley
|
||||
+ lastName: bergevin
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- age: 26
|
||||
+ age: 45
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- visits: 99
|
||||
+ visits: 20
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- status: In Relationship
|
||||
+ status: Complicated
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- progress: 70
|
||||
+ progress: 10
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</DocumentFragment>"
|
||||
`;
|
||||
|
||||
371
src/plugin-hooks/tests/__snapshots__/useGroupBy.test.js.snap
Normal file
371
src/plugin-hooks/tests/__snapshots__/useGroupBy.test.js.snap
Normal file
@ -0,0 +1,371 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders a filterable table 1`] = `
|
||||
"Snapshot Diff:
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
<span
|
||||
class=\\"\\"
|
||||
style=\\"cursor: pointer;\\"
|
||||
title=\\"Toggle GroupBy\\"
|
||||
>
|
||||
- 👊
|
||||
+ 🛑
|
||||
</span>
|
||||
- First Name
|
||||
+ Last Name
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
@@ -44,11 +44,11 @@
|
||||
style=\\"cursor: pointer;\\"
|
||||
title=\\"Toggle GroupBy\\"
|
||||
>
|
||||
👊
|
||||
</span>
|
||||
- Last Name
|
||||
+ First Name
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
@@ -107,138 +107,119 @@
|
||||
class=\\"\\"
|
||||
>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- firstName: tanner
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
+ <span
|
||||
+ style=\\"cursor: pointer;\\"
|
||||
>
|
||||
- lastName: linsley
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- age: 29
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- visits: 100
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- status: In Relationship
|
||||
+ 👉
|
||||
+ </span>
|
||||
+ lastName: linsley (2)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- progress: 50
|
||||
- </td>
|
||||
- </tr>
|
||||
- <tr
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- firstName: derek
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
- lastName: perkins
|
||||
+ 2 Names
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- age: 40
|
||||
+ 27.5 (avg)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- visits: 40
|
||||
+ 199 (total)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- status: Single
|
||||
+ status: null
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- progress: 80
|
||||
+ 60 (med)
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=\\"\\"
|
||||
>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- firstName: joe
|
||||
+ <span
|
||||
+ style=\\"cursor: pointer;\\"
|
||||
+ >
|
||||
+ 👉
|
||||
+ </span>
|
||||
+ lastName: perkins (1)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- lastName: bergevin
|
||||
+ 1 Names
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- age: 45
|
||||
+ 40 (avg)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- visits: 20
|
||||
+ 40 (total)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- status: Complicated
|
||||
+ status: null
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- progress: 10
|
||||
+ 80 (med)
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class=\\"\\"
|
||||
>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- firstName: jaylen
|
||||
+ <span
|
||||
+ style=\\"cursor: pointer;\\"
|
||||
+ >
|
||||
+ 👉
|
||||
+ </span>
|
||||
+ lastName: bergevin (1)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- lastName: linsley
|
||||
+ 1 Names
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- age: 26
|
||||
+ 45 (avg)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- visits: 99
|
||||
+ 20 (total)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- status: In Relationship
|
||||
+ status: null
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- progress: 70
|
||||
+ 10 (med)
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</DocumentFragment>"
|
||||
`;
|
||||
|
||||
exports[`renders a filterable table 2`] = `
|
||||
"Snapshot Diff:
|
||||
- First value
|
||||
+ Second value
|
||||
|
||||
@@ -6,17 +6,29 @@
|
||||
<tr
|
||||
class=\\"\\"
|
||||
>
|
||||
<th
|
||||
class=\\"\\"
|
||||
- colspan=\\"2\\"
|
||||
+ colspan=\\"1\\"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
- colspan=\\"4\\"
|
||||
+ colspan=\\"1\\"
|
||||
+ >
|
||||
+ Info
|
||||
+ </th>
|
||||
+ <th
|
||||
+ class=\\"\\"
|
||||
+ colspan=\\"1\\"
|
||||
+ >
|
||||
+ Name
|
||||
+ </th>
|
||||
+ <th
|
||||
+ class=\\"\\"
|
||||
+ colspan=\\"3\\"
|
||||
>
|
||||
Info
|
||||
</th>
|
||||
</tr>
|
||||
<tr
|
||||
@@ -42,13 +54,13 @@
|
||||
<span
|
||||
class=\\"\\"
|
||||
style=\\"cursor: pointer;\\"
|
||||
title=\\"Toggle GroupBy\\"
|
||||
>
|
||||
- 👊
|
||||
+ 🛑
|
||||
</span>
|
||||
- First Name
|
||||
+ Visits
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
@@ -57,11 +69,11 @@
|
||||
style=\\"cursor: pointer;\\"
|
||||
title=\\"Toggle GroupBy\\"
|
||||
>
|
||||
👊
|
||||
</span>
|
||||
- Age
|
||||
+ First Name
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
@@ -70,11 +82,11 @@
|
||||
style=\\"cursor: pointer;\\"
|
||||
title=\\"Toggle GroupBy\\"
|
||||
>
|
||||
👊
|
||||
</span>
|
||||
- Visits
|
||||
+ Age
|
||||
</th>
|
||||
<th
|
||||
class=\\"\\"
|
||||
colspan=\\"1\\"
|
||||
>
|
||||
@@ -114,10 +126,13 @@
|
||||
>
|
||||
👉
|
||||
</span>
|
||||
lastName: linsley (2)
|
||||
</td>
|
||||
+ <td
|
||||
+ class=\\"\\"
|
||||
+ />
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
2 Names
|
||||
</td>
|
||||
@@ -127,15 +142,10 @@
|
||||
27.5 (avg)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- 199 (total)
|
||||
- </td>
|
||||
- <td
|
||||
- class=\\"\\"
|
||||
- >
|
||||
status: null
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
@@ -155,22 +165,20 @@
|
||||
</span>
|
||||
lastName: perkins (1)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
- >
|
||||
- 1 Names
|
||||
- </td>
|
||||
+ />
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- 40 (avg)
|
||||
+ 1 Names
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- 40 (total)
|
||||
+ 40 (avg)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
status: null
|
||||
@@ -194,22 +202,20 @@
|
||||
</span>
|
||||
lastName: bergevin (1)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
- >
|
||||
- 1 Names
|
||||
- </td>
|
||||
+ />
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- 45 (avg)
|
||||
+ 1 Names
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
- 20 (total)
|
||||
+ 45 (avg)
|
||||
</td>
|
||||
<td
|
||||
class=\\"\\"
|
||||
>
|
||||
status: null"
|
||||
`;
|
||||
@ -1,6 +1,5 @@
|
||||
import '@testing-library/react/cleanup-after-each'
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
// NOTE: jest-dom adds handy assertions to Jest and is recommended, but not required
|
||||
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
@ -73,7 +72,7 @@ function Table({ columns, data }) {
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()}>
|
||||
{column.render('Header')}
|
||||
{column.render('Filter')}
|
||||
{column.canFilter ? column.render('Filter') : null}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
@ -139,19 +138,21 @@ function App() {
|
||||
return <Table columns={columns} data={data} />
|
||||
}
|
||||
|
||||
test('renders a sortable table', () => {
|
||||
const { getByText, asFragment } = render(<App />)
|
||||
test('renders a filterable table', () => {
|
||||
const { getAllByPlaceholderText, asFragment } = render(<App />)
|
||||
|
||||
const beforeSort = asFragment()
|
||||
const filterInputs = getAllByPlaceholderText('Search...')
|
||||
|
||||
fireEvent.click(getByText('First Name'))
|
||||
const beforeFilter = asFragment()
|
||||
|
||||
const afterSort1 = asFragment()
|
||||
fireEvent.change(filterInputs[1], { target: { value: 'l' } })
|
||||
|
||||
fireEvent.click(getByText('First Name'))
|
||||
const afterFilter1 = asFragment()
|
||||
|
||||
const afterSort2 = asFragment()
|
||||
fireEvent.change(filterInputs[1], { target: { value: 'er' } })
|
||||
|
||||
expect(beforeSort).toMatchDiffSnapshot(afterSort1)
|
||||
expect(afterSort1).toMatchDiffSnapshot(afterSort2)
|
||||
const afterFilter2 = asFragment()
|
||||
|
||||
expect(beforeFilter).toMatchDiffSnapshot(afterFilter1)
|
||||
expect(afterFilter1).toMatchDiffSnapshot(afterFilter2)
|
||||
})
|
||||
|
||||
207
src/plugin-hooks/tests/useGroupBy.test.js
Normal file
207
src/plugin-hooks/tests/useGroupBy.test.js
Normal file
@ -0,0 +1,207 @@
|
||||
import '@testing-library/react/cleanup-after-each'
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import { useTable } from '../../hooks/useTable'
|
||||
import { useGroupBy } from '../useGroupBy'
|
||||
import { useExpanded } from '../useExpanded'
|
||||
|
||||
const data = [
|
||||
{
|
||||
firstName: 'tanner',
|
||||
lastName: 'linsley',
|
||||
age: 29,
|
||||
visits: 100,
|
||||
status: 'In Relationship',
|
||||
progress: 50,
|
||||
},
|
||||
{
|
||||
firstName: 'derek',
|
||||
lastName: 'perkins',
|
||||
age: 40,
|
||||
visits: 40,
|
||||
status: 'Single',
|
||||
progress: 80,
|
||||
},
|
||||
{
|
||||
firstName: 'joe',
|
||||
lastName: 'bergevin',
|
||||
age: 45,
|
||||
visits: 20,
|
||||
status: 'Complicated',
|
||||
progress: 10,
|
||||
},
|
||||
{
|
||||
firstName: 'jaylen',
|
||||
lastName: 'linsley',
|
||||
age: 26,
|
||||
visits: 99,
|
||||
status: 'In Relationship',
|
||||
progress: 70,
|
||||
},
|
||||
]
|
||||
|
||||
const defaultColumn = {
|
||||
Cell: ({ value, column: { id } }) => `${id}: ${value}`,
|
||||
Filter: ({ filterValue, setFilter }) => (
|
||||
<input
|
||||
value={filterValue || ''}
|
||||
onChange={e => {
|
||||
setFilter(e.target.value || undefined) // Set undefined to remove the filter entirely
|
||||
}}
|
||||
placeholder="Search..."
|
||||
/>
|
||||
),
|
||||
}
|
||||
|
||||
function Table({ columns, data }) {
|
||||
const { getTableProps, headerGroups, rows, prepareRow } = useTable(
|
||||
{
|
||||
columns,
|
||||
data,
|
||||
defaultColumn,
|
||||
},
|
||||
useGroupBy,
|
||||
useExpanded
|
||||
)
|
||||
|
||||
return (
|
||||
<table {...getTableProps()}>
|
||||
<thead>
|
||||
{headerGroups.map(headerGroup => (
|
||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||
{headerGroup.headers.map(column => (
|
||||
<th {...column.getHeaderProps()}>
|
||||
{column.canGroupBy ? (
|
||||
// If the column can be grouped, let's add a toggle
|
||||
<span {...column.getGroupByToggleProps()}>
|
||||
{column.grouped ? '🛑' : '👊'}
|
||||
</span>
|
||||
) : null}
|
||||
{column.render('Header')}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map(
|
||||
(row, i) =>
|
||||
prepareRow(row) || (
|
||||
<tr {...row.getRowProps()}>
|
||||
{row.cells.map(cell => {
|
||||
return (
|
||||
<td {...cell.getCellProps()}>
|
||||
{cell.grouped ? (
|
||||
<>
|
||||
<span
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => row.toggleExpanded()}
|
||||
>
|
||||
{row.isExpanded ? '👇' : '👉'}
|
||||
</span>
|
||||
{cell.render('Cell')} ({row.subRows.length})
|
||||
</>
|
||||
) : cell.aggregated ? (
|
||||
cell.render('Aggregated')
|
||||
) : cell.repeatedValue ? null : (
|
||||
cell.render('Cell')
|
||||
)}
|
||||
</td>
|
||||
)
|
||||
})}
|
||||
</tr>
|
||||
)
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
|
||||
function roundedMedian(values) {
|
||||
let min = values[0] || ''
|
||||
let max = values[0] || ''
|
||||
|
||||
values.forEach(value => {
|
||||
min = Math.min(min, value)
|
||||
max = Math.max(max, value)
|
||||
})
|
||||
|
||||
return Math.round((min + max) / 2)
|
||||
}
|
||||
|
||||
function App() {
|
||||
const columns = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: 'Name',
|
||||
columns: [
|
||||
{
|
||||
Header: 'First Name',
|
||||
accessor: 'firstName',
|
||||
aggregate: ['sum', 'count'],
|
||||
Aggregated: ({ value }) => `${value} Names`,
|
||||
},
|
||||
{
|
||||
Header: 'Last Name',
|
||||
accessor: 'lastName',
|
||||
aggregate: ['sum', 'uniqueCount'],
|
||||
Aggregated: ({ value }) => `${value} Unique Names`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
Header: 'Info',
|
||||
columns: [
|
||||
{
|
||||
Header: 'Age',
|
||||
accessor: 'age',
|
||||
aggregate: 'average',
|
||||
Aggregated: ({ value }) => `${value} (avg)`,
|
||||
},
|
||||
{
|
||||
Header: 'Visits',
|
||||
accessor: 'visits',
|
||||
aggregate: 'sum',
|
||||
Aggregated: ({ value }) => `${value} (total)`,
|
||||
},
|
||||
{
|
||||
Header: 'Status',
|
||||
accessor: 'status',
|
||||
},
|
||||
{
|
||||
Header: 'Profile Progress',
|
||||
accessor: 'progress',
|
||||
aggregate: roundedMedian,
|
||||
Aggregated: ({ value }) => `${value} (med)`,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
return <Table columns={columns} data={data} />
|
||||
}
|
||||
|
||||
test('renders a filterable table', () => {
|
||||
const { getAllByText, asFragment } = render(<App />)
|
||||
|
||||
const groupByButtons = getAllByText('👊')
|
||||
|
||||
const beforeGrouping = asFragment()
|
||||
|
||||
fireEvent.click(groupByButtons[1])
|
||||
|
||||
const afterGrouping1 = asFragment()
|
||||
|
||||
fireEvent.click(groupByButtons[3])
|
||||
|
||||
const afterGrouping2 = asFragment()
|
||||
|
||||
expect(beforeGrouping).toMatchDiffSnapshot(afterGrouping1)
|
||||
expect(afterGrouping1).toMatchDiffSnapshot(afterGrouping2)
|
||||
})
|
||||
@ -1,6 +1,5 @@
|
||||
import '@testing-library/react/cleanup-after-each'
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
// NOTE: jest-dom adds handy assertions to Jest and is recommended, but not required
|
||||
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
|
||||
@ -181,14 +181,6 @@ function useMain(instance) {
|
||||
}
|
||||
})
|
||||
|
||||
// then filter any rows without subcolumns because it would be strange to show
|
||||
filteredRows = filteredRows.filter(row => {
|
||||
if (!row.subRows) {
|
||||
return true
|
||||
}
|
||||
return row.subRows.length > 0
|
||||
})
|
||||
|
||||
return filteredRows
|
||||
}
|
||||
|
||||
|
||||
@ -38,6 +38,10 @@ const propTypes = {
|
||||
|
||||
export const useGroupBy = hooks => {
|
||||
hooks.columnsBeforeHeaderGroups.push(columnsBeforeHeaderGroups)
|
||||
hooks.columnsBeforeHeaderGroupsDeps.push((deps, instance) => {
|
||||
deps.push(instance.state[0].groupBy)
|
||||
return deps
|
||||
})
|
||||
hooks.useMain.push(useMain)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user