Skip to content

Commit

Permalink
test: add unit tests for SplitPane
Browse files Browse the repository at this point in the history
  • Loading branch information
mortalYoung committed Nov 18, 2021
1 parent f7af6ef commit c24d7d3
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/components/split/SplitPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ const SplitPane = ({

let count = 0;
let restSize = rect[getSplitSizeName().sizeName];

const nextRes = res.map((size) => {
// convert percent and px to absolute number
// count the auto number
Expand Down Expand Up @@ -238,16 +239,18 @@ const SplitPane = ({

const rect = wrapper.current!.getBoundingClientRect();
let restSize = rect[getSplitSizeName().sizeName];
let count = 0;
const wipSizes = sizes.map((size, index) => {
if (stratygies[index] === 'keep') {
restSize = restSize - size;
return size;
}
count += 1;
return 'pave';
});

return wipSizes.map((size) =>
size === 'pave' ? restSize : size
size === 'pave' ? restSize / count : size
);
});
}, 150),
Expand All @@ -270,11 +273,7 @@ const SplitPane = ({
}
const res: boolean[] = [];
for (let index = 0; index < childrenKey.length; index++) {
if (typeof propAllowResize[index] === 'boolean') {
res.push(propAllowResize[index]);
} else {
res.push(true);
}
res.push(propAllowResize[index]);
}
if (isEqual(res, allowResize)) {
return allowResize;
Expand All @@ -290,6 +289,7 @@ const SplitPane = ({
const size = this.sum + (sizes[paneIndex - 1] || 0);
// @ts-ignore
this.sum = size;

return (
<Pane
key={paneIndex}
Expand Down
83 changes: 83 additions & 0 deletions src/components/split/__tests__/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Test The SplitPane Component Match Snapshot 1`] = `
<DocumentFragment>
<div
class="mo-split"
>
<div
class="mo-split__sash"
>
<div
class="mo-split__sash__item mo-split__sash__item--vertical"
style="width: 4px; left: -2px;"
/>
<div
class="mo-split__sash__item mo-split__sash__item--vertical"
style="width: 4px; left: 18px;"
/>
</div>
<div
class="mo-split__pane"
>
<div
class="mo-split__pane__item mo-split__pane__item--visible"
style="left: 0px; width: 20px;"
>
<div>
1
</div>
</div>
<div
class="mo-split__pane__item mo-split__pane__item--visible"
style="left: 20px; width: 20px;"
>
<div>
2
</div>
</div>
</div>
</div>
</DocumentFragment>
`;

exports[`Test The SplitPane Component Match Snapshot in horizontal 1`] = `
<DocumentFragment>
<div
class="mo-split"
>
<div
class="mo-split__sash"
>
<div
class="mo-split__sash__item mo-split__sash__item--horizontal"
style="height: 4px; top: -2px;"
/>
<div
class="mo-split__sash__item mo-split__sash__item--horizontal"
style="height: 4px; top: 18px;"
/>
</div>
<div
class="mo-split__pane"
>
<div
class="mo-split__pane__item mo-split__pane__item--visible"
style="top: 0px; height: 20px;"
>
<div>
1
</div>
</div>
<div
class="mo-split__pane__item mo-split__pane__item--visible"
style="top: 20px; height: 20px;"
>
<div>
2
</div>
</div>
</div>
</div>
</DocumentFragment>
`;
250 changes: 250 additions & 0 deletions src/components/split/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
import { sleep } from '@test/utils';
import { cleanup, fireEvent, render } from '@testing-library/react';
import React from 'react';
import { act } from 'react-dom/test-utils';
import {
paneItemClassName,
sashDisabledClassName,
sashHoverClassName,
sashItemClassName,
} from '../base';
import SplitPane from '../SplitPane';

afterEach(cleanup);

describe('Test The SplitPane Component', () => {
let original;
beforeEach(() => {
original = HTMLElement.prototype.getBoundingClientRect;
// @ts-ignore
HTMLElement.prototype.getBoundingClientRect = () => ({
width: 500,
height: 0,
});
});

afterEach(() => {
HTMLElement.prototype.getBoundingClientRect = original;
});

test('Match Snapshot', () => {
const { asFragment } = render(
<SplitPane sizes={[20, 20]} onChange={jest.fn()}>
<div>1</div>
<div>2</div>
</SplitPane>
);
expect(asFragment()).toMatchSnapshot();
});

test('Match Snapshot in horizontal', () => {
const { asFragment } = render(
<SplitPane sizes={[20, 20]} split="horizontal" onChange={jest.fn()}>
<div>1</div>
<div>2</div>
</SplitPane>
);
expect(asFragment()).toMatchSnapshot();
});

test('Should NOT resizable', () => {
const { container } = render(
<SplitPane
sizes={[20, 20]}
allowResize={false}
onChange={jest.fn()}
>
<div>1</div>
<div>2</div>
</SplitPane>
);

const sashs = container.querySelectorAll(`.${sashItemClassName}`);

expect(sashs.length).toBe(2);
expect(
Array.prototype.every.call(sashs, (sash: Element) =>
sash.classList.contains(sashDisabledClassName)
)
).toBeTruthy();
});

test('Should support each resizable', () => {
const { container } = render(
<SplitPane
sizes={[20, 20]}
allowResize={[false, true]}
onChange={jest.fn()}
>
<div>1</div>
<div>2</div>
</SplitPane>
);

const sashs = container.querySelectorAll(`.${sashItemClassName}`);

expect(sashs.length).toBe(2);
expect(sashs[0].classList.contains(sashDisabledClassName)).toBeTruthy();
expect(sashs[1].classList.contains(sashDisabledClassName)).toBeFalsy();
});

test('Should convert "auto" and "xxxpx" and "xxx%" to absolute number ', () => {
const { container } = render(
<SplitPane
sizes={['10%', '10px']}
style={{ width: 500 }}
onChange={jest.fn()}
>
<div>1</div>
<div>2</div>
<div>3</div>
</SplitPane>
);

const panes = container.querySelectorAll<HTMLDivElement>(
`.${paneItemClassName}`
);

expect(panes.length).toBe(3);
expect(panes[0].style.width).toBe('50px');
expect(panes[1].style.width).toBe('10px');
expect(panes[2].style.width).toBe('440px');
});

test('Should support to adjust panes', () => {
const mockFn = jest.fn();
const { container, getByRole } = render(
<SplitPane
role="split"
sizes={['10%', '10px']}
style={{ width: 500 }}
onChange={mockFn}
>
<div>1</div>
<div>2</div>
<div>3</div>
</SplitPane>
);

const wrapper = getByRole('split');
const sashs = container.querySelectorAll(`.${sashItemClassName}`);
fireEvent.mouseDown(sashs[2]);
fireEvent.mouseMove(wrapper, { clientX: 10, clientY: 10 });
fireEvent.mouseUp(wrapper);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toEqual([50, 20, 430]);
});

test('Should with hover className in sashs', async () => {
const { container } = render(
<SplitPane
role="split"
sizes={['10%', '10px']}
style={{ width: 500 }}
onChange={jest.fn()}
>
<div>1</div>
<div>2</div>
<div>3</div>
</SplitPane>
);

const sashs = container.querySelectorAll(`.${sashItemClassName}`);

await act(async () => {
fireEvent.mouseEnter(sashs[1]);
await sleep(150);
});

expect(sashs[0].classList).not.toContain(sashHoverClassName);
expect(sashs[1].classList).toContain(sashHoverClassName);

fireEvent.mouseLeave(sashs[1]);
expect(sashs[1].classList).not.toContain(sashHoverClassName);
});

test('Should support to resize', async () => {
const mockFn = jest.fn();
mockFn
.mockImplementationOnce(() => ['keep', 'keep', 'pave'])
.mockImplementationOnce(() => 'keep')
.mockImplementationOnce(() => undefined);
const { container } = render(
<SplitPane
role="split"
sizes={['10%', '10px']}
style={{ width: 500 }}
onChange={jest.fn()}
onResizeStrategy={mockFn}
>
<div>1</div>
<div>2</div>
<div>3</div>
</SplitPane>
);

await act(async () => {
// @ts-ignore
HTMLElement.prototype.getBoundingClientRect = () => ({
width: 1000,
height: 0,
});

// Trigger the window resize event.
fireEvent(window, new Event('resize'));
await sleep(150);
});

let panes = container.querySelectorAll<HTMLDivElement>(
`.${paneItemClassName}`
);
expect(mockFn).toBeCalled();
// normal strategy, to specify one pane to be pave
expect(panes[0].style.width).toBe('50px');
expect(panes[1].style.width).toBe('10px');
expect(panes[2].style.width).toBe('940px');

await act(async () => {
// @ts-ignore
HTMLElement.prototype.getBoundingClientRect = () => ({
width: 1500,
height: 0,
});

// Trigger the window resize event.
fireEvent(window, new Event('resize'));
await sleep(150);
});

panes = container.querySelectorAll<HTMLDivElement>(
`.${paneItemClassName}`
);
expect(mockFn).toBeCalled();
// to specify global strategy to be keep
expect(panes[0].style.width).toBe('50px');
expect(panes[1].style.width).toBe('10px');
expect(panes[2].style.width).toBe('940px');

await act(async () => {
// @ts-ignore
HTMLElement.prototype.getBoundingClientRect = () => ({
width: 2000,
height: 0,
});

// Trigger the window resize event.
fireEvent(window, new Event('resize'));
await sleep(150);
});

panes = container.querySelectorAll<HTMLDivElement>(
`.${paneItemClassName}`
);
expect(mockFn).toBeCalled();
// abnormal strategy, same as returns 'pave', we don't recommend to set it
expect(panes[0].style.width).toBe(`${2000 / 3}px`);
expect(panes[1].style.width).toBe(`${2000 / 3}px`);
expect(panes[2].style.width).toBe(`${2000 / 3}px`);
});
});
1 change: 1 addition & 0 deletions src/components/split/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './SplitPane';
export { default } from './SplitPane';

0 comments on commit c24d7d3

Please sign in to comment.