Pop-up dictionary browser extension for language learning. Successor to Yomichan. (PERSONAL FORK)
1/*
2 * Copyright (C) 2023-2025 Yomitan Authors
3 * Copyright (C) 2020-2022 Yomichan Authors
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19import {describe, expect, test} from 'vitest';
20import {HotkeyUtil} from '../ext/js/input/hotkey-util.js';
21
22describe('HotkeyUtil', () => {
23 describe('CommandConversions', () => {
24 /* eslint-disable @stylistic/no-multi-spaces */
25 /** @type {{os: import('environment').OperatingSystem, command: string, expectedCommand: string, expectedInput: {key: string, modifiers: import('input').Modifier[]}}[]} */
26 const data = [
27 {os: 'win', command: 'Alt+F', expectedCommand: 'Alt+F', expectedInput: {key: 'KeyF', modifiers: ['alt']}},
28 {os: 'win', command: 'F1', expectedCommand: 'F1', expectedInput: {key: 'F1', modifiers: []}},
29
30 {os: 'win', command: 'Ctrl+Alt+Shift+F1', expectedCommand: 'Ctrl+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['ctrl', 'alt', 'shift']}},
31 {os: 'win', command: 'MacCtrl+Alt+Shift+F1', expectedCommand: 'Ctrl+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['ctrl', 'alt', 'shift']}},
32 {os: 'win', command: 'Command+Alt+Shift+F1', expectedCommand: 'Command+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['meta', 'alt', 'shift']}},
33
34 {os: 'mac', command: 'Ctrl+Alt+Shift+F1', expectedCommand: 'Command+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['meta', 'alt', 'shift']}},
35 {os: 'mac', command: 'MacCtrl+Alt+Shift+F1', expectedCommand: 'MacCtrl+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['ctrl', 'alt', 'shift']}},
36 {os: 'mac', command: 'Command+Alt+Shift+F1', expectedCommand: 'Command+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['meta', 'alt', 'shift']}},
37
38 {os: 'linux', command: 'Ctrl+Alt+Shift+F1', expectedCommand: 'Ctrl+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['ctrl', 'alt', 'shift']}},
39 {os: 'linux', command: 'MacCtrl+Alt+Shift+F1', expectedCommand: 'Ctrl+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['ctrl', 'alt', 'shift']}},
40 {os: 'linux', command: 'Command+Alt+Shift+F1', expectedCommand: 'Command+Alt+Shift+F1', expectedInput: {key: 'F1', modifiers: ['meta', 'alt', 'shift']}},
41 ];
42 /* eslint-enable @stylistic/no-multi-spaces */
43
44 const hotkeyUtil = new HotkeyUtil();
45 for (const {command, os, expectedInput, expectedCommand} of data) {
46 test(`${command} on ${os} -> ${JSON.stringify(expectedInput)}`, () => {
47 hotkeyUtil.os = os;
48 const input = structuredClone(hotkeyUtil.convertCommandToInput(command));
49 expect(input).toStrictEqual(expectedInput);
50 const command2 = hotkeyUtil.convertInputToCommand(input.key, input.modifiers);
51 expect(command2).toStrictEqual(expectedCommand);
52 });
53 }
54 });
55
56 describe('DisplayNames', () => {
57 /* eslint-disable @stylistic/no-multi-spaces */
58 /** @type {{os: import('environment').OperatingSystem, key: ?string, modifiers: import('input').Modifier[], expected: string}[]} */
59 const data = [
60 {os: 'win', key: null, modifiers: [], expected: ''},
61 {os: 'win', key: 'KeyF', modifiers: [], expected: 'F'},
62 {os: 'win', key: 'F1', modifiers: [], expected: 'F1'},
63 {os: 'win', key: null, modifiers: ['ctrl'], expected: 'Ctrl'},
64 {os: 'win', key: 'KeyF', modifiers: ['ctrl'], expected: 'Ctrl + F'},
65 {os: 'win', key: 'F1', modifiers: ['ctrl'], expected: 'Ctrl + F1'},
66 {os: 'win', key: null, modifiers: ['alt'], expected: 'Alt'},
67 {os: 'win', key: 'KeyF', modifiers: ['alt'], expected: 'Alt + F'},
68 {os: 'win', key: 'F1', modifiers: ['alt'], expected: 'Alt + F1'},
69 {os: 'win', key: null, modifiers: ['shift'], expected: 'Shift'},
70 {os: 'win', key: 'KeyF', modifiers: ['shift'], expected: 'Shift + F'},
71 {os: 'win', key: 'F1', modifiers: ['shift'], expected: 'Shift + F1'},
72 {os: 'win', key: null, modifiers: ['meta'], expected: 'Windows'},
73 {os: 'win', key: 'KeyF', modifiers: ['meta'], expected: 'Windows + F'},
74 {os: 'win', key: 'F1', modifiers: ['meta'], expected: 'Windows + F1'},
75 {os: 'win', key: null, modifiers: ['mouse1'], expected: 'Mouse 1'},
76 {os: 'win', key: 'KeyF', modifiers: ['mouse1'], expected: 'Mouse 1 + F'},
77 {os: 'win', key: 'F1', modifiers: ['mouse1'], expected: 'Mouse 1 + F1'},
78
79 {os: 'mac', key: null, modifiers: [], expected: ''},
80 {os: 'mac', key: 'KeyF', modifiers: [], expected: 'F'},
81 {os: 'mac', key: 'F1', modifiers: [], expected: 'F1'},
82 {os: 'mac', key: null, modifiers: ['ctrl'], expected: 'Ctrl'},
83 {os: 'mac', key: 'KeyF', modifiers: ['ctrl'], expected: 'Ctrl + F'},
84 {os: 'mac', key: 'F1', modifiers: ['ctrl'], expected: 'Ctrl + F1'},
85 {os: 'mac', key: null, modifiers: ['alt'], expected: 'Opt'},
86 {os: 'mac', key: 'KeyF', modifiers: ['alt'], expected: 'Opt + F'},
87 {os: 'mac', key: 'F1', modifiers: ['alt'], expected: 'Opt + F1'},
88 {os: 'mac', key: null, modifiers: ['shift'], expected: 'Shift'},
89 {os: 'mac', key: 'KeyF', modifiers: ['shift'], expected: 'Shift + F'},
90 {os: 'mac', key: 'F1', modifiers: ['shift'], expected: 'Shift + F1'},
91 {os: 'mac', key: null, modifiers: ['meta'], expected: 'Cmd'},
92 {os: 'mac', key: 'KeyF', modifiers: ['meta'], expected: 'Cmd + F'},
93 {os: 'mac', key: 'F1', modifiers: ['meta'], expected: 'Cmd + F1'},
94 {os: 'mac', key: null, modifiers: ['mouse1'], expected: 'Mouse 1'},
95 {os: 'mac', key: 'KeyF', modifiers: ['mouse1'], expected: 'Mouse 1 + F'},
96 {os: 'mac', key: 'F1', modifiers: ['mouse1'], expected: 'Mouse 1 + F1'},
97
98 {os: 'linux', key: null, modifiers: [], expected: ''},
99 {os: 'linux', key: 'KeyF', modifiers: [], expected: 'F'},
100 {os: 'linux', key: 'F1', modifiers: [], expected: 'F1'},
101 {os: 'linux', key: null, modifiers: ['ctrl'], expected: 'Ctrl'},
102 {os: 'linux', key: 'KeyF', modifiers: ['ctrl'], expected: 'Ctrl + F'},
103 {os: 'linux', key: 'F1', modifiers: ['ctrl'], expected: 'Ctrl + F1'},
104 {os: 'linux', key: null, modifiers: ['alt'], expected: 'Alt'},
105 {os: 'linux', key: 'KeyF', modifiers: ['alt'], expected: 'Alt + F'},
106 {os: 'linux', key: 'F1', modifiers: ['alt'], expected: 'Alt + F1'},
107 {os: 'linux', key: null, modifiers: ['shift'], expected: 'Shift'},
108 {os: 'linux', key: 'KeyF', modifiers: ['shift'], expected: 'Shift + F'},
109 {os: 'linux', key: 'F1', modifiers: ['shift'], expected: 'Shift + F1'},
110 {os: 'linux', key: null, modifiers: ['meta'], expected: 'Super'},
111 {os: 'linux', key: 'KeyF', modifiers: ['meta'], expected: 'Super + F'},
112 {os: 'linux', key: 'F1', modifiers: ['meta'], expected: 'Super + F1'},
113 {os: 'linux', key: null, modifiers: ['mouse1'], expected: 'Mouse 1'},
114 {os: 'linux', key: 'KeyF', modifiers: ['mouse1'], expected: 'Mouse 1 + F'},
115 {os: 'linux', key: 'F1', modifiers: ['mouse1'], expected: 'Mouse 1 + F1'},
116
117 {os: 'unknown', key: null, modifiers: [], expected: ''},
118 {os: 'unknown', key: 'KeyF', modifiers: [], expected: 'F'},
119 {os: 'unknown', key: 'F1', modifiers: [], expected: 'F1'},
120 {os: 'unknown', key: null, modifiers: ['ctrl'], expected: 'Ctrl'},
121 {os: 'unknown', key: 'KeyF', modifiers: ['ctrl'], expected: 'Ctrl + F'},
122 {os: 'unknown', key: 'F1', modifiers: ['ctrl'], expected: 'Ctrl + F1'},
123 {os: 'unknown', key: null, modifiers: ['alt'], expected: 'Alt'},
124 {os: 'unknown', key: 'KeyF', modifiers: ['alt'], expected: 'Alt + F'},
125 {os: 'unknown', key: 'F1', modifiers: ['alt'], expected: 'Alt + F1'},
126 {os: 'unknown', key: null, modifiers: ['shift'], expected: 'Shift'},
127 {os: 'unknown', key: 'KeyF', modifiers: ['shift'], expected: 'Shift + F'},
128 {os: 'unknown', key: 'F1', modifiers: ['shift'], expected: 'Shift + F1'},
129 {os: 'unknown', key: null, modifiers: ['meta'], expected: 'Meta'},
130 {os: 'unknown', key: 'KeyF', modifiers: ['meta'], expected: 'Meta + F'},
131 {os: 'unknown', key: 'F1', modifiers: ['meta'], expected: 'Meta + F1'},
132 {os: 'unknown', key: null, modifiers: ['mouse1'], expected: 'Mouse 1'},
133 {os: 'unknown', key: 'KeyF', modifiers: ['mouse1'], expected: 'Mouse 1 + F'},
134 {os: 'unknown', key: 'F1', modifiers: ['mouse1'], expected: 'Mouse 1 + F1'},
135 ];
136 /* eslint-enable @stylistic/no-multi-spaces */
137
138 const hotkeyUtil = new HotkeyUtil();
139
140 test.each(data)('$key with $modifiers on $os -> display value $expected', ({os, key, modifiers, expected}) => {
141 hotkeyUtil.os = os;
142 const displayName = hotkeyUtil.getInputDisplayValue(key, modifiers);
143 expect(displayName).toStrictEqual(expected);
144 });
145 });
146
147 describe('SortModifiers', () => {
148 /** @type {{modifiers: import('input').Modifier[], expected: import('input').Modifier[]}[]} */
149 const data = [
150 {modifiers: [], expected: []},
151 {modifiers: ['shift', 'alt', 'ctrl', 'mouse4', 'meta', 'mouse1', 'mouse0'], expected: ['meta', 'ctrl', 'alt', 'shift', 'mouse0', 'mouse1', 'mouse4']},
152 ];
153
154 const hotkeyUtil = new HotkeyUtil();
155 for (const {modifiers, expected} of data) {
156 test(`[${modifiers.join(',')}] -> [${expected.join(',')}]`, () => {
157 const modifiers2 = hotkeyUtil.sortModifiers(modifiers);
158 expect(modifiers2).toStrictEqual(modifiers);
159 expect(modifiers2).toStrictEqual(expected);
160 });
161 }
162 });
163});