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')
8 exports['test exports'] = ($vimfx) ->
9 vimfx = createConfigAPI($vimfx)
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',
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')
23 exports['test vimfx.get and vimfx.set'] = ($vimfx, teardown) ->
24 vimfx = createConfigAPI($vimfx)
26 resetHintChars = prefs.tmp('hints.chars', 'ab cd')
27 resetBlacklist = prefs.tmp('blacklist', null)
28 originalOptions = Object.assign({}, $vimfx.options)
32 $vimfx.options = originalOptions
35 assert.equal(vimfx.get('hints.chars'), 'ab cd')
36 assert.ok(not prefs.has('blacklist'))
38 vimfx.set('hints.chars', 'xy z')
39 assert.equal(vimfx.get('hints.chars'), 'xy z')
41 vimfx.set('blacklist', 'test')
42 assert.equal(vimfx.get('blacklist'), 'test')
44 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
45 assert.arrayEqual(Object.keys(vimfx.get('translations')), ['KeyQ'])
46 assert.arrayEqual(vimfx.get('translations').KeyQ, ['ö', 'Ö'])
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')), [])
53 exports['test vimfx.getDefault'] = ($vimfx, teardown) ->
54 vimfx = createConfigAPI($vimfx)
56 reset = prefs.tmp('hints.chars', 'ab cd')
61 assert.equal(vimfx.getDefault('hints.chars'), defaults.options['hints.chars'])
63 exports['test customization'] = ($vimfx, teardown) ->
64 vimfx = createConfigAPI($vimfx)
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: ['ö', 'Ö']})
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
79 event = {code: 'KeyQ', key: 'q'}
81 # Add a simple test command.
84 description: 'Test command'
86 vimfx.set('custom.mode.normal.test_command', 'ö')
88 # Add a slightly more complex command.
89 vimfx.get('categories')['new_category'] = {
95 description: 'Test ignore mode command'
97 category: 'new_category'
99 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
101 $vimfx.createKeyTrees()
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)
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)
115 modes = $vimfx.getGroupedCommands({enabledOnly: true})
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'
122 [..., {command: test_command}] = category_misc.commands
123 assert.equal(test_command.description, 'Test command')
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, ['ö'])
133 # Remove the added commands.
134 delete vimfx.modes.normal.commands.test_command
135 delete vimfx.modes.ignore.commands.test_command
136 $vimfx.createKeyTrees()
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)
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)
152 modes = $vimfx.getGroupedCommands({enabledOnly: true})
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'
159 [..., {command: last_command}] = category_misc.commands
160 assert.notEqual(last_command.description, 'Test command')
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')
167 exports['test vimfx.addCommand order'] = ($vimfx, teardown) ->
168 vimfx = createConfigAPI($vimfx)
171 delete vimfx.modes.normal.commands.test_command
176 description: 'Test command'
178 }, Function.prototype)
179 vimfx.set('custom.mode.normal.test_command', 'ö')
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'
186 [{command: first_command}] = category_misc.commands
187 assert.equal(first_command.description, 'Test command')
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)
193 exports['test vimfx.addOptionOverrides'] = ($vimfx, teardown) ->
194 vimfx = createConfigAPI($vimfx)
196 originalOptions = Object.assign({}, $vimfx.options)
197 originalOptionOverrides = $vimfx.optionOverrides?[..]
198 $vimfx.optionOverrides = null
199 $vimfx.options.prevent_autofocus = true
201 reset?() # Defined below.
202 $vimfx.options = originalOptions
203 $vimfx.optionOverrides = originalOptionOverrides
206 vimfx.addOptionOverrides(
208 (location) -> location.hostname == 'example.com'
209 {prevent_autofocus: false}
213 assert.equal($vimfx.options.prevent_autofocus, true)
215 reset = testUtils.stub(utils, 'getCurrentLocation', -> {
216 hostname: 'example.com'
219 assert.equal($vimfx.options.prevent_autofocus, false)
221 $vimfx.emit('shutdown')
222 assert.equal($vimfx.options.prevent_autofocus, true)
224 exports['test vimfx.addKeyOverrides'] = ($vimfx, teardown) ->
225 vimfx = createConfigAPI($vimfx)
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 = {}
233 resetScrollToBottom?() # Defined below.
234 resetExitIgnoreMode?() # Defined below.
235 resetGetCurrentLocation?() # Defined below.
236 $vimfx.options = originalOptions
237 $vimfx.keyOverrides = originalKeyOverrides
240 vimfx.addKeyOverrides(
242 (location) -> location.hostname == 'example.co'
246 (location) -> location.href == 'about:blank'
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')
256 match = $vimfx.consumeKeyEvent(
257 {key: 'j'}, {mode: 'ignore', focusType: 'none'}
261 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
262 hostname: 'example.co'
266 match = $vimfx.consumeKeyEvent(
267 {key: '1'}, {mode: 'normal', focusType: 'none'}
269 assert.equal(match.type, 'count')
270 assert.equal(match.count, 1)
272 match = $vimfx.consumeKeyEvent(
273 {key: 'j'}, {mode: 'normal', focusType: 'none'}
277 match = $vimfx.consumeKeyEvent(
278 {key: 'foobar', ctrlKey: true},
279 {mode: 'normal', focusType: 'none'}
283 match = $vimfx.consumeKeyEvent(
285 {mode: 'normal', focusType: 'none'}
287 assert.equal(match.type, 'partial')
288 match = $vimfx.consumeKeyEvent(
290 {mode: 'normal', focusType: 'none'}
292 assert.equal(match.type, 'full')
293 assert.equal(match.count, undefined)
295 $vimfx.reset('ignore')
297 match = $vimfx.consumeKeyEvent(
299 {mode: 'ignore', focusType: 'none'}
303 match = $vimfx.consumeKeyEvent(
305 {mode: 'ignore', focusType: 'none'}
307 assert.equal(match.type, 'full')
310 $vimfx.emit('shutdown')
312 $vimfx.reset('normal')
313 match = $vimfx.consumeKeyEvent(
315 {mode: 'normal', focusType: 'none'}
319 $vimfx.reset('ignore')
320 match = $vimfx.consumeKeyEvent(
322 {mode: 'ignore', focusType: 'none'}
326 exports['test vimfx.send'] = ($vimfx) ->
327 vimfx = createConfigAPI($vimfx)
329 messageManager = new testUtils.MockMessageManager()
330 vim = new testUtils.MockVim(messageManager)
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)
337 vimfx.send(vim, 'message2', null, ->)
338 assert.equal(messageManager.sendAsyncMessageCalls, 2)
339 assert.equal(messageManager.addMessageListenerCalls, 1)
340 assert.equal(messageManager.removeMessageListenerCalls, 0)
342 $vimfx.emit('shutdown')
343 assert.equal(messageManager.sendAsyncMessageCalls, 2)
344 assert.equal(messageManager.addMessageListenerCalls, 1)
345 assert.equal(messageManager.removeMessageListenerCalls, 0)
347 exports['test vimfx.on and vimfx.off'] = ($vimfx) ->
348 vimfx = createConfigAPI($vimfx)
351 count = -> callCount += 1
352 vimfx.on('foo', count)
353 vimfx.on('bar', count)
356 assert.equal(callCount, 1)
359 assert.equal(callCount, 2)
361 vimfx.off('bar', count)
363 assert.equal(callCount, 2)
365 $vimfx.emit('shutdown')
368 assert.equal(callCount, 2)
370 exports['test vimfx.[gs]et(Default)? errors'] = ($vimfx) ->
371 vimfx = createConfigAPI($vimfx)
373 assert.throws(/unknown option/i, 'undefined', ->
377 assert.throws(/unknown option/i, 'undefined', ->
381 assert.throws(/unknown option/i, 'undefined', ->
385 assert.throws(/unknown option/i, 'unknown_pref', ->
386 vimfx.get('unknown_pref')
389 assert.throws(/unknown option/i, 'unknown_pref', ->
390 vimfx.getDefault('unknown_pref')
393 assert.throws(/no default/i, 'custom.mode.normal.foo', ->
394 vimfx.getDefault('custom.mode.normal.foo')
397 assert.throws(/no default/i, 'translations', ->
398 vimfx.getDefault('translations')
401 assert.throws(/unknown option/i, 'unknown_pref', ->
402 vimfx.set('unknown_pref', 'foo')
405 assert.throws(/boolean, number, string or null/i, 'undefined', ->
406 vimfx.set('hints.chars')
409 assert.throws(/boolean, number, string or null/i, 'object', ->
410 vimfx.set('hints.chars', ['a', 'b', 'c'])
413 exports['test vimfx.addCommand errors'] = ($vimfx) ->
414 vimfx = createConfigAPI($vimfx)
416 assert.throws(/name.+string.+required/i, 'undefined', ->
420 assert.throws(/name.+a-z.+underscore/i, 'Command', ->
421 vimfx.addCommand({name: 'Command'})
424 assert.throws(/name.+a-z.+underscore/i, 'command-name', ->
425 vimfx.addCommand({name: 'command-name'})
428 assert.throws(/name.+a-z.+underscore/i, 'ö', ->
429 vimfx.addCommand({name: 'ö'})
432 assert.throws(/non-empty description/i, 'undefined', ->
433 vimfx.addCommand({name: 'test'})
436 assert.throws(/non-empty description/i, '', ->
437 vimfx.addCommand({name: 'test', description: ''})
440 assert.throws(/unknown mode.+available.+normal/i, 'toString', ->
441 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
444 assert.throws(/unknown category.+available.+location/i, 'toString', ->
445 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
448 assert.throws(/order.+number/i, 'false', ->
449 vimfx.addCommand({name: 'test', description: 'Test', order: false})
452 assert.throws(/function/i, 'undefined', ->
453 vimfx.addCommand({name: 'test', description: 'Test'})
456 assert.throws(/function/i, 'false', ->
457 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
460 exports['test vimfx.add{Option,Key}Overrides errors'] = ($vimfx) ->
461 vimfx = createConfigAPI($vimfx)
463 # Passing nothing is OK, and just shouldn’t throw.
464 vimfx.addOptionOverrides()
465 vimfx.addKeyOverrides()
467 assert.throws(/array/i, '1', ->
468 vimfx.addOptionOverrides(1)
471 assert.throws(/array/i, '1', ->
472 vimfx.addKeyOverrides(1)
475 assert.throws(/length 2/i, '0', ->
476 vimfx.addOptionOverrides([])
479 assert.throws(/length 2/i, '0', ->
480 vimfx.addKeyOverrides([])
483 assert.throws(/length 2/i, '1', ->
484 vimfx.addOptionOverrides([1])
487 assert.throws(/length 2/i, '1', ->
488 vimfx.addKeyOverrides([1])
491 assert.throws(/length 2/i, '3', ->
492 vimfx.addOptionOverrides([1, 2, 3])
495 assert.throws(/length 2/i, '3', ->
496 vimfx.addKeyOverrides([1, 2, 3])
499 assert.throws(/function/i, 'null', ->
500 vimfx.addOptionOverrides([null, 2])
503 assert.throws(/function/i, 'null', ->
504 vimfx.addKeyOverrides([null, 2])
507 assert.throws(/object/i, 'null', ->
508 vimfx.addOptionOverrides([(-> true), null])
511 assert.throws(/array of strings/i, '[object Object]', ->
512 vimfx.addKeyOverrides([(-> true), {j: false}])
515 assert.throws(/array of strings/i, '1,2', ->
516 vimfx.addKeyOverrides([(-> true), [1, 2]])
519 exports['test vimfx.{on,off} errors'] = ($vimfx) ->
520 vimfx = createConfigAPI($vimfx)
522 assert.throws(/string/i, 'undefined', ->
526 assert.throws(/string/i, 'undefined', ->
530 assert.throws(/string/i, '1', ->
534 assert.throws(/string/i, '1', ->
538 assert.throws(/function/i, 'undefined', ->
542 assert.throws(/function/i, 'undefined', ->
546 assert.throws(/function/i, 'null', ->
547 vimfx.on('event', null)
550 assert.throws(/function/i, 'null', ->
551 vimfx.off('event', null)
554 exports['test vimfx.send errors'] = ($vimfx) ->
555 vimfx = createConfigAPI($vimfx)
557 vim = new testUtils.MockVim()
559 assert.throws(/vim object/i, 'undefined', ->
563 assert.throws(/vim object/i, '[object Object]', ->
564 vimfx.send({mode: 'normal'})
567 assert.throws(/message string/i, 'undefined', ->
571 assert.throws(/message string/i, 'false', ->
572 vimfx.send(vim, false)
575 assert.throws(/not.+function/i, 'function() {}', ->
576 vimfx.send(vim, 'message', ->)
579 assert.throws(/if provided.+function/i, '5', ->
580 vimfx.send(vim, 'message', null, 5)