[39m
@@ -152,7 +152,7 @@ Ignored nodes: comments, script, style
`)
expect(() => queries.getCellByRowAndColumnHeaders(container, 'A', 'B', 1))
.toThrowErrorMatchingInlineSnapshot(`
-"Found no rows with A in the first column and B in the 2nd header
+"Found no rows with A in the first column and with B in the 2nd header
[36m
[39m
[36m
[39m
@@ -206,77 +206,174 @@ Ignored nodes: comments, script, style
expect(queries.getAllCells(container)).toHaveLength(48)
})
- it('should find cells by row and column headings', () => {
- const container = render(simpleTable)
- expect(
- queries.getCellByRowAndColumnHeaders(container, 'trouble', 'Status').id
- ).toEqual('body-cell-29')
- expect(
- queries.getCellByRowAndColumnHeaders(container, 'reason', 'Age').id
- ).toEqual('body-cell-21')
- expect(
- queries.queryCellByRowAndColumnHeaders(container, 'NOT A ROW', 'Status')
- ).toBeNull()
- expect(
- queries.queryCellByRowAndColumnHeaders(
+ describe('should find cells by row and column headings', () => {
+ it('using exact test match', () => {
+ const container = render(simpleTable)
+ expect(
+ queries.getCellByRowAndColumnHeaders(container, 'trouble', 'Status').id
+ ).toEqual('body-cell-29')
+ expect(
+ queries.getCellByRowAndColumnHeaders(container, 'reason', 'Age').id
+ ).toEqual('body-cell-21')
+ expect(
+ queries.queryCellByRowAndColumnHeaders(container, 'NOT A ROW', 'Status')
+ ).toBeNull()
+ expect(
+ queries.queryCellByRowAndColumnHeaders(
+ container,
+ 'trouble',
+ 'Not a column'
+ )
+ ).toBeNull()
+ })
+ it('using a regex', () => {
+ const container = render(simpleTable)
+ expect(
+ queries.getCellByRowAndColumnHeaders(container, /trouble/, /Status/).id
+ ).toEqual('body-cell-29')
+ expect(
+ queries.getCellByRowAndColumnHeaders(container, /reason/, /Age/).id
+ ).toEqual('body-cell-21')
+ expect(
+ queries.queryCellByRowAndColumnHeaders(container, /NOT A ROW/, /Status/)
+ ).toBeNull()
+ expect(
+ queries.queryCellByRowAndColumnHeaders(
+ container,
+ /trouble/,
+ /Not a column/
+ )
+ ).toBeNull()
+ expect(
+ queries.queryCellByRowAndColumnHeaders(container, /.*/, /Not a column/)
+ ).toBeNull()
+ expect(
+ queries.queryAllCellsByRowAndColumnHeaders(container, /.*/, /Age/)
+ ).toHaveLength(8)
+ expect(
+ queries.queryAllCellsByRowAndColumnHeaders(container, /reason/, /.*/)
+ ).toHaveLength(1)
+ expect(
+ queries.queryAllCellsByRowAndColumnHeaders(container, /.*/, /.*/)
+ ).toHaveLength(8)
+ })
+ })
+
+ describe('should find column cells by header text', () => {
+ it('using exact test match', () => {
+ const container = render(simpleTable)
+ expect(
+ queries.queryAllColumnCellsByHeaderText(container, 'NOT A COLUMN')
+ ).toHaveLength(0)
+ const ageCells = queries.getAllColumnCellsByHeaderText(container, 'Age')
+ expect(ageCells).toHaveLength(8)
+ expect(ageCells.map((cell) => cell.id)).toEqual([
+ 'header-cell-3',
+ 'body-cell-3',
+ 'body-cell-9',
+ 'body-cell-15',
+ 'body-cell-21',
+ 'body-cell-27',
+ 'body-cell-33',
+ 'body-cell-39'
+ ])
+ const statusCells = queries.getAllColumnCellsByHeaderText(
container,
- 'trouble',
- 'Not a column'
+ /Status/
)
- ).toBeNull()
- })
+ expect(statusCells).toHaveLength(8)
+ expect(statusCells.map((cell) => cell.id)).toEqual([
+ 'header-cell-5',
+ 'body-cell-5',
+ 'body-cell-11',
+ 'body-cell-17',
+ 'body-cell-23',
+ 'body-cell-29',
+ 'body-cell-35',
+ 'body-cell-41'
+ ])
+ })
- it('should find column cells by header text', () => {
- const container = render(simpleTable)
- expect(
- queries.queryAllColumnCellsByHeaderText(container, 'NOT A COLUMN')
- ).toHaveLength(0)
- const ageCells = queries.getAllColumnCellsByHeaderText(container, 'Age')
- expect(ageCells).toHaveLength(8)
- expect(ageCells.map((cell) => cell.id)).toEqual([
- 'header-cell-3',
- 'body-cell-3',
- 'body-cell-9',
- 'body-cell-15',
- 'body-cell-21',
- 'body-cell-27',
- 'body-cell-33',
- 'body-cell-39'
- ])
- const statusCells = queries.getAllColumnCellsByHeaderText(
- container,
- 'Status'
- )
- expect(statusCells).toHaveLength(8)
- expect(statusCells.map((cell) => cell.id)).toEqual([
- 'header-cell-5',
- 'body-cell-5',
- 'body-cell-11',
- 'body-cell-17',
- 'body-cell-23',
- 'body-cell-29',
- 'body-cell-35',
- 'body-cell-41'
- ])
+ it('using a regex match', () => {
+ const container = render(simpleTable)
+ expect(
+ queries.queryAllColumnCellsByHeaderText(container, /NOT A COLUMN/)
+ ).toHaveLength(0)
+ expect(
+ queries.queryAllColumnCellsByHeaderText(container, /.*/)
+ ).toHaveLength(8)
+ const ageCells = queries.getAllColumnCellsByHeaderText(container, /Age/)
+ expect(ageCells).toHaveLength(8)
+ expect(ageCells.map((cell) => cell.id)).toEqual([
+ 'header-cell-3',
+ 'body-cell-3',
+ 'body-cell-9',
+ 'body-cell-15',
+ 'body-cell-21',
+ 'body-cell-27',
+ 'body-cell-33',
+ 'body-cell-39'
+ ])
+ const statusCells = queries.getAllColumnCellsByHeaderText(
+ container,
+ /Status/
+ )
+ expect(statusCells).toHaveLength(8)
+ expect(statusCells.map((cell) => cell.id)).toEqual([
+ 'header-cell-5',
+ 'body-cell-5',
+ 'body-cell-11',
+ 'body-cell-17',
+ 'body-cell-23',
+ 'body-cell-29',
+ 'body-cell-35',
+ 'body-cell-41'
+ ])
+ })
})
- it('should find rows by the first cell text', () => {
- const container = render(simpleTable)
- expect(
- queries.queryAllRowsByFirstCellText(container, 'NOT A ROW')
- ).toHaveLength(0)
- expect(queries.getAllRowsByFirstCellText(container, 'reason')).toHaveLength(
- 1
- )
- expect(queries.getRowByFirstCellText(container, 'reason').id).toEqual(
- 'body-row-4'
- )
- expect(queries.getRowByFirstCellText(container, 'First Name').id).toEqual(
- 'header-row'
- )
- expect(queries.getRowByFirstCellText(container, 'midnight').id).toEqual(
- 'body-row-2'
- )
+ describe('should find rows by the first cell text', () => {
+ it('using exact text match', () => {
+ const container = render(simpleTable)
+ expect(
+ queries.queryAllRowsByFirstCellText(container, 'NOT A ROW')
+ ).toHaveLength(0)
+ expect(
+ queries.getAllRowsByFirstCellText(container, 'reason')
+ ).toHaveLength(1)
+ expect(queries.getRowByFirstCellText(container, 'reason').id).toEqual(
+ 'body-row-4'
+ )
+ expect(queries.getRowByFirstCellText(container, 'First Name').id).toEqual(
+ 'header-row'
+ )
+ expect(queries.getRowByFirstCellText(container, 'midnight').id).toEqual(
+ 'body-row-2'
+ )
+ })
+
+ it('using a regex', () => {
+ const container = render(simpleTable)
+ expect(
+ queries.queryAllRowsByFirstCellText(
+ container,
+ /this-regex-has-no-match/
+ )
+ ).toHaveLength(0)
+ expect(
+ queries.getAllRowsByFirstCellText(container, /reas*/)
+ ).toHaveLength(1)
+ expect(queries.getAllRowsByFirstCellText(container, /.*/)).toHaveLength(8)
+ expect(queries.getRowByFirstCellText(container, 'reason').id).toEqual(
+ 'body-row-4'
+ )
+ expect(queries.getRowByFirstCellText(container, 'First Name').id).toEqual(
+ 'header-row'
+ )
+ expect(queries.getRowByFirstCellText(container, 'midnight').id).toEqual(
+ 'body-row-2'
+ )
+ })
})
it('should find rowgroups', () => {
diff --git a/src/rowByFirstCellText.ts b/src/rowByFirstCellText.ts
index a8523ab..44307f6 100644
--- a/src/rowByFirstCellText.ts
+++ b/src/rowByFirstCellText.ts
@@ -4,7 +4,7 @@ import { queryAllCells } from './cells'
function queryAllRowsByFirstCellText(
container: HTMLElement,
- textContent: string
+ textQuery: string | RegExp,
) {
const rows = queryAllRows(container)
return rows.filter((row) => {
@@ -13,17 +13,29 @@ function queryAllRowsByFirstCellText(
return false
}
- // TODO - make normaliser customisable, support textmatch
- return (
- getDefaultNormalizer()(cellsInRow[0].textContent || '') === textContent
- )
+ const cellNormalizedTextContent = getDefaultNormalizer()(cellsInRow[0].textContent || '');
+
+ if (typeof textQuery === 'string') {
+ return cellNormalizedTextContent === textQuery
+ }
+
+ return textQuery.test(cellNormalizedTextContent)
})
}
-const getMultipleError = (_c: Element | null, textContent: string) =>
- `Found multiple rows with ${textContent} in the first cell`
-const getMissingError = (_c: Element | null, textContent: string) =>
- `Found no rows with ${textContent} in the first cell`
+const getMultipleError = (_c: Element | null, textQuery: string | RegExp) => {
+ if (typeof textQuery === 'string') {
+ return `Found multiple rows with ${textQuery} in the first cell`
+ }
+ return `Found multiple rows matching ${textQuery} in the first cell`
+}
+
+const getMissingError = (_c: Element | null, textQuery: string | RegExp) => {
+ if (typeof textQuery === 'string') {
+ return `Found no rows with ${textQuery} in the first cell`
+ }
+ return `Found no rows matching ${textQuery} in the first cell`
+}
const [
queryRowByFirstCellText,
@@ -31,7 +43,7 @@ const [
getRowByFirstCellText,
findAllRowsByFirstCellText,
findRowByFirstCellText
-] = queryHelpers.buildQueries(
+] = queryHelpers.buildQueries<[string | RegExp]>(
queryAllRowsByFirstCellText,
getMultipleError,
getMissingError
diff --git a/src/utils/columnIndexByHeaderText.ts b/src/utils/columnIndexByHeaderText.ts
index 05aa8a2..dc9dd29 100644
--- a/src/utils/columnIndexByHeaderText.ts
+++ b/src/utils/columnIndexByHeaderText.ts
@@ -6,7 +6,7 @@ import { getColspan } from './colspan'
export const getColumnIndexByHeaderText = (
container: HTMLElement,
- textContent: string,
+ textQuery: string | RegExp,
headerRowIndex = 0
) => {
const headerCellsByRow = queryAllRowsByRowgroupType(
@@ -21,9 +21,17 @@ export const getColumnIndexByHeaderText = (
const headerRowToUse = headerCellsByRow[headerRowIndex]
const cellIndex = headerRowToUse.findIndex((cell) => {
- // TODO - allow normaliser to be overridden
- return getDefaultNormalizer()(cell.textContent || '') === textContent
+ const cellNormalizedTextContent = getDefaultNormalizer()(
+ cell.textContent || ''
+ )
+
+ if (typeof textQuery === 'string') {
+ return cellNormalizedTextContent === textQuery
+ }
+
+ return textQuery.test(cellNormalizedTextContent)
})
+
if (cellIndex === -1) {
return -1
}
diff --git a/src/utils/stringOrRegexError.ts b/src/utils/stringOrRegexError.ts
new file mode 100644
index 0000000..9f2dce5
--- /dev/null
+++ b/src/utils/stringOrRegexError.ts
@@ -0,0 +1,2 @@
+export const stringOrRegexError = (text: string | RegExp) =>
+ typeof text === 'string' ? `with ${text}` : `matching ${text}`