input.test.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import Input, { Input as BaseInput } from '../index';
  2. import Icon from '../../icons/index';
  3. import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
  4. import GraphemeSplitter from 'grapheme-splitter';
  5. import { isString, isFunction } from 'lodash';
  6. function getValueLength(str) {
  7. if (isString(str)) {
  8. const splitter = new GraphemeSplitter();
  9. return splitter.countGraphemes(str);
  10. } else {
  11. return -1;
  12. }
  13. }
  14. describe('Input', () => {
  15. // it('call foundation destory when compoonent Unmount', () => {
  16. // });
  17. it('input should call onChange when value change', () => {
  18. let inputValue = 'semi';
  19. let event = { target: { value: inputValue } };
  20. let onChange = value => {
  21. console.log(value);
  22. };
  23. let spyOnChange = sinon.spy(onChange);
  24. const input = mount(<Input onChange={spyOnChange} />);
  25. input.find('input').simulate('change', event);
  26. expect(spyOnChange.calledOnce).toBe(true);
  27. expect(spyOnChange.calledWithMatch(inputValue)).toBe(true);
  28. });
  29. it('input with custom className & style', () => {
  30. const wrapper = mount(<Input className="test" style={{ color: 'red' }} />);
  31. expect(wrapper.hasClass('test')).toEqual(true);
  32. expect(wrapper.find('div.test')).toHaveStyle('color', 'red');
  33. });
  34. // TODO ,找不到focus的className
  35. // it('input autofocus', () => {
  36. // const wrapper = mount(<Input autofocus={true} />);
  37. // wrapper.setProps({ autofocus: true })
  38. // wrapper.update();
  39. // expect(wrapper.find(`.${BASE_CLASS_PREFIX}-input-wrapper-focus`)).toEqual(true);
  40. // });
  41. it('input different size', () => {
  42. const largeInput = mount(<Input size="large" />);
  43. const defaultInput = mount(<Input />);
  44. const smallInput = mount(<Input size="small" />);
  45. expect(largeInput.find(`.${BASE_CLASS_PREFIX}-input-large`)).toHaveLength(1);
  46. expect(smallInput.find(`.${BASE_CLASS_PREFIX}-input-small`)).toHaveLength(1);
  47. });
  48. it('input with placeholder', () => {
  49. let placeholderText = `semi placeholder`;
  50. const input = mount(<Input placeholder={placeholderText} />);
  51. let inputDom = input.find('input');
  52. expect(inputDom.props().placeholder).toEqual(placeholderText);
  53. });
  54. it('input with defaultValue', () => {
  55. let defaultValue = 'semi';
  56. const inputWithDefaultValue = mount(<Input defaultValue={defaultValue} />);
  57. const inputDom = inputWithDefaultValue.find('input');
  58. expect(inputDom.instance().value).toEqual(defaultValue);
  59. });
  60. it('input disabled when props.disabled', () => {
  61. const disabledInput = mount(<Input disabled />);
  62. expect(disabledInput.exists(`.${BASE_CLASS_PREFIX}-input-wrapper-disabled`)).toEqual(true);
  63. expect(disabledInput.find(`.${BASE_CLASS_PREFIX}-input-disabled`)).toHaveLength(1);
  64. });
  65. it('input different validateStatus', () => {
  66. const warningInput = mount(<Input validateStatus="warning" />);
  67. const errorInput = mount(<Input validateStatus="error" />);
  68. const normalInput = mount(<Input />);
  69. expect(warningInput.exists(`.${BASE_CLASS_PREFIX}-input-wrapper-warning`)).toEqual(true);
  70. expect(errorInput.exists(`.${BASE_CLASS_PREFIX}-input-wrapper-error`)).toEqual(true);
  71. expect(normalInput.exists(`.${BASE_CLASS_PREFIX}-input-wrapper-error`)).toEqual(false);
  72. expect(normalInput.exists(`.${BASE_CLASS_PREFIX}-input-wrapper-warning`)).toEqual(false);
  73. });
  74. // TODO,同上,focus时才会展示clearBtn,autoFocus似乎不起作用
  75. // it('input clearable', () => {
  76. // const clearableInput = mount(<Input clearable defaultValue='semi' autofocus/>);
  77. // expect(clearableInput.find('input').instance().value).toEqual('semi');
  78. // // clearableInput.find(`.${BASE_CLASS_PREFIX}-input-clearbtn`).simulate('click');
  79. // })
  80. it('input with prefix / suffix', () => {
  81. let suffix = <div className="suffix">suffix</div>;
  82. let prefix = <div className="prefix">prefix</div>;
  83. const withNodeSuffix = mount(<Input suffix={suffix} />);
  84. const withNodePrefix = mount(<Input prefix={prefix} />);
  85. expect(withNodeSuffix.contains(suffix)).toEqual(true);
  86. expect(withNodePrefix.contains(prefix)).toEqual(true);
  87. });
  88. it('input addonBefore / addonAfter', () => {
  89. let input = mount(<Input addonBefore="https://" addonAfter=".com" />);
  90. expect(input.find(`.${BASE_CLASS_PREFIX}-input-prepend`).getDOMNode().textContent).toEqual('https://');
  91. expect(input.find(`.${BASE_CLASS_PREFIX}-input-append`).getDOMNode().textContent).toEqual('.com');
  92. });
  93. it('input password', () => {
  94. const pwInput = mount(<Input type="password" />);
  95. expect(pwInput.find('input').instance().type).toEqual('password');
  96. });
  97. it('input password mode', () => {
  98. const inputMode = mount(<Input mode="password" />);
  99. const input = inputMode.find('input');
  100. expect(input.instance().type).toEqual('password');
  101. });
  102. it('input controlled mode', () => {
  103. let initValue = 'semi';
  104. let onChange = value => {
  105. console.log(value);
  106. };
  107. let spyOnChange = sinon.spy(onChange);
  108. const input = mount(<Input onChange={spyOnChange} value={initValue} />);
  109. const inputDom = input.find('input');
  110. expect(inputDom.instance().value).toEqual(initValue);
  111. let newInputValue = 'vita lemon';
  112. let event = { target: { value: newInputValue } };
  113. input.find('input').simulate('change', event);
  114. expect(spyOnChange.calledOnce).toBe(true);
  115. expect(spyOnChange.calledWithMatch(newInputValue)).toBe(true);
  116. input.setProps({ value: newInputValue });
  117. expect(inputDom.instance().value).toEqual(newInputValue);
  118. });
  119. // TODO InputGroup
  120. // TODO onClear 回调
  121. it('click prefix/suffix focus', () => {
  122. const spyFocus = sinon.spy(() => {});
  123. const inputNode = mount(<Input style={{ width: 200 }} onFocus={spyFocus} prefix="search" defaultValue="Semi Design" />);
  124. const inputNode2 = mount(<Input style={{ width: 200 }} onFocus={spyFocus} suffix="search" defaultValue="Semi Design" />);
  125. inputNode.find(`.${BASE_CLASS_PREFIX}-input-prefix`).simulate('click');
  126. expect(inputNode.find(BaseInput).state('isFocus')).toEqual(true);
  127. inputNode2.find(`.${BASE_CLASS_PREFIX}-input-suffix`).simulate('click');
  128. expect(inputNode2.find(BaseInput).state('isFocus')).toEqual(true);
  129. });
  130. it('test input GraphemeSplitter function', () => {
  131. const testCases = [
  132. ['💖', 1],
  133. ['字节跳动', 4],
  134. ['Semi 💖', 6],
  135. ['💖💖💖💖💖', 5],
  136. ['🤣', 1],
  137. ['1️⃣', 1],
  138. ['👨‍👨‍👦', 1],
  139. ];
  140. for (let item of testCases) {
  141. const [value, result] = item;
  142. expect(getValueLength(value)).toEqual(result);
  143. }
  144. });
  145. it('test getValueLength onChange', () => {
  146. let inputValue = '0123456789semi design';
  147. let event = { target: { value: inputValue } };
  148. let onChange = value => {
  149. console.log(value);
  150. };
  151. let spyOnChange = sinon.spy(onChange);
  152. const input = mount(<Input onChange={spyOnChange} maxLength={10} getValueLength={getValueLength} />);
  153. input.find('input').simulate('change', event);
  154. expect(spyOnChange.calledOnce).toBe(true);
  155. expect(spyOnChange.calledWithMatch(inputValue)).toBe(false);
  156. });
  157. it('test visibleLength controlled mode', () => {
  158. let value = '0123456789semi design';
  159. const input = mount(<Input value={value} maxLength={10} getValueLength={getValueLength} />);
  160. const inputDom = input.find('input');
  161. expect(inputDom.instance().value).toEqual(value);
  162. });
  163. it('test minLength + getValueLength', () => {
  164. let inputValue = '💖💖💖';
  165. let minLength = 4;
  166. let event = { target: { value: inputValue } };
  167. let onChange = value => {
  168. console.log(value);
  169. };
  170. let spyOnChange = sinon.spy(onChange);
  171. const input = mount(<Input onChange={spyOnChange} minLength={minLength} getValueLength={getValueLength} />);
  172. const inputDom = input.find('input');
  173. inputDom.simulate('change', event);
  174. expect(spyOnChange.calledOnce).toBe(true);
  175. expect(spyOnChange.calledWithMatch(inputValue)).toBe(true);
  176. expect(inputDom.instance().minLength).toEqual(inputValue.length + (minLength - getValueLength(inputValue)));
  177. });
  178. it('test truncateValue function', () => {
  179. function truncateValue(value, maxLength, getValueLength) {
  180. if (isFunction(getValueLength)) {
  181. let truncatedValue = '';
  182. for (let i = 1, len = value.length; i <= len; i++) {
  183. const currentValue = value.slice(0, i);
  184. if (getValueLength(currentValue) > maxLength) {
  185. return truncatedValue;
  186. } else {
  187. truncatedValue = currentValue;
  188. }
  189. }
  190. return truncatedValue;
  191. } else {
  192. return value.slice(0, maxLength);
  193. }
  194. }
  195. const testCases = [
  196. // 没有传递函数
  197. ['Semi Design', 4, null, 'Semi'],
  198. ['💖', 0, null, ''],
  199. ['🆗', 1, null, '\ud83c'],
  200. // 自定义valueLength
  201. ['Semi Design', 4, getValueLength, 'Semi'],
  202. ['💖💖💖💖💖💖💖💖💖💖👨‍👩‍👧‍👦', 10, getValueLength, '💖💖💖💖💖💖💖💖💖💖'],
  203. ['💖', 0, getValueLength, ''],
  204. ['🆗', 1, getValueLength, '🆗'],
  205. ];
  206. for (let [value, length, fc, result] of testCases) {
  207. expect(truncateValue(value, length, fc)).toBe(result);
  208. }
  209. })
  210. });