diff --git a/package.json b/package.json index 2531d34..6d6b02b 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "@types/react-dom": "^16.0.11", "@types/warning": "^3.0.0", "@umijs/fabric": "^1.1.9", + "enzyme": "^3.11.0", "enzyme-to-json": "^3.1.4", "father": "^2.13.6", "lodash.debounce": "^4.0.8", diff --git a/src/Mentions.tsx b/src/Mentions.tsx index fd36f42..9123ec6 100644 --- a/src/Mentions.tsx +++ b/src/Mentions.tsx @@ -72,11 +72,14 @@ class Mentions extends React.Component { rows: 1, }; - public static getDerivedStateFromProps(props: MentionsProps, prevState: MentionsState) { + public static getDerivedStateFromProps( + props: MentionsProps, + prevState: MentionsState, + ) { const newState: Partial = {}; if ('value' in props && props.value !== prevState.value) { - newState.value = props.value; + newState.value = props.value || ''; } return newState; @@ -115,7 +118,9 @@ class Mentions extends React.Component { } }; - public onChange: React.ChangeEventHandler = ({ target: { value } }) => { + public onChange: React.ChangeEventHandler = ({ + target: { value }, + }) => { this.triggerChange(value); }; @@ -166,18 +171,23 @@ class Mentions extends React.Component { const { prefix = '', onSearch, validateSearch } = this.props; const target = event.target as HTMLTextAreaElement; const selectionStartText = getBeforeSelectionText(target); - const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex( - selectionStartText, - prefix, - ); + const { + location: measureIndex, + prefix: measurePrefix, + } = getLastMeasureIndex(selectionStartText, prefix); // Skip if match the white key list - if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) { + if ( + [KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== + -1 + ) { return; } if (measureIndex !== -1) { - const measureText = selectionStartText.slice(measureIndex + measurePrefix.length); + const measureText = selectionStartText.slice( + measureIndex + measurePrefix.length, + ); const validateMeasure: boolean = validateSearch(measureText, this.props); const matchOption = !!this.getOptions(measureText).length; @@ -295,7 +305,11 @@ class Mentions extends React.Component { return list; }; - public startMeasure(measureText: string, measurePrefix: string, measureLocation: number) { + public startMeasure( + measureText: string, + measurePrefix: string, + measureLocation: number, + ) { this.setState({ measuring: true, measureText, @@ -325,7 +339,13 @@ class Mentions extends React.Component { } public render() { - const { value, measureLocation, measurePrefix, measuring, activeIndex } = this.state; + const { + value, + measureLocation, + measurePrefix, + measuring, + activeIndex, + } = this.state; const { prefixCls, placement, diff --git a/tests/Mentions.spec.jsx b/tests/Mentions.spec.jsx index e31067c..d66cf80 100644 --- a/tests/Mentions.spec.jsx +++ b/tests/Mentions.spec.jsx @@ -32,7 +32,11 @@ describe('Mentions', () => { it('not lose focus if click on dropdown', () => { const onBlur = jest.fn(); - const wrapper = createMentions({ autoFocus: true, defaultValue: '@', onBlur }); + const wrapper = createMentions({ + autoFocus: true, + defaultValue: '@', + onBlur, + }); // Inject to trigger measure wrapper.instance().startMeasure('b', '@', 1); @@ -45,14 +49,14 @@ describe('Mentions', () => { wrapper.find('textarea').simulate('focus'); // This is not good but code focus not work in simulate jest.runAllTimers(); - expect(onBlur).not.toBeCalled(); + expect(onBlur).not.toHaveBeenCalled(); }); it('focus', () => { const onFocus = jest.fn(); const wrapper = createMentions({ onFocus }); wrapper.find('textarea').simulate('focus'); - expect(onFocus).toBeCalled(); + expect(onFocus).toHaveBeenCalled(); }); it('blur', () => { @@ -60,7 +64,7 @@ describe('Mentions', () => { const wrapper = createMentions({ onBlur }); wrapper.find('textarea').simulate('blur'); jest.runAllTimers(); - expect(onBlur).toBeCalled(); + expect(onBlur).toHaveBeenCalled(); }); it('focus() & blur()', () => { @@ -69,7 +73,9 @@ describe('Mentions', () => { expect(document.activeElement).toBe(wrapper.find('textarea').instance()); wrapper.instance().blur(); - expect(document.activeElement).not.toBe(wrapper.find('textarea').instance()); + expect(document.activeElement).not.toBe( + wrapper.find('textarea').instance(), + ); }); }); @@ -85,6 +91,9 @@ describe('Mentions', () => { wrapper.setProps({ value: 'cat' }); expect(wrapper.find('textarea').props().value).toBe('cat'); + + wrapper.setProps({ value: undefined }); + expect(wrapper.find('textarea').props().value).toBe(''); }); it('onChange', () => { @@ -93,7 +102,7 @@ describe('Mentions', () => { wrapper.find('textarea').simulate('change', { target: { value: 'bamboo' }, }); - expect(onChange).toBeCalledWith('bamboo'); + expect(onChange).toHaveBeenCalledWith('bamboo'); }); }); @@ -105,7 +114,9 @@ describe('Mentions', () => { }); it('function', () => { - const wrapper = createMentions({ filterOption: (_, { value }) => value.includes('a') }); + const wrapper = createMentions({ + filterOption: (_, { value }) => value.includes('a'), + }); simulateInput(wrapper, '@notExist'); expect(wrapper.find('DropdownMenu').props().options.length).toBe(2); });