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 SplitVertical from './SplitVertical';
import DragCaptureZone from '../DragCaptureZone/DragCaptureZone';
import { Motion } from 'react-motion';
import { MOSTLY_STABLE_DELAY } from '../../util/constants';
describe('SplitVertical', () => {
common(SplitVertical);
describe('render', () => {
it('should render an inner element with the left, right, and divider elements as children', () => {
const wrapper = shallow();
const motionWrapper = wrapper.find(Motion).shallow();
assert.equal(wrapper.find('.lucid-SplitVertical').length, 1);
assert.equal(motionWrapper.find('.lucid-SplitVertical-inner').length, 1);
assert.equal(
motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-LeftPane'
).length,
1
);
assert.equal(
motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-Divider'
).length,
1
);
assert.equal(
motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-RightPane'
).length,
1
);
});
it('should render expanded & collapsed', () => {
const wrapper = mount();
expect(wrapper).toMatchSnapshot();
expect(
wrapper.setProps({ isExpanded: false }).render()
).toMatchSnapshot();
});
});
describe('pass throughs', () => {
describe('root pass throughs', () => {
let wrapper: any;
beforeEach(() => {
const props = {
...SplitVertical.defaultProps,
children: [
,
,
],
collapseShift: 1,
isResizeable: false,
className: 'wut',
style: { marginRight: 10 },
initialState: { test: true },
callbackId: 1,
'data-testid': 10,
};
wrapper = mount();
});
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
});
it('passes through props not defined in `propTypes` to the root element.', () => {
const rootProps = wrapper.find('.lucid-SplitVertical').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-SplitVertical').props();
forEach(
[
'isExpanded',
'isAnimated',
'onResizing',
'isResizeable',
'onResize',
'collapseShift',
'RightPane',
'LeftPane',
'Divider',
'initialState',
'callbackId',
],
(prop) => {
expect(has(rootProps, prop)).toBe(false);
}
);
});
it('passes through and omits the correct props for the `SplitVertical.LeftPane`.', () => {
const leftPaneProps = wrapper
.find('.lucid-SplitVertical-LeftPane')
.props();
// included props
forEach(['className', 'style', 'data-testid', 'children'], (prop) => {
expect(has(leftPaneProps, prop)).toBe(true);
});
// excluded props
forEach(
['isPrimary', 'width', 'callbackId', 'initialState'],
(prop) => {
expect(has(leftPaneProps, prop)).toBe(false);
}
);
});
it('passes through and omits the correct props for the `SplitVertical.RightPane`.', () => {
const rightPaneProps = wrapper
.find('.lucid-SplitVertical-RightPane')
.props();
// included props
forEach(['className', 'style', 'data-testid', 'children'], (prop) => {
expect(has(rightPaneProps, prop)).toBe(true);
});
// excluded props
forEach(
['isPrimary', 'width', 'initialState', 'callbackId'],
(prop) => {
expect(has(rightPaneProps, prop)).toBe(false);
}
);
});
});
describe('DragCaptureZone pass throughs: dividerProps', () => {
let wrapper: any;
beforeEach(() => {
const props = {
...SplitVertical.defaultProps,
children: (
),
collapseShift: 1,
isResizeable: true, // renders the resizable Divider
className: 'wut',
style: { marginRight: 10 },
initialState: { test: true },
callbackId: 1,
'data-testid': 10,
};
wrapper = mount();
});
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
});
it('passes through and omits the correct props for the resizable `SplitVerticalDivider` child element.', () => {
const dividerProps = wrapper
.find('DragCaptureZone.lucid-SplitVertical-Divider')
.props();
expect(
wrapper
.find('DragCaptureZone.lucid-SplitVertical-Divider')
.prop(['className'])
).toContain('test Divider');
expect(
wrapper
.find('DragCaptureZone.lucid-SplitVertical-Divider')
.prop(['style'])
).toMatchObject({
marginLeft: 10,
});
expect(
wrapper
.find('DragCaptureZone.lucid-SplitVertical-Divider')
.prop(['data-testid'])
).toBe(11);
expect(
wrapper
.find('DragCaptureZone.lucid-SplitVertical-Divider')
.prop(['callbackId'])
).toBe(2);
// callbackId is passed through becuase the divider is a custom React element
forEach(
['className', 'data-testid', 'style', 'children', 'callbackId'],
(prop) => {
expect(has(dividerProps, prop)).toBe(true);
}
);
// note initial state is explicitly omitted in the code,
// and it also is not permitted as a prop on `SplitVertical.Divider`
forEach(['initialState'], (prop) => {
expect(has(dividerProps, prop)).toBe(false);
});
});
});
describe('Not resizeable dividerProps', () => {
let wrapper: any;
beforeEach(() => {
const props = {
...SplitVertical.defaultProps,
children: (
),
collapseShift: 1,
isResizeable: false, // renders the not resizeable Divider
className: 'wut',
style: { marginRight: 10 },
initialState: { test: true },
callbackId: 1,
'data-testid': 10,
};
wrapper = mount();
});
afterEach(() => {
if (wrapper) {
wrapper.unmount();
}
});
it('passes through and omits the correct props for the resizable `SplitVerticalDivider` child element.', () => {
const dividerProps = wrapper
.find('div.lucid-SplitVertical-Divider')
.props();
expect(
wrapper.find('div.lucid-SplitVertical-Divider').prop(['className'])
).toContain('test Divider');
expect(
wrapper.find('div.lucid-SplitVertical-Divider').prop(['style'])
).toMatchObject({
marginLeft: 10,
});
expect(
wrapper.find('div.lucid-SplitVertical-Divider').prop(['data-testid'])
).toBe(11);
// included props
forEach(['className', 'data-testid', 'style', 'children'], (prop) => {
expect(has(dividerProps, prop)).toBe(true);
});
// excluded props
forEach(['initialState', 'callbackId'], (prop) => {
expect(has(dividerProps, prop)).toBe(false);
});
});
});
});
describe('props', () => {
describe('isExpanded', () => {
let mountWrapper: any;
afterEach(() => {
if (mountWrapper) {
mountWrapper.unmount();
}
});
it('should default to true', () => {
const wrapper = shallow();
assert(wrapper.hasClass('lucid-SplitVertical-is-expanded'));
});
it('should apply the &-is-expanded css class when true', () => {
const wrapper = shallow();
assert(wrapper.hasClass('lucid-SplitVertical-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-SplitVertical.lucid-SplitVertical-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(() => {
wrapper.update();
assert.equal(
wrapper.find('.lucid-SplitVertical.lucid-SplitVertical-is-animated')
.length,
1
);
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-SplitVertical.lucid-SplitVertical-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 width - 64px when the right pane is primary [mostly stable]', (done) => {
wrapper = mount(
,
{ attachTo: mountTestDiv }
);
_.delay(() => {
const secondaryPaneDiv = mountTestDiv.querySelector(
'.lucid-SplitVertical-is-secondary'
);
const width = secondaryPaneDiv.getBoundingClientRect().width;
wrapper.update();
const slideAmount = wrapper.find(Motion).prop('style').slideAmount;
expect(slideAmount).toEqual(width - 64);
done();
}, MOSTLY_STABLE_DELAY);
});
it('should translated by width - 64px when the left pane is primary [mostly stable]', (done) => {
wrapper = mount(
,
{ attachTo: mountTestDiv }
);
_.delay(() => {
const secondaryPaneDiv = mountTestDiv.querySelector(
'.lucid-SplitVertical-is-secondary'
);
const width = secondaryPaneDiv.getBoundingClientRect().width;
wrapper.update();
const slideAmount = wrapper.find(Motion).prop('style').slideAmount;
assert.equal(
width - 64,
slideAmount,
'must be translated by width - 64px'
);
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 width = 100;
const dX = 122;
const onResizing = jest.fn();
wrapper = mount(
foo
bar
,
{ attachTo: mountTestDiv }
);
const { onDragStart, onDrag, onDragEnd } = wrapper
.find(DragCaptureZone)
.props();
const lastArg = { event: {} };
onDragStart(lastArg);
onDrag({ dX: dX }, lastArg);
onDragEnd({ dX: dX + 1 }, lastArg);
expect(onResizing).toHaveBeenCalled();
const [firstArg, { props, event }] = _.last(onResizing.mock.calls);
expect(firstArg).toEqual(dX);
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.exists()) {
wrapper.unmount();
}
if (mountTestDiv) {
mountTestDiv.parentNode.removeChild(mountTestDiv);
}
});
it('should be called when the DragCaptureZone calls the onDragEnd event handler', () => {
const width = 100;
const dX = 122;
const onResize = jest.fn();
wrapper = mount(
foo
bar
,
{ attachTo: mountTestDiv }
);
const { onDragStart, onDrag, onDragEnd } = wrapper
.find(DragCaptureZone)
.props();
const lastArg = { event: {} };
onDragStart(lastArg);
onDrag({ dX: dX }, lastArg);
onDragEnd({ dX: dX + 1 }, lastArg);
expect(onResize).toHaveBeenCalled();
const [firstArg, { props, event }] = _.last(onResize.mock.calls);
expect(firstArg).toEqual(dX + 1);
expect(props).toEqual(wrapper.props());
expect(event).toEqual(lastArg.event);
});
describe('isResizeable', () => {
it('shoult set -is-resizeable class on divider', () => {
const wrapper = shallow();
const dividerDivWrapper = wrapper
.find(Motion)
.shallow()
.find(DragCaptureZone)
.shallow({ disableLifecycleMethods: true })
.first();
assert(
dividerDivWrapper.hasClass(
'lucid-SplitVertical-Divider-is-resizeable'
)
);
});
it('should not set -is-resizeable class on divider', () => {
const wrapper = shallow();
const motionWrapper = wrapper.find(Motion).shallow();
assert(
!motionWrapper
.find('.lucid-SplitVertical-Divider')
.hasClass('lucid-SplitVertical-Divider-is-resizeable')
);
});
});
});
});
describe('child components', () => {
describe('LeftPane', () => {
it('should render children passed in', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const LeftPane = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-LeftPane'
);
assert.equal(
'Search Filters',
LeftPane.text(),
'must render children passed in'
);
});
it('should set the right pane as secondary when the left pane is set to primary', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const RightPane = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-RightPane'
);
assert(
RightPane.hasClass('lucid-SplitVertical-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 LeftPane: any = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-LeftPane'
);
assert.equal(
123,
LeftPane.prop('style').flexBasis,
'must set the flexBasis to match the given width'
);
});
});
describe('RightPane', () => {
it('should render children passed in', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const RightPane = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-RightPane'
);
assert.equal(
'Search Filters',
RightPane.text(),
'must render children passed in'
);
});
it('should set the left pane as secondary when the right pane is set to primary', () => {
const wrapper = shallow(
Search Filters
);
const motionWrapper = wrapper.find(Motion).shallow();
const LeftPane = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-LeftPane'
);
assert(
LeftPane.hasClass('lucid-SplitVertical-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 RightPane: any = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-RightPane'
);
assert.equal(
123,
RightPane.prop('style').flexBasis,
'must set the flexBasis to match the given width'
);
});
});
describe('Divider', () => {
it('should render children passed in', () => {
const wrapper = shallow(
Resize
);
const motionWrapper = wrapper.find(Motion).shallow();
const dividerWrapper = motionWrapper.find(
'.lucid-SplitVertical-inner > .lucid-SplitVertical-Divider'
);
assert.equal(
'Resize',
dividerWrapper.children().text(),
'must render children passed in'
);
});
});
});
});