import * as React from 'react'; import { render, screen } from '@testing-library/react'; import kebabCase from 'lodash/kebabCase'; import { Grid } from '../Grid'; import { View } from '../../View'; import { Card } from '../../Card'; import { ComponentPropsToStylePropsMap, GridContainerStyleProps, GridItemStyleProps, } from '../../types'; import { ComponentClassNames } from '../../shared/constants'; import { errorMessageWrapper } from '../../utils/testUtils'; import { convertGridSpan } from '../../shared/styleUtils'; export const testGridItemStyleProps: GridItemStyleProps = { area: '1 / 1 / 2 / 2', column: '1 / span 2', columnEnd: 'auto', // columnSpan: 3, // Left out to test separately below, since this changes the row property columnStart: '1', row: '2 / span', rowEnd: '3', // rowSpan: 2, // Left out to test separately below, since this changes the row property rowStart: '1', }; export const testGridContainerStyleProps: GridContainerStyleProps = { alignContent: 'center', alignItems: 'center', autoColumns: '1fr', autoFlow: 'row dense', autoRows: 'minmax(30px, auto)', columnGap: '1rem', gap: '2rem', justifyContent: 'space-between', rowGap: '3rem', templateAreas: `"a a a" "b c c" " b c c"`, templateColumns: '1fr 2fr', templateRows: '2fr 1fr', }; export const expectGridContainerStyleProps = (element: HTMLElement): void => { Object.keys(testGridContainerStyleProps).forEach((key) => { errorMessageWrapper( () => expect( element.style.getPropertyValue( kebabCase(ComponentPropsToStylePropsMap[key]) ) ).toBe(testGridContainerStyleProps[key]), `Grid container "${key}" style prop error (see above)` ); }); }; export function expectGridItemStyleProps(element: HTMLElement): void { Object.keys(testGridItemStyleProps).forEach((key) => { errorMessageWrapper( () => expect( element.style.getPropertyValue( kebabCase(ComponentPropsToStylePropsMap[key]) ) ).toBe(testGridItemStyleProps[key]), `Grid item ${key} style prop error (see above)` ); }); } describe('Grid:', () => { const testId = 'gridPrimitive'; const itemTestId = 'gridItem'; it('can apply Grid container styling via style prop', async () => { render(); const grid = await screen.findByTestId(testId); expectGridContainerStyleProps(grid); }); it('has default class and can apply a custom className', async () => { render(); const grid = await screen.findByTestId(testId); expect(grid).toHaveClass('custom-grid'); expect(grid).toHaveClass(ComponentClassNames.Grid); }); it('should forward ref to DOM element', async () => { const ref = React.createRef(); render(); await screen.findByTestId(testId); expect(ref.current?.nodeName).toBe('DIV'); }); it('can render any arbitrary data-* attribute', async () => { render(); const view = await screen.findByTestId(testId); expect(view.dataset['demo']).toBe('true'); }); describe('Grid items:', () => { const cardTestId = `${itemTestId}-card`; it('can apply Grid item styling via style prop', async () => { const viewTestId = `${itemTestId}-view`; const cardTestId = `${itemTestId}-card`; render( 1 2 ); const view = await screen.findByTestId(viewTestId); const card = await screen.findByTestId(cardTestId); expectGridItemStyleProps(view); expectGridItemStyleProps(card); }); it('rowSpan and columnSpan can set row and column values', async () => { const { row, column, ...rest } = testGridItemStyleProps; const styleProps = { ...rest, columnSpan: 2, rowSpan: 4, }; render( 2 ); const card = await screen.findByTestId(cardTestId); expect( card.style.getPropertyValue( kebabCase(ComponentPropsToStylePropsMap.row) ) ).toBe(convertGridSpan(styleProps.rowSpan)); expect( card.style.getPropertyValue( kebabCase(ComponentPropsToStylePropsMap.column) ) ).toBe(convertGridSpan(styleProps.columnSpan)); }); it('rowSpan and columnSpan are overwritten by row and column values', async () => { const styleProps = { ...testGridItemStyleProps, columnSpan: 2, rowSpan: 4, }; render( 2 ); const card = await screen.findByTestId(cardTestId); expect( card.style.getPropertyValue( kebabCase(ComponentPropsToStylePropsMap.row) ) ).toBe(styleProps.row); expect( card.style.getPropertyValue( kebabCase(ComponentPropsToStylePropsMap.column) ) ).toBe(styleProps.column); }); }); });