import { render, RenderResult, screen } from '@testing-library/react'; import React, { ComponentType } from 'react'; export type ComponentTestOptions = { defaultProps?: any; forward?: boolean; domAttr?: boolean; className?: boolean; style?: boolean; }; type BasicProps = { style?: any; className?: string }; export function baselineComponent( RawComponent: ComponentType, { forward = true, style = true, className = true, domAttr = true, }: ComponentTestOptions = {}, ) { const Component: ComponentType = RawComponent; it('renders', () => { let api: RenderResult; // mount expect(() => api = render()).not.toThrow(); // update expect(() => api.rerender()).not.toThrow(); // unmount expect(() => api.unmount()).not.toThrow(); }); forward && it('forwards attributes', () => { const { rerender } = render(( )); // forward DOM attributes domAttr && expect(screen.queryByTestId('__cmp__')).toBeTruthy(); if (className || style) { const styledNode = document.querySelector('.__cls__'); // forwards className className && expect(styledNode).toBeTruthy(); const customClassList = Array.from(styledNode.classList).filter((cls) => cls !== '__cls__'); // forwards style style && expect(styledNode.style.background).toBe('red'); const customStyleCount = styledNode.style.length; rerender(); // does not replace default className className && expect(Array.from(styledNode.classList)).toEqual(customClassList); // does not replace default styles style && expect(styledNode.style.length) .toEqual(styledNode.style.background ? customStyleCount : customStyleCount - 1); } }); } type RectOptions = { x?: number; y?: number; w?: number; h?: number }; export function mockRect(el: HTMLElement | ({} & any), { x = 0, y = 0, w = 0, h = 0 }: RectOptions) { if (!el) { return; } el.getBoundingClientRect = () => ({ x, y, width: w, height: h, left: x, top: y, right: x + w, bottom: y + h, toJSON() { JSON.stringify(this); }, }); }