]> git.gir.st - VimFx.git/blob - extension/test/test-api.coffee
Implement filtering hints by text and related changes
[VimFx.git] / extension / test / test-api.coffee
1 ###
2 # Copyright Simon Lydell 2015, 2016.
3 #
4 # This file is part of VimFx.
5 #
6 # VimFx is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # VimFx is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with VimFx. If not, see <http://www.gnu.org/licenses/>.
18 ###
19
20 testUtils = require('./utils')
21 createConfigAPI = require('../lib/api')
22 defaults = require('../lib/defaults')
23 prefs = require('../lib/prefs')
24 utils = require('../lib/utils')
25
26 {throws} = testUtils
27
28 exports['test exports'] = (assert, $vimfx) ->
29 vimfx = createConfigAPI($vimfx)
30
31 assert.equal(typeof vimfx.get, 'function', 'get')
32 assert.equal(typeof vimfx.getDefault, 'function', 'getDefault')
33 assert.equal(typeof vimfx.set, 'function', 'set')
34 assert.equal(typeof vimfx.addCommand, 'function', 'addCommand')
35 assert.equal(typeof vimfx.addOptionOverrides, 'function',
36 'addOptionOverrides')
37 assert.equal(typeof vimfx.addKeyOverrides, 'function', 'addKeyOverrides')
38 assert.equal(typeof vimfx.send, 'function', 'send')
39 assert.equal(typeof vimfx.on, 'function', 'on')
40 assert.equal(typeof vimfx.off, 'function', 'off')
41 assert.equal(vimfx.modes, $vimfx.modes, 'modes')
42
43 exports['test vimfx.get and vimfx.set'] = (assert, $vimfx, teardown) ->
44 vimfx = createConfigAPI($vimfx)
45
46 resetHintChars = prefs.tmp('hints.chars', 'ab cd')
47 resetBlacklist = prefs.tmp('blacklist', null)
48 originalOptions = Object.assign({}, $vimfx.options)
49 teardown(->
50 resetHintChars?()
51 resetBlacklist?()
52 $vimfx.options = originalOptions
53 )
54
55 assert.equal(vimfx.get('hints.chars'), 'ab cd')
56 assert.ok(not prefs.has('blacklist'))
57
58 vimfx.set('hints.chars', 'xy z')
59 assert.equal(vimfx.get('hints.chars'), 'xy z')
60
61 vimfx.set('blacklist', 'test')
62 assert.equal(vimfx.get('blacklist'), 'test')
63
64 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
65 assert.deepEqual(vimfx.get('translations'), {KeyQ: ['ö', 'Ö']})
66
67 $vimfx.emit('shutdown')
68 assert.equal(vimfx.get('hints.chars'), 'ab cd')
69 assert.ok(not prefs.has('blacklist'))
70 assert.deepEqual(vimfx.get('translations'), {})
71
72 exports['test vimfx.getDefault'] = (assert, $vimfx, teardown) ->
73 vimfx = createConfigAPI($vimfx)
74
75 reset = prefs.tmp('hints.chars', 'ab cd')
76 teardown(->
77 reset?()
78 )
79
80 assert.equal(vimfx.getDefault('hints.chars'), defaults.options['hints.chars'])
81
82 exports['test customization'] = (assert, $vimfx, teardown) ->
83 vimfx = createConfigAPI($vimfx)
84
85 originalOptions = Object.assign({}, $vimfx.options)
86 originalCategories = Object.assign({}, $vimfx.options.categories)
87 $vimfx.options.keyValidator = null
88 $vimfx.options.ignore_keyboard_layout = true
89 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
90 teardown(->
91 $vimfx.options = originalOptions
92 $vimfx.options.categories = originalCategories
93 delete $vimfx.modes.normal.commands.test_command
94 delete $vimfx.modes.ignore.commands.test_command
95 )
96
97 nonce = {}
98 event = {code: 'KeyQ', key: 'q'}
99
100 # Add a simple test command.
101 vimfx.addCommand({
102 name: 'test_command'
103 description: 'Test command'
104 }, -> nonce)
105 vimfx.set('custom.mode.normal.test_command', 'ö')
106
107 # Add a slightly more complex command.
108 vimfx.get('categories')['new_category'] = {
109 name: 'New category'
110 order: -100
111 }
112 vimfx.addCommand({
113 name: 'test_command'
114 description: 'Test ignore mode command'
115 mode: 'ignore'
116 category: 'new_category'
117 }, -> nonce)
118 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
119
120 $vimfx.createKeyTrees()
121
122 # Test that the new simple command can be run.
123 $vimfx.reset('normal')
124 match = $vimfx.consumeKeyEvent(event, {mode: 'normal', focusType: 'none'})
125 assert.equal(match.type, 'full')
126 assert.equal(match.command.run(), nonce)
127
128 # Test that the new complex command can be run.
129 $vimfx.reset('ignore')
130 match = $vimfx.consumeKeyEvent(event, {mode: 'ignore', focusType: 'none'})
131 assert.equal(match.type, 'full')
132 assert.equal(match.command.run(), nonce)
133
134 modes = $vimfx.getGroupedCommands({enabledOnly: true})
135
136 # Test that the new simple command can show up in the help dialog.
137 mode_normal = modes.find((mode) -> mode._name == 'normal')
138 category_misc = mode_normal.categories.find(
139 (category) -> category._name == 'misc'
140 )
141 [..., {command: test_command}] = category_misc.commands
142 assert.equal(test_command.description, 'Test command')
143
144 # Test that the new complex command can show up in the help dialog.
145 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
146 [category_new] = mode_ignore.categories
147 assert.equal(category_new.name, 'New category')
148 [test_command] = category_new.commands
149 assert.equal(test_command.command.description, 'Test ignore mode command')
150 assert.deepEqual(test_command.enabledSequences, ['ö'])
151
152 # Remove the added commands.
153 delete vimfx.modes.normal.commands.test_command
154 delete vimfx.modes.ignore.commands.test_command
155 $vimfx.createKeyTrees()
156
157 # Test that the new simple command cannot be run.
158 $vimfx.reset('normal')
159 match = $vimfx.consumeKeyEvent(event, {mode: 'normal', focusType: 'none'})
160 if match.type == 'full'
161 value = try match.command.run() catch then null
162 assert.notEqual(value, nonce)
163
164 # Test that the new complex command cannot be run.
165 $vimfx.reset('ignore')
166 match = $vimfx.consumeKeyEvent(event, {mode: 'ignore', focusType: 'none'})
167 if match.type == 'full'
168 value = try match.command.run() catch then null
169 assert.notEqual(value, nonce)
170
171 modes = $vimfx.getGroupedCommands({enabledOnly: true})
172
173 # Test that the new simple command cannot show up in the help dialog.
174 mode_normal = modes.find((mode) -> mode._name == 'normal')
175 category_misc = mode_normal.categories.find(
176 (category) -> category._name == 'misc'
177 )
178 [..., {command: last_command}] = category_misc.commands
179 assert.notEqual(last_command.description, 'Test command')
180
181 # Test that the new complex command cannot show up in the help dialog.
182 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
183 [first_category] = mode_ignore.categories
184 assert.notEqual(first_category.name, 'New category')
185
186 exports['test vimfx.addCommand order'] = (assert, $vimfx, teardown) ->
187 vimfx = createConfigAPI($vimfx)
188
189 teardown(->
190 delete vimfx.modes.normal.commands.test_command
191 )
192
193 vimfx.addCommand({
194 name: 'test_command'
195 description: 'Test command'
196 order: 0
197 }, Function.prototype)
198 vimfx.set('custom.mode.normal.test_command', 'ö')
199
200 modes = $vimfx.getGroupedCommands()
201 mode_normal = modes.find((mode) -> mode._name == 'normal')
202 category_misc = mode_normal.categories.find(
203 (category) -> category._name == 'misc'
204 )
205 [{command: first_command}] = category_misc.commands
206 assert.equal(first_command.description, 'Test command')
207
208 assert.ok('test_command' of vimfx.modes.normal.commands)
209 $vimfx.emit('shutdown')
210 assert.ok('test_command' not of vimfx.modes.normal.commands)
211
212 exports['test vimfx.addOptionOverrides'] = (assert, $vimfx, teardown) ->
213 vimfx = createConfigAPI($vimfx)
214
215 originalOptions = Object.assign({}, $vimfx.options)
216 originalOptionOverrides = Object.assign({}, $vimfx.optionOverrides)
217 $vimfx.optionOverrides = null
218 $vimfx.options.prevent_autofocus = true
219 teardown(->
220 reset?() # Defined below.
221 $vimfx.options = originalOptions
222 $vimfx.optionOverrides = originalOptionOverrides
223 )
224
225 vimfx.addOptionOverrides(
226 [
227 (location) -> location.hostname == 'example.com'
228 {prevent_autofocus: false}
229 ]
230 )
231
232 assert.equal($vimfx.options.prevent_autofocus, true)
233
234 reset = testUtils.stub(utils, 'getCurrentLocation', -> {
235 hostname: 'example.com'
236 })
237
238 assert.equal($vimfx.options.prevent_autofocus, false)
239
240 $vimfx.emit('shutdown')
241 assert.equal($vimfx.options.prevent_autofocus, true)
242
243 exports['test vimfx.addKeyOverrides'] = (assert, $vimfx, teardown) ->
244 vimfx = createConfigAPI($vimfx)
245
246 originalOptions = Object.assign({}, $vimfx.options)
247 originalKeyOverrides = Object.assign({}, $vimfx.keyOverrides)
248 $vimfx.options.keyValidator = null
249 $vimfx.options.ignore_keyboard_layout = false
250 $vimfx.options.translations = {}
251 teardown(->
252 resetScrollToBottom?() # Defined below.
253 resetGetCurrentLocation?() # Defined below.
254 $vimfx.options = originalOptions
255 $vimfx.keyOverrides = originalKeyOverrides
256 )
257
258 vimfx.addKeyOverrides(
259 [
260 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
261 ['j', '<c-foobar>']
262 ],
263 [
264 (location, mode) -> mode == 'ignore' and location.href == 'about:blank'
265 ['<escape>']
266 ]
267 )
268
269 resetScrollToBottom = prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j')
270 $vimfx.createKeyTrees()
271 $vimfx.reset('normal')
272
273 match = $vimfx.consumeKeyEvent(
274 {key: 'j'}, {mode: 'ignore', focusType: 'none'}
275 )
276 assert.ok(match)
277
278 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
279 hostname: 'example.co'
280 href: 'about:blank'
281 })
282
283 match = $vimfx.consumeKeyEvent(
284 {key: '1'}, {mode: 'normal', focusType: 'none'}
285 )
286 assert.equal(match.type, 'count')
287 assert.equal(match.count, 1)
288
289 match = $vimfx.consumeKeyEvent(
290 {key: 'j'}, {mode: 'normal', focusType: 'none'}
291 )
292 assert.ok(not match)
293
294 match = $vimfx.consumeKeyEvent(
295 {key: 'foobar', ctrlKey: true},
296 {mode: 'normal', focusType: 'none'}
297 )
298 assert.ok(not match)
299
300 match = $vimfx.consumeKeyEvent(
301 {key: 'foobar'},
302 {mode: 'normal', focusType: 'none'}
303 )
304 assert.equal(match.type, 'partial')
305 match = $vimfx.consumeKeyEvent(
306 {key: 'j'},
307 {mode: 'normal', focusType: 'none'}
308 )
309 assert.equal(match.type, 'full')
310 assert.strictEqual(match.count, undefined)
311
312 $vimfx.reset('ignore')
313
314 match = $vimfx.consumeKeyEvent(
315 {key: 'j'},
316 {mode: 'ignore', focusType: 'none'}
317 )
318 assert.ok(match)
319
320 match = $vimfx.consumeKeyEvent(
321 {key: 'escape'},
322 {mode: 'ignore', focusType: 'none'}
323 )
324 assert.ok(not match)
325
326 $vimfx.emit('shutdown')
327
328 $vimfx.reset('normal')
329 match = $vimfx.consumeKeyEvent(
330 {key: 'j'},
331 {mode: 'normal', focusType: 'none'}
332 )
333 assert.ok(match)
334
335 $vimfx.reset('ignore')
336 match = $vimfx.consumeKeyEvent(
337 {key: 'escape'},
338 {mode: 'ignore', focusType: 'none'}
339 )
340 assert.ok(match)
341
342 exports['test vimfx.send'] = (assert, $vimfx) ->
343 vimfx = createConfigAPI($vimfx)
344
345 messageManager = new testUtils.MockMessageManager()
346 vim = new testUtils.MockVim(messageManager)
347
348 vimfx.send(vim, 'message', {example: 5})
349 assert.equal(messageManager.sendAsyncMessageCalls, 1)
350 assert.equal(messageManager.addMessageListenerCalls, 0)
351 assert.equal(messageManager.removeMessageListenerCalls, 0)
352
353 vimfx.send(vim, 'message2', null, ->)
354 assert.equal(messageManager.sendAsyncMessageCalls, 2)
355 assert.equal(messageManager.addMessageListenerCalls, 1)
356 assert.equal(messageManager.removeMessageListenerCalls, 0)
357
358 $vimfx.emit('shutdown')
359 assert.equal(messageManager.sendAsyncMessageCalls, 2)
360 assert.equal(messageManager.addMessageListenerCalls, 1)
361 assert.equal(messageManager.removeMessageListenerCalls, 0)
362
363 exports['test vimfx.on and vimfx.off'] = (assert, $vimfx) ->
364 vimfx = createConfigAPI($vimfx)
365
366 callCount = 0
367 count = -> callCount += 1
368 vimfx.on('foo', count)
369 vimfx.on('bar', count)
370
371 $vimfx.emit('foo')
372 assert.equal(callCount, 1)
373
374 $vimfx.emit('bar')
375 assert.equal(callCount, 2)
376
377 vimfx.off('bar', count)
378 $vimfx.emit('bar')
379 assert.equal(callCount, 2)
380
381 $vimfx.emit('shutdown')
382
383 $vimfx.emit('foo')
384 assert.equal(callCount, 2)
385
386 exports['test vimfx.[gs]et(Default)? errors'] = (assert, $vimfx) ->
387 vimfx = createConfigAPI($vimfx)
388
389 throws(assert, /unknown pref/i, 'undefined', ->
390 vimfx.get()
391 )
392
393 throws(assert, /unknown pref/i, 'undefined', ->
394 vimfx.getDefault()
395 )
396
397 throws(assert, /unknown pref/i, 'undefined', ->
398 vimfx.set()
399 )
400
401 throws(assert, /unknown pref/i, 'unknown_pref', ->
402 vimfx.get('unknown_pref')
403 )
404
405 throws(assert, /unknown pref/i, 'unknown_pref', ->
406 vimfx.getDefault('unknown_pref')
407 )
408
409 throws(assert, /no default/i, 'custom.mode.normal.foo', ->
410 vimfx.getDefault('custom.mode.normal.foo')
411 )
412
413 throws(assert, /no default/i, 'translations', ->
414 vimfx.getDefault('translations')
415 )
416
417 throws(assert, /unknown pref/i, 'unknown_pref', ->
418 vimfx.set('unknown_pref', 'foo')
419 )
420
421 throws(assert, /boolean, number, string or null/i, 'undefined', ->
422 vimfx.set('hints.chars')
423 )
424
425 throws(assert, /boolean, number, string or null/i, 'object', ->
426 vimfx.set('hints.chars', ['a', 'b', 'c'])
427 )
428
429 exports['test vimfx.addCommand errors'] = (assert, $vimfx) ->
430 vimfx = createConfigAPI($vimfx)
431
432 throws(assert, /name.+string.+required/i, 'undefined', ->
433 vimfx.addCommand()
434 )
435
436 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
437 vimfx.addCommand({name: 'Command'})
438 )
439
440 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
441 vimfx.addCommand({name: 'command-name'})
442 )
443
444 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
445 vimfx.addCommand({name: 'ö'})
446 )
447
448 throws(assert, /non-empty description/i, 'undefined', ->
449 vimfx.addCommand({name: 'test'})
450 )
451
452 throws(assert, /non-empty description/i, '', ->
453 vimfx.addCommand({name: 'test', description: ''})
454 )
455
456 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
457 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
458 )
459
460 throws(assert, /unknown category.+available.+location/i, 'toString', ->
461 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
462 )
463
464 throws(assert, /order.+number/i, 'false', ->
465 vimfx.addCommand({name: 'test', description: 'Test', order: false})
466 )
467
468 throws(assert, /function/i, 'undefined', ->
469 vimfx.addCommand({name: 'test', description: 'Test'})
470 )
471
472 throws(assert, /function/i, 'false', ->
473 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
474 )
475
476 exports['test vimfx.send errors'] = (assert, $vimfx) ->
477 vimfx = createConfigAPI($vimfx)
478
479 vim = new testUtils.MockVim()
480
481 throws(assert, /vim object/i, 'undefined', ->
482 vimfx.send()
483 )
484
485 throws(assert, /vim object/i, '[object Object]', ->
486 vimfx.send({mode: 'normal'})
487 )
488
489 throws(assert, /message string/i, 'undefined', ->
490 vimfx.send(vim)
491 )
492
493 throws(assert, /message string/i, 'false', ->
494 vimfx.send(vim, false)
495 )
496
497 throws(assert, /not.+function/i, 'function () {}', ->
498 vimfx.send(vim, 'message', ->)
499 )
500
501 throws(assert, /if provided.+function/i, '5', ->
502 vimfx.send(vim, 'message', null, 5)
503 )
Imprint / Impressum