2 # Copyright Simon Lydell 2015.
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 prefs = require('../lib/prefs')
22 { utils: Cu } = Components
24 { getAPI } = Cu.import(
25 Services.prefs.getCharPref('extensions.VimFx.api_url'), {}
28 exports['test exports'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
29 assert.equal(typeof vimfx.get, 'function', 'get')
30 assert.equal(typeof vimfx.set, 'function', 'set')
31 assert.equal(typeof vimfx.addCommand, 'function', 'addCommand')
32 assert.equal(typeof vimfx.addOptionOverrides, 'function',
34 assert.equal(typeof vimfx.addKeyOverrides, 'function', 'addKeyOverrides')
35 assert.equal(typeof vimfx.on, 'function', 'on')
36 assert.equal(typeof vimfx.refresh, 'function', 'refresh')
37 assert.equal(vimfx.modes, passed_vimfx.modes, 'modes')
38 assert.equal(vimfx.categories, passed_vimfx.options.categories, 'categories')
41 exports['test get'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
42 prefs.tmp('hint_chars', 'abcd', ->
43 assert.equal(vimfx.get('hint_chars'), 'abcd')
47 exports['test customization'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
48 # Save some values that need to be temporarily changed below.
49 originalOptions = Object.assign({}, passed_vimfx.options)
50 originalCategories = Object.assign({}, passed_vimfx.options.categories)
52 # Setup some settings for testing.
53 passed_vimfx.options.keyValidator = null
54 passed_vimfx.options.ignore_keyboard_layout = true
55 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
58 event = {code: 'KeyQ'}
60 # Add a simple test command.
63 description: 'Test command'
65 vimfx.set('custom.mode.normal.test_command', 'ö')
67 # Add a slightly more complex command.
68 vimfx.categories['new_category'] = {
69 name: -> 'New category'
74 description: 'Test insert mode command'
76 category: 'new_category'
78 vimfx.set('custom.mode.insert.test_command', 'ö <ö> <c-c-invalid>')
80 # Test that the new simple command can be run.
81 passed_vimfx.reset('normal')
82 match = passed_vimfx.consumeKeyEvent(event, 'normal')
83 assert.equal(match.type, 'full')
84 assert.equal(match.command.run(), nonce)
86 # Test that the new complex command can be run.
87 passed_vimfx.reset('insert')
88 match = passed_vimfx.consumeKeyEvent(event, 'insert')
89 assert.equal(match.type, 'full')
90 assert.equal(match.command.run(), nonce)
92 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
94 # Test that the new simple command can show up in the help dialog.
95 mode_normal = modes.find((mode) -> mode._name == 'normal')
96 category_misc = mode_normal.categories.find(
97 (category) -> category._name == 'misc'
99 [ ..., { command: test_command } ] = category_misc.commands
100 assert.equal(test_command.description(), 'Test command')
102 # Test that the new complex command can show up in the help dialog.
103 mode_insert = modes.find((mode) -> mode._name == 'insert')
104 [ category_new ] = mode_insert.categories
105 assert.equal(category_new.name, 'New category')
106 [ test_command ] = category_new.commands
107 assert.equal(test_command.command.description(), 'Test insert mode command')
108 assert.deepEqual(test_command.enabledSequences, ['<ö>'])
110 # Remove the added commands.
111 delete vimfx.modes.normal.commands.test_command
112 delete vimfx.modes.insert.commands.test_command
115 # Test that the new simple command cannot be run.
116 passed_vimfx.reset('normal')
117 match = passed_vimfx.consumeKeyEvent(event, 'normal')
118 if match.type == 'full'
119 value = try match.command.run() catch then null
120 assert.notEqual(value, nonce)
122 # Test that the new complex command cannot be run.
123 passed_vimfx.reset('insert')
124 match = passed_vimfx.consumeKeyEvent(event, 'insert')
125 if match.type == 'full'
126 value = try match.command.run() catch then null
127 assert.notEqual(value, nonce)
129 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
131 # Test that the new simple command cannot show up in the help dialog.
132 mode_normal = modes.find((mode) -> mode._name == 'normal')
133 category_misc = mode_normal.categories.find(
134 (category) -> category._name == 'misc'
136 [ ..., { command: last_command } ] = category_misc.commands
137 assert.notEqual(last_command.description(), 'Test command')
139 # Test that the new complex command cannot show up in the help dialog.
140 mode_insert = modes.find((mode) -> mode._name == 'insert')
141 [ first_category ] = mode_insert.categories
142 assert.notEqual(first_category.name, 'New category')
144 # Restore original values.
145 passed_vimfx.options = originalOptions
146 passed_vimfx.options.categories = originalCategories
149 exports['test addCommand order'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
152 description: 'Test command'
155 vimfx.set('custom.mode.normal.test_command', 'ö')
157 modes = passed_vimfx.getGroupedCommands()
158 mode_normal = modes.find((mode) -> mode._name == 'normal')
159 category_misc = mode_normal.categories.find(
160 (category) -> category._name == 'misc'
162 [ { command: first_command } ] = category_misc.commands
163 assert.equal(first_command.description(), 'Test command')
165 delete vimfx.modes.normal.commands.test_command
168 exports['test addOptionOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
169 originalOptions = Object.assign({}, passed_vimfx.options)
170 originalOptionOverrides = Object.assign({}, passed_vimfx.optionOverrides)
172 passed_vimfx.optionOverrides = null
173 passed_vimfx.options.prevent_autofocus = true
175 vimfx.addOptionOverrides(
177 (location) -> location.hostname == 'example.com'
178 {prevent_autofocus: false}
182 assert.equal(passed_vimfx.options.prevent_autofocus, true)
184 passed_vimfx.currentVim =
186 location: {hostname: 'example.com'}
188 assert.equal(passed_vimfx.options.prevent_autofocus, false)
190 passed_vimfx.options = originalOptions
191 passed_vimfx.optionOverrides = originalOptionOverrides
194 exports['test addKeyOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
195 originalOptions = Object.assign({}, passed_vimfx.options)
196 originalKeyOverrides = Object.assign({}, passed_vimfx.keyOverrides)
198 passed_vimfx.options.keyValidator = null
199 passed_vimfx.options.ignore_keyboard_layout = false
200 passed_vimfx.options.translations = {}
202 vimfx.addKeyOverrides(
204 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
208 (location, mode) -> mode == 'insert' and location.href == 'about:blank'
213 prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j', ->
214 passed_vimfx.reset('normal')
216 match = passed_vimfx.consumeKeyEvent({key: 'j'}, 'insert')
219 passed_vimfx.currentVim =
221 location: {hostname: 'example.co', href: 'about:blank'}
223 match = passed_vimfx.consumeKeyEvent({key: '1'}, 'normal')
224 assert.equal(match.type, 'count')
225 assert.equal(match.count, 1)
227 match = passed_vimfx.consumeKeyEvent({key: 'j'}, 'normal')
230 match = passed_vimfx.consumeKeyEvent({key: 'foobar', ctrlKey: true},
234 match = passed_vimfx.consumeKeyEvent({key: 'foobar'}, 'normal')
235 assert.equal(match.type, 'partial')
236 match = passed_vimfx.consumeKeyEvent({key: 'j'}, 'normal')
237 assert.equal(match.type, 'full')
238 assert.strictEqual(match.count, undefined)
240 passed_vimfx.reset('insert')
242 match = passed_vimfx.consumeKeyEvent({key: 'j'}, 'insert')
245 match = passed_vimfx.consumeKeyEvent({key: 'escape'}, 'insert')
249 passed_vimfx.options = originalOptions
250 passed_vimfx.keyOverrides = originalKeyOverrides
253 exports['test vimfx.[gs]et errors'] = (assert) -> getAPI((vimfx) ->
254 throws(assert, /unknown pref/i, 'undefined', ->
258 throws(assert, /unknown pref/i, 'undefined', ->
262 throws(assert, /unknown pref/i, 'unknown_pref', ->
263 vimfx.get('unknown_pref')
266 throws(assert, /unknown pref/i, 'unknown_pref', ->
267 vimfx.set('unknown_pref', 'foo')
270 throws(assert, /boolean, number, string or null/i, 'undefined', ->
271 vimfx.set('hint_chars')
274 throws(assert, /boolean, number, string or null/i, 'object', ->
275 vimfx.set('hint_chars', ['a', 'b', 'c'])
279 exports['test vimfx.addCommand errors'] = (assert) -> getAPI((vimfx) ->
280 throws(assert, /name.+string.+required/i, 'undefined', ->
284 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
285 vimfx.addCommand({name: 'Command'})
288 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
289 vimfx.addCommand({name: 'command-name'})
292 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
293 vimfx.addCommand({name: 'ö'})
296 throws(assert, /non-empty description/i, 'undefined', ->
297 vimfx.addCommand({name: 'test'})
300 throws(assert, /non-empty description/i, '', ->
301 vimfx.addCommand({name: 'test', description: ''})
304 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
305 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
308 throws(assert, /unknown category.+available.+location/i, 'toString', ->
309 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
312 throws(assert, /order.+number/i, 'false', ->
313 vimfx.addCommand({name: 'test', description: 'Test', order: false})
316 throws(assert, /function/i, 'undefined', ->
317 vimfx.addCommand({name: 'test', description: 'Test'})
320 throws(assert, /function/i, 'false', ->
321 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
325 throws = (assert, regex, badValue, fn) ->
328 assert.ok(error.message.startsWith('VimFx:'), 'start with VimFx')
329 assert.ok(error.message.endsWith(": #{ badValue }"), 'show bad value')
330 assert.ok(regex.test(error.message), 'regex match')