Skip to content

Commit

Permalink
Refactors and adding unit tests for various components (#279)
Browse files Browse the repository at this point in the history
  • Loading branch information
prabhuignoto authored Jul 30, 2023
1 parent f737581 commit c6a6ad1
Show file tree
Hide file tree
Showing 38 changed files with 1,125 additions and 645 deletions.
32 changes: 0 additions & 32 deletions .github/workflows/auto-pr.yml

This file was deleted.

11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@babel/preset-env": "^7.22.9",
"@babel/preset-react": "^7.22.5",
"@babel/preset-typescript": "^7.22.5",
"@relative-ci/agent": "^4.1.5",
"@relative-ci/agent": "^4.1.6",
"@sentry/react": "^7.60.1",
"@sentry/tracing": "^7.60.1",
"@types/bluebird": "^3.5.38",
Expand All @@ -27,14 +27,14 @@
"autoprefixer": "^10.4.14",
"cssnano": "^6.0.1",
"esbuild": "^0.18.17",
"eslint": "^8.45.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "2.27.5",
"eslint": "^8.46.0",
"eslint-config-prettier": "^8.9.0",
"eslint-plugin-import": "2.28.0",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "^7.33.0",
"eslint-plugin-react": "^7.33.1",
"eslint-plugin-sort-keys-fix": "^1.1.2",
"eslint-plugin-typescript-sort-keys": "^2.3.0",
"fork-ts-checker-webpack-plugin": "^8.0.0",
Expand Down Expand Up @@ -112,6 +112,7 @@
},
"packageManager": "[email protected]",
"devDependencies": {
"@testing-library/react-hooks": "^8.0.1",
"@vitest/coverage-v8": "^0.33.0",
"postcss-scss": "^4.0.6"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ exports[`Accordion > should render snapshot 1`] = `
class="_accordion_f93c7f _no-border_f93c7f"
>
<div
aria-controls="accordion-body-6LlnNHQy5ZaWAV195KxJH"
aria-controls="accordion-body-Uk25XS3N-TG7sBDcLAlFp"
aria-expanded="false"
class="_header_c2ceb5 _focusable_c2ceb5 _size_c2ceb5"
id="accordion--yzse4L0aEQcS43-8698q"
id="accordion-mTU_zI6Ifp__d7oEZ1LJY"
role="heading"
style="--rc-accordion-header-height: 40px; outline: none; position: relative;"
tabindex="0"
Expand Down Expand Up @@ -40,9 +40,9 @@ exports[`Accordion > should render snapshot 1`] = `
/>
</div>
<div
aria-labelledby="accordion--yzse4L0aEQcS43-8698q"
aria-labelledby="accordion-mTU_zI6Ifp__d7oEZ1LJY"
class="_body_f93c7f _animate_f93c7f _close_f93c7f"
id="accordion-body-6LlnNHQy5ZaWAV195KxJH"
id="accordion-body-Uk25XS3N-TG7sBDcLAlFp"
role="region"
style="--title-color: #000; --transition: cubic-bezier(0.19, 1, 0.22, 1); --max-height: 0px;"
>
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/avatar/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const getClassNames = classNames;
*
* @component
*
* @param {object} props - The component's props
* @param {'sm'|'md'|'lg'} props.size - The size of the avatar (small by default)
* @param {ReactNode} props.children - The content to be rendered inside the avatar
* @param {string} props.letter - The letter to be displayed when no children are provided
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/block-quote/block-quote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export interface BlockQuoteProps {
*
* @component
*
* @param {object} props - The component's props
* @param {ReactNode} props.children - The content to be rendered inside the blockquote
* @param {boolean} props.showInfoIcon - Determines if the InfoIcon should be displayed (default: true)
* @param {'sm'|'md'|'lg'} props.size - The size of the blockquote (small by default)
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/breadcrumb/breadcrumb-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import styles from './breadcrumb.module.scss';
*
* An individual breadcrumb item, which consists of a link and an optional icon.
*
* @param {object} props - Properties passed down from parent
* @param {string} props.id - Unique identifier for the breadcrumb item
* @param {function} props.onSelected - Callback to handle selection events
* @param {boolean} props.showChevron - Flag to control the display of chevron icon
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/breadcrumb/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ interface BreadCrumbItemModel {
*
* A list of links that help indicate the current page's location in the app navigation hierarchy.
*
* @param {object} props - Properties passed down from parent
* @param {ReactNode} props.children - React nodes for the breadcrumb's content
* @param {function} props.onSelected - Callback to handle selection events
* @param {string} props.icon - The icon type for the breadcrumbs
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import styles from './button.module.scss';
*
* @component
*
* @param {object} props - The component's props
* @param {boolean} props.border - Determines whether the button has a border. Default is true.
* @param {ReactNode} props.children - The content inside the button. Can be text or an element.
* @param {boolean} props.disabled - Determines whether the button is disabled. Default is false.
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { useMemo } from 'react';
*
* @component
*
* @param {object} props - The component's props
* @param {'left'|'right'|'center'} props.alignFooter - The alignment of the footer. Default is 'left'.
* @param {'left'|'right'|'center'} props.alignHeader - The alignment of the header. Default is 'left'.
* @param {boolean} props.border - Determines whether the card has a border. Default is false.
Expand Down
7 changes: 0 additions & 7 deletions packages/lib/components/carousel/carousel-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ import { Button } from '../button/button';
import { CarouselButtonProps } from './carousel-model';
import styles from './carousel.module.scss';

/**
* CarouselButton is a React Function Component for displaying the next and previous buttons of the carousel.
* It receives several props to handle its behavior and styling.
*
* @param {Object} CarouselButtonProps - The properties that define the CarouselButton component.
* @returns {JSX.Element} The CarouselButton component.
*/
const CarouselButton: React.FunctionComponent<CarouselButtonProps> = ({
onClick,
position = 'left',
Expand Down
8 changes: 1 addition & 7 deletions packages/lib/components/carousel/carousel-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ import React, { CSSProperties, ReactNode, useMemo } from 'react';
import { CarouselItemsProps } from './carousel-model';
import styles from './carousel.module.scss';

/**
* CarouselItems is a React Function Component for displaying the items of the carousel.
* It receives several props to handle its behavior and styling.
*
* @param {Object} CarouselItemsProps - The properties that define the CarouselItems component.
* @returns {JSX.Element} The CarouselItems component.
*/

const CarouselItems: React.FunctionComponent<CarouselItemsProps> = ({
activePage = 0,
carouselItems,
Expand Down
4 changes: 2 additions & 2 deletions packages/lib/components/checkbox-group/checkbox-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ export interface CheckboxGroupProps {
* This is a custom checkbox group component that supports various customization options.
* It receives several props to handle its behavior and styling.
*
* @param {Object} CheckboxGroupProps - The properties that define the CheckBoxGroup component.
* @returns {JSX.Element} The CheckBoxGroup component.
*
* @param {boolean} RTL - If true, applies right-to-left styles to the checkbox group.
* @param {boolean} border - Adds a border to the checkbox group.
Expand All @@ -42,6 +40,8 @@ export interface CheckboxGroupProps {
* @param {function} onChange - The function to call when the checkbox state changes.
* @param {Array} options - The array of CheckboxProps for each checkbox in the group.
* @param {string} size - The size of the checkbox group ('sm', 'md', 'lg').
*
* @returns {JSX.Element} The CheckBoxGroup component.
*/
const CheckBoxGroup: React.FunctionComponent<CheckboxGroupProps> = ({
options = [],
Expand Down
1 change: 0 additions & 1 deletion packages/lib/components/checkbox/checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import styles from './checkbox.module.scss';
* CheckBox is a React Function Component for displaying a custom checkbox with various customization options.
* It receives several props to handle its behavior and styling.
*
* @param {Object} CheckboxProps - The properties that define the CheckBox component.
* @returns {JSX.Element} The CheckBox component.
*
* @param {boolean} autoHeight - Adjusts the height of the checkbox automatically.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { useCloseOnEscape } from '../useCloseOnEsc';
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';

describe('useCloseOnEscape', () => {
let container: HTMLDivElement;
let handler;

beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
handler = vi.fn();
});

afterEach(() => {
document.body.removeChild(container);
container.remove();
});

it('should call handler when Escape key is pressed', () => {
renderHook(() => useCloseOnEscape(handler, { current: container }));

act(() => {
const event = new KeyboardEvent('keyup', { key: 'Escape' });
container.dispatchEvent(event);
});

expect(handler).toHaveBeenCalled();
});

it('should not call handler when other key is pressed', () => {
renderHook(() => useCloseOnEscape(handler, { current: container }));

act(() => {
const event = new KeyboardEvent('keyup', { key: 'Enter' });
container.dispatchEvent(event);
});

expect(handler).not.toHaveBeenCalled();
});

it('should not attach event listener when element does not exist', () => {
renderHook(() => useCloseOnEscape(handler, { current: null }));

act(() => {
const event = new KeyboardEvent('keyup', { key: 'Escape' });
container.dispatchEvent(event);
});

expect(handler).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { useFirstRender } from '../useFirstRender';
import { describe, it, expect } from 'vitest';

describe('useFirstRender hook', () => {
it('should return true on first render', () => {
const { result, rerender } = renderHook(() => useFirstRender());

rerender();

expect(result.current.current).toBe(false);
});

it('should return the same reference for every render', () => {
const { result, rerender } = renderHook(() => useFirstRender());
const initialReference = result.current;

act(() => {
rerender();
});

expect(result.current).toBe(initialReference);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { renderHook, act } from '@testing-library/react-hooks';
import { useRef } from 'react';
import { describe, it, assert } from 'vitest';
import useFocusNew from '../useFocusNew';
import styles from '../focus.module.scss';

describe('useFocusNew hook', () => {
it('should add focus ring when keyup event is triggered', () => {
const ref = { current: document.createElement('div') };
const callback = () => {};
const { rerender } = renderHook(() => useFocusNew(ref, callback));

act(() => {
const event = new KeyboardEvent('keyup', { key: 'Enter' });
ref.current.dispatchEvent(event);
});

rerender();

assert(
ref.current.querySelector(`.${styles.focus_ring_active}`) !== null,
'Focus ring should be active'
);
});

it('should remove focus ring when focusout event is triggered', () => {
const ref = { current: document.createElement('div') };
const callback = () => {};
const { rerender } = renderHook(() => useFocusNew(ref, callback));

act(() => {
const event = new Event('focusout');
ref.current.dispatchEvent(event);
});

rerender();

assert(
ref.current.querySelector(`.${styles.focus_ring_inactive}`) !== null,
'Focus ring should be inactive'
);
});

it('should call the callback when Enter or Space is pressed', () => {
let callCount = 0;
const callback = () => {
callCount++;
};
const ref = { current: document.createElement('div') };

const { rerender } = renderHook(() => useFocusNew(ref, callback));

act(() => {
const event = new KeyboardEvent('keyup', { key: 'Enter' });
ref.current.dispatchEvent(event);
});

rerender();

assert.equal(
callCount,
1,
'callback should be called once when Enter is pressed'
);
});
});
Loading

1 comment on commit c6a6ad1

@vercel
Copy link

@vercel vercel bot commented on c6a6ad1 Jul 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.