mirror of
https://github.com/mathuo/dockview
synced 2025-03-09 15:32:03 +00:00
test: add tests
This commit is contained in:
parent
43548618ba
commit
10256672b4
@ -1,5 +1,14 @@
|
||||
import * as React from 'react';
|
||||
|
||||
/**
|
||||
* useful utility type to erase readonly signatures for testing purposes
|
||||
*
|
||||
* @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#readonly-mapped-type-modifiers-and-readonly-arrays
|
||||
*/
|
||||
export type Writable<T> = T extends object
|
||||
? { -readonly [K in keyof T]: Writable<T[K]> }
|
||||
: T;
|
||||
|
||||
export function setMockRefElement(node: Partial<HTMLElement>): void {
|
||||
const mockRef = {
|
||||
get current() {
|
||||
@ -25,3 +34,13 @@ export function createOffsetDragOverEvent(params: {
|
||||
Object.defineProperty(event, 'clientY', { get: () => params.clientY });
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* `jest.runAllTicks` doesn't seem to exhaust all events in the micro-task queue so
|
||||
* as a **hacky** alternative we'll wait for an empty Promise to complete which runs
|
||||
* on the micro-task queue so will force a run-to-completion emptying the queue
|
||||
* of any pending micro-task
|
||||
*/
|
||||
export function exhaustMicrotaskQueue(): Promise<void> {
|
||||
return new Promise<void>((resolve) => resolve());
|
||||
}
|
||||
|
@ -1,8 +1,145 @@
|
||||
import { OverlayRenderContainer } from '../overlayRenderContainer';
|
||||
import { Droptarget } from '../dnd/droptarget';
|
||||
import { IDockviewPanel } from '../dockview/dockviewPanel';
|
||||
import { Emitter } from '../events';
|
||||
import { IRenderable, OverlayRenderContainer } from '../overlayRenderContainer';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { Writable, exhaustMicrotaskQueue } from './__test_utils__/utils';
|
||||
|
||||
describe('overlayRenderContainer', () => {
|
||||
test('abc', () => {
|
||||
const el = document.createElement('div');
|
||||
const cut = new OverlayRenderContainer(el);
|
||||
test('add a view that is not currently in the DOM', async () => {
|
||||
const parentContainer = document.createElement('div');
|
||||
|
||||
const cut = new OverlayRenderContainer(parentContainer);
|
||||
|
||||
const panelContentEl = document.createElement('div');
|
||||
|
||||
const onDidVisibilityChange = new Emitter<any>();
|
||||
const onDidDimensionsChange = new Emitter<any>();
|
||||
|
||||
const panel = fromPartial<IDockviewPanel>({
|
||||
api: {
|
||||
id: 'test_panel_id',
|
||||
onDidVisibilityChange: onDidVisibilityChange.event,
|
||||
onDidDimensionsChange: onDidDimensionsChange.event,
|
||||
isVisible: true,
|
||||
},
|
||||
view: {
|
||||
content: {
|
||||
element: panelContentEl,
|
||||
},
|
||||
},
|
||||
group: {
|
||||
api: {
|
||||
location: 'grid',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const dropTarget = fromPartial<Droptarget>({});
|
||||
|
||||
const refContainerEl = document.createElement('div');
|
||||
|
||||
const referenceContainer: IRenderable = {
|
||||
element: refContainerEl,
|
||||
dropTarget,
|
||||
};
|
||||
|
||||
(parentContainer as jest.Mocked<HTMLDivElement>).getBoundingClientRect =
|
||||
jest
|
||||
.fn<DOMRect, []>()
|
||||
.mockReturnValueOnce(
|
||||
fromPartial<DOMRect>({
|
||||
left: 100,
|
||||
top: 200,
|
||||
width: 1000,
|
||||
height: 500,
|
||||
})
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
fromPartial<DOMRect>({
|
||||
left: 101,
|
||||
top: 201,
|
||||
width: 1000,
|
||||
height: 500,
|
||||
})
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
fromPartial<DOMRect>({
|
||||
left: 100,
|
||||
top: 200,
|
||||
width: 1000,
|
||||
height: 500,
|
||||
})
|
||||
);
|
||||
|
||||
(refContainerEl as jest.Mocked<HTMLDivElement>).getBoundingClientRect =
|
||||
jest
|
||||
.fn<DOMRect, []>()
|
||||
.mockReturnValueOnce(
|
||||
fromPartial<DOMRect>({
|
||||
left: 150,
|
||||
top: 300,
|
||||
width: 100,
|
||||
height: 200,
|
||||
})
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
fromPartial<DOMRect>({
|
||||
left: 150,
|
||||
top: 300,
|
||||
width: 101,
|
||||
height: 201,
|
||||
})
|
||||
)
|
||||
.mockReturnValueOnce(
|
||||
fromPartial<DOMRect>({
|
||||
left: 150,
|
||||
top: 300,
|
||||
width: 100,
|
||||
height: 200,
|
||||
})
|
||||
);
|
||||
|
||||
const container = cut.setReferenceContentContainer(
|
||||
panel,
|
||||
referenceContainer
|
||||
);
|
||||
|
||||
await exhaustMicrotaskQueue();
|
||||
|
||||
expect(panelContentEl.parentElement).toBe(container);
|
||||
expect(container.parentElement).toBe(parentContainer);
|
||||
|
||||
expect(container.style.display).toBe('');
|
||||
|
||||
expect(container.style.left).toBe('50px');
|
||||
expect(container.style.top).toBe('100px');
|
||||
expect(container.style.width).toBe('100px');
|
||||
expect(container.style.height).toBe('200px');
|
||||
expect(refContainerEl.getBoundingClientRect).toHaveBeenCalledTimes(1);
|
||||
|
||||
onDidDimensionsChange.fire({});
|
||||
expect(container.style.display).toBe('');
|
||||
|
||||
expect(container.style.left).toBe('49px');
|
||||
expect(container.style.top).toBe('99px');
|
||||
expect(container.style.width).toBe('101px');
|
||||
expect(container.style.height).toBe('201px');
|
||||
expect(refContainerEl.getBoundingClientRect).toHaveBeenCalledTimes(2);
|
||||
|
||||
(panel as Writable<IDockviewPanel>).api.isVisible = false;
|
||||
onDidVisibilityChange.fire({});
|
||||
expect(container.style.display).toBe('none');
|
||||
expect(refContainerEl.getBoundingClientRect).toHaveBeenCalledTimes(2);
|
||||
|
||||
(panel as Writable<IDockviewPanel>).api.isVisible = true;
|
||||
onDidVisibilityChange.fire({});
|
||||
expect(container.style.display).toBe('');
|
||||
|
||||
expect(container.style.left).toBe('50px');
|
||||
expect(container.style.top).toBe('100px');
|
||||
expect(container.style.width).toBe('100px');
|
||||
expect(container.style.height).toBe('200px');
|
||||
expect(refContainerEl.getBoundingClientRect).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
});
|
||||
|
@ -89,6 +89,14 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
);
|
||||
};
|
||||
|
||||
const visibilityChanged = () => {
|
||||
if (panel.api.isVisible) {
|
||||
resize();
|
||||
}
|
||||
|
||||
focusContainer.style.display = panel.api.isVisible ? '' : 'none';
|
||||
};
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
/**
|
||||
* since container is positioned absoutely we must explicitly forward
|
||||
@ -117,9 +125,13 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
* the content is still maintained within the DOM hence DOM specific attributes
|
||||
* such as scroll position are maintained when next made visible.
|
||||
*/
|
||||
focusContainer.style.display = event.isVisible ? '' : 'none';
|
||||
visibilityChanged();
|
||||
}),
|
||||
panel.api.onDidDimensionsChange(() => {
|
||||
if (!panel.api.isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
resize();
|
||||
}),
|
||||
{
|
||||
@ -140,7 +152,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
* calling the first resize as other size-altering events may still occur before
|
||||
* the end of the stack-frame.
|
||||
*/
|
||||
resize();
|
||||
visibilityChanged();
|
||||
});
|
||||
|
||||
this.map[panel.api.id].disposable = disposable;
|
||||
|
Loading…
Reference in New Issue
Block a user