2021-08-30 13:25:32 +08:00
import React , { useState } from 'react' ;
2017-01-30 20:05:47 +08:00
import { mount } from 'enzyme' ;
2019-08-06 15:02:05 +08:00
// eslint-disable-next-line import/no-unresolved
2017-07-16 15:39:21 +08:00
import Form from '../../form' ;
2019-02-07 11:39:16 +08:00
import Input from '..' ;
2017-11-19 01:41:40 +08:00
import focusTest from '../../../tests/shared/focusTest' ;
2019-08-26 22:53:20 +08:00
import mountTest from '../../../tests/shared/mountTest' ;
2020-01-02 19:10:16 +08:00
import rtlTest from '../../../tests/shared/rtlTest' ;
2017-01-30 20:05:47 +08:00
2017-09-27 09:56:30 +08:00
describe ( 'Input' , ( ) => {
2019-03-07 15:47:43 +08:00
const errorSpy = jest . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
afterEach ( ( ) => {
errorSpy . mockReset ( ) ;
} ) ;
afterAll ( ( ) => {
errorSpy . mockRestore ( ) ;
} ) ;
2017-11-19 01:41:40 +08:00
focusTest ( Input ) ;
2019-08-26 22:53:20 +08:00
mountTest ( Input ) ;
2019-08-27 16:13:43 +08:00
mountTest ( Input . Group ) ;
2017-11-19 01:41:40 +08:00
2020-01-02 19:10:16 +08:00
rtlTest ( Input ) ;
rtlTest ( Input . Group ) ;
2017-11-16 17:12:36 +08:00
it ( 'should support maxLength' , ( ) => {
2018-12-27 11:46:22 +08:00
const wrapper = mount ( < Input maxLength = { 3 } / > ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2017-09-27 09:56:30 +08:00
} ) ;
2018-08-28 18:54:21 +08:00
it ( 'select()' , ( ) => {
2018-12-07 20:02:01 +08:00
const wrapper = mount ( < Input / > ) ;
2018-08-28 18:54:21 +08:00
wrapper . instance ( ) . select ( ) ;
} ) ;
2019-03-07 15:47:43 +08:00
2020-02-09 11:57:42 +08:00
it ( 'should support size' , ( ) => {
const wrapper = mount ( < Input size = "large" / > ) ;
expect ( wrapper . find ( 'input' ) . hasClass ( 'ant-input-lg' ) ) . toBe ( true ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2020-02-09 11:57:42 +08:00
} ) ;
it ( 'should support size in form' , ( ) => {
const wrapper = mount (
< Form size = "large" >
< Form . Item >
< Input / >
< / F o r m . I t e m >
< / F o r m > ,
) ;
expect ( wrapper . find ( 'input' ) . hasClass ( 'ant-input-lg' ) ) . toBe ( true ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2020-02-09 11:57:42 +08:00
} ) ;
2019-03-07 15:47:43 +08:00
describe ( 'focus trigger warning' , ( ) => {
it ( 'not trigger' , ( ) => {
const wrapper = mount ( < Input suffix = "bamboo" / > ) ;
2020-04-14 23:04:23 +08:00
wrapper . find ( 'input' ) . instance ( ) . focus ( ) ;
2019-03-07 15:47:43 +08:00
wrapper . setProps ( {
suffix : 'light' ,
} ) ;
2019-04-03 15:54:26 +08:00
expect ( errorSpy ) . not . toHaveBeenCalled ( ) ;
2019-03-07 15:47:43 +08:00
} ) ;
it ( 'trigger warning' , ( ) => {
2020-02-04 17:57:34 +08:00
const wrapper = mount ( < Input / > , { attachTo : document . body } ) ;
2020-04-14 23:04:23 +08:00
wrapper . find ( 'input' ) . instance ( ) . focus ( ) ;
2019-03-07 15:47:43 +08:00
wrapper . setProps ( {
suffix : 'light' ,
} ) ;
2019-04-03 15:54:26 +08:00
expect ( errorSpy ) . toHaveBeenCalledWith (
2019-03-07 15:47:43 +08:00
'Warning: [antd: Input] When Input is focused, dynamic add or remove prefix / suffix will make it lose focus caused by dom structure change. Read more: https://ant.design/components/input/#FAQ' ,
) ;
2020-02-04 17:57:34 +08:00
wrapper . unmount ( ) ;
2019-03-07 15:47:43 +08:00
} ) ;
} ) ;
2020-11-06 11:48:50 +08:00
it ( 'set mouse cursor position' , ( ) => {
const defaultValue = '11111' ;
const valLength = defaultValue . length ;
const wrapper = mount ( < Input autoFocus defaultValue = { defaultValue } / > ) ;
wrapper . instance ( ) . setSelectionRange ( valLength , valLength ) ;
expect ( wrapper . instance ( ) . input . selectionStart ) . toEqual ( 5 ) ;
expect ( wrapper . instance ( ) . input . selectionEnd ) . toEqual ( 5 ) ;
} ) ;
2017-09-27 09:56:30 +08:00
} ) ;
2017-11-01 12:12:16 +08:00
2020-10-30 15:27:37 +08:00
describe ( 'prefix and suffix' , ( ) => {
it ( 'should support className when has suffix' , ( ) => {
const wrapper = mount ( < Input suffix = "suffix" className = "my-class-name" / > ) ;
expect ( wrapper . getDOMNode ( ) . className . includes ( 'my-class-name' ) ) . toBe ( true ) ;
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . className . includes ( 'my-class-name' ) ) . toBe ( false ) ;
} ) ;
it ( 'should support className when has prefix' , ( ) => {
const wrapper = mount ( < Input prefix = "prefix" className = "my-class-name" / > ) ;
expect ( wrapper . getDOMNode ( ) . className . includes ( 'my-class-name' ) ) . toBe ( true ) ;
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . className . includes ( 'my-class-name' ) ) . toBe ( false ) ;
} ) ;
2022-01-13 16:23:27 +08:00
it ( 'should support hidden when has prefix or suffix' , ( ) => {
const wrapper = mount (
< >
< Input prefix = "prefix" hidden className = "prefix-with-hidden" / >
< Input suffix = "suffix" hidden className = "suffix-with-hidden" / >
< / > ,
) ;
expect ( wrapper . find ( '.prefix-with-hidden' ) . at ( 0 ) . getDOMNode ( ) . hidden ) . toBe ( true ) ;
expect ( wrapper . find ( '.suffix-with-hidden' ) . at ( 0 ) . getDOMNode ( ) . hidden ) . toBe ( true ) ;
} ) ;
2020-10-30 15:27:37 +08:00
} ) ;
2017-07-16 15:39:21 +08:00
describe ( 'As Form Control' , ( ) => {
2017-11-16 17:12:36 +08:00
it ( 'should be reset when wrapped in form.getFieldDecorator without initialValue' , ( ) => {
2019-07-03 20:14:39 +08:00
const Demo = ( ) => {
const [ form ] = Form . useForm ( ) ;
const reset = ( ) => {
2018-06-22 21:05:13 +08:00
form . resetFields ( ) ;
2018-12-07 20:02:01 +08:00
} ;
2018-06-22 21:05:13 +08:00
2019-07-03 20:14:39 +08:00
return (
< Form form = { form } >
< Form . Item name = "input" >
< Input / >
< / F o r m . I t e m >
< Form . Item name = "textarea" >
< Input . TextArea / >
< / F o r m . I t e m >
< button type = "button" onClick = { reset } >
reset
< / b u t t o n >
< / F o r m >
) ;
} ;
const wrapper = mount ( < Demo / > ) ;
2017-07-16 15:39:21 +08:00
wrapper . find ( 'input' ) . simulate ( 'change' , { target : { value : '111' } } ) ;
wrapper . find ( 'textarea' ) . simulate ( 'change' , { target : { value : '222' } } ) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '111' ) ;
expect ( wrapper . find ( 'textarea' ) . prop ( 'value' ) ) . toBe ( '222' ) ;
wrapper . find ( 'button' ) . simulate ( 'click' ) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '' ) ;
expect ( wrapper . find ( 'textarea' ) . prop ( 'value' ) ) . toBe ( '' ) ;
} ) ;
} ) ;
2017-11-01 12:12:16 +08:00
2021-10-15 16:23:47 +08:00
describe ( 'should support showCount' , ( ) => {
it ( 'maxLength' , ( ) => {
const wrapper = mount ( < Input maxLength = { 5 } showCount value = "12345" / > ) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '12345' ) ;
expect ( wrapper . find ( '.ant-input-show-count-suffix' ) . getDOMNode ( ) . innerHTML ) . toBe ( '5 / 5' ) ;
} ) ;
it ( 'control exceed maxLength' , ( ) => {
const wrapper = mount ( < Input maxLength = { 5 } showCount value = "12345678" / > ) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '12345678' ) ;
expect ( wrapper . find ( '.ant-input-show-count-suffix' ) . getDOMNode ( ) . innerHTML ) . toBe ( '8 / 5' ) ;
} ) ;
describe ( 'emoji' , ( ) => {
it ( 'should minimize value between emoji length and maxLength' , ( ) => {
const wrapper = mount ( < Input maxLength = { 1 } showCount value = "👀" / > ) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '👀' ) ;
expect ( wrapper . find ( '.ant-input-show-count-suffix' ) . getDOMNode ( ) . innerHTML ) . toBe ( '1 / 1' ) ;
const wrapper1 = mount ( < Input maxLength = { 2 } showCount value = "👀" / > ) ;
expect ( wrapper1 . find ( '.ant-input-show-count-suffix' ) . getDOMNode ( ) . innerHTML ) . toBe ( '1 / 2' ) ;
} ) ;
it ( 'slice emoji' , ( ) => {
const wrapper = mount ( < Input maxLength = { 5 } showCount value = "1234😂" / > ) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '1234😂' ) ;
expect ( wrapper . find ( '.ant-input-show-count-suffix' ) . getDOMNode ( ) . innerHTML ) . toBe ( '5 / 5' ) ;
} ) ;
} ) ;
it ( 'count formatter' , ( ) => {
const wrapper = mount (
< Input
maxLength = { 5 }
showCount = { { formatter : ( { count , maxLength } ) => ` ${ count } , ${ maxLength } ` } }
value = "12345"
/ > ,
) ;
expect ( wrapper . find ( 'input' ) . prop ( 'value' ) ) . toBe ( '12345' ) ;
expect ( wrapper . find ( '.ant-input-show-count-suffix' ) . getDOMNode ( ) . innerHTML ) . toBe ( '5, 5' ) ;
} ) ;
} ) ;
2018-12-26 22:34:29 +08:00
describe ( 'Input allowClear' , ( ) => {
it ( 'should change type when click' , ( ) => {
const wrapper = mount ( < Input allowClear / > ) ;
wrapper . find ( 'input' ) . simulate ( 'change' , { target : { value : '111' } } ) ;
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . value ) . toEqual ( '111' ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2020-04-14 23:04:23 +08:00
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'click' ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2018-12-26 22:34:29 +08:00
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . value ) . toEqual ( '' ) ;
} ) ;
2018-12-28 15:48:05 +08:00
2019-02-07 11:39:16 +08:00
it ( 'should not show icon if value is undefined, null or empty string' , ( ) => {
const wrappers = [ null , undefined , '' ] . map ( val => mount ( < Input allowClear value = { val } / > ) ) ;
wrappers . forEach ( wrapper => {
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . value ) . toEqual ( '' ) ;
2020-04-14 23:04:23 +08:00
expect ( wrapper . find ( '.ant-input-clear-icon-hidden' ) . exists ( ) ) . toBeTruthy ( ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2019-02-07 11:39:16 +08:00
} ) ;
} ) ;
it ( 'should not show icon if defaultValue is undefined, null or empty string' , ( ) => {
const wrappers = [ null , undefined , '' ] . map ( val =>
mount ( < Input allowClear defaultValue = { val } / > ) ,
) ;
wrappers . forEach ( wrapper => {
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . value ) . toEqual ( '' ) ;
2020-04-14 23:04:23 +08:00
expect ( wrapper . find ( '.ant-input-clear-icon-hidden' ) . exists ( ) ) . toBeTruthy ( ) ;
2020-02-17 19:12:42 +08:00
expect ( wrapper . render ( ) ) . toMatchSnapshot ( ) ;
2019-02-07 11:39:16 +08:00
} ) ;
} ) ;
2018-12-28 15:48:05 +08:00
it ( 'should trigger event correctly' , ( ) => {
let argumentEventObject ;
let argumentEventObjectValue ;
const onChange = e => {
argumentEventObject = e ;
argumentEventObjectValue = e . target . value ;
} ;
const wrapper = mount ( < Input allowClear defaultValue = "111" onChange = { onChange } / > ) ;
2020-04-14 23:04:23 +08:00
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'click' ) ;
2018-12-28 15:48:05 +08:00
expect ( argumentEventObject . type ) . toBe ( 'click' ) ;
expect ( argumentEventObjectValue ) . toBe ( '' ) ;
2020-04-14 23:04:23 +08:00
expect ( wrapper . find ( 'input' ) . at ( 0 ) . getDOMNode ( ) . value ) . toBe ( '' ) ;
2018-12-28 15:48:05 +08:00
} ) ;
it ( 'should trigger event correctly on controlled mode' , ( ) => {
let argumentEventObject ;
let argumentEventObjectValue ;
const onChange = e => {
argumentEventObject = e ;
argumentEventObjectValue = e . target . value ;
} ;
const wrapper = mount ( < Input allowClear value = "111" onChange = { onChange } / > ) ;
2020-04-14 23:04:23 +08:00
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'click' ) ;
2018-12-28 15:48:05 +08:00
expect ( argumentEventObject . type ) . toBe ( 'click' ) ;
expect ( argumentEventObjectValue ) . toBe ( '' ) ;
2020-04-14 23:04:23 +08:00
expect ( wrapper . find ( 'input' ) . at ( 0 ) . getDOMNode ( ) . value ) . toBe ( '111' ) ;
2018-12-28 15:48:05 +08:00
} ) ;
2019-03-05 11:16:13 +08:00
it ( 'should focus input after clear' , ( ) => {
2020-02-04 17:57:34 +08:00
const wrapper = mount ( < Input allowClear defaultValue = "111" / > , { attachTo : document . body } ) ;
2020-04-14 23:04:23 +08:00
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'click' ) ;
expect ( document . activeElement ) . toBe ( wrapper . find ( 'input' ) . at ( 0 ) . getDOMNode ( ) ) ;
2020-02-04 17:57:34 +08:00
wrapper . unmount ( ) ;
2019-03-05 11:16:13 +08:00
} ) ;
2019-08-26 22:58:00 +08:00
2020-02-20 19:56:22 +08:00
[ 'disabled' , 'readOnly' ] . forEach ( prop => {
it ( ` should not support allowClear when it is ${ prop } ` , ( ) => {
const wrapper = mount ( < Input allowClear defaultValue = "111" { ... { [ prop ] : true } } / > ) ;
2020-04-14 23:04:23 +08:00
expect ( wrapper . find ( '.ant-input-clear-icon-hidden' ) . exists ( ) ) . toBeTruthy ( ) ;
2020-02-20 19:56:22 +08:00
} ) ;
2019-08-26 22:58:00 +08:00
} ) ;
2020-10-30 15:27:37 +08:00
// https://github.com/ant-design/ant-design/issues/27444
it ( 'should support className' , ( ) => {
const wrapper = mount ( < Input allowClear className = "my-class-name" / > ) ;
expect ( wrapper . getDOMNode ( ) . className . includes ( 'my-class-name' ) ) . toBe ( true ) ;
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . className . includes ( 'my-class-name' ) ) . toBe ( false ) ;
} ) ;
2021-06-30 13:48:22 +08:00
// https://github.com/ant-design/ant-design/issues/31200
it ( 'should not lost focus when clear input' , ( ) => {
const onBlur = jest . fn ( ) ;
const wrapper = mount ( < Input allowClear defaultValue = "value" onBlur = { onBlur } / > , {
attachTo : document . body ,
} ) ;
wrapper . find ( 'input' ) . getDOMNode ( ) . focus ( ) ;
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'mouseDown' ) ;
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'click' ) ;
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'mouseUp' ) ;
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'focus' ) ;
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . getDOMNode ( ) . click ( ) ;
expect ( onBlur ) . not . toBeCalled ( ) ;
wrapper . unmount ( ) ;
} ) ;
2021-08-30 13:25:32 +08:00
// https://github.com/ant-design/ant-design/issues/31927
it ( 'should correctly when useState' , ( ) => {
const App = ( ) => {
const [ query , setQuery ] = useState ( '' ) ;
return (
< Input
allowClear
value = { query }
onChange = { e => {
setQuery ( ( ) => e . target . value ) ;
} }
/ >
) ;
} ;
const wrapper = mount ( < App / > ) ;
wrapper . find ( 'input' ) . getDOMNode ( ) . focus ( ) ;
wrapper . find ( 'input' ) . simulate ( 'change' , { target : { value : '111' } } ) ;
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . value ) . toEqual ( '111' ) ;
wrapper . find ( '.ant-input-clear-icon' ) . at ( 0 ) . simulate ( 'click' ) ;
expect ( wrapper . find ( 'input' ) . getDOMNode ( ) . value ) . toEqual ( '' ) ;
wrapper . unmount ( ) ;
} ) ;
2021-12-29 11:32:49 +08:00
it ( 'not crash when value is number' , ( ) => {
const wrapper = mount ( < Input suffix = "Bamboo" value = { 1 } / > ) ;
expect ( wrapper ) . toBeTruthy ( ) ;
} ) ;
2018-12-26 22:34:29 +08:00
} ) ;