Skip to content

Commit

Permalink
feat: add built-in service (#471)
Browse files Browse the repository at this point in the history
* feat: add built-in service

* feat: add built-in service for explorer

* feat: add built-in modules for editor

* feat: activitybar support to sortIndex

* feat: add built-in service for editorTree

* ci: fix ci problems

* test: improve unit test

* feat: add built-in service for setting

* feat: add built-in service for problems

* feat: add built-in for notification

* feat: add built-in service for statusBar

* test: update the snapshot and improve testings about default value

* feat: add built-in service for search

* feat: add built-in service in panel

* feat: add built-in for keybinding

* feat: add built-in for menu

* feat: add built-in for folderTree

* test: update snapshot

* test: add unit tests for built-in service

* feat: add the initView method for base Controller

* feat: support to autoInject the controllers in Provider

* test: update snapshot

* test: add unit tests for controllers

* feat: add the annotations for built-in service

* test: add unit tests for controllers

* test: add unit tests for controllers

* feat: add built-in for activityBar
  • Loading branch information
mortalYoung authored Oct 21, 2021
1 parent 35e66fd commit d96e2b3
Show file tree
Hide file tree
Showing 90 changed files with 3,585 additions and 1,778 deletions.
21 changes: 12 additions & 9 deletions src/components/actionBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,18 @@ export function ActionBar<T = any>(props: IActionBarProps<T>) {

const claNames = classNames(defaultActionBarClassName, className);

const items = data.map((item: IActionBarItemProps<T>, index) => (
<ActionBarItem
key={item.id}
{...item}
onContextMenuClick={onContextMenuClick}
data-index={index}
onClick={mergeFunctions(onClick, item.onClick)}
/>
));
const items = data.map(
(item: IActionBarItemProps<T>, index) =>
item.id && (
<ActionBarItem
key={item.id}
{...item}
onContextMenuClick={onContextMenuClick}
data-index={index}
onClick={mergeFunctions(onClick, item.onClick)}
/>
)
);

return (
<div className={claNames} {...custom}>
Expand Down
132 changes: 132 additions & 0 deletions src/controller/__tests__/editorTree.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {
ExplorerService,
BuiltinService,
EditorTreeService,
} from 'mo/services';
import { constants, modules } from 'mo/services/builtinService/const';
import 'reflect-metadata';
import { container } from 'tsyringe';
import { EditorTreeController } from '../explorer/editorTree';

const editorTreeController = container.resolve(EditorTreeController);
const editorTreeService = container.resolve(EditorTreeService);
const explorerService = container.resolve(ExplorerService);
const builtinService = container.resolve(BuiltinService);

describe('The editor tree controller', () => {
test('Should inject the default value into service', () => {
editorTreeController.initView();

const { data } = explorerService.getState();
expect(data).toHaveLength(1);
const {
groupToolbar,
...restEditor
} = modules.builtInExplorerEditorPanel;
expect(data[0]).toEqual(expect.objectContaining(restEditor));

explorerService.reset();
});

test('Should support to controll the default value', () => {
builtinService.inactiveModule('builtInExplorerEditorPanel');
editorTreeController.initView();
const { data } = explorerService.getState();
expect(data).toHaveLength(0);

builtinService.reset();
});

test('Should execute the onContextMenu method', () => {
const mockItem = { id: constants.EDITOR_MENU_CLOSE };
const mockGroupId = 1;
const mockFile = { id: 'file' };
const mockFn = jest.fn();
editorTreeService.onClose(mockFn);
editorTreeController.onContextMenu(mockItem, mockGroupId, mockFile);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockFile.id);
expect(mockFn.mock.calls[0][1]).toBe(mockGroupId);
mockFn.mockClear();

// close others
editorTreeService.onCloseOthers(mockFn);
mockItem.id = constants.EDITOR_MENU_CLOSE_OTHERS;
editorTreeController.onContextMenu(mockItem, mockGroupId, mockFile);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toEqual(mockFile);
expect(mockFn.mock.calls[0][1]).toBe(mockGroupId);
mockFn.mockClear();

// close saved
editorTreeService.onCloseSaved(mockFn);
mockItem.id = constants.EDITOR_MENU_CLOSE_SAVED;
editorTreeController.onContextMenu(mockItem, mockGroupId, mockFile);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toEqual(mockGroupId);
mockFn.mockClear();

// close all
editorTreeService.onCloseAll(mockFn);
mockItem.id = constants.EDITOR_MENU_CLOSE_ALL;
editorTreeController.onContextMenu(mockItem, mockGroupId, mockFile);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toEqual(mockGroupId);
mockFn.mockClear();

// default
editorTreeService.onContextMenu(mockFn);
mockItem.id = 'custom-id';
editorTreeController.onContextMenu(mockItem, mockGroupId, mockFile);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toEqual(mockItem);
expect(mockFn.mock.calls[0][1]).toEqual(mockFile);
expect(mockFn.mock.calls[0][2]).toEqual(mockGroupId);
});

test('Should support to emit events', () => {
const mockTabId = '1';
const mockGroupId = 1;
const mockFn = jest.fn();
editorTreeService.onClose(mockFn);
editorTreeController.onClose(mockTabId, mockGroupId);

expect(mockFn).toBeCalled();
mockFn.mockClear();

// onSelect
editorTreeService.onSelect(mockFn);
editorTreeController.onSelect(mockTabId, mockGroupId);
expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockTabId);
expect(mockFn.mock.calls[0][1]).toBe(mockGroupId);
mockFn.mockClear();

// onCloseGroup
editorTreeService.onCloseAll(mockFn);
editorTreeController.onCloseGroup(mockGroupId);
expect(mockFn).toBeCalled();
mockFn.mockClear();

// onSaveGroup
editorTreeService.onSaveAll(mockFn);
editorTreeController.onSaveGroup(mockGroupId);
expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockGroupId);
mockFn.mockClear();

// onToolbarClick
const mockToolbar = { id: 'test' };
editorTreeService.onToolbarClick(mockFn);
editorTreeController.onToolbarClick(mockToolbar, mockGroupId);
expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockToolbar);
expect(mockFn.mock.calls[0][1]).toBe(mockGroupId);
mockFn.mockClear();
});
});
209 changes: 209 additions & 0 deletions src/controller/__tests__/explorer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { EditorTreeEvent, ExplorerEvent, FileTypes } from 'mo/model';
import {
ActivityBarService,
SidebarService,
ExplorerService,
BuiltinService,
} from 'mo/services';
import { constants, modules } from 'mo/services/builtinService/const';
import 'reflect-metadata';
import { container } from 'tsyringe';
import { ExplorerController, FolderTreeController } from '..';

const explorerController = container.resolve(ExplorerController);

const activityBarService = container.resolve(ActivityBarService);
const sidebarService = container.resolve(SidebarService);
const explorerService = container.resolve(ExplorerService);
const folderTreeController = container.resolve(FolderTreeController);
const builtinService = container.resolve(BuiltinService);

describe('The explorer controller', () => {
test('Should support to inject the default value into service', () => {
explorerController.initView();

const { headerToolBar, data } = explorerService.getState();
expect(headerToolBar.id).toBe(modules.builtInExplorerHeaderToolbar.id);
expect(headerToolBar.icon).toBe(
modules.builtInExplorerHeaderToolbar.icon
);
expect(headerToolBar.title).toBe(
modules.builtInExplorerHeaderToolbar.title
);
expect(headerToolBar.contextMenu).toHaveLength(1);

expect(data).toHaveLength(1);
expect(data[0]).toEqual(
expect.objectContaining(modules.builtInExplorerFolderPanel)
);

const {
data: activityBarData,
selected,
} = activityBarService.getState();
expect(activityBarData).toHaveLength(1);
expect(activityBarData![0]).toEqual(
expect.objectContaining(modules.builtInExplorerActivityItem)
);
expect(selected).toBe(modules.builtInExplorerActivityItem.id);

const { current, panes } = sidebarService.getState();
expect(panes).toHaveLength(1);
expect(panes[0]).toEqual(
expect.objectContaining({
id: constants.EXPLORER_ACTIVITY_ITEM,
title: 'EXPLORER',
})
);
expect(current).toBe(constants.EXPLORER_ACTIVITY_ITEM);

explorerService.reset();
activityBarService.reset();
sidebarService.reset();
});

test('Should support to controll the default value by built-in service', () => {
builtinService.inactiveModule('builtInExplorerActivityItem');
builtinService.inactiveModule('builtInExplorerFolderPanel');
builtinService.inactiveModule('builtInExplorerHeaderToolbar');

explorerController.initView();
const { data, headerToolBar } = explorerService.getState();
expect(headerToolBar).toEqual({});
expect(data).toHaveLength(0);

const {
data: activityBarData,
selected,
} = activityBarService.getState();
expect(activityBarData).toHaveLength(0);
expect(selected).toBe('');

const { current, panes } = sidebarService.getState();
expect(panes).toHaveLength(0);
expect(current).toBe('');

builtinService.reset();
});

test('Should support to emit the onClick method', () => {
explorerController.initView();

const mockFn = jest.fn();
explorerService.onClick(mockFn);

const mockEvent = {} as any;
const mockItem = { id: 'test' };
explorerController.onClick(mockEvent, mockItem);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockEvent);
expect(mockFn.mock.calls[0][1]).toBe(mockItem);
});

test('Should execute onActionsContextMenuClick', () => {
const original = explorerService.togglePanel;
const mockFn = jest.fn();
explorerService.togglePanel = mockFn;

const mockItem = { id: 'test' };
explorerController.onActionsContextMenuClick({} as any, mockItem);
expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockItem.id);

explorerService.togglePanel = original;
});

test('Should support to emit the onCollapseChange method', () => {
const mockFn = jest.fn();
explorerController.subscribe(ExplorerEvent.onCollapseChange, mockFn);

const mockKeys = [1, 2, 3];
explorerController.onCollapseChange(mockKeys);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockKeys);
});

test('Should support to execute the onToolbarClick method', () => {
const original = folderTreeController.createTreeNode;
const mockFn = jest.fn();
folderTreeController.createTreeNode = mockFn;

const mockItem = { id: constants.NEW_FILE_COMMAND_ID };
const mockParentPanel = { id: 'test', name: 'test' };
explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(FileTypes.File);

mockFn.mockClear();

mockItem.id = constants.NEW_FOLDER_COMMAND_ID;
explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(FileTypes.Folder);

folderTreeController.createTreeNode = original;
});

test('Should support to execute the onToolbarClick method', () => {
// REMOVE_COMMAND_ID
const mockItem = { id: constants.REMOVE_COMMAND_ID };
const mockParentPanel = { id: 'test', name: 'test' };

const mockFn = jest.fn();
explorerService.onRemovePanel(mockFn);

explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockParentPanel);

// EXPLORER_TOGGLE_CLOSE_ALL_EDITORS
mockItem.id = constants.EXPLORER_TOGGLE_CLOSE_ALL_EDITORS;
mockFn.mockClear();
expect(mockFn).not.toBeCalled();
explorerController.subscribe(EditorTreeEvent.onCloseAll, mockFn);

explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();

// EXPLORER_TOGGLE_SAVE_ALL
mockItem.id = constants.EXPLORER_TOGGLE_SAVE_ALL;
mockFn.mockClear();
expect(mockFn).not.toBeCalled();
explorerController.subscribe(EditorTreeEvent.onSaveAll, mockFn);

explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();

// EXPLORER_TOGGLE_VERTICAL
mockItem.id = constants.EXPLORER_TOGGLE_VERTICAL;
mockFn.mockClear();
expect(mockFn).not.toBeCalled();
explorerController.subscribe(
EditorTreeEvent.onSplitEditorLayout,
mockFn
);

explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();

// default
mockItem.id = 'custom-id';
mockFn.mockClear();
expect(mockFn).not.toBeCalled();
explorerService.onPanelToolbarClick(mockFn);

explorerController.onToolbarClick(mockItem, mockParentPanel);

expect(mockFn).toBeCalled();
expect(mockFn.mock.calls[0][0]).toBe(mockParentPanel);
expect(mockFn.mock.calls[0][1]).toBe(mockItem.id);
});
});
Loading

0 comments on commit d96e2b3

Please sign in to comment.