]> git.gir.st - VimFx.git/blob - extension/test/test-api.coffee
Fix `vimfx.send` test
[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 assert = require('./assert')
21 testUtils = require('./utils')
22 createConfigAPI = require('../lib/api')
23 defaults = require('../lib/defaults')
24 prefs = require('../lib/prefs')
25 utils = require('../lib/utils')
26
27 exports['test exports'] = ($vimfx) ->
28 vimfx = createConfigAPI($vimfx)
29
30 assert.equal(typeof vimfx.get, 'function', 'get')
31 assert.equal(typeof vimfx.getDefault, 'function', 'getDefault')
32 assert.equal(typeof vimfx.set, 'function', 'set')
33 assert.equal(typeof vimfx.addCommand, 'function', 'addCommand')
34 assert.equal(typeof vimfx.addOptionOverrides, 'function',
35 'addOptionOverrides')
36 assert.equal(typeof vimfx.addKeyOverrides, 'function', 'addKeyOverrides')
37 assert.equal(typeof vimfx.send, 'function', 'send')
38 assert.equal(typeof vimfx.on, 'function', 'on')
39 assert.equal(typeof vimfx.off, 'function', 'off')
40 assert.equal(vimfx.modes, $vimfx.modes, 'modes')
41
42 exports['test vimfx.get and vimfx.set'] = ($vimfx, teardown) ->
43 vimfx = createConfigAPI($vimfx)
44
45 resetHintChars = prefs.tmp('hints.chars', 'ab cd')
46 resetBlacklist = prefs.tmp('blacklist', null)
47 originalOptions = Object.assign({}, $vimfx.options)
48 teardown(->
49 resetHintChars?()
50 resetBlacklist?()
51 $vimfx.options = originalOptions
52 )
53
54 assert.equal(vimfx.get('hints.chars'), 'ab cd')
55 assert.ok(not prefs.has('blacklist'))
56
57 vimfx.set('hints.chars', 'xy z')
58 assert.equal(vimfx.get('hints.chars'), 'xy z')
59
60 vimfx.set('blacklist', 'test')
61 assert.equal(vimfx.get('blacklist'), 'test')
62
63 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
64 assert.arrayEqual(Object.keys(vimfx.get('translations')), ['KeyQ'])
65 assert.arrayEqual(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.arrayEqual(Object.keys(vimfx.get('translations')), [])
71
72 exports['test vimfx.getDefault'] = ($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'] = ($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.arrayEqual(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'] = ($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'] = ($vimfx, teardown) ->
213 vimfx = createConfigAPI($vimfx)
214
215 originalOptions = Object.assign({}, $vimfx.options)
216 originalOptionOverrides = $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'] = ($vimfx, teardown) ->
244 vimfx = createConfigAPI($vimfx)
245
246 originalOptions = Object.assign({}, $vimfx.options)
247 originalKeyOverrides = $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 resetExitIgnoreMode?() # Defined below.
254 resetGetCurrentLocation?() # Defined below.
255 $vimfx.options = originalOptions
256 $vimfx.keyOverrides = originalKeyOverrides
257 )
258
259 vimfx.addKeyOverrides(
260 [
261 (location) -> location.hostname == 'example.co'
262 ['j', '<c-foobar>']
263 ],
264 [
265 (location) -> location.href == 'about:blank'
266 ['<escape>']
267 ]
268 )
269
270 resetScrollToBottom = prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j')
271 resetExitIgnoreMode = prefs.tmp('mode.ignore.exit', '<escape>')
272 $vimfx.createKeyTrees()
273 $vimfx.reset('normal')
274
275 match = $vimfx.consumeKeyEvent(
276 {key: 'j'}, {mode: 'ignore', focusType: 'none'}
277 )
278 assert.ok(match)
279
280 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
281 hostname: 'example.co'
282 href: 'about:blank'
283 })
284
285 match = $vimfx.consumeKeyEvent(
286 {key: '1'}, {mode: 'normal', focusType: 'none'}
287 )
288 assert.equal(match.type, 'count')
289 assert.equal(match.count, 1)
290
291 match = $vimfx.consumeKeyEvent(
292 {key: 'j'}, {mode: 'normal', focusType: 'none'}
293 )
294 assert.ok(not match)
295
296 match = $vimfx.consumeKeyEvent(
297 {key: 'foobar', ctrlKey: true},
298 {mode: 'normal', focusType: 'none'}
299 )
300 assert.ok(not match)
301
302 match = $vimfx.consumeKeyEvent(
303 {key: 'foobar'},
304 {mode: 'normal', focusType: 'none'}
305 )
306 assert.equal(match.type, 'partial')
307 match = $vimfx.consumeKeyEvent(
308 {key: 'j'},
309 {mode: 'normal', focusType: 'none'}
310 )
311 assert.equal(match.type, 'full')
312 assert.equal(match.count, undefined)
313
314 $vimfx.reset('ignore')
315
316 match = $vimfx.consumeKeyEvent(
317 {key: 'j'},
318 {mode: 'ignore', focusType: 'none'}
319 )
320 assert.ok(match)
321
322 match = $vimfx.consumeKeyEvent(
323 {key: 'escape'},
324 {mode: 'ignore', focusType: 'none'}
325 )
326 assert.equal(match.type, 'full')
327 assert.ok(match)
328
329 $vimfx.emit('shutdown')
330
331 $vimfx.reset('normal')
332 match = $vimfx.consumeKeyEvent(
333 {key: 'j'},
334 {mode: 'normal', focusType: 'none'}
335 )
336 assert.ok(match)
337
338 $vimfx.reset('ignore')
339 match = $vimfx.consumeKeyEvent(
340 {key: 'escape'},
341 {mode: 'ignore', focusType: 'none'}
342 )
343 assert.ok(match)
344
345 exports['test vimfx.send'] = ($vimfx) ->
346 vimfx = createConfigAPI($vimfx)
347
348 messageManager = new testUtils.MockMessageManager()
349 vim = new testUtils.MockVim(messageManager)
350
351 vimfx.send(vim, 'message', {example: 5})
352 assert.equal(messageManager.sendAsyncMessageCalls, 1)
353 assert.equal(messageManager.addMessageListenerCalls, 0)
354 assert.equal(messageManager.removeMessageListenerCalls, 0)
355
356 vimfx.send(vim, 'message2', null, ->)
357 assert.equal(messageManager.sendAsyncMessageCalls, 2)
358 assert.equal(messageManager.addMessageListenerCalls, 1)
359 assert.equal(messageManager.removeMessageListenerCalls, 0)
360
361 $vimfx.emit('shutdown')
362 assert.equal(messageManager.sendAsyncMessageCalls, 2)
363 assert.equal(messageManager.addMessageListenerCalls, 1)
364 assert.equal(messageManager.removeMessageListenerCalls, 0)
365
366 exports['test vimfx.on and vimfx.off'] = ($vimfx) ->
367 vimfx = createConfigAPI($vimfx)
368
369 callCount = 0
370 count = -> callCount += 1
371 vimfx.on('foo', count)
372 vimfx.on('bar', count)
373
374 $vimfx.emit('foo')
375 assert.equal(callCount, 1)
376
377 $vimfx.emit('bar')
378 assert.equal(callCount, 2)
379
380 vimfx.off('bar', count)
381 $vimfx.emit('bar')
382 assert.equal(callCount, 2)
383
384 $vimfx.emit('shutdown')
385
386 $vimfx.emit('foo')
387 assert.equal(callCount, 2)
388
389 exports['test vimfx.[gs]et(Default)? errors'] = ($vimfx) ->
390 vimfx = createConfigAPI($vimfx)
391
392 assert.throws(/unknown option/i, 'undefined', ->
393 vimfx.get()
394 )
395
396 assert.throws(/unknown option/i, 'undefined', ->
397 vimfx.getDefault()
398 )
399
400 assert.throws(/unknown option/i, 'undefined', ->
401 vimfx.set()
402 )
403
404 assert.throws(/unknown option/i, 'unknown_pref', ->
405 vimfx.get('unknown_pref')
406 )
407
408 assert.throws(/unknown option/i, 'unknown_pref', ->
409 vimfx.getDefault('unknown_pref')
410 )
411
412 assert.throws(/no default/i, 'custom.mode.normal.foo', ->
413 vimfx.getDefault('custom.mode.normal.foo')
414 )
415
416 assert.throws(/no default/i, 'translations', ->
417 vimfx.getDefault('translations')
418 )
419
420 assert.throws(/unknown option/i, 'unknown_pref', ->
421 vimfx.set('unknown_pref', 'foo')
422 )
423
424 assert.throws(/boolean, number, string or null/i, 'undefined', ->
425 vimfx.set('hints.chars')
426 )
427
428 assert.throws(/boolean, number, string or null/i, 'object', ->
429 vimfx.set('hints.chars', ['a', 'b', 'c'])
430 )
431
432 exports['test vimfx.addCommand errors'] = ($vimfx) ->
433 vimfx = createConfigAPI($vimfx)
434
435 assert.throws(/name.+string.+required/i, 'undefined', ->
436 vimfx.addCommand()
437 )
438
439 assert.throws(/name.+a-z.+underscore/i, 'Command', ->
440 vimfx.addCommand({name: 'Command'})
441 )
442
443 assert.throws(/name.+a-z.+underscore/i, 'command-name', ->
444 vimfx.addCommand({name: 'command-name'})
445 )
446
447 assert.throws(/name.+a-z.+underscore/i, 'ö', ->
448 vimfx.addCommand({name: 'ö'})
449 )
450
451 assert.throws(/non-empty description/i, 'undefined', ->
452 vimfx.addCommand({name: 'test'})
453 )
454
455 assert.throws(/non-empty description/i, '', ->
456 vimfx.addCommand({name: 'test', description: ''})
457 )
458
459 assert.throws(/unknown mode.+available.+normal/i, 'toString', ->
460 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
461 )
462
463 assert.throws(/unknown category.+available.+location/i, 'toString', ->
464 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
465 )
466
467 assert.throws(/order.+number/i, 'false', ->
468 vimfx.addCommand({name: 'test', description: 'Test', order: false})
469 )
470
471 assert.throws(/function/i, 'undefined', ->
472 vimfx.addCommand({name: 'test', description: 'Test'})
473 )
474
475 assert.throws(/function/i, 'false', ->
476 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
477 )
478
479 exports['test vimfx.add{Option,Key}Overrides errors'] = ($vimfx) ->
480 vimfx = createConfigAPI($vimfx)
481
482 # Passing nothing is OK, and just shouldn’t throw.
483 vimfx.addOptionOverrides()
484 vimfx.addKeyOverrides()
485
486 assert.throws(/array/i, '1', ->
487 vimfx.addOptionOverrides(1)
488 )
489
490 assert.throws(/array/i, '1', ->
491 vimfx.addKeyOverrides(1)
492 )
493
494 assert.throws(/length 2/i, '0', ->
495 vimfx.addOptionOverrides([])
496 )
497
498 assert.throws(/length 2/i, '0', ->
499 vimfx.addKeyOverrides([])
500 )
501
502 assert.throws(/length 2/i, '1', ->
503 vimfx.addOptionOverrides([1])
504 )
505
506 assert.throws(/length 2/i, '1', ->
507 vimfx.addKeyOverrides([1])
508 )
509
510 assert.throws(/length 2/i, '3', ->
511 vimfx.addOptionOverrides([1, 2, 3])
512 )
513
514 assert.throws(/length 2/i, '3', ->
515 vimfx.addKeyOverrides([1, 2, 3])
516 )
517
518 assert.throws(/function/i, 'null', ->
519 vimfx.addOptionOverrides([null, 2])
520 )
521
522 assert.throws(/function/i, 'null', ->
523 vimfx.addKeyOverrides([null, 2])
524 )
525
526 assert.throws(/object/i, 'null', ->
527 vimfx.addOptionOverrides([(-> true), null])
528 )
529
530 assert.throws(/array of strings/i, '[object Object]', ->
531 vimfx.addKeyOverrides([(-> true), {j: false}])
532 )
533
534 assert.throws(/array of strings/i, '1,2', ->
535 vimfx.addKeyOverrides([(-> true), [1, 2]])
536 )
537
538 exports['test vimfx.{on,off} errors'] = ($vimfx) ->
539 vimfx = createConfigAPI($vimfx)
540
541 assert.throws(/string/i, 'undefined', ->
542 vimfx.on()
543 )
544
545 assert.throws(/string/i, 'undefined', ->
546 vimfx.off()
547 )
548
549 assert.throws(/string/i, '1', ->
550 vimfx.on(1)
551 )
552
553 assert.throws(/string/i, '1', ->
554 vimfx.off(1)
555 )
556
557 assert.throws(/function/i, 'undefined', ->
558 vimfx.on('event')
559 )
560
561 assert.throws(/function/i, 'undefined', ->
562 vimfx.off('event')
563 )
564
565 assert.throws(/function/i, 'null', ->
566 vimfx.on('event', null)
567 )
568
569 assert.throws(/function/i, 'null', ->
570 vimfx.off('event', null)
571 )
572
573 exports['test vimfx.send errors'] = ($vimfx) ->
574 vimfx = createConfigAPI($vimfx)
575
576 vim = new testUtils.MockVim()
577
578 assert.throws(/vim object/i, 'undefined', ->
579 vimfx.send()
580 )
581
582 assert.throws(/vim object/i, '[object Object]', ->
583 vimfx.send({mode: 'normal'})
584 )
585
586 assert.throws(/message string/i, 'undefined', ->
587 vimfx.send(vim)
588 )
589
590 assert.throws(/message string/i, 'false', ->
591 vimfx.send(vim, false)
592 )
593
594 assert.throws(/not.+function/i, 'function() {}', ->
595 vimfx.send(vim, 'message', ->)
596 )
597
598 assert.throws(/if provided.+function/i, '5', ->
599 vimfx.send(vim, 'message', null, 5)
600 )
Imprint / Impressum