|
|
@@ -1,22 +1,22 @@
|
|
|
import TextArea from '../textarea';
|
|
|
import Icon from '../../icons/index';
|
|
|
import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
|
|
|
+import truncateValue from '../../../semi-foundation/input/util/truncateValue';
|
|
|
import GraphemeSplitter from 'grapheme-splitter';
|
|
|
import { isString } from 'lodash';
|
|
|
|
|
|
function getValueLength(str) {
|
|
|
- if (isString(str)) {
|
|
|
- const splitter = new GraphemeSplitter();
|
|
|
- return splitter.countGraphemes(str);
|
|
|
- } else {
|
|
|
- return -1;
|
|
|
- }
|
|
|
+ if (isString(str)) {
|
|
|
+ const splitter = new GraphemeSplitter();
|
|
|
+ return splitter.countGraphemes(str);
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
describe('TextArea', () => {
|
|
|
-
|
|
|
it('TextArea with custom className & style', () => {
|
|
|
- const wrapper = mount(<TextArea className='test' style={{ color: 'red' }} />);
|
|
|
+ const wrapper = mount(<TextArea className="test" style={{ color: 'red' }} />);
|
|
|
expect(wrapper.hasClass('test')).toEqual(true);
|
|
|
expect(wrapper.find('div.test')).toHaveStyle('color', 'red');
|
|
|
});
|
|
|
@@ -39,7 +39,7 @@ describe('TextArea', () => {
|
|
|
textArea.find('textarea').simulate('change', event);
|
|
|
expect(spyOnChange.calledOnce).toBe(true);
|
|
|
expect(spyOnChange.calledWithMatch(textAreaValue)).toBe(true);
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
it('TextArea show maxCount', () => {
|
|
|
const textarea = mount(<TextArea maxCount={10} />);
|
|
|
@@ -54,21 +54,24 @@ describe('TextArea', () => {
|
|
|
const textarea = mount(<TextArea placeholder={placeholderText} />);
|
|
|
let textareaDom = textarea.find('textarea');
|
|
|
expect(textareaDom.props().placeholder).toEqual(placeholderText);
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
it('TextArea disabled', () => {
|
|
|
const textarea = mount(<TextArea disabled />);
|
|
|
let textareaDom = textarea.find(`textarea.${BASE_CLASS_PREFIX}-input-textarea-disabled`);
|
|
|
expect(textareaDom.props().disabled).toEqual(true);
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
it('TextArea showClear / onClear', () => {
|
|
|
- const spyOnClear = sinon.spy(()=>{});
|
|
|
- const textarea = mount(<TextArea showClear defaultValue='123' onClear={spyOnClear}/>);
|
|
|
- textarea.simulate('mouseEnter', {}).find(`.${BASE_CLASS_PREFIX}-input-clearbtn`).simulate('click');
|
|
|
+ const spyOnClear = sinon.spy(() => {});
|
|
|
+ const textarea = mount(<TextArea showClear defaultValue="123" onClear={spyOnClear} />);
|
|
|
+ textarea
|
|
|
+ .simulate('mouseEnter', {})
|
|
|
+ .find(`.${BASE_CLASS_PREFIX}-input-clearbtn`)
|
|
|
+ .simulate('click');
|
|
|
expect(spyOnClear.calledOnce).toBe(true);
|
|
|
expect(textarea.find(`.${BASE_CLASS_PREFIX}-input-textarea`).getDOMNode().textContent).toEqual('');
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
// TODO
|
|
|
// it('TextArea autosize', () => {
|
|
|
@@ -95,7 +98,7 @@ describe('TextArea', () => {
|
|
|
console.log(e);
|
|
|
};
|
|
|
let spyOnChange = sinon.spy(onChange);
|
|
|
- const textArea = mount(<TextArea onChange={spyOnChange} value='semi' />);
|
|
|
+ const textArea = mount(<TextArea onChange={spyOnChange} value="semi" />);
|
|
|
const textareaDom = textArea.find('textarea');
|
|
|
expect(textareaDom.instance().value).toEqual('semi');
|
|
|
let newValue = 'vita lemon';
|
|
|
@@ -125,10 +128,12 @@ describe('TextArea', () => {
|
|
|
let event1 = { target: { value: inputValue1 } };
|
|
|
|
|
|
let onChange = value => {
|
|
|
- console.log(value);
|
|
|
+ console.log(value);
|
|
|
};
|
|
|
let spyOnChange = sinon.spy(onChange);
|
|
|
- const textArea = mount(<TextArea onChange={spyOnChange} minLength={minLength} getValueLength={getValueLength} />);
|
|
|
+ const textArea = mount(
|
|
|
+ <TextArea onChange={spyOnChange} minLength={minLength} getValueLength={getValueLength} />
|
|
|
+ );
|
|
|
const textAreaDom = textArea.find('textarea');
|
|
|
|
|
|
textAreaDom.simulate('change', event);
|
|
|
@@ -138,7 +143,7 @@ describe('TextArea', () => {
|
|
|
|
|
|
textAreaDom.simulate('change', event1);
|
|
|
expect(spyOnChange.calledWithMatch(textAreaDom)).toBe(true);
|
|
|
- expect(textAreaDom.instance().minLength).toEqual(minLength)
|
|
|
+ expect(textAreaDom.instance().minLength).toEqual(minLength);
|
|
|
});
|
|
|
|
|
|
it('test maxLength + truncateValue', () => {
|
|
|
@@ -149,7 +154,9 @@ describe('TextArea', () => {
|
|
|
};
|
|
|
|
|
|
let spyOnChange = sinon.spy(onChange);
|
|
|
- const textArea = mount(<TextArea onChange={spyOnChange} maxLength={maxLength} getValueLength={getValueLength} />);
|
|
|
+ const textArea = mount(
|
|
|
+ <TextArea onChange={spyOnChange} maxLength={maxLength} getValueLength={getValueLength} />
|
|
|
+ );
|
|
|
const textAreaDom = textArea.find('textarea');
|
|
|
textAreaDom.simulate('change', event);
|
|
|
expect(spyOnChange.calledOnce).toBe(true);
|
|
|
@@ -157,7 +164,7 @@ describe('TextArea', () => {
|
|
|
}
|
|
|
|
|
|
const testCases = [
|
|
|
- // 自定义valueLength
|
|
|
+ // 自定义valueLength
|
|
|
['Semi', 5, getValueLength, 'Semi'],
|
|
|
['Semi Design', 4, getValueLength, 'Semi'],
|
|
|
['💖💖💖💖💖💖💖💖💖💖👨👩👧👦', 10, getValueLength, '💖💖💖💖💖💖💖💖💖💖'],
|
|
|
@@ -168,5 +175,53 @@ describe('TextArea', () => {
|
|
|
for (let [value, length, fc, result] of testCases) {
|
|
|
expect(truncateValue(value, length, fc)).toBe(result);
|
|
|
}
|
|
|
- })
|
|
|
-})
|
|
|
+ });
|
|
|
+
|
|
|
+ it('test truncateValue', () => {
|
|
|
+ expect(truncateValue({ value: 'Semi Design', getValueLength, maxLength: 4 })).toBe('Semi');
|
|
|
+ expect(truncateValue({ value: 'Semi', getValueLength, maxLength: 4 })).toBe('Semi');
|
|
|
+ expect(truncateValue({ value: 'Se', getValueLength, maxLength: 1 })).toBe('S');
|
|
|
+ expect(truncateValue({ value: 'S', getValueLength, maxLength: 2 })).toBe('S');
|
|
|
+ expect(truncateValue({ value: '', getValueLength, maxLength: 2 })).toBe('');
|
|
|
+
|
|
|
+ expect(truncateValue({ value: '💖💖💖💖💖', getValueLength, maxLength: 4 })).toBe('💖💖💖💖');
|
|
|
+ expect(truncateValue({ value: '💖💖💖💖', getValueLength, maxLength: 4 })).toBe('💖💖💖💖');
|
|
|
+ expect(truncateValue({ value: '💖', getValueLength, maxLength: 1 })).toBe('💖');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('test truncateValue function call time', () => {
|
|
|
+ function truncateValue(inputValue, maxLength) {
|
|
|
+ let event = { target: { value: inputValue } };
|
|
|
+
|
|
|
+ let spyTruncateValue = sinon.spy((str) => {
|
|
|
+ console.log('call getValueLength', str);
|
|
|
+ if (isString(str)) {
|
|
|
+ const splitter = new GraphemeSplitter();
|
|
|
+ return splitter.countGraphemes(str);
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ const textArea = mount(
|
|
|
+ <TextArea maxLength={maxLength} getValueLength={spyTruncateValue} />
|
|
|
+ );
|
|
|
+ const textAreaDom = textArea.find('textarea');
|
|
|
+ textAreaDom.simulate('change', event);
|
|
|
+ // 超出判断一次,截断判断 LogN 次
|
|
|
+ const expectedValue = 1 + Math.ceil(Math.log2(inputValue.length));
|
|
|
+ console.log('expectedValue', expectedValue);
|
|
|
+ expect(spyTruncateValue.callCount).toBeLessThanOrEqual(expectedValue);
|
|
|
+ return textAreaDom.instance().value;
|
|
|
+ }
|
|
|
+
|
|
|
+ const testCases = [
|
|
|
+ ['Semi Design', 4],
|
|
|
+ [Array.from({ length: 1000 }).fill('👨👩👧👦').join(''), 500],
|
|
|
+ ];
|
|
|
+
|
|
|
+ for (let [value, length, expectedCalcTimes] of testCases) {
|
|
|
+ truncateValue(value, length, expectedCalcTimes);
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|