From 575a1d7031177b01594efd12a346e37c7770c105 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sun, 16 Apr 2023 21:53:28 +0100 Subject: [PATCH] test: remove smells and test --- .../dockview/dockviewPanelModel.spec.ts | 258 +++++++++++++----- .../src/dockview/deserializer.ts | 30 +- .../src/dockview/dockviewPanelModel.ts | 32 ++- 3 files changed, 218 insertions(+), 102 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts index b1cf604b0..aacf0ca93 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewPanelModel.spec.ts @@ -4,27 +4,39 @@ import { } from '../../dockview/dockviewComponent'; import { DockviewPanelModel } from '../../dockview/dockviewPanelModel'; import { IContentRenderer, ITabRenderer } from '../../dockview/types'; +import { GroupPanelFrameworkComponentFactory } from '../../dockview/options'; +import { DefaultTab } from '../../dockview/components/tab/defaultTab'; describe('dockviewGroupPanel', () => { - test('that dispose is called on content and tab renderers when present', () => { - const contentMock = jest.fn(() => { + let contentMock: jest.Mock; + let tabMock: jest.Mock; + let accessorMock: jest.Mock; + + beforeEach(() => { + contentMock = jest.fn(() => { const partial: Partial = { element: document.createElement('div'), dispose: jest.fn(), + update: jest.fn(), + onGroupChange: jest.fn(), + onPanelVisibleChange: jest.fn(), }; return partial as IContentRenderer; }); - const tabMock = jest.fn(() => { + tabMock = jest.fn(() => { const partial: Partial = { element: document.createElement('div'), dispose: jest.fn(), + update: jest.fn(), + onGroupChange: jest.fn(), + onPanelVisibleChange: jest.fn(), }; return partial as IContentRenderer; }); - const accessorMock = jest.fn, []>(() => { - return { + accessorMock = jest.fn(() => { + const partial: Partial = { options: { components: { contentComponent: contentMock, @@ -34,8 +46,12 @@ describe('dockviewGroupPanel', () => { }, }, }; - }); + return partial as DockviewComponent; + }); + }); + + test('that dispose is called on content and tab renderers when present', () => { const cut = new DockviewPanelModel( new accessorMock(), 'id', @@ -50,34 +66,6 @@ describe('dockviewGroupPanel', () => { }); test('that update is called on content and tab renderers when present', () => { - const contentMock = jest.fn(() => { - const partial: Partial = { - element: document.createElement('div'), - update: jest.fn(), - }; - return partial as IContentRenderer; - }); - - const tabMock = jest.fn(() => { - const partial: Partial = { - element: document.createElement('div'), - update: jest.fn(), - }; - return partial as IContentRenderer; - }); - - const accessorMock = jest.fn, []>(() => { - return { - options: { - components: { - contentComponent: contentMock, - }, - tabComponents: { - tabComponent: tabMock, - }, - }, - }; - }); const cut = new DockviewPanelModel( new accessorMock(), 'id', @@ -94,36 +82,6 @@ describe('dockviewGroupPanel', () => { }); test('that events are fired', () => { - const contentMock = jest.fn(() => { - const partial: Partial = { - element: document.createElement('div'), - onGroupChange: jest.fn(), - onPanelVisibleChange: jest.fn(), - }; - return partial as IContentRenderer; - }); - - const tabMock = jest.fn(() => { - const partial: Partial = { - element: document.createElement('div'), - onGroupChange: jest.fn(), - onPanelVisibleChange: jest.fn(), - }; - return partial as IContentRenderer; - }); - - const accessorMock = jest.fn, []>(() => { - return { - options: { - components: { - contentComponent: contentMock, - }, - tabComponents: { - tabComponent: tabMock, - }, - }, - }; - }); const cut = new DockviewPanelModel( new accessorMock(), 'id', @@ -168,4 +126,176 @@ describe('dockviewGroupPanel', () => { expect(cut.content.onPanelVisibleChange).toHaveBeenCalledTimes(2); expect(cut.tab.onPanelVisibleChange).toHaveBeenCalledTimes(2); }); + + test('that the default tab is created', () => { + accessorMock = jest.fn(() => { + const partial: Partial = { + options: { + components: { + contentComponent: contentMock, + }, + tabComponents: { + tabComponent: jest + .fn() + .mockImplementation(() => tabMock), + }, + }, + }; + + return partial as DockviewComponent; + }); + + const cut = new DockviewPanelModel( + new accessorMock(), + 'id', + 'contentComponent', + 'tabComponent' + ); + + expect(cut.tab).toEqual(tabMock); + }); + + test('that the provided default tab is chosen when no implementation is provided', () => { + accessorMock = jest.fn(() => { + const partial: Partial = { + options: { + components: { + contentComponent: contentMock, + }, + tabComponents: { + tabComponent: jest + .fn() + .mockImplementation(() => tabMock), + }, + defaultTabComponent: 'tabComponent', + }, + }; + + return partial as DockviewComponent; + }); + + const cut = new DockviewPanelModel( + new accessorMock(), + 'id', + 'contentComponent' + ); + + expect(cut.tab).toEqual(tabMock); + }); + + test('that the framework tab is created when provided tab is a framework tab', () => { + const tab = jest.fn(); + const tabFactory = jest.fn().mockImplementation(() => tab); + + accessorMock = jest.fn(() => { + const partial: Partial = { + options: { + components: { + contentComponent: contentMock, + }, + frameworkTabComponents: { + tabComponent: tabMock, + }, + frameworkComponentFactory: (< + Partial + >{ + tab: { createComponent: tabFactory }, + }) as GroupPanelFrameworkComponentFactory, + }, + }; + + return partial as DockviewComponent; + }); + + const cut = new DockviewPanelModel( + new accessorMock(), + 'id', + 'contentComponent', + 'tabComponent' + ); + + expect(tabFactory).toHaveBeenCalledWith('id', 'tabComponent', tabMock); + expect(cut.tab).toEqual(tab); + }); + + test('that is library default tab instance is created when no alternative exists', () => { + accessorMock = jest.fn(() => { + const partial: Partial = { + options: { + components: { + contentComponent: contentMock, + }, + }, + }; + + return partial as DockviewComponent; + }); + + const cut = new DockviewPanelModel( + new accessorMock(), + 'id', + 'contentComponent' + ); + + expect(cut.tab instanceof DefaultTab).toBeTruthy(); + }); + + test('that the default content is created', () => { + accessorMock = jest.fn(() => { + const partial: Partial = { + options: { + components: { + contentComponent: jest.fn().mockImplementation(() => { + return contentMock; + }), + }, + }, + }; + + return partial as DockviewComponent; + }); + + const cut = new DockviewPanelModel( + new accessorMock(), + 'id', + 'contentComponent' + ); + + expect(cut.content).toEqual(contentMock); + }); + + test('that the framework content is created', () => { + const content = jest.fn(); + const contentFactory = jest.fn().mockImplementation(() => content); + + accessorMock = jest.fn(() => { + const partial: Partial = { + options: { + frameworkComponents: { + contentComponent: contentMock, + }, + frameworkComponentFactory: (< + Partial + >{ + content: { createComponent: contentFactory }, + }) as GroupPanelFrameworkComponentFactory, + }, + }; + + return partial as DockviewComponent; + }); + + const cut = new DockviewPanelModel( + new accessorMock(), + 'id', + 'contentComponent' + ); + + expect(contentFactory).toHaveBeenCalledWith( + 'id', + 'contentComponent', + contentMock + ); + expect(cut.content).toEqual(content); + }); }); diff --git a/packages/dockview-core/src/dockview/deserializer.ts b/packages/dockview-core/src/dockview/deserializer.ts index 5c6936c4d..82daa7381 100644 --- a/packages/dockview-core/src/dockview/deserializer.ts +++ b/packages/dockview-core/src/dockview/deserializer.ts @@ -1,9 +1,7 @@ -import { GroupviewPanelState, ITabRenderer } from './types'; +import { GroupviewPanelState } from './types'; import { DockviewGroupPanel } from './dockviewGroupPanel'; import { DockviewPanel, IDockviewPanel } from './dockviewPanel'; import { IDockviewComponent } from './dockviewComponent'; -import { createComponent } from '../panel/componentFactory'; -import { DefaultTab } from './components/tab/defaultTab'; import { DockviewPanelModel } from './dockviewPanelModel'; import { DockviewApi } from '../api/component.api'; @@ -14,7 +12,7 @@ export interface IPanelDeserializer { ): IDockviewPanel; } -// depreciated +// @depreciated interface LegacyState extends GroupviewPanelState { view?: { tab?: { id: string }; @@ -42,30 +40,6 @@ export class DefaultDockviewDeserialzier implements IPanelDeserializer { ? viewData.tab?.id : panelData.tabComponent; - let tab: ITabRenderer; - - if (tabComponent) { - tab = createComponent( - panelId, - tabComponent, - this.layout.options.tabComponents, - this.layout.options.frameworkTabComponents, - this.layout.options.frameworkComponentFactory?.tab, - () => new DefaultTab() - ); - } else if (this.layout.options.defaultTabComponent) { - tab = createComponent( - panelId, - this.layout.options.defaultTabComponent, - this.layout.options.tabComponents, - this.layout.options.frameworkTabComponents, - this.layout.options.frameworkComponentFactory?.tab, - () => new DefaultTab() - ); - } else { - tab = new DefaultTab(); - } - const view = new DockviewPanelModel( this.layout, panelId, diff --git a/packages/dockview-core/src/dockview/dockviewPanelModel.ts b/packages/dockview-core/src/dockview/dockviewPanelModel.ts index c8e2aee8f..b29bcd12c 100644 --- a/packages/dockview-core/src/dockview/dockviewPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewPanelModel.ts @@ -43,8 +43,7 @@ export class DockviewPanelModel implements IDockviewPanelModel { readonly tabComponent?: string ) { this._content = this.createContentComponent(this.id, contentComponent); - this._tab = - this.createTabComponent(this.id, tabComponent) ?? new DefaultTab(); + this._tab = this.createTabComponent(this.id, tabComponent); } init(params: GroupPanelPartInitParameters): void { @@ -108,13 +107,26 @@ export class DockviewPanelModel implements IDockviewPanelModel { id: string, componentName?: string ): ITabRenderer { - return createComponent( - id, - componentName, - this.accessor.options.tabComponents || {}, - this.accessor.options.frameworkTabComponents, - this.accessor.options.frameworkComponentFactory?.tab, - () => new DefaultTab() - ); + if (componentName) { + return createComponent( + id, + componentName, + this.accessor.options.tabComponents, + this.accessor.options.frameworkTabComponents, + this.accessor.options.frameworkComponentFactory?.tab, + () => new DefaultTab() + ); + } else if (this.accessor.options.defaultTabComponent) { + return createComponent( + id, + this.accessor.options.defaultTabComponent, + this.accessor.options.tabComponents, + this.accessor.options.frameworkTabComponents, + this.accessor.options.frameworkComponentFactory?.tab, + () => new DefaultTab() + ); + } else { + return new DefaultTab(); + } } }