-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
340 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,350 @@ | ||
import { render } from '../../__tests__/utils'; | ||
import type { DSize } from '../../utils/types'; | ||
import type { DButtonProps } from './Button'; | ||
|
||
import { render, fireEvent } from '../../__tests__/utils'; | ||
import { DCompose } from '../compose'; | ||
import { DButton } from './index'; | ||
|
||
const dPrefix = 'rd-'; | ||
|
||
const getTypeClass = (dType: DButtonProps['dType'], prefix = dPrefix) => { | ||
return `${prefix}button--${dType || 'primary'}`; | ||
}; | ||
const getThemeClass = (dTheme: DButtonProps['dTheme'], prefix = 't') => { | ||
return `${prefix}-${dTheme || 'primary'}`; | ||
}; | ||
const getOtherClass = (ots?: 'icon' | DSize | 'block' | DButtonProps['dVariant'] | 'icon-right', separator = '--', prefix = dPrefix) => { | ||
return !ots ? `${prefix}button` : `${prefix}button${separator}${ots || ''}`; | ||
}; | ||
|
||
const sleep = (time: number) => | ||
new Promise((resolve) => | ||
setTimeout(() => { | ||
resolve(''); | ||
}, time) | ||
); | ||
|
||
describe('DButton', () => { | ||
const text = 'This is DButton'; | ||
|
||
it('should `children` work', () => { | ||
const { getByText } = render(<DButton children={text} />); | ||
expect(getByText(text)).toBeInTheDocument(); | ||
}); | ||
|
||
describe('the type property of DButton', () => { | ||
it('should render with the root, text, and primary classes but no others', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole, getByText } = render( | ||
<DButton className="cust-btn" type="submit"> | ||
{buttonText} | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
expect(getByText(buttonText)).toBeInTheDocument(); | ||
expect(button.classList.contains(`cust-btn`)).toBe(true); | ||
expect(button.classList.contains(getOtherClass())).toBe(true); | ||
expect(button.classList.contains(getTypeClass('primary'))).toBe(true); | ||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
|
||
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
expect(button.getAttribute('type')).toBe('submit'); | ||
}); | ||
|
||
it('should render a text secondary button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dType="secondary">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getTypeClass('secondary'))).toBe(true); | ||
expect(button.classList.contains(getOtherClass())).toBe(true); | ||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
|
||
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
|
||
it('should render a text outline button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dType="outline">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getTypeClass('outline'))).toBe(true); | ||
expect(button.classList.contains(getOtherClass())).toBe(true); | ||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
|
||
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
|
||
it('should render a text dashed button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dType="dashed">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getTypeClass('dashed'))).toBe(true); | ||
expect(button.classList.contains(getOtherClass())).toBe(true); | ||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
|
||
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
|
||
it('should render a text text button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dType="text">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getTypeClass('text'))).toBe(true); | ||
expect(button.classList.contains(getOtherClass())).toBe(true); | ||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
|
||
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
|
||
it('should render a text link button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dType="link">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getTypeClass('link'))).toBe(true); | ||
expect(button.classList.contains(getOtherClass())).toBe(true); | ||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
|
||
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true); | ||
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
}); | ||
|
||
describe('the theme property of DButton', () => { | ||
it('should render a primary button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dTheme="primary">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getThemeClass('primary'))).toBe(true); | ||
}); | ||
|
||
it('should render a success button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dTheme="success">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getThemeClass('success'))).toBe(true); | ||
}); | ||
|
||
it('should render a warning button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dTheme="warning">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getThemeClass('warning'))).toBe(true); | ||
}); | ||
|
||
it('should render a danger button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dTheme="danger">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.classList.contains(getThemeClass('danger'))).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('the icon property of DButton', () => { | ||
it('should render a button with icon', () => { | ||
const buttonText = 'Hello World'; | ||
const mockIcon = <div>icon</div>; | ||
const { getByRole, getByText } = render(<DButton dIcon={mockIcon}>{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
const icon = getByText('icon'); | ||
|
||
expect(icon).toBeInTheDocument(); | ||
expect(button.contains(icon)).toBe(true); | ||
expect(button.getElementsByClassName(getOtherClass('icon', '__'))).toBeTruthy(); | ||
}); | ||
|
||
it('should render a icon on the right', () => { | ||
const mockIcon = <div>icon</div>; | ||
const { getByRole } = render( | ||
<DButton dIcon={mockIcon} dIconRight> | ||
Hello World | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
expect(button.className.includes(getOtherClass('icon-right'))).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('the disabled property of DButton', () => { | ||
it('should render a clickable button', () => { | ||
const buttonText = 'Hello World'; | ||
const cb = jest.fn(); | ||
const { getByRole } = render(<DButton onClick={cb}>{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
expect(cb).not.toBeCalled(); | ||
|
||
fireEvent.click(button); | ||
expect(cb.mock.calls.length).toBe(1); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
|
||
it('should render a disabled button', () => { | ||
const buttonText = 'Hello World'; | ||
const cb = jest.fn(); | ||
const { getByRole } = render(<DButton disabled>{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(cb).not.toBeCalled(); | ||
expect(button['disabled']).toBe(true); | ||
fireEvent.click(button); | ||
expect(cb).not.toBeCalled(); | ||
expect(button.classList.contains('is-loading')).not.toBe(true); | ||
}); | ||
}); | ||
|
||
describe('the loading property of DButton', () => { | ||
it('should render a loading-button', () => { | ||
const buttonText = 'Hello World'; | ||
const cb = jest.fn(); | ||
const { getByRole } = render( | ||
<DButton dLoading={true} onClick={cb}> | ||
{buttonText} | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
expect(button.className.includes('is-loading')).toBe(true); | ||
expect(button.querySelector(`.${dPrefix}button__icon`)).toBeInTheDocument(); | ||
fireEvent.click(button); | ||
expect(cb).not.toBeCalled(); | ||
}); | ||
|
||
it('should render a loading-button without icon', () => { | ||
const buttonText = 'Hello World'; | ||
const cb = jest.fn(); | ||
const mockIcon = <div>icon</div>; | ||
const { getByRole, queryByText } = render( | ||
<DButton dIcon={mockIcon} dLoading onClick={cb}> | ||
{buttonText} | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
const icon = queryByText('icon'); | ||
|
||
expect(icon).toBeNull(); | ||
expect(button.className.includes('is-loading')).toBe(true); | ||
expect(button.getElementsByClassName(getOtherClass('icon', '__'))).toBeTruthy(); | ||
fireEvent.click(button); | ||
expect(cb.mock.calls.length).toBe(0); | ||
}); | ||
}); | ||
|
||
describe('the block property of DButton', () => { | ||
it('should render a button that suitable for its parent width', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dBlock>{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
expect(button.className.includes(getOtherClass('block'))).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('the size property of DButton', () => { | ||
it('should render a small button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dSize="smaller">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.className.includes(getOtherClass('smaller'))).toBe(true); | ||
}); | ||
|
||
it('should render a large button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render(<DButton dSize="larger">{buttonText}</DButton>); | ||
const button = getByRole('button'); | ||
|
||
expect(button.className.includes(getOtherClass('larger'))).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('the variant property of DButton', () => { | ||
it('should render a circle button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render( | ||
<DButton dSize="larger" dVariant="circle"> | ||
{buttonText} | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
expect(button.className.includes(getOtherClass('circle'))).toBe(true); | ||
}); | ||
|
||
it('should render a round button', () => { | ||
const buttonText = 'Hello World'; | ||
const { getByRole } = render( | ||
<DButton dSize="larger" dVariant="round"> | ||
{buttonText} | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
expect(button.className.includes(getOtherClass('round'))).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('Emotion compatibility', () => { | ||
it('should have a wave by default', async () => { | ||
const { getByRole } = render( | ||
<DButton dSize="larger" dVariant="round"> | ||
Hello World | ||
</DButton> | ||
); | ||
const button = getByRole('button'); | ||
|
||
expect(button.querySelector('.rd-wave')).toBeNull(); | ||
fireEvent.click(button); | ||
expect(button.querySelector('.rd-wave')).toBeTruthy(); | ||
// animation-duration | ||
await sleep(4 * 1000); | ||
|
||
expect(button.querySelector('rd-wave')).toBeNull(); | ||
}); | ||
|
||
it('the properties of size and disabled should be inherited from DCmpose', () => { | ||
const { container, getAllByRole } = render( | ||
<DCompose dSize="larger" dDisabled={true}> | ||
<DButton id="middle-btn1">middle-btn1</DButton> | ||
<DButton id="middle-btn2">middle-btn2</DButton> | ||
<DButton id="middle-btn3">middle-btn3</DButton> | ||
<DButton id="small-btn" dSize="smaller"> | ||
small-btn | ||
</DButton> | ||
</DCompose> | ||
); | ||
const buttons = getAllByRole('button'); | ||
expect(buttons.length).toBe(4); | ||
for (let idx = 0; idx < buttons.length; idx++) { | ||
expect(buttons[idx]['disabled']).toBe(true); | ||
} | ||
expect(container.querySelector('#middle-btn1')?.className.includes(getOtherClass('larger'))).toBe(true); | ||
expect(container.querySelector('#small-btn')?.className.includes(getOtherClass('smaller'))).toBe(true); | ||
}); | ||
}); | ||
}); |