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