Merge pull request #201 from mathuo/198-vanillajs-rendering-and-persistance

test
This commit is contained in:
mathuo 2023-03-14 00:12:53 +08:00 committed by GitHub
commit 1f3bed9740
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 413 additions and 1 deletions

View File

@ -0,0 +1,31 @@
import { addGhostImage } from '../../dnd/ghost';
describe('ghost', () => {
beforeEach(() => {
jest.useFakeTimers();
jest.clearAllTimers();
});
test('that a custom class is added, the element is added to the document and all is removed afterwards', () => {
const dataTransferMock = jest.fn<Partial<DataTransfer>, []>(() => {
return {
setDragImage: jest.fn(),
};
});
const element = document.createElement('div');
const dataTransfer = <DataTransfer>new dataTransferMock();
addGhostImage(dataTransfer, element);
expect(element.className).toBe('dv-dragged');
expect(element.parentElement).toBe(document.body);
expect(dataTransfer.setDragImage).toBeCalledTimes(1);
expect(dataTransfer.setDragImage).toBeCalledWith(element, 0, 0);
jest.runAllTimers();
expect(element.className).toBe('');
expect(element.parentElement).toBe(null);
});
});

View File

@ -1,4 +1,4 @@
import { addClasses } from '../dom';
import { addClasses, removeClasses } from '../dom';
export function addGhostImage(
dataTransfer: DataTransfer,
@ -11,6 +11,7 @@ export function addGhostImage(
dataTransfer.setDragImage(ghostElement, 0, 0);
setTimeout(() => {
removeClasses(ghostElement, 'dv-dragged');
ghostElement.remove();
}, 0);
}

View File

@ -0,0 +1,52 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { DockviewApi } from 'dockview-core';
import {
IDockviewPanelProps,
DockviewReact,
DockviewReadyEvent,
} from '../../dockview/dockview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('gridview react', () => {
let components: PanelCollection<IDockviewPanelProps>;
beforeEach(() => {
components = {
default: (props: IDockviewPanelProps) => {
return <div>hello world</div>;
},
};
});
test('default', () => {
let api: DockviewApi | undefined;
const onReady = (event: DockviewReadyEvent) => {
api = event.api;
};
render(<DockviewReact components={components} onReady={onReady} />);
expect(api).toBeTruthy();
});
test('is sized to container', () => {
setMockRefElement({
clientHeight: 450,
clientWidth: 650,
appendChild: jest.fn(),
});
let api: DockviewApi | undefined;
const onReady = (event: DockviewReadyEvent) => {
api = event.api;
};
render(<DockviewReact components={components} onReady={onReady} />);
expect(api.width).toBe(650);
expect(api.height).toBe(450);
});
});

View File

@ -0,0 +1,58 @@
import {
DockviewGroupPanel,
DockviewGroupPanelApi,
DockviewGroupPanelModel,
} from 'dockview-core';
import { ReactGroupControlsRendererPart } from '../../dockview/groupControlsRenderer';
describe('groupControlsRenderer', () => {
test('#1', () => {
const groupviewMock = jest.fn<Partial<DockviewGroupPanelModel>, []>(
() => {
return {
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
onDidActivePanelChange: jest.fn(),
};
}
);
const groupview = new groupviewMock() as DockviewGroupPanelModel;
const groupPanelMock = jest.fn<Partial<DockviewGroupPanel>, []>(() => {
return {
api: {} as DockviewGroupPanelApi as any,
model: groupview,
};
});
const groupPanel = new groupPanelMock() as DockviewGroupPanel;
const cut = new ReactGroupControlsRendererPart(
jest.fn(),
{
addPortal: jest.fn(),
},
groupPanel
);
expect(cut.element.childNodes.length).toBe(0);
expect(cut.element.className).toBe('dockview-react-part');
expect(cut.part).toBeUndefined();
cut.init({
containerApi: <any>jest.fn(),
api: <any>{
onDidActiveChange: jest.fn(),
},
});
const update = jest.fn();
jest.spyOn(cut.part!, 'update').mockImplementation(update);
cut.update({ params: { valueA: 'A' } });
expect(update).toBeCalledWith({ valueA: 'A' });
});
});

View File

@ -0,0 +1,64 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { GridviewApi, Orientation } from 'dockview-core';
import {
IGridviewPanelProps,
GridviewReact,
GridviewReadyEvent,
} from '../../gridview/gridview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('gridview react', () => {
let components: PanelCollection<IGridviewPanelProps>;
beforeEach(() => {
components = {
default: (props: IGridviewPanelProps) => {
return <div>hello world</div>;
},
};
});
test('default', () => {
let api: GridviewApi | undefined;
const onReady = (event: GridviewReadyEvent) => {
api = event.api;
};
render(
<GridviewReact
orientation={Orientation.VERTICAL}
components={components}
onReady={onReady}
/>
);
expect(api).toBeTruthy();
});
test('is sized to container', () => {
setMockRefElement({
clientHeight: 450,
clientWidth: 650,
appendChild: jest.fn(),
});
let api: GridviewApi | undefined;
const onReady = (event: GridviewReadyEvent) => {
api = event.api;
};
render(
<GridviewReact
orientation={Orientation.VERTICAL}
components={components}
onReady={onReady}
/>
);
expect(api.width).toBe(650);
expect(api.height).toBe(450);
});
});

View File

@ -0,0 +1,52 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { PaneviewApi } from 'dockview-core';
import {
IPaneviewPanelProps,
PaneviewReact,
PaneviewReadyEvent,
} from '../../paneview/paneview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('gridview react', () => {
let components: PanelCollection<IPaneviewPanelProps>;
beforeEach(() => {
components = {
default: (props: IPaneviewPanelProps) => {
return <div>hello world</div>;
},
};
});
test('default', () => {
let api: PaneviewApi | undefined;
const onReady = (event: PaneviewReadyEvent) => {
api = event.api;
};
render(<PaneviewReact components={components} onReady={onReady} />);
expect(api).toBeTruthy();
});
test('is sized to container', () => {
setMockRefElement({
clientHeight: 450,
clientWidth: 650,
appendChild: jest.fn(),
});
let api: PaneviewApi | undefined;
const onReady = (event: PaneviewReadyEvent) => {
api = event.api;
};
render(<PaneviewReact components={components} onReady={onReady} />);
expect(api.width).toBe(650);
expect(api.height).toBe(450);
});
});

View File

@ -0,0 +1,90 @@
import { ReactPart } from '../react';
import * as React from 'react';
import { render, screen, act } from '@testing-library/react';
interface TestInterface {
valueA: string;
valueB: number;
}
describe('react', () => {
describe('ReactPart', () => {
test('update underlying component via ReactPart class', () => {
let api: ReactPart<TestInterface>;
const onReady = (_api: ReactPart<TestInterface>) => {
api = _api;
};
render(<TestWrapper onReady={onReady} component={Component} />);
expect(api).toBeTruthy();
expect(screen.getByTestId('valueA').textContent).toBe('stringA');
expect(screen.getByTestId('valueB').textContent).toBe('42');
act(() => {
api.update({ valueB: '32' });
});
expect(screen.getByTestId('valueA').textContent).toBe('stringA');
expect(screen.getByTestId('valueB').textContent).toBe('32');
act(() => {
api.update({ valueA: 'anotherStringA', valueB: '22' });
});
expect(screen.getByTestId('valueA').textContent).toBe(
'anotherStringA'
);
expect(screen.getByTestId('valueB').textContent).toBe('22');
});
});
});
const Component = (props: TestInterface) => {
return (
<div>
<div data-testid="valueA">{props.valueA}</div>
<div data-testid="valueB">{props.valueB}</div>
</div>
);
};
const TestWrapper = (props: {
component: React.FunctionComponent<TestInterface>;
onReady: (api: ReactPart<TestInterface>) => void;
}) => {
const [portal, setPortal] = React.useState<React.ReactPortal[]>([]);
const ref = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const cut = new ReactPart<TestInterface>(
ref.current,
{
addPortal: (portal: React.ReactPortal) => {
setPortal((_) => [..._, portal]);
return {
dispose: () => {
setPortal((_) => _.filter((_) => _ !== portal));
},
};
},
},
props.component,
{
valueA: 'stringA',
valueB: 42,
}
);
props.onReady(cut);
return () => {
cut.dispose();
};
}, []);
return <div ref={ref}>{portal}</div>;
};

View File

@ -0,0 +1,64 @@
import * as React from 'react';
import { render } from '@testing-library/react';
import { SplitviewApi, Orientation } from 'dockview-core';
import {
ISplitviewPanelProps,
SplitviewReact,
SplitviewReadyEvent,
} from '../../splitview/splitview';
import { PanelCollection } from '../../types';
import { setMockRefElement } from '../__test_utils__/utils';
describe('splitview react', () => {
let components: PanelCollection<ISplitviewPanelProps>;
beforeEach(() => {
components = {
default: (props: ISplitviewPanelProps) => {
return <div>hello world</div>;
},
};
});
test('default', () => {
let api: SplitviewApi | undefined;
const onReady = (event: SplitviewReadyEvent) => {
api = event.api;
};
render(
<SplitviewReact
orientation={Orientation.VERTICAL}
components={components}
onReady={onReady}
/>
);
expect(api).toBeTruthy();
});
test('is sized to container', () => {
setMockRefElement({
clientHeight: 450,
clientWidth: 650,
appendChild: jest.fn(),
});
let api: SplitviewApi | undefined;
const onReady = (event: SplitviewReadyEvent) => {
api = event.api;
};
render(
<SplitviewReact
orientation={Orientation.VERTICAL}
components={components}
onReady={onReady}
/>
);
expect(api.width).toBe(650);
expect(api.height).toBe(450);
});
});