From 3e9f96bdbfee1c1ca8603826f82a8d586a82599e Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Wed, 3 Jan 2024 13:09:55 +0000 Subject: [PATCH] test: gridview tests --- .../src/__tests__/gridview/gridview.spec.ts | 245 +++++++++++++++++- packages/dockview-core/src/constants.ts | 3 + .../src/dockview/dockviewComponent.ts | 14 +- 3 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 packages/dockview-core/src/constants.ts diff --git a/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts b/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts index 4350aa04a..2b95757dc 100644 --- a/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts +++ b/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts @@ -19,13 +19,17 @@ class MockGridview implements IGridView { >().event; element: HTMLElement = document.createElement('div'); + width: number = 0; + height: number = 0; + constructor(private id?: string) { this.element.className = 'mock-grid-view'; this.element.id = `${id ?? ''}`; } layout(width: number, height: number): void { - // + this.width = width; + this.height = height; } toJSON(): object { @@ -760,4 +764,243 @@ describe('gridview', () => { el = gridview.element.querySelectorAll('.mock-grid-view'); expect(el.length).toBe(5); }); + + test('gridview nested proportional layouts', () => { + const gridview = new Gridview( + true, + { separatorBorder: '' }, + Orientation.HORIZONTAL + ); + gridview.layout(1000, 1000); + + const view1 = new MockGridview('1'); + const view2 = new MockGridview('2'); + const view3 = new MockGridview('3'); + const view4 = new MockGridview('4'); + const view5 = new MockGridview('5'); + const view6 = new MockGridview('6'); + + gridview.addView(view1, Sizing.Distribute, [0]); + gridview.addView(view2, Sizing.Distribute, [1]); + gridview.addView(view3, Sizing.Distribute, [1, 1]); + gridview.addView(view4, Sizing.Distribute, [1, 1, 0]); + gridview.addView(view5, Sizing.Distribute, [1, 1, 0, 0]); + gridview.addView(view6, Sizing.Distribute, [1, 1, 0, 0, 0]); + + const views = [view1, view2, view3, view4, view5, view6]; + + const dimensions = [ + { width: 500, height: 1000 }, + { width: 500, height: 500 }, + { width: 250, height: 500 }, + { width: 250, height: 250 }, + { width: 125, height: 250 }, + { width: 125, height: 250 }, + ]; + + expect( + views.map((view) => ({ + width: view.width, + height: view.height, + })) + ).toEqual(dimensions); + + gridview.layout(2000, 1500); + + expect( + views.map((view) => ({ + width: view.width, + height: view.height, + })) + ).toEqual( + dimensions.map(({ width, height }) => ({ + width: width * 2, + height: height * 1.5, + })) + ); + + gridview.layout(200, 2000); + + expect( + views.map((view) => ({ + width: view.width, + height: view.height, + })) + ).toEqual( + dimensions.map(({ width, height }) => ({ + width: width * 0.2, + height: height * 2, + })) + ); + }); + + test('that maximizeView retains original dimensions when restored', () => { + const gridview = new Gridview( + true, + { separatorBorder: '' }, + Orientation.HORIZONTAL + ); + gridview.layout(1000, 1000); + + const view1 = new MockGridview('1'); + const view2 = new MockGridview('2'); + const view3 = new MockGridview('3'); + const view4 = new MockGridview('4'); + const view5 = new MockGridview('5'); + const view6 = new MockGridview('6'); + + gridview.addView(view1, Sizing.Distribute, [0]); + gridview.addView(view2, Sizing.Distribute, [1]); + gridview.addView(view3, Sizing.Distribute, [1, 1]); + gridview.addView(view4, Sizing.Distribute, [1, 1, 0]); + gridview.addView(view5, Sizing.Distribute, [1, 1, 0, 0]); + gridview.addView(view6, Sizing.Distribute, [1, 1, 0, 0, 0]); + + /** + * _____________________________________________ + * | | | + * | | 2 | + * | | | + * | 1 |_______________________| + * | | | 4 | + * | | 3 |_____________| + * | | | 5 | 6 | + * |_____________________|_________|______|______| + */ + + const views = [view1, view2, view3, view4, view5, view6]; + + const dimensions = [ + { width: 500, height: 1000 }, + { width: 500, height: 500 }, + { width: 250, height: 500 }, + { width: 250, height: 250 }, + { width: 125, height: 250 }, + { width: 125, height: 250 }, + ]; + + function assertLayout() { + expect( + views.map((view) => ({ + width: view.width, + height: view.height, + })) + ).toEqual(dimensions); + } + + // base case assertions + assertLayout(); + expect(gridview.hasMaximizedView()).toBeFalsy(); + + /** + * maximize each view individually and then return to the standard view + * checking on each iteration that the original layout dimensions + * are restored + */ + for (const view of views) { + gridview.maximizeView(view); + expect(gridview.hasMaximizedView()).toBeTruthy(); + gridview.exitMaximizedView(); + assertLayout(); + } + }); + + test('that maximizedView is exited when a views visibility is changed', () => { + const gridview = new Gridview( + true, + { separatorBorder: '' }, + Orientation.HORIZONTAL + ); + gridview.layout(1000, 1000); + + const view1 = new MockGridview('1'); + const view2 = new MockGridview('2'); + const view3 = new MockGridview('3'); + + gridview.addView(view1, Sizing.Distribute, [0]); + gridview.addView(view2, Sizing.Distribute, [1]); + gridview.addView(view3, Sizing.Distribute, [1, 1]); + + expect(gridview.hasMaximizedView()).toBeFalsy(); + gridview.maximizeView(view2); + expect(gridview.hasMaximizedView()).toBeTruthy(); + + gridview.setViewVisible([0], true); + expect(gridview.hasMaximizedView()).toBeFalsy(); + }); + + test('that maximizedView is exited when a view is moved', () => { + const gridview = new Gridview( + true, + { separatorBorder: '' }, + Orientation.HORIZONTAL + ); + gridview.layout(1000, 1000); + + const view1 = new MockGridview('1'); + const view2 = new MockGridview('2'); + const view3 = new MockGridview('3'); + const view4 = new MockGridview('4'); + + gridview.addView(view1, Sizing.Distribute, [0]); + gridview.addView(view2, Sizing.Distribute, [1]); + gridview.addView(view3, Sizing.Distribute, [1, 1]); + gridview.addView(view4, Sizing.Distribute, [1, 1, 0]); + + expect(gridview.hasMaximizedView()).toBeFalsy(); + gridview.maximizeView(view2); + expect(gridview.hasMaximizedView()).toBeTruthy(); + + gridview.moveView([1, 1], 0, 1); + expect(gridview.hasMaximizedView()).toBeFalsy(); + }); + + test('that maximizedView is exited when a view is added', () => { + const gridview = new Gridview( + true, + { separatorBorder: '' }, + Orientation.HORIZONTAL + ); + gridview.layout(1000, 1000); + + const view1 = new MockGridview('1'); + const view2 = new MockGridview('2'); + const view3 = new MockGridview('3'); + const view4 = new MockGridview('4'); + + gridview.addView(view1, Sizing.Distribute, [0]); + gridview.addView(view2, Sizing.Distribute, [1]); + gridview.addView(view3, Sizing.Distribute, [1, 1]); + + expect(gridview.hasMaximizedView()).toBeFalsy(); + gridview.maximizeView(view2); + expect(gridview.hasMaximizedView()).toBeTruthy(); + + gridview.addView(view4, Sizing.Distribute, [1, 1, 0]); + expect(gridview.hasMaximizedView()).toBeFalsy(); + }); + + test('that maximizedView is exited when a view is removed', () => { + const gridview = new Gridview( + true, + { separatorBorder: '' }, + Orientation.HORIZONTAL + ); + gridview.layout(1000, 1000); + + const view1 = new MockGridview('1'); + const view2 = new MockGridview('2'); + const view3 = new MockGridview('3'); + + gridview.addView(view1, Sizing.Distribute, [0]); + gridview.addView(view2, Sizing.Distribute, [1]); + gridview.addView(view3, Sizing.Distribute, [1, 1]); + + expect(gridview.hasMaximizedView()).toBeFalsy(); + gridview.maximizeView(view2); + expect(gridview.hasMaximizedView()).toBeTruthy(); + + gridview.removeView([1, 1]); + expect(gridview.hasMaximizedView()).toBeFalsy(); + }); }); diff --git a/packages/dockview-core/src/constants.ts b/packages/dockview-core/src/constants.ts new file mode 100644 index 000000000..b8b9fd3f6 --- /dev/null +++ b/packages/dockview-core/src/constants.ts @@ -0,0 +1,3 @@ +export const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; + +export const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 }; diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 6460244b4..e09d95cae 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -59,6 +59,10 @@ import { DockviewPanelRenderer, } from './components/greadyRenderContainer'; import { DockviewPopoutGroupPanel } from './dockviewPopoutGroupPanel'; +import { + DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE, + DEFAULT_FLOATING_GROUP_POSITION, +} from '../constants'; function getTheme(element: HTMLElement): string | undefined { function toClassList(element: HTMLElement) { @@ -87,8 +91,6 @@ function getTheme(element: HTMLElement): string | undefined { return theme; } -const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; - export interface PanelReference { update: (event: { params: { [key: string]: any } }) => void; remove: () => void; @@ -583,9 +585,13 @@ export class DockviewComponent group.model.location = 'floating'; const overlayLeft = - typeof coord?.x === 'number' ? Math.max(coord.x, 0) : 100; + typeof coord?.x === 'number' + ? Math.max(coord.x, 0) + : DEFAULT_FLOATING_GROUP_POSITION.left; const overlayTop = - typeof coord?.y === 'number' ? Math.max(coord.y, 0) : 100; + typeof coord?.y === 'number' + ? Math.max(coord.y, 0) + : DEFAULT_FLOATING_GROUP_POSITION.top; const overlay = new Overlay({ container: this.gridview.element,