import _ from 'lodash';
import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme';
import { common, controls } from '../../util/generic-tests';
import * as KEYCODE from '../../constants/key-code';
import assert from 'assert';
import TextField from './TextField';
import { MOSTLY_STABLE_DELAY } from '../../util/constants';
const defaultProps = TextField.defaultProps;
describe('TextField', () => {
common(TextField);
controls(TextField, {
callbackName: 'onChange',
controlSelector: '.lucid-TextField',
eventType: 'change',
additionalProps: {
value: '123',
},
});
describe('props', () => {
it('should pass though some props to its underlying textarea or input element', () => {
//const onBlurFunc = () => {};
const style = { margin: 10 };
const wrapper = shallow(
);
assert.strictEqual(wrapper.find('input').prop('disabled'), true);
assert.strictEqual(wrapper.find('input').prop('style'), style);
assert.strictEqual(wrapper.find('input').prop('rows'), 10);
assert.strictEqual(wrapper.find('input').prop('value'), 'test');
});
it('should not pass though several props to its underlying textarea or input element', () => {
const nonFinalProps = [
'onChangeDebounced',
'onSubmit',
'debounceLevel',
'lazyLevel',
'initialState',
'callbackId',
'children',
];
const onChangeDebounced = () => {};
const onSubmit = () => {};
const wrapper = shallow(
);
nonFinalProps.forEach((nonFinalProp) => {
assert.strictEqual(wrapper.find('input').prop(nonFinalProp), undefined);
});
});
});
it('should correctly debounce onChangeDebounced [mostly stable]', (done) => {
const event = {
target: {
value: 'yolo',
},
persist: _.noop,
};
const onChangeDebounced = sinon.spy();
const wrapper = shallow(
);
wrapper.find('input').simulate('change', event);
assert(onChangeDebounced.notCalled);
_.delay(() => {
assert(onChangeDebounced.called);
assert.strictEqual(onChangeDebounced.args[0][0], 'yolo');
done();
}, MOSTLY_STABLE_DELAY);
});
it('should accept a new `value` prop immediately if the user has not typed anything recently', () => {
const wrapper = shallow();
wrapper.setProps({ value: 'end' });
assert.strictEqual(wrapper.state('value'), 'end');
});
// This test had value, but it's been known to be flaky.
it('should postpone state changes if the user recently typed something in [mostly stable]', (done) => {
const wrapper = shallow(
);
// Order of operations is crucial for this test
// 1) User starts typing something in
// 2) New props comes in from above while the user is typing
// 3) The props shouldn't take effect until the lazyLevel has elapsed
assert.strictEqual(wrapper.state('value'), 'start');
wrapper
.find('input')
.simulate('change', { target: { value: 'user typed' } });
wrapper.setProps({ value: 'end' });
assert.strictEqual(wrapper.state('value'), 'user typed');
_.delay(() => {
assert.strictEqual(wrapper.state('value'), 'end');
done();
}, MOSTLY_STABLE_DELAY);
});
it('should callback onSubmit when the user hits enter', () => {
const onSubmit = sinon.spy();
const wrapper = shallow(
);
wrapper.find('input').simulate('keydown', {
keyCode: KEYCODE.Enter,
target: {
value: 'yolo',
},
});
assert(onSubmit.called);
assert.strictEqual(onSubmit.args[0][0], 'yolo');
});
it('should callback onBlur when the leaves input', () => {
const onBlur = sinon.spy();
const wrapper = shallow();
wrapper.find('input').simulate('blur', {
target: {
value: 'yolo',
},
});
assert(onBlur.calledOnce);
assert.strictEqual(onBlur.args[0][0], 'yolo');
});
it('should respect isDisabled', () => {
const wrapper = shallow();
assert.strictEqual(wrapper.find('input').prop('disabled'), true);
});
it('should respect isMultiLine', () => {
const wrapper = shallow();
assert.strictEqual(wrapper.find('textarea').length, 1);
assert.strictEqual(
wrapper.find('.lucid-TextField-is-multi-line').length,
1
);
});
it('should respect onKeyDown if passed in', () => {
const onKeyDown = jest.fn();
const wrapper = shallow(
);
wrapper.find('input').simulate('keydown', {});
expect(onKeyDown).toBeCalled();
});
it('should call `event.persist` for `onChangeDebounced`', () => {
const event = {
target: {
value: 'yolo',
},
persist: sinon.spy(),
};
const onChangeDebounced = () => {}; // intentionally not _.noop
const wrapper = shallow(
);
assert(event.persist.notCalled);
wrapper.find('input').simulate('change', event);
assert(event.persist.called);
});
it('should flush the `onChangeDebounced`-handled event before blurring', () => {
const onBlur = sinon.spy();
const internalChangeSpy = sinon.spy();
const onChangeDebounced = () => {
assert(onBlur.notCalled);
internalChangeSpy();
};
const event = {
target: {
value: 'foo',
},
persist: () => {},
};
const wrapper = shallow(
);
wrapper.find('input').simulate('change', event);
assert(internalChangeSpy.notCalled);
wrapper.find('input').simulate('blur');
assert(internalChangeSpy.calledOnce);
assert(onBlur.calledOnce);
});
it('should flush the `onChangeDebounced`-handled event before submitting', () => {
const onSubmit = sinon.spy();
const internalChangeSpy = sinon.spy();
const onChangeDebounced = () => {
assert(onSubmit.notCalled);
internalChangeSpy();
};
const event = {
target: {
value: 'foo',
},
persist: () => {},
};
const wrapper = shallow(
);
wrapper.find('input').simulate('change', event);
assert(internalChangeSpy.notCalled);
wrapper.find('input').simulate('keydown', {
keyCode: KEYCODE.Enter,
target: {
value: 'foo',
},
});
assert(internalChangeSpy.calledOnce);
assert(onSubmit.calledOnce);
});
});