Skip to content

Commit d2e198c

Browse files
junruizhangxiejay97
junruizhang
authored andcommitted
test(ui): add test of button
1 parent c5a81ea commit d2e198c

File tree

1 file changed

+340
-1
lines changed

1 file changed

+340
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,350 @@
1-
import { render } from '../../__tests__/utils';
1+
import type { DSize } from '../../utils/types';
2+
import type { DButtonProps } from './Button';
3+
4+
import { render, fireEvent } from '../../__tests__/utils';
5+
import { DCompose } from '../compose';
26
import { DButton } from './index';
37

8+
const dPrefix = 'rd-';
9+
10+
const getTypeClass = (dType: DButtonProps['dType'], prefix = dPrefix) => {
11+
return `${prefix}button--${dType || 'primary'}`;
12+
};
13+
const getThemeClass = (dTheme: DButtonProps['dTheme'], prefix = 't') => {
14+
return `${prefix}-${dTheme || 'primary'}`;
15+
};
16+
const getOtherClass = (ots?: 'icon' | DSize | 'block' | DButtonProps['dVariant'] | 'icon-right', separator = '--', prefix = dPrefix) => {
17+
return !ots ? `${prefix}button` : `${prefix}button${separator}${ots || ''}`;
18+
};
19+
20+
const sleep = (time: number) =>
21+
new Promise((resolve) =>
22+
setTimeout(() => {
23+
resolve('');
24+
}, time)
25+
);
26+
427
describe('DButton', () => {
528
const text = 'This is DButton';
629

730
it('should `children` work', () => {
831
const { getByText } = render(<DButton children={text} />);
932
expect(getByText(text)).toBeInTheDocument();
1033
});
34+
35+
describe('the type property of DButton', () => {
36+
it('should render with the root, text, and primary classes but no others', () => {
37+
const buttonText = 'Hello World';
38+
const { getByRole, getByText } = render(
39+
<DButton className="cust-btn" type="submit">
40+
{buttonText}
41+
</DButton>
42+
);
43+
const button = getByRole('button');
44+
expect(getByText(buttonText)).toBeInTheDocument();
45+
expect(button.classList.contains(`cust-btn`)).toBe(true);
46+
expect(button.classList.contains(getOtherClass())).toBe(true);
47+
expect(button.classList.contains(getTypeClass('primary'))).toBe(true);
48+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
49+
50+
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true);
51+
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true);
52+
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true);
53+
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true);
54+
expect(button.classList.contains('is-loading')).not.toBe(true);
55+
expect(button.getAttribute('type')).toBe('submit');
56+
});
57+
58+
it('should render a text secondary button', () => {
59+
const buttonText = 'Hello World';
60+
const { getByRole } = render(<DButton dType="secondary">{buttonText}</DButton>);
61+
const button = getByRole('button');
62+
63+
expect(button.classList.contains(getTypeClass('secondary'))).toBe(true);
64+
expect(button.classList.contains(getOtherClass())).toBe(true);
65+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
66+
67+
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true);
68+
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true);
69+
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true);
70+
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true);
71+
expect(button.classList.contains('is-loading')).not.toBe(true);
72+
});
73+
74+
it('should render a text outline button', () => {
75+
const buttonText = 'Hello World';
76+
const { getByRole } = render(<DButton dType="outline">{buttonText}</DButton>);
77+
const button = getByRole('button');
78+
79+
expect(button.classList.contains(getTypeClass('outline'))).toBe(true);
80+
expect(button.classList.contains(getOtherClass())).toBe(true);
81+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
82+
83+
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true);
84+
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true);
85+
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true);
86+
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true);
87+
expect(button.classList.contains('is-loading')).not.toBe(true);
88+
});
89+
90+
it('should render a text dashed button', () => {
91+
const buttonText = 'Hello World';
92+
const { getByRole } = render(<DButton dType="dashed">{buttonText}</DButton>);
93+
const button = getByRole('button');
94+
95+
expect(button.classList.contains(getTypeClass('dashed'))).toBe(true);
96+
expect(button.classList.contains(getOtherClass())).toBe(true);
97+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
98+
99+
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true);
100+
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true);
101+
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true);
102+
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true);
103+
expect(button.classList.contains('is-loading')).not.toBe(true);
104+
});
105+
106+
it('should render a text text button', () => {
107+
const buttonText = 'Hello World';
108+
const { getByRole } = render(<DButton dType="text">{buttonText}</DButton>);
109+
const button = getByRole('button');
110+
111+
expect(button.classList.contains(getTypeClass('text'))).toBe(true);
112+
expect(button.classList.contains(getOtherClass())).toBe(true);
113+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
114+
115+
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true);
116+
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true);
117+
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true);
118+
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true);
119+
expect(button.classList.contains('is-loading')).not.toBe(true);
120+
});
121+
122+
it('should render a text link button', () => {
123+
const buttonText = 'Hello World';
124+
const { getByRole } = render(<DButton dType="link">{buttonText}</DButton>);
125+
const button = getByRole('button');
126+
127+
expect(button.classList.contains(getTypeClass('link'))).toBe(true);
128+
expect(button.classList.contains(getOtherClass())).toBe(true);
129+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
130+
131+
expect(button.classList.contains(getOtherClass('icon'))).not.toBe(true);
132+
expect(button.classList.contains(getOtherClass('block'))).not.toBe(true);
133+
expect(button.classList.contains(getOtherClass('smaller'))).not.toBe(true);
134+
expect(button.classList.contains(getOtherClass('larger'))).not.toBe(true);
135+
expect(button.classList.contains('is-loading')).not.toBe(true);
136+
});
137+
});
138+
139+
describe('the theme property of DButton', () => {
140+
it('should render a primary button', () => {
141+
const buttonText = 'Hello World';
142+
const { getByRole } = render(<DButton dTheme="primary">{buttonText}</DButton>);
143+
const button = getByRole('button');
144+
145+
expect(button.classList.contains(getThemeClass('primary'))).toBe(true);
146+
});
147+
148+
it('should render a success button', () => {
149+
const buttonText = 'Hello World';
150+
const { getByRole } = render(<DButton dTheme="success">{buttonText}</DButton>);
151+
const button = getByRole('button');
152+
153+
expect(button.classList.contains(getThemeClass('success'))).toBe(true);
154+
});
155+
156+
it('should render a warning button', () => {
157+
const buttonText = 'Hello World';
158+
const { getByRole } = render(<DButton dTheme="warning">{buttonText}</DButton>);
159+
const button = getByRole('button');
160+
161+
expect(button.classList.contains(getThemeClass('warning'))).toBe(true);
162+
});
163+
164+
it('should render a danger button', () => {
165+
const buttonText = 'Hello World';
166+
const { getByRole } = render(<DButton dTheme="danger">{buttonText}</DButton>);
167+
const button = getByRole('button');
168+
169+
expect(button.classList.contains(getThemeClass('danger'))).toBe(true);
170+
});
171+
});
172+
173+
describe('the icon property of DButton', () => {
174+
it('should render a button with icon', () => {
175+
const buttonText = 'Hello World';
176+
const mockIcon = <div>icon</div>;
177+
const { getByRole, getByText } = render(<DButton dIcon={mockIcon}>{buttonText}</DButton>);
178+
const button = getByRole('button');
179+
const icon = getByText('icon');
180+
181+
expect(icon).toBeInTheDocument();
182+
expect(button.contains(icon)).toBe(true);
183+
expect(button.getElementsByClassName(getOtherClass('icon', '__'))).toBeTruthy();
184+
});
185+
186+
it('should render a icon on the right', () => {
187+
const mockIcon = <div>icon</div>;
188+
const { getByRole } = render(
189+
<DButton dIcon={mockIcon} dIconRight>
190+
Hello World
191+
</DButton>
192+
);
193+
const button = getByRole('button');
194+
expect(button.className.includes(getOtherClass('icon-right'))).toBe(true);
195+
});
196+
});
197+
198+
describe('the disabled property of DButton', () => {
199+
it('should render a clickable button', () => {
200+
const buttonText = 'Hello World';
201+
const cb = jest.fn();
202+
const { getByRole } = render(<DButton onClick={cb}>{buttonText}</DButton>);
203+
const button = getByRole('button');
204+
expect(cb).not.toBeCalled();
205+
206+
fireEvent.click(button);
207+
expect(cb.mock.calls.length).toBe(1);
208+
expect(button.classList.contains('is-loading')).not.toBe(true);
209+
});
210+
211+
it('should render a disabled button', () => {
212+
const buttonText = 'Hello World';
213+
const cb = jest.fn();
214+
const { getByRole } = render(<DButton disabled>{buttonText}</DButton>);
215+
const button = getByRole('button');
216+
217+
expect(cb).not.toBeCalled();
218+
expect(button['disabled']).toBe(true);
219+
fireEvent.click(button);
220+
expect(cb).not.toBeCalled();
221+
expect(button.classList.contains('is-loading')).not.toBe(true);
222+
});
223+
});
224+
225+
describe('the loading property of DButton', () => {
226+
it('should render a loading-button', () => {
227+
const buttonText = 'Hello World';
228+
const cb = jest.fn();
229+
const { getByRole } = render(
230+
<DButton dLoading={true} onClick={cb}>
231+
{buttonText}
232+
</DButton>
233+
);
234+
const button = getByRole('button');
235+
expect(button.className.includes('is-loading')).toBe(true);
236+
expect(button.querySelector(`.${dPrefix}button__icon`)).toBeInTheDocument();
237+
fireEvent.click(button);
238+
expect(cb).not.toBeCalled();
239+
});
240+
241+
it('should render a loading-button without icon', () => {
242+
const buttonText = 'Hello World';
243+
const cb = jest.fn();
244+
const mockIcon = <div>icon</div>;
245+
const { getByRole, queryByText } = render(
246+
<DButton dIcon={mockIcon} dLoading onClick={cb}>
247+
{buttonText}
248+
</DButton>
249+
);
250+
const button = getByRole('button');
251+
const icon = queryByText('icon');
252+
253+
expect(icon).toBeNull();
254+
expect(button.className.includes('is-loading')).toBe(true);
255+
expect(button.getElementsByClassName(getOtherClass('icon', '__'))).toBeTruthy();
256+
fireEvent.click(button);
257+
expect(cb.mock.calls.length).toBe(0);
258+
});
259+
});
260+
261+
describe('the block property of DButton', () => {
262+
it('should render a button that suitable for its parent width', () => {
263+
const buttonText = 'Hello World';
264+
const { getByRole } = render(<DButton dBlock>{buttonText}</DButton>);
265+
const button = getByRole('button');
266+
expect(button.className.includes(getOtherClass('block'))).toBe(true);
267+
});
268+
});
269+
270+
describe('the size property of DButton', () => {
271+
it('should render a small button', () => {
272+
const buttonText = 'Hello World';
273+
const { getByRole } = render(<DButton dSize="smaller">{buttonText}</DButton>);
274+
const button = getByRole('button');
275+
276+
expect(button.className.includes(getOtherClass('smaller'))).toBe(true);
277+
});
278+
279+
it('should render a large button', () => {
280+
const buttonText = 'Hello World';
281+
const { getByRole } = render(<DButton dSize="larger">{buttonText}</DButton>);
282+
const button = getByRole('button');
283+
284+
expect(button.className.includes(getOtherClass('larger'))).toBe(true);
285+
});
286+
});
287+
288+
describe('the variant property of DButton', () => {
289+
it('should render a circle button', () => {
290+
const buttonText = 'Hello World';
291+
const { getByRole } = render(
292+
<DButton dSize="larger" dVariant="circle">
293+
{buttonText}
294+
</DButton>
295+
);
296+
const button = getByRole('button');
297+
expect(button.className.includes(getOtherClass('circle'))).toBe(true);
298+
});
299+
300+
it('should render a round button', () => {
301+
const buttonText = 'Hello World';
302+
const { getByRole } = render(
303+
<DButton dSize="larger" dVariant="round">
304+
{buttonText}
305+
</DButton>
306+
);
307+
const button = getByRole('button');
308+
expect(button.className.includes(getOtherClass('round'))).toBe(true);
309+
});
310+
});
311+
312+
describe('Emotion compatibility', () => {
313+
it('should have a wave by default', async () => {
314+
const { getByRole } = render(
315+
<DButton dSize="larger" dVariant="round">
316+
Hello World
317+
</DButton>
318+
);
319+
const button = getByRole('button');
320+
321+
expect(button.querySelector('.rd-wave')).toBeNull();
322+
fireEvent.click(button);
323+
expect(button.querySelector('.rd-wave')).toBeTruthy();
324+
// animation-duration
325+
await sleep(4 * 1000);
326+
327+
expect(button.querySelector('rd-wave')).toBeNull();
328+
});
329+
330+
it('the properties of size and disabled should be inherited from DCmpose', () => {
331+
const { container, getAllByRole } = render(
332+
<DCompose dSize="larger" dDisabled={true}>
333+
<DButton id="middle-btn1">middle-btn1</DButton>
334+
<DButton id="middle-btn2">middle-btn2</DButton>
335+
<DButton id="middle-btn3">middle-btn3</DButton>
336+
<DButton id="small-btn" dSize="smaller">
337+
small-btn
338+
</DButton>
339+
</DCompose>
340+
);
341+
const buttons = getAllByRole('button');
342+
expect(buttons.length).toBe(4);
343+
for (let idx = 0; idx < buttons.length; idx++) {
344+
expect(buttons[idx]['disabled']).toBe(true);
345+
}
346+
expect(container.querySelector('#middle-btn1')?.className.includes(getOtherClass('larger'))).toBe(true);
347+
expect(container.querySelector('#small-btn')?.className.includes(getOtherClass('smaller'))).toBe(true);
348+
});
349+
});
11350
});

0 commit comments

Comments
 (0)