2 # Copyright Simon Lydell 2015, 2016.
4 # This file is part of VimFx.
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.
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.
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/>.
20 testUtils = require('./utils')
21 createConfigAPI = require('../lib/api')
22 defaults = require('../lib/defaults')
23 prefs = require('../lib/prefs')
24 utils = require('../lib/utils')
28 exports['test exports'] = (assert, $vimfx) ->
29 vimfx = createConfigAPI($vimfx)
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',
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')
43 exports['test vimfx.get and vimfx.set'] = (assert, $vimfx, teardown) ->
44 vimfx = createConfigAPI($vimfx)
46 resetHintChars = prefs.tmp('hint_chars', 'abcd')
47 resetBlacklist = prefs.tmp('black_list', null)
48 originalOptions = Object.assign({}, $vimfx.options)
52 $vimfx.options = originalOptions
55 assert.equal(vimfx.get('hint_chars'), 'abcd')
56 assert.ok(not prefs.has('black_list'))
58 vimfx.set('hint_chars', 'xyz')
59 assert.equal(vimfx.get('hint_chars'), 'xyz')
61 vimfx.set('black_list', 'test')
62 assert.equal(vimfx.get('black_list'), 'test')
64 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
65 assert.deepEqual(vimfx.get('translations'), {KeyQ: ['ö', 'Ö']})
67 $vimfx.emit('shutdown')
68 assert.equal(vimfx.get('hint_chars'), 'abcd')
69 assert.ok(not prefs.has('black_list'))
70 assert.deepEqual(vimfx.get('translations'), {})
72 exports['test vimfx.getDefault'] = (assert, $vimfx, teardown) ->
73 vimfx = createConfigAPI($vimfx)
75 reset = prefs.tmp('hint_chars', 'abcd')
80 assert.equal(vimfx.getDefault('hint_chars'), defaults.options.hint_chars)
82 exports['test customization'] = (assert, $vimfx, teardown) ->
83 vimfx = createConfigAPI($vimfx)
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: ['ö', 'Ö']})
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
98 event = {code: 'KeyQ'}
100 # Add a simple test command.
103 description: 'Test command'
105 vimfx.set('custom.mode.normal.test_command', 'ö')
107 # Add a slightly more complex command.
108 vimfx.get('categories')['new_category'] = {
114 description: 'Test ignore mode command'
116 category: 'new_category'
118 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
120 $vimfx.createKeyTrees()
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)
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)
134 modes = $vimfx.getGroupedCommands({enabledOnly: true})
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'
141 [..., {command: test_command}] = category_misc.commands
142 assert.equal(test_command.description, 'Test command')
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, ['ö'])
152 # Remove the added commands.
153 delete vimfx.modes.normal.commands.test_command
154 delete vimfx.modes.ignore.commands.test_command
155 $vimfx.createKeyTrees()
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)
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)
171 modes = $vimfx.getGroupedCommands({enabledOnly: true})
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'
178 [..., {command: last_command}] = category_misc.commands
179 assert.notEqual(last_command.description, 'Test command')
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')
186 exports['test vimfx.addCommand order'] = (assert, $vimfx, teardown) ->
187 vimfx = createConfigAPI($vimfx)
190 delete vimfx.modes.normal.commands.test_command
195 description: 'Test command'
197 }, Function.prototype)
198 vimfx.set('custom.mode.normal.test_command', 'ö')
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'
205 [{command: first_command}] = category_misc.commands
206 assert.equal(first_command.description, 'Test command')
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)
212 exports['test vimfx.addOptionOverrides'] = (assert, $vimfx, teardown) ->
213 vimfx = createConfigAPI($vimfx)
215 originalOptions = Object.assign({}, $vimfx.options)
216 originalOptionOverrides = Object.assign({}, $vimfx.optionOverrides)
217 $vimfx.optionOverrides = null
218 $vimfx.options.prevent_autofocus = true
220 reset?() # Defined below.
221 $vimfx.options = originalOptions
222 $vimfx.optionOverrides = originalOptionOverrides
225 vimfx.addOptionOverrides(
227 (location) -> location.hostname == 'example.com'
228 {prevent_autofocus: false}
232 assert.equal($vimfx.options.prevent_autofocus, true)
234 reset = testUtils.stub(utils, 'getCurrentLocation', -> {
235 hostname: 'example.com'
238 assert.equal($vimfx.options.prevent_autofocus, false)
240 $vimfx.emit('shutdown')
241 assert.equal($vimfx.options.prevent_autofocus, true)
243 exports['test vimfx.addKeyOverrides'] = (assert, $vimfx, teardown) ->
244 vimfx = createConfigAPI($vimfx)
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 = {}
252 resetScrollToBottom?() # Defined below.
253 resetGetCurrentLocation?() # Defined below.
254 $vimfx.options = originalOptions
255 $vimfx.keyOverrides = originalKeyOverrides
258 vimfx.addKeyOverrides(
260 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
264 (location, mode) -> mode == 'ignore' and location.href == 'about:blank'
269 resetScrollToBottom = prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j')
270 $vimfx.createKeyTrees()
271 $vimfx.reset('normal')
273 match = $vimfx.consumeKeyEvent({key: 'j'},
274 {mode: 'ignore', focusType: 'none'})
277 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
278 hostname: 'example.co'
282 match = $vimfx.consumeKeyEvent({key: '1'},
283 {mode: 'normal', focusType: 'none'})
284 assert.equal(match.type, 'count')
285 assert.equal(match.count, 1)
287 match = $vimfx.consumeKeyEvent({key: 'j'},
288 {mode: 'normal', focusType: 'none'})
291 match = $vimfx.consumeKeyEvent({key: 'foobar', ctrlKey: true},
292 {mode: 'normal', focusType: 'none'})
295 match = $vimfx.consumeKeyEvent({key: 'foobar'},
296 {mode: 'normal', focusType: 'none'})
297 assert.equal(match.type, 'partial')
298 match = $vimfx.consumeKeyEvent({key: 'j'},
299 {mode: 'normal', focusType: 'none'})
300 assert.equal(match.type, 'full')
301 assert.strictEqual(match.count, undefined)
303 $vimfx.reset('ignore')
305 match = $vimfx.consumeKeyEvent({key: 'j'},
306 {mode: 'ignore', focusType: 'none'})
309 match = $vimfx.consumeKeyEvent({key: 'escape'},
310 {mode: 'ignore', focusType: 'none'})
313 $vimfx.emit('shutdown')
315 $vimfx.reset('normal')
316 match = $vimfx.consumeKeyEvent({key: 'j'},
317 {mode: 'normal', focusType: 'none'})
320 $vimfx.reset('ignore')
321 match = $vimfx.consumeKeyEvent({key: 'escape'},
322 {mode: 'ignore', focusType: 'none'})
325 exports['test vimfx.send'] = (assert, $vimfx) ->
326 vimfx = createConfigAPI($vimfx)
328 messageManager = new testUtils.MockMessageManager()
329 vim = new testUtils.MockVim(messageManager)
331 vimfx.send(vim, 'message', {example: 5})
332 assert.equal(messageManager.sendAsyncMessageCalls, 1)
333 assert.equal(messageManager.addMessageListenerCalls, 0)
334 assert.equal(messageManager.removeMessageListenerCalls, 0)
336 vimfx.send(vim, 'message2', null, ->)
337 assert.equal(messageManager.sendAsyncMessageCalls, 2)
338 assert.equal(messageManager.addMessageListenerCalls, 1)
339 assert.equal(messageManager.removeMessageListenerCalls, 0)
341 $vimfx.emit('shutdown')
342 assert.equal(messageManager.sendAsyncMessageCalls, 2)
343 assert.equal(messageManager.addMessageListenerCalls, 1)
344 assert.equal(messageManager.removeMessageListenerCalls, 0)
346 exports['test vimfx.on and vimfx.off'] = (assert, $vimfx) ->
347 vimfx = createConfigAPI($vimfx)
350 count = -> callCount += 1
351 vimfx.on('foo', count)
352 vimfx.on('bar', count)
355 assert.equal(callCount, 1)
358 assert.equal(callCount, 2)
360 vimfx.off('bar', count)
362 assert.equal(callCount, 2)
364 $vimfx.emit('shutdown')
367 assert.equal(callCount, 2)
369 exports['test vimfx.[gs]et(Default)? errors'] = (assert, $vimfx) ->
370 vimfx = createConfigAPI($vimfx)
372 throws(assert, /unknown pref/i, 'undefined', ->
376 throws(assert, /unknown pref/i, 'undefined', ->
380 throws(assert, /unknown pref/i, 'undefined', ->
384 throws(assert, /unknown pref/i, 'unknown_pref', ->
385 vimfx.get('unknown_pref')
388 throws(assert, /unknown pref/i, 'unknown_pref', ->
389 vimfx.getDefault('unknown_pref')
392 throws(assert, /no default/i, 'custom.mode.normal.foo', ->
393 vimfx.getDefault('custom.mode.normal.foo')
396 throws(assert, /no default/i, 'translations', ->
397 vimfx.getDefault('translations')
400 throws(assert, /unknown pref/i, 'unknown_pref', ->
401 vimfx.set('unknown_pref', 'foo')
404 throws(assert, /boolean, number, string or null/i, 'undefined', ->
405 vimfx.set('hint_chars')
408 throws(assert, /boolean, number, string or null/i, 'object', ->
409 vimfx.set('hint_chars', ['a', 'b', 'c'])
412 exports['test vimfx.addCommand errors'] = (assert, $vimfx) ->
413 vimfx = createConfigAPI($vimfx)
415 throws(assert, /name.+string.+required/i, 'undefined', ->
419 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
420 vimfx.addCommand({name: 'Command'})
423 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
424 vimfx.addCommand({name: 'command-name'})
427 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
428 vimfx.addCommand({name: 'ö'})
431 throws(assert, /non-empty description/i, 'undefined', ->
432 vimfx.addCommand({name: 'test'})
435 throws(assert, /non-empty description/i, '', ->
436 vimfx.addCommand({name: 'test', description: ''})
439 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
440 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
443 throws(assert, /unknown category.+available.+location/i, 'toString', ->
444 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
447 throws(assert, /order.+number/i, 'false', ->
448 vimfx.addCommand({name: 'test', description: 'Test', order: false})
451 throws(assert, /function/i, 'undefined', ->
452 vimfx.addCommand({name: 'test', description: 'Test'})
455 throws(assert, /function/i, 'false', ->
456 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
459 exports['test vimfx.send errors'] = (assert, $vimfx) ->
460 vimfx = createConfigAPI($vimfx)
462 vim = new testUtils.MockVim()
464 throws(assert, /vim object/i, 'undefined', ->
468 throws(assert, /vim object/i, '[object Object]', ->
469 vimfx.send({mode: 'normal'})
472 throws(assert, /message string/i, 'undefined', ->
476 throws(assert, /message string/i, 'false', ->
477 vimfx.send(vim, false)
480 throws(assert, /not.+function/i, 'function () {}', ->
481 vimfx.send(vim, 'message', ->)
484 throws(assert, /if provided.+function/i, '5', ->
485 vimfx.send(vim, 'message', null, 5)