fix: restore native text context menu
This commit is contained in:
120
tests/unit/context-menu.test.ts
Normal file
120
tests/unit/context-menu.test.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
createTextContextMenuTemplate,
|
||||
type TextContextMenuContext,
|
||||
} from '@electron/main/context-menu';
|
||||
|
||||
type ContextOverrides = {
|
||||
isEditable?: boolean;
|
||||
selectionText?: string;
|
||||
editFlags?: Partial<Electron.EditFlags>;
|
||||
};
|
||||
|
||||
function context(overrides: ContextOverrides = {}): TextContextMenuContext {
|
||||
return {
|
||||
isEditable: overrides.isEditable ?? false,
|
||||
selectionText: overrides.selectionText ?? '',
|
||||
editFlags: {
|
||||
canUndo: false,
|
||||
canRedo: false,
|
||||
canCut: false,
|
||||
canCopy: false,
|
||||
canPaste: false,
|
||||
canDelete: false,
|
||||
canSelectAll: false,
|
||||
canEditRichly: false,
|
||||
...overrides.editFlags,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function enabledByRole(template: Electron.MenuItemConstructorOptions[] | null) {
|
||||
return Object.fromEntries(
|
||||
(template ?? [])
|
||||
.filter((item) => item.role)
|
||||
.map((item) => [item.role, item.enabled]),
|
||||
);
|
||||
}
|
||||
|
||||
describe('text context menu', () => {
|
||||
it('does not create a menu for ordinary non-editable content', () => {
|
||||
expect(createTextContextMenuTemplate(context())).toBeNull();
|
||||
});
|
||||
|
||||
it('allows paste and select all in an editable control without a selection', () => {
|
||||
const template = createTextContextMenuTemplate(context({
|
||||
isEditable: true,
|
||||
editFlags: {
|
||||
canPaste: true,
|
||||
canSelectAll: true,
|
||||
},
|
||||
}));
|
||||
|
||||
expect(template?.map((item) => item.label ?? item.type)).toEqual([
|
||||
'剪切',
|
||||
'复制',
|
||||
'粘贴',
|
||||
'separator',
|
||||
'全选',
|
||||
]);
|
||||
expect(enabledByRole(template)).toEqual({
|
||||
cut: false,
|
||||
copy: false,
|
||||
paste: true,
|
||||
selectAll: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('enables every requested action for an editable selection when supported', () => {
|
||||
const template = createTextContextMenuTemplate(context({
|
||||
isEditable: true,
|
||||
selectionText: 'Makelore',
|
||||
editFlags: {
|
||||
canCut: true,
|
||||
canCopy: true,
|
||||
canPaste: true,
|
||||
canSelectAll: true,
|
||||
},
|
||||
}));
|
||||
|
||||
expect(enabledByRole(template)).toEqual({
|
||||
cut: true,
|
||||
copy: true,
|
||||
paste: true,
|
||||
selectAll: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps cut and paste disabled for a read-only selection', () => {
|
||||
const template = createTextContextMenuTemplate(context({
|
||||
selectionText: 'Makelore',
|
||||
editFlags: {
|
||||
canCut: true,
|
||||
canCopy: true,
|
||||
canPaste: true,
|
||||
canSelectAll: true,
|
||||
},
|
||||
}));
|
||||
|
||||
expect(enabledByRole(template)).toEqual({
|
||||
cut: false,
|
||||
copy: true,
|
||||
paste: false,
|
||||
selectAll: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('respects disabled renderer editing capabilities', () => {
|
||||
const template = createTextContextMenuTemplate(context({
|
||||
isEditable: true,
|
||||
selectionText: 'Makelore',
|
||||
}));
|
||||
|
||||
expect(enabledByRole(template)).toEqual({
|
||||
cut: false,
|
||||
copy: false,
|
||||
paste: false,
|
||||
selectAll: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user