Browse Source

Refactor ComponentDelete

typed-command-runs
Artur Arseniev 5 months ago
parent
commit
5d1190a84f
  1. 2
      packages/core/src/commands/registry.ts
  2. 24
      packages/core/src/commands/view/ComponentDelete.ts
  3. 58
      packages/core/test/specs/commands/view/ComponentDelete.ts

2
packages/core/src/commands/registry.ts

@ -13,6 +13,7 @@ import type { ComponentNextCommandRegistryRun } from './view/ComponentNext';
import type { ComponentPrevCommandRegistryRun } from './view/ComponentPrev';
import type { ComponentEnterCommandRegistryRun } from './view/ComponentEnter';
import type { ComponentExitCommandRegistryRun } from './view/ComponentExit';
import type { ComponentDeleteCommandRegistryRun } from './view/ComponentDelete';
import type { CopyComponentCommandRegistryRun } from './view/CopyComponent';
import type { PasteComponentCommandRegistryRun } from './view/PasteComponent';
import type { CanvasMoveCommandRegistryRun, CanvasMoveCommandRegistryStop } from './view/CanvasMove';
@ -49,6 +50,7 @@ export interface CommandRegistryRun
ComponentPrevCommandRegistryRun,
ComponentEnterCommandRegistryRun,
ComponentExitCommandRegistryRun,
ComponentDeleteCommandRegistryRun,
CopyComponentCommandRegistryRun,
PasteComponentCommandRegistryRun,
CanvasMoveCommandRegistryRun,

24
packages/core/src/commands/view/ComponentDelete.ts

@ -1,9 +1,19 @@
import { isArray } from 'underscore';
import Component from '../../dom_components/model/Component';
import { CommandObject } from './CommandAbstract';
import type Component from '../../dom_components/model/Component';
import Editor from '../../editor';
import type { CommandPublicFnFromHandler } from '../registryHelpers';
import CommandAbstract from './CommandAbstract';
const command: CommandObject<{ component?: Component }> = {
run(ed, s, opts = {}) {
export interface ComponentDeleteRunOptions {
component?: Component | Component[];
}
export interface ComponentDeleteCommandRegistryRun {
'core:component-delete': CommandPublicFnFromHandler<CommandComponentDelete['run']>;
}
export default class CommandComponentDelete extends CommandAbstract<ComponentDeleteRunOptions> {
run(ed: Editor, s: any, opts: ComponentDeleteRunOptions = {}) {
const removed: Component[] = [];
let components = opts.component || ed.getSelectedAll();
components = isArray(components) ? [...components] : [components];
@ -23,7 +33,5 @@ const command: CommandObject<{ component?: Component }> = {
ed.selectRemove(removed);
return removed;
},
};
export default command;
}
}

58
packages/core/test/specs/commands/view/ComponentDelete.ts

@ -0,0 +1,58 @@
import ComponentDelete from '../../../../src/commands/view/ComponentDelete';
describe('ComponentDelete command', () => {
test('should remove selected removable components', () => {
const command = new ComponentDelete({ em: { logWarning: jest.fn() } });
const componentA = { get: jest.fn(() => true), remove: jest.fn() };
const componentB = { get: jest.fn(() => true), remove: jest.fn() };
const editor = {
getSelectedAll: jest.fn(() => [componentA, componentB]),
selectRemove: jest.fn(),
};
const result = command.run(editor as any, null, {});
expect(componentA.remove).toHaveBeenCalledTimes(1);
expect(componentB.remove).toHaveBeenCalledTimes(1);
expect(editor.selectRemove).toHaveBeenCalledWith([componentA, componentB]);
expect(result).toEqual([componentA, componentB]);
});
test('should use delegated remove target when available', () => {
const command = new ComponentDelete({ em: { logWarning: jest.fn() } });
const delegated = { remove: jest.fn() };
const component = {
get: jest.fn(() => true),
delegate: {
remove: jest.fn(() => delegated),
},
};
const editor = {
getSelectedAll: jest.fn(() => [component]),
selectRemove: jest.fn(),
};
command.run(editor as any, null, {});
expect(component.delegate.remove).toHaveBeenCalledWith(component);
expect(delegated.remove).toHaveBeenCalledTimes(1);
expect(editor.selectRemove).toHaveBeenCalledWith([component]);
});
test('should warn and skip non-removable components', () => {
const logWarning = jest.fn();
const command = new ComponentDelete({ em: { logWarning } });
const component = { get: jest.fn(() => false), remove: jest.fn() };
const editor = {
getSelectedAll: jest.fn(() => [component]),
selectRemove: jest.fn(),
};
const result = command.run(editor as any, null, {});
expect(logWarning).toHaveBeenCalledWith('The element is not removable', { component });
expect(component.remove).not.toHaveBeenCalled();
expect(editor.selectRemove).toHaveBeenCalledWith([]);
expect(result).toEqual([]);
});
});
Loading…
Cancel
Save