import _, { forEach, has } from 'lodash';
import React from 'react';
import { shallow, mount } from 'enzyme';
import assert from 'assert';
import { common } from '../../util/generic-tests';
import SplitHorizontal, {
SplitHorizontalTopPane,
SplitHorizontalBottomPane,
} from './SplitHorizontal';
import DragCaptureZone from '../DragCaptureZone/DragCaptureZone';
import { Motion } from 'react-motion';
import { MOSTLY_STABLE_DELAY } from '../../util/constants';
describe('SplitHorizontal', () => {
common(SplitHorizontal);
describe('render', () => {
it('should render an inner element with the top, bottom, and divider elements as children', () => {
const wrapper = shallow();
const motionWrapper = wrapper.find(Motion).shallow();
assert.equal(wrapper.find('.lucid-SplitHorizontal').length, 1);
assert.equal(
motionWrapper.find('.lucid-SplitHorizontal-inner').length,
1
);
assert.equal(
motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-TopPane'
).length,
1
);
assert.equal(
motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-Divider'
).length,
1
);
assert.equal(
motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-BottomPane'
).length,
1
);
});
it('should render expanded & collapsed', () => {
const wrapper = mount();
expect(wrapper).toMatchSnapshot();
expect(
wrapper.setProps({ isExpanded: false }).render()
).toMatchSnapshot();
});
});
describe('props', () => {
describe('isExpanded', () => {
let mountWrapper: any;
afterEach(() => {
if (mountWrapper) {
mountWrapper.unmount();
}
});
it('should default to true', () => {
const wrapper = shallow();
assert(wrapper.hasClass('lucid-SplitHorizontal-is-expanded'));
});
it('should apply the &-is-expanded css class when true', () => {
const wrapper = shallow();
assert(wrapper.hasClass('lucid-SplitHorizontal-is-expanded'));
});
it('should not apply the &-is-expanded css class when false [mostly stable]', (done) => {
mountWrapper = mount();
assert(!mountWrapper.hasClass('lucid-SplitHorizontal-is-expanded'));
_.delay(done, MOSTLY_STABLE_DELAY);
});
});
describe('isAnimated', () => {
let wrapper: any;
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
});
it('should default to false [mostly stable]', (done) => {
wrapper = mount();
_.delay(() => {
assert.equal(
wrapper.find(
'.lucid-SplitHorizontal.lucid-SplitHorizontal-is-animated'
).length,
0
);
done();
}, MOSTLY_STABLE_DELAY);
});
it('should apply the &-is-animated class when true, after initial render [mostly stable]', (done) => {
wrapper = mount();
_.delay(() => {
assert(
wrapper.render().hasClass('lucid-SplitHorizontal-is-animated')
);
done();
}, MOSTLY_STABLE_DELAY);
});
it('should not apply the &-is-animated class when false [mostly stable]', (done) => {
wrapper = mount();
_.delay(() => {
assert.equal(
wrapper.find(
'.lucid-SplitHorizontal.lucid-SplitHorizontal-is-animated'
).length,
0
);
done();
}, MOSTLY_STABLE_DELAY);
});
});
describe('collapseShift', () => {
let wrapper: any;
let mountTestDiv: any;
beforeEach(() => {
mountTestDiv = document.createElement('div');
document.body.appendChild(mountTestDiv);
});
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
if (mountTestDiv) {
mountTestDiv.parentNode.removeChild(mountTestDiv);
}
});
it('should translated by height - 64px when the bottom pane is primary [mostly stable]', (done) => {
wrapper = mount(
,
{ attachTo: mountTestDiv }
);
_.delay(() => {
const secondaryPaneDiv = mountTestDiv.querySelector(
'.lucid-SplitHorizontal-is-secondary'
);
const height = secondaryPaneDiv.getBoundingClientRect().height;
wrapper.update();
const slideAmount = wrapper.find(Motion).prop('style').slideAmount;
expect(slideAmount).toEqual(height - 64);
done();
}, MOSTLY_STABLE_DELAY);
});
it('should translated by height - 64px when the top pane is primary [mostly stable]', (done) => {
wrapper = mount(
,
{ attachTo: mountTestDiv }
);
_.delay(() => {
const secondaryPaneDiv = mountTestDiv.querySelector(
'.lucid-SplitHorizontal-is-secondary'
);
const height = secondaryPaneDiv.getBoundingClientRect().height;
wrapper.update();
const slideAmount = wrapper.find(Motion).prop('style').slideAmount;
expect(slideAmount).toEqual(height - 64);
done();
}, MOSTLY_STABLE_DELAY);
});
});
describe('onResizing', () => {
let wrapper: any;
let mountTestDiv: any;
beforeEach(() => {
mountTestDiv = document.createElement('div');
document.body.appendChild(mountTestDiv);
});
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
if (mountTestDiv) {
mountTestDiv.parentNode.removeChild(mountTestDiv);
}
});
it('should be called when the DragCaptureZone calls the onDrag event handler', () => {
const onResizing = jest.fn();
wrapper = mount(
,
{ attachTo: mountTestDiv }
);
const { onDragStart, onDrag, onDragEnd } = wrapper
.find(DragCaptureZone)
.props();
const lastArg = { event: {} };
onDragStart(lastArg);
onDrag({ dY: 122 }, lastArg);
onDragEnd({ dY: 123 }, lastArg);
expect(onResizing).toHaveBeenCalled();
const [firstArg, { props, event }] = _.last(onResizing.mock.calls);
expect(firstArg).toEqual(122);
expect(props).toEqual(wrapper.props());
expect(event).toEqual(lastArg.event);
});
});
describe('onResize', () => {
let wrapper: any;
let mountTestDiv: any;
beforeEach(() => {
mountTestDiv = document.createElement('div');
document.body.appendChild(mountTestDiv);
});
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
if (mountTestDiv) {
mountTestDiv.parentNode.removeChild(mountTestDiv);
}
});
it('should be called when the DragCaptureZone calls the onDragEnd event handler', () => {
const onResize = jest.fn();
wrapper = mount(
,
{ attachTo: mountTestDiv }
);
const { onDragStart, onDrag, onDragEnd } = wrapper
.find(DragCaptureZone)
.props();
const lastArg = { event: {} };
onDragStart(lastArg);
onDrag({ dY: 122 }, lastArg);
onDragEnd({ dY: 123 }, lastArg);
expect(onResize).toHaveBeenCalled();
const [firstArg, { props, event }] = _.last(onResize.mock.calls);
expect(firstArg).toEqual(123);
expect(props).toEqual(wrapper.props());
expect(event).toEqual(lastArg.event);
});
});
describe('root pass throughs', () => {
let wrapper: any;
const defaultProps = SplitHorizontal.defaultProps;
beforeEach(() => {
const props = {
...defaultProps,
isExpanded: false,
isAnimated: true,
collapseShift: 1,
TopPane:
post-ironic etsy roof party
,
BottomPane: heirloom street art church-key
,
Divider: 'D I V I D E R',
className: 'wut',
style: { marginRight: 10 },
initialState: { test: true },
callbackId: 1,
'data-testid': 10,
};
wrapper = shallow();
});
afterEach(() => {
wrapper.unmount();
});
it('passes through props not defined in `propTypes` to the root element.', () => {
const rootProps = wrapper.find('.lucid-SplitHorizontal').props();
expect(wrapper.first().prop(['className'])).toContain('wut');
expect(wrapper.first().prop(['style'])).toMatchObject({
marginRight: 10,
});
expect(wrapper.first().prop(['data-testid'])).toBe(10);
// 'className' and style are plucked from the pass through object
// but still appears becuase each one is also directly added to the root element as a prop
forEach(['className', 'data-testid', 'style', 'children'], (prop) => {
expect(has(rootProps, prop)).toBe(true);
});
});
it('omits the props defined in `propTypes` (plus, in addition, `initialState`, and `callbackId`) from the root element', () => {
const rootProps = wrapper.find('.lucid-SplitHorizontal').props();
forEach(
[
'isExpanded',
'isAnimated',
'onResizing',
'onResize',
'collapseShift',
'TopPane',
'BottomPane',
'Divider',
'onSelect',
'onToggle',
'initialState',
'callbackId',
],
(prop) => {
expect(has(rootProps, prop)).toBe(false);
}
);
});
});
});
describe('child components', () => {
describe('TopPane', () => {
it('should render children passed in', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const TopPane = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-TopPane'
);
assert.equal(
'Search Filters',
TopPane.text(),
'must render children passed in'
);
});
it('should set the bottom pane as secondary when the top pane is set to primary', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const BottomPane = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-BottomPane'
);
assert(
BottomPane.hasClass('lucid-SplitHorizontal-is-secondary'),
'must have the secondary className'
);
});
it('should pass thru the with to flexBasis', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const TopPane: any = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-TopPane'
);
assert.equal(
123,
TopPane.prop('style').flexBasis,
'must set the flexBasis to match the given height'
);
});
describe('TopPane pass throughs', () => {
let topPaneWrapper: any;
const topPaneDefaultProps = SplitHorizontalTopPane.defaultProps;
beforeEach(() => {
const props = {
...topPaneDefaultProps,
height: 321,
isPrimary: true,
className: 'wut',
initialState: { test: true },
callbackId: 1,
'data-testid': 10,
};
topPaneWrapper = mount(
Search Filters
);
});
afterEach(() => {
topPaneWrapper.unmount();
});
it('should pass through props not defined in the TopPane `propTypes`', () => {
const topPaneProps = topPaneWrapper
.find('.lucid-SplitHorizontal-TopPane')
.props();
expect(
topPaneWrapper
.find('.lucid-SplitHorizontal-TopPane')
.prop(['className'])
).toContain('wut');
expect(
topPaneWrapper
.find('.lucid-SplitHorizontal-TopPane')
.prop(['data-testid'])
).toBe(10);
forEach(['className', 'data-testid', 'style', 'children'], (prop) => {
expect(has(topPaneProps, prop)).toBe(true);
});
});
it('omits the props defined in TopPane `propTypes`, (plus, in addition, `initialState`, and `callbackId`) from the TopPane element', () => {
const topPaneProps = topPaneWrapper
.find('.lucid-SplitHorizontal-TopPane')
.props();
forEach(
['height', 'isPrimary', 'initialState', 'callbackId'],
(prop) => {
expect(has(topPaneProps, prop)).toBe(false);
}
);
});
});
});
describe('BottomPane', () => {
it('should render children passed in', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const BottomPane = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-BottomPane'
);
assert.equal(
'Search Filters',
BottomPane.text(),
'must render children passed in'
);
});
it('should set the top pane as secondary when the bottom pane is set to primary', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const BottomPane = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-TopPane'
);
assert(
BottomPane.hasClass('lucid-SplitHorizontal-is-secondary'),
'must have the secondary className'
);
});
it('should pass thru the with to flexBasis', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const BottomPane: any = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-BottomPane'
);
assert.equal(
123,
BottomPane.prop('style').flexBasis,
'must set the flexBasis to match the given height'
);
});
describe('BottomPane pass throughs', () => {
let bottomPaneWrapper: any;
const bottomPaneDefaultProps = SplitHorizontalBottomPane.defaultProps;
beforeEach(() => {
const props = {
...bottomPaneDefaultProps,
height: 321,
isPrimary: true,
className: 'wut',
initialState: { test: true },
callbackId: 1,
'data-testid': 10,
};
bottomPaneWrapper = mount(
Search Filters
);
});
afterEach(() => {
bottomPaneWrapper.unmount();
});
it('should pass through props not defined in the BottomPane `propTypes`', () => {
const bottomPaneProps = bottomPaneWrapper
.find('.lucid-SplitHorizontal-BottomPane')
.props();
expect(
bottomPaneWrapper
.find('.lucid-SplitHorizontal-BottomPane')
.prop(['className'])
).toContain('wut');
expect(
bottomPaneWrapper
.find('.lucid-SplitHorizontal-BottomPane')
.prop(['data-testid'])
).toBe(10);
forEach(['className', 'data-testid', 'style', 'children'], (prop) => {
expect(has(bottomPaneProps, prop)).toBe(true);
});
});
it('omits the props defined in BottomPane `propTypes`, (plus, in addition, `initialState`, and `callbackId`) from the TopPane element', () => {
const bottomPaneProps = bottomPaneWrapper
.find('.lucid-SplitHorizontal-BottomPane')
.props();
forEach(
['height', 'isPrimary', 'initialState', 'callbackId'],
(prop) => {
expect(has(bottomPaneProps, prop)).toBe(false);
}
);
});
});
});
describe('Divider', () => {
it('should render children passed in', () => {
const wrapper = shallow(
Resize
);
const motionWrapper = wrapper.find(Motion).shallow();
const dividerWrapper = motionWrapper.find(
'.lucid-SplitHorizontal-inner > .lucid-SplitHorizontal-Divider'
);
assert.equal(
'Resize',
dividerWrapper.children().text(),
'must render children passed in'
);
});
});
});
});