-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: setup jest for unit test hooks and component from joi (janhq#3540
) * chore: setup jest for unit test hooks and component from joi * chore: update gitignore * chore: exclude jest setup file from tsconfig
- Loading branch information
Showing
16 changed files
with
626 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = { | ||
preset: 'ts-jest', | ||
testEnvironment: 'node', | ||
roots: ['<rootDir>/src'], | ||
testMatch: ['**/*.test.*'], | ||
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], | ||
testEnvironment: 'jsdom', | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import React from 'react' | ||
import '@testing-library/jest-dom' | ||
import { render, screen, fireEvent } from '@testing-library/react' | ||
import { Accordion, AccordionItem } from './index' | ||
|
||
// Mock the SCSS import | ||
jest.mock('./styles.scss', () => ({})) | ||
|
||
describe('Accordion', () => { | ||
it('renders accordion with items', () => { | ||
render( | ||
<Accordion defaultValue={['item1']}> | ||
<AccordionItem value="item1" title="Item 1"> | ||
Content 1 | ||
</AccordionItem> | ||
<AccordionItem value="item2" title="Item 2"> | ||
Content 2 | ||
</AccordionItem> | ||
</Accordion> | ||
) | ||
|
||
expect(screen.getByText('Item 1')).toBeInTheDocument() | ||
expect(screen.getByText('Item 2')).toBeInTheDocument() | ||
}) | ||
|
||
it('expands and collapses accordion items', () => { | ||
render( | ||
<Accordion defaultValue={[]}> | ||
<AccordionItem value="item1" title="Item 1"> | ||
Content 1 | ||
</AccordionItem> | ||
</Accordion> | ||
) | ||
|
||
const trigger = screen.getByText('Item 1') | ||
|
||
// Initially, content should not be visible | ||
expect(screen.queryByText('Content 1')).not.toBeInTheDocument() | ||
|
||
// Click to expand | ||
fireEvent.click(trigger) | ||
expect(screen.getByText('Content 1')).toBeInTheDocument() | ||
|
||
// Click to collapse | ||
fireEvent.click(trigger) | ||
expect(screen.queryByText('Content 1')).not.toBeInTheDocument() | ||
}) | ||
|
||
it('respects defaultValue prop', () => { | ||
render( | ||
<Accordion defaultValue={['item2']}> | ||
<AccordionItem value="item1" title="Item 1"> | ||
Content 1 | ||
</AccordionItem> | ||
<AccordionItem value="item2" title="Item 2"> | ||
Content 2 | ||
</AccordionItem> | ||
</Accordion> | ||
) | ||
|
||
expect(screen.queryByText('Content 1')).not.toBeInTheDocument() | ||
expect(screen.getByText('Content 2')).toBeInTheDocument() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React from 'react' | ||
import { render, screen } from '@testing-library/react' | ||
import '@testing-library/jest-dom' | ||
import { Badge, badgeConfig } from './index' | ||
|
||
// Mock the styles | ||
jest.mock('./styles.scss', () => ({})) | ||
|
||
describe('@joi/core/Badge', () => { | ||
it('renders with default props', () => { | ||
render(<Badge>Test Badge</Badge>) | ||
const badge = screen.getByText('Test Badge') | ||
expect(badge).toBeInTheDocument() | ||
expect(badge).toHaveClass('badge') | ||
expect(badge).toHaveClass('badge--primary') | ||
expect(badge).toHaveClass('badge--medium') | ||
expect(badge).toHaveClass('badge--solid') | ||
}) | ||
|
||
it('applies custom className', () => { | ||
render(<Badge className="custom-class">Test Badge</Badge>) | ||
const badge = screen.getByText('Test Badge') | ||
expect(badge).toHaveClass('custom-class') | ||
}) | ||
|
||
it('renders with different themes', () => { | ||
const themes = Object.keys(badgeConfig.variants.theme) | ||
themes.forEach((theme) => { | ||
render(<Badge theme={theme as any}>Test Badge {theme}</Badge>) | ||
const badge = screen.getByText(`Test Badge ${theme}`) | ||
expect(badge).toHaveClass(`badge--${theme}`) | ||
}) | ||
}) | ||
|
||
it('renders with different variants', () => { | ||
const variants = Object.keys(badgeConfig.variants.variant) | ||
variants.forEach((variant) => { | ||
render(<Badge variant={variant as any}>Test Badge {variant}</Badge>) | ||
const badge = screen.getByText(`Test Badge ${variant}`) | ||
expect(badge).toHaveClass(`badge--${variant}`) | ||
}) | ||
}) | ||
|
||
it('renders with different sizes', () => { | ||
const sizes = Object.keys(badgeConfig.variants.size) | ||
sizes.forEach((size) => { | ||
render(<Badge size={size as any}>Test Badge {size}</Badge>) | ||
const badge = screen.getByText(`Test Badge ${size}`) | ||
expect(badge).toHaveClass(`badge--${size}`) | ||
}) | ||
}) | ||
|
||
it('fails when a new theme is added without updating the test', () => { | ||
const expectedThemes = [ | ||
'primary', | ||
'secondary', | ||
'warning', | ||
'success', | ||
'info', | ||
'destructive', | ||
] | ||
const actualThemes = Object.keys(badgeConfig.variants.theme) | ||
expect(actualThemes).toEqual(expectedThemes) | ||
}) | ||
|
||
it('fails when a new variant is added without updating the test', () => { | ||
const expectedVariant = ['solid', 'soft', 'outline'] | ||
const actualVariants = Object.keys(badgeConfig.variants.variant) | ||
expect(actualVariants).toEqual(expectedVariant) | ||
}) | ||
|
||
it('fails when a new size is added without updating the test', () => { | ||
const expectedSizes = ['small', 'medium', 'large'] | ||
const actualSizes = Object.keys(badgeConfig.variants.size) | ||
expect(actualSizes).toEqual(expectedSizes) | ||
}) | ||
|
||
it('fails when a new variant CVA is added without updating the test', () => { | ||
const expectedVariantsCVA = ['theme', 'variant', 'size'] | ||
const actualVariant = Object.keys(badgeConfig.variants) | ||
expect(actualVariant).toEqual(expectedVariantsCVA) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import React from 'react' | ||
import { render, screen } from '@testing-library/react' | ||
import '@testing-library/jest-dom' | ||
import { Button, buttonConfig } from './index' | ||
|
||
// Mock the styles | ||
jest.mock('./styles.scss', () => ({})) | ||
|
||
describe('Button', () => { | ||
it('renders with default props', () => { | ||
render(<Button>Click me</Button>) | ||
const button = screen.getByRole('button', { name: /click me/i }) | ||
expect(button).toBeInTheDocument() | ||
expect(button).toHaveClass('btn btn--primary btn--medium btn--solid') | ||
}) | ||
|
||
it('renders as a child component when asChild is true', () => { | ||
render( | ||
<Button asChild> | ||
<a href="/">Link Button</a> | ||
</Button> | ||
) | ||
const link = screen.getByRole('link', { name: /link button/i }) | ||
expect(link).toBeInTheDocument() | ||
expect(link).toHaveClass('btn btn--primary btn--medium btn--solid') | ||
}) | ||
|
||
it.each(Object.keys(buttonConfig.variants.theme))( | ||
'renders with theme %s', | ||
(theme) => { | ||
render(<Button theme={theme as any}>Theme Button</Button>) | ||
const button = screen.getByRole('button', { name: /theme button/i }) | ||
expect(button).toHaveClass(`btn btn--${theme}`) | ||
} | ||
) | ||
|
||
it.each(Object.keys(buttonConfig.variants.variant))( | ||
'renders with variant %s', | ||
(variant) => { | ||
render(<Button variant={variant as any}>Variant Button</Button>) | ||
const button = screen.getByRole('button', { name: /variant button/i }) | ||
expect(button).toHaveClass(`btn btn--${variant}`) | ||
} | ||
) | ||
|
||
it.each(Object.keys(buttonConfig.variants.size))( | ||
'renders with size %s', | ||
(size) => { | ||
render(<Button size={size as any}>Size Button</Button>) | ||
const button = screen.getByRole('button', { name: /size button/i }) | ||
expect(button).toHaveClass(`btn btn--${size}`) | ||
} | ||
) | ||
|
||
it('renders with block prop', () => { | ||
render(<Button block>Block Button</Button>) | ||
const button = screen.getByRole('button', { name: /block button/i }) | ||
expect(button).toHaveClass('btn btn--block') | ||
}) | ||
|
||
it('merges custom className with generated classes', () => { | ||
render(<Button className="custom-class">Custom Class Button</Button>) | ||
const button = screen.getByRole('button', { name: /custom class button/i }) | ||
expect(button).toHaveClass( | ||
'btn btn--primary btn--medium btn--solid custom-class' | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import React from 'react' | ||
import { render, fireEvent, act } from '@testing-library/react' | ||
import { useClickOutside } from './index' | ||
|
||
// Mock component to test the hook | ||
const TestComponent: React.FC<{ onClickOutside: () => void }> = ({ | ||
onClickOutside, | ||
}) => { | ||
const ref = useClickOutside(onClickOutside) | ||
return <div ref={ref as React.RefObject<HTMLDivElement>}>Test</div> | ||
} | ||
|
||
describe('@joi/hooks/useClickOutside', () => { | ||
it('should call handler when clicking outside', () => { | ||
const handleClickOutside = jest.fn() | ||
const { container } = render( | ||
<TestComponent onClickOutside={handleClickOutside} /> | ||
) | ||
|
||
act(() => { | ||
fireEvent.mouseDown(document.body) | ||
}) | ||
|
||
expect(handleClickOutside).toHaveBeenCalledTimes(1) | ||
}) | ||
|
||
it('should not call handler when clicking inside', () => { | ||
const handleClickOutside = jest.fn() | ||
const { getByText } = render( | ||
<TestComponent onClickOutside={handleClickOutside} /> | ||
) | ||
|
||
act(() => { | ||
fireEvent.mouseDown(getByText('Test')) | ||
}) | ||
|
||
expect(handleClickOutside).not.toHaveBeenCalled() | ||
}) | ||
|
||
it('should work with custom events', () => { | ||
const handleClickOutside = jest.fn() | ||
const TestComponentWithCustomEvent: React.FC = () => { | ||
const ref = useClickOutside(handleClickOutside, ['click']) | ||
return <div ref={ref as React.RefObject<HTMLDivElement>}>Test</div> | ||
} | ||
|
||
render(<TestComponentWithCustomEvent />) | ||
|
||
act(() => { | ||
fireEvent.click(document.body) | ||
}) | ||
|
||
expect(handleClickOutside).toHaveBeenCalledTimes(1) | ||
}) | ||
}) |
Oops, something went wrong.