timePicker.test.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. import * as React from 'react';
  2. import Button from '../../button';
  3. import TimePicker from '../TimePicker';
  4. import Locale from '../../locale/source/zh_CN';
  5. import { clear } from 'jest-date-mock';
  6. import * as _ from 'lodash-es';
  7. import { IconClose } from '@douyinfe/semi-icons';
  8. import { genAfterEach, genBeforeEach, mount, sleep, trigger } from '../../_test_/utils';
  9. import { isTimeFormatLike } from '@douyinfe/semi-foundation/timePicker/utils';
  10. import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
  11. describe(`TimePicker`, () => {
  12. beforeEach(() => {
  13. clear();
  14. genBeforeEach()();
  15. });
  16. afterEach(genAfterEach());
  17. it(`test time picker appearance`, async () => {
  18. const defaultHour = 10;
  19. const defaultMinute = 24;
  20. const defaultSeconds = 18;
  21. const onFoucs = sinon.spy();
  22. const elem = mount(
  23. <TimePicker
  24. onFocus={onFoucs}
  25. panelHeader={<strong>Select Time</strong>}
  26. locale={Locale.TimePicker}
  27. localeCode={Locale.code}
  28. defaultOpen={true}
  29. scrollItemProps={{ cycled: false }}
  30. format={'HH:mm:ss'}
  31. defaultValue={`${defaultHour}:${defaultMinute}:${defaultSeconds}`}
  32. panelFooter={<strong>Select Time</strong>}
  33. />
  34. );
  35. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-scrolllist`).length).toBe(1);
  36. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-timepicker`).length).toBe(1);
  37. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-scrolllist-header`).length).toBe(1);
  38. expect(document.querySelectorAll(`.${BASE_CLASS_PREFIX}-scrolllist-footer`).length).toBe(1);
  39. // click minute
  40. const minuteUl = elem.find(`.${BASE_CLASS_PREFIX}-timepicker-panel-list-minute .${BASE_CLASS_PREFIX}-scrolllist-list-outer ul`);
  41. const minuteLis = minuteUl.find(`li`);
  42. minuteUl.simulate('click', { target: minuteLis.at(0).getDOMNode(), nativeEvent: null });
  43. await sleep(200);
  44. const newMinute = 0;
  45. let currentDate = elem.state('value')[newMinute];
  46. expect(currentDate.getHours()).toBe(defaultHour);
  47. expect(currentDate.getMinutes()).toBe(newMinute);
  48. // focus
  49. elem.find(`input`).simulate('focus');
  50. await sleep(200);
  51. expect(onFoucs.calledOnce).toBeTruthy();
  52. // input value
  53. const newInputHour = 10;
  54. const newInputMinute = 18;
  55. const newInputSeconds = 18;
  56. elem.find(`input`).simulate('change', {
  57. target: { value: `${newInputHour}:${newInputMinute}:${newInputSeconds}` },
  58. });
  59. await sleep(200);
  60. currentDate = elem.state('value')[0];
  61. expect(currentDate.getMinutes()).toBe(newInputMinute);
  62. // click inside
  63. document.querySelector(`.${BASE_CLASS_PREFIX}-scrolllist`).click();
  64. expect(elem.state('open')).toBe(true);
  65. // click outside
  66. // document.body.click();
  67. trigger(document, 'mousedown');
  68. await sleep(200);
  69. expect(elem.state('open')).toBe(false);
  70. });
  71. it(`test controlled value`, async () => {
  72. const defaultHour = 10;
  73. const defaultMinute = 24;
  74. const defaultSeconds = 18;
  75. const elem0 = mount(
  76. <TimePicker
  77. panelHeader={<strong>Select Time</strong>}
  78. locale={Locale.TimePicker}
  79. localeCode={Locale.code}
  80. defaultOpen={true}
  81. scrollItemProps={{ cycled: false }}
  82. format={'HH:mm:ss'}
  83. value={`${defaultHour}:${defaultMinute}:${defaultSeconds}`}
  84. panelFooter={<strong>Select Time</strong>}
  85. />
  86. );
  87. const newInputHour = 10;
  88. const newInputMinute = 18;
  89. const newInputSeconds = 18;
  90. elem0.find(`input`).simulate('change', {
  91. target: { value: `${newInputHour}:${newInputMinute}:${newInputSeconds}` },
  92. });
  93. await sleep(200);
  94. let currentDate0 = elem0.state('value')[0];
  95. expect(currentDate0.getMinutes()).toBe(defaultMinute);
  96. });
  97. it(`test controlled value with onchange`, async () => {
  98. const defaultHour = 10;
  99. const defaultMinute = 24;
  100. const defaultSeconds = 18;
  101. const onChange = sinon.spy((date, str) => {
  102. elem1.setProps({ value: date });
  103. });
  104. const elem1 = mount(
  105. <TimePicker
  106. onChange={onChange}
  107. panelHeader={<strong>Select Time</strong>}
  108. locale={Locale.TimePicker}
  109. localeCode={Locale.code}
  110. defaultOpen={true}
  111. scrollItemProps={{ cycled: false }}
  112. format={'HH:mm:ss'}
  113. value={`${defaultHour}:${defaultMinute}:${defaultSeconds}`}
  114. panelFooter={<strong>Select Time</strong>}
  115. />
  116. );
  117. const newInputHour = 10;
  118. const newInputMinute = 18;
  119. const newInputSeconds = 18;
  120. elem1.find(`input`).simulate('change', {
  121. target: { value: `${newInputHour}:${newInputMinute}:${newInputSeconds}` },
  122. });
  123. await sleep(200);
  124. let currentDate1 = elem1.state('value')[0];
  125. expect(currentDate1.getMinutes()).toBe(newInputMinute);
  126. });
  127. it(`test controlled open`, async () => {
  128. const defaultHour = 10;
  129. const defaultMinute = 24;
  130. const defaultSeconds = 18;
  131. const defaultOpen = true;
  132. const onChange = sinon.spy((date, str) => {
  133. elem1.setProps({ value: date });
  134. });
  135. const onOpenChange = sinon.spy(open => elem.setProps({ open }));
  136. const elem = mount(
  137. <TimePicker
  138. motion={false}
  139. onOpenChange={onOpenChange}
  140. open={defaultOpen}
  141. onChange={onChange}
  142. panelHeader={<strong>Select Time</strong>}
  143. locale={Locale.TimePicker}
  144. localeCode={Locale.code}
  145. scrollItemProps={{ cycled: false }}
  146. format={'HH:mm:ss'}
  147. value={`${defaultHour}:${defaultMinute}:${defaultSeconds}`}
  148. panelFooter={<Button icon={<IconClose />} onClick={() => elem.setProps({ open: false })} />}
  149. />
  150. );
  151. expect(elem.state('open')).toBe(true);
  152. // click close button
  153. document.querySelector(`.${BASE_CLASS_PREFIX}-scrolllist-footer .${BASE_CLASS_PREFIX}-button`).click();
  154. elem.setProps({ open: false });
  155. await sleep(200);
  156. expect(elem.state('open')).toBe(false);
  157. expect(onOpenChange.calledOnce).toBeFalsy();
  158. elem.setProps({ open: true });
  159. document.body.click();
  160. await sleep(200);
  161. expect(elem.state('open')).toBe(true);
  162. });
  163. it(`test range picker appearance`, async () => {
  164. const defaultValue = ['上午 10:12', '上午 11:08'];
  165. const formatToken = `a hh:mm`;
  166. const use12Hours = true;
  167. const elem = mount(
  168. <TimePicker
  169. use12Hours={use12Hours}
  170. focusOnOpen
  171. format={formatToken}
  172. type={'timeRange'}
  173. locale={Locale.TimePicker}
  174. localeCode={Locale.code}
  175. defaultValue={defaultValue}
  176. scrollItemProps={{ cycled: false, mode: 'normal' }}
  177. defaultOpen
  178. />
  179. );
  180. await sleep(200);
  181. const all = elem.find(`.${BASE_CLASS_PREFIX}-scrolllist`);
  182. expect(all.length).toBe(2);
  183. // click hour list to change hour to 11
  184. const newHour = 9;
  185. const hourUl = all.at(0).find(`.${BASE_CLASS_PREFIX}-timepicker-panel-list-hour ul`);
  186. const hourLis = hourUl.children(`li`);
  187. expect(hourLis.length).toBe(use12Hours ? 12 : 24);
  188. const nextSelectedLi = hourLis.at(newHour);
  189. expect(nextSelectedLi).not.toBeUndefined();
  190. nextSelectedLi.simulate('click');
  191. await sleep(200);
  192. expect(elem.state('value')[0].getHours()).toBe(newHour);
  193. });
  194. it('test isTimeFormatLike function', () => {
  195. const testCases = [
  196. ['10:24:00', 'HH:mm:ss', true],
  197. ['10:24:0', 'HH:mm:ss', false],
  198. ['10:2:00', 'HH:mm:ss', false],
  199. ['1:24:00', 'HH:mm:ss', false],
  200. ['10:24', 'HH:mm', true],
  201. ['10:2', 'HH:mm', false],
  202. ['1:24', 'HH:mm', false],
  203. ['24:30', 'mm:ss', true],
  204. ['24:3', 'mm:ss', false],
  205. ['2:30', 'mm:ss', false],
  206. ['10', 'HH', true],
  207. ['1', 'HH', false],
  208. ['10', 'mm', true],
  209. ['1', 'mm', false],
  210. ['10', 'ss', true],
  211. ['1', 'ss', false],
  212. ['2021 10:24:00', 'yyyy HH:mm:ss', true],
  213. ['2021 10:24:0', 'yyyy HH:mm:ss', false],
  214. ['2021 10:2:0', 'yyyy HH:mm:ss', false],
  215. ['2021 1:24:0', 'yyyy HH:mm:ss', false],
  216. ['上午 12:00:02', 'a h:mm:ss', true],
  217. ['上午 12:00:0', 'a h:mm:ss', false],
  218. ['上午 12:0:00', 'a h:mm:ss', false],
  219. ];
  220. testCases.forEach(test => {
  221. const [time, format, result] = test;
  222. expect(isTimeFormatLike(time, format)).toBe(result);
  223. })
  224. });
  225. it('click clear', async () => {
  226. const onChange = sinon.spy();
  227. let props = {
  228. defaultValue: "10:23:15",
  229. showClear: true,
  230. onChange,
  231. autofocus: true,
  232. locale: Locale.TimePicker,
  233. localeCode: Locale.code
  234. };
  235. const elem = mount(<TimePicker {...props} />);
  236. const clearBtn = elem.find('.semi-input-clearbtn');
  237. clearBtn.simulate('mouseDown');
  238. expect(onChange.called).toBeTruthy();
  239. const args = onChange.getCall(0).args;
  240. expect(args[0]).toBe(undefined);
  241. expect(args[1]).toBe('');
  242. });
  243. });