Skip to content

Commit

Permalink
TreeGrid: Add tests for callback functions (#38942)
Browse files Browse the repository at this point in the history
* TreeGrid: Add tests for onExpand and onCollapse callbacks

* Remove unneeded width attribute

* Add tests for onFocusRow

* Add changelog entry
  • Loading branch information
andrewserong authored Feb 22, 2022
1 parent 314c984 commit 69c57ce
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 21 deletions.
4 changes: 4 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Fix spin buttons of number inputs in Safari ([#38840](https://github.com/WordPress/gutenberg/pull/38840))

### Enhancements

- `TreeGrid`: Add tests for `onCollapseRow`, `onExpandRow`, and `onFocusRow` callback functions. ([#38942](https://github.com/WordPress/gutenberg/pull/38942)).

## 19.4.0 (2022-02-10)

### Bug Fix
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TreeGrid renders a table, tbody and any child elements 1`] = `
<table
onKeyDown={[Function]}
role="treegrid"
>
<tbody>
<tr>
<td>
Test
</td>
</tr>
</tbody>
</table>
`;
exports[`TreeGrid simple rendering renders a table, tbody and any child elements 1`] = `"<table role=\\"treegrid\\"><tbody><tr><td>Test</td></tr></tbody></table>"`;
233 changes: 226 additions & 7 deletions packages/components/src/tree-grid/test/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,242 @@
/**
* External dependencies
*/
import TestRenderer from 'react-test-renderer';
import { fireEvent, render, screen } from '@testing-library/react';

/**
* WordPress dependencies
*/
import { LEFT, RIGHT, UP, DOWN } from '@wordpress/keycodes';
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import TreeGrid from '../';

const TestButton = forwardRef( ( { ...props }, ref ) => (
<button { ...props } ref={ ref }></button>
) );

describe( 'TreeGrid', () => {
it( 'renders a table, tbody and any child elements', () => {
const renderer = TestRenderer.create(
<TreeGrid>
<tr>
<td>Test</td>
const originalGetClientRects = window.Element.prototype.getClientRects;

// `getClientRects` needs to be mocked so that `isVisible` from the `@wordpress/dom`
// `focusable` module can pass, in a JSDOM env where the DOM elements have no width/height.
const mockedGetClientRects = jest.fn( () => [
{
x: 0,
y: 0,
width: 100,
height: 100,
},
] );

beforeAll( () => {
window.Element.prototype.getClientRects = jest.fn(
mockedGetClientRects
);
} );

afterAll( () => {
window.Element.prototype.getClientRects = originalGetClientRects;
} );

describe( 'simple rendering', () => {
it( 'renders a table, tbody and any child elements', () => {
const { container } = render(
<TreeGrid>
<tr>
<td>Test</td>
</tr>
</TreeGrid>
);

expect( container.innerHTML ).toMatchSnapshot();
} );
} );

describe( 'onExpandRow', () => {
it( 'should call onExpandRow when pressing Right Arrow on a collapsed row', () => {
const onExpandRow = jest.fn();

render(
<TreeGrid onExpandRow={ onExpandRow }>
<tr role="row" aria-expanded="true">
<td>
<TestButton>Row 1</TestButton>
</td>
</tr>
<tr role="row" aria-expanded="false">
<td>
<TestButton>Row 2</TestButton>
</td>
</tr>
<tr role="row" aria-expanded="true">
<td>
<TestButton>Row 3</TestButton>
</td>
</tr>
</TreeGrid>
);

screen.getByText( 'Row 2' ).focus();
const row2Element = screen.getByText( 'Row 2' ).closest( 'tr' );

fireEvent.keyDown( screen.getByText( 'Row 2' ), {
key: 'ArrowRight',
keyCode: RIGHT,
currentTarget: row2Element,
} );

expect( onExpandRow ).toHaveBeenCalledWith( row2Element );
} );
} );

describe( 'onCollapseRow', () => {
it( 'should call onCollapseRow when pressing Left Arrow on an expanded row', () => {
const onCollapseRow = jest.fn();

render(
<TreeGrid onCollapseRow={ onCollapseRow }>
<tr role="row" aria-expanded="false">
<td>
<TestButton>Row 1</TestButton>
</td>
</tr>
<tr role="row" aria-expanded="true">
<td>
<TestButton>Row 2</TestButton>
</td>
</tr>
<tr role="row" aria-expanded="false">
<td>
<TestButton>Row 3</TestButton>
</td>
</tr>
</TreeGrid>
);

screen.getByText( 'Row 2' ).focus();
const row2Element = screen.getByText( 'Row 2' ).closest( 'tr' );

fireEvent.keyDown( screen.getByText( 'Row 2' ), {
key: 'ArrowLeft',
keyCode: LEFT,
currentTarget: row2Element,
} );

expect( onCollapseRow ).toHaveBeenCalledWith( row2Element );
} );
} );

describe( 'onFocusRow', () => {
const TestTree = ( { onFocusRow } ) => (
<TreeGrid onFocusRow={ onFocusRow }>
<tr role="row" aria-expanded="false">
<td>
<TestButton>Row 1</TestButton>
</td>
</tr>
<tr role="row" aria-expanded="true">
<td>
<TestButton>Row 2</TestButton>
</td>
</tr>
<tr role="row" aria-expanded="false">
<td>
<TestButton>Row 3</TestButton>
</td>
</tr>
</TreeGrid>
);

expect( renderer.toJSON() ).toMatchSnapshot();
it( 'should call onFocusRow with event, start and end nodes when pressing Down Arrow', () => {
const onFocusRow = jest.fn();
render( <TestTree onFocusRow={ onFocusRow } /> );

screen.getByText( 'Row 2' ).focus();

const row2Element = screen.getByText( 'Row 2' ).closest( 'tr' );
const row3Element = screen.getByText( 'Row 3' ).closest( 'tr' );

fireEvent.keyDown( screen.getByText( 'Row 2' ), {
key: 'ArrowDown',
keyCode: DOWN,
currentTarget: row2Element,
} );

expect( onFocusRow ).toHaveBeenCalledWith(
expect.objectContaining( { key: 'ArrowDown', keyCode: DOWN } ),
row2Element,
row3Element
);
} );

it( 'should call onFocusRow with event, start and end nodes when pressing Up Arrow', () => {
const onFocusRow = jest.fn();
render( <TestTree onFocusRow={ onFocusRow } /> );

screen.getByText( 'Row 2' ).focus();

const row2Element = screen.getByText( 'Row 2' ).closest( 'tr' );
const row1Element = screen.getByText( 'Row 1' ).closest( 'tr' );

fireEvent.keyDown( screen.getByText( 'Row 2' ), {
key: 'ArrowUp',
keyCode: UP,
currentTarget: row2Element,
} );

expect( onFocusRow ).toHaveBeenCalledWith(
expect.objectContaining( { key: 'ArrowUp', keyCode: UP } ),
row2Element,
row1Element
);
} );

it( 'should call onFocusRow when shift key is held', () => {
const onFocusRow = jest.fn();
render( <TestTree onFocusRow={ onFocusRow } /> );

screen.getByText( 'Row 2' ).focus();

const row2Element = screen.getByText( 'Row 2' ).closest( 'tr' );
const row1Element = screen.getByText( 'Row 1' ).closest( 'tr' );

fireEvent.keyDown( screen.getByText( 'Row 2' ), {
key: 'ArrowUp',
keyCode: UP,
currentTarget: row2Element,
shiftKey: true,
} );

expect( onFocusRow ).toHaveBeenLastCalledWith(
expect.objectContaining( {
key: 'ArrowUp',
keyCode: UP,
shiftKey: true,
} ),
row2Element,
row1Element
);

fireEvent.keyDown( screen.getByText( 'Row 1' ), {
key: 'ArrowDown',
keyCode: DOWN,
currentTarget: row1Element,
shiftKey: true,
} );

expect( onFocusRow ).toHaveBeenLastCalledWith(
expect.objectContaining( {
key: 'ArrowDown',
keyCode: DOWN,
shiftKey: true,
} ),
row1Element,
row2Element
);
} );
} );
} );

0 comments on commit 69c57ce

Please sign in to comment.