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
@ -71,4 +71,4 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0"
|
"node": ">=18.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
import * as React from 'react';
|
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 {
|
export function setMockRefElement(node: Partial<HTMLElement>): void {
|
||||||
const mockRef = {
|
const mockRef = {
|
||||||
get current() {
|
get current() {
|
||||||
@ -25,3 +34,13 @@ export function createOffsetDragOverEvent(params: {
|
|||||||
Object.defineProperty(event, 'clientY', { get: () => params.clientY });
|
Object.defineProperty(event, 'clientY', { get: () => params.clientY });
|
||||||
return event;
|
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', () => {
|
describe('overlayRenderContainer', () => {
|
||||||
test('abc', () => {
|
test('add a view that is not currently in the DOM', async () => {
|
||||||
const el = document.createElement('div');
|
const parentContainer = document.createElement('div');
|
||||||
const cut = new OverlayRenderContainer(el);
|
|
||||||
|
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(
|
const disposable = new CompositeDisposable(
|
||||||
/**
|
/**
|
||||||
* since container is positioned absoutely we must explicitly forward
|
* 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
|
* the content is still maintained within the DOM hence DOM specific attributes
|
||||||
* such as scroll position are maintained when next made visible.
|
* such as scroll position are maintained when next made visible.
|
||||||
*/
|
*/
|
||||||
focusContainer.style.display = event.isVisible ? '' : 'none';
|
visibilityChanged();
|
||||||
}),
|
}),
|
||||||
panel.api.onDidDimensionsChange(() => {
|
panel.api.onDidDimensionsChange(() => {
|
||||||
|
if (!panel.api.isVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
resize();
|
resize();
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
@ -140,7 +152,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
|||||||
* calling the first resize as other size-altering events may still occur before
|
* calling the first resize as other size-altering events may still occur before
|
||||||
* the end of the stack-frame.
|
* the end of the stack-frame.
|
||||||
*/
|
*/
|
||||||
resize();
|
visibilityChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.map[panel.api.id].disposable = disposable;
|
this.map[panel.api.id].disposable = disposable;
|
||||||
|
Loading…
Reference in New Issue
Block a user