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')
40 exports['test get'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
41 prefs.tmp('hint_chars', 'abcd', ->
42 assert.equal(vimfx.get('hint_chars'), 'abcd')
46 exports['test customization'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
47 # Save some values that need to be temporarily changed below.
48 originalOptions = Object.assign({}, passed_vimfx.options)
49 originalCategories = Object.assign({}, passed_vimfx.options.categories)
51 # Setup some settings for testing.
52 passed_vimfx.options.keyValidator = null
53 passed_vimfx.options.ignore_keyboard_layout = true
54 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
57 event = {code: 'KeyQ'}
59 # Add a simple test command.
62 description: 'Test command'
64 vimfx.set('custom.mode.normal.test_command', 'ö')
66 # Add a slightly more complex command.
67 vimfx.get('categories')['new_category'] = {
68 name: -> 'New category'
73 description: 'Test ignore mode command'
75 category: 'new_category'
77 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
79 # Test that the new simple command can be run.
80 passed_vimfx.reset('normal')
81 match = passed_vimfx.consumeKeyEvent(event, {mode: 'normal'})
82 assert.equal(match.type, 'full')
83 assert.equal(match.command.run(), nonce)
85 # Test that the new complex command can be run.
86 passed_vimfx.reset('ignore')
87 match = passed_vimfx.consumeKeyEvent(event, {mode: 'ignore'})
88 assert.equal(match.type, 'full')
89 assert.equal(match.command.run(), nonce)
91 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
93 # Test that the new simple command can show up in the help dialog.
94 mode_normal = modes.find((mode) -> mode._name == 'normal')
95 category_misc = mode_normal.categories.find(
96 (category) -> category._name == 'misc'
98 [ ..., { command: test_command } ] = category_misc.commands
99 assert.equal(test_command.description(), 'Test command')
101 # Test that the new complex command can show up in the help dialog.
102 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
103 [ category_new ] = mode_ignore.categories
104 assert.equal(category_new.name, 'New category')
105 [ test_command ] = category_new.commands
106 assert.equal(test_command.command.description(), 'Test ignore mode command')
107 assert.deepEqual(test_command.enabledSequences, ['<ö>'])
109 # Remove the added commands.
110 delete vimfx.modes.normal.commands.test_command
111 delete vimfx.modes.ignore.commands.test_command
114 # Test that the new simple command cannot be run.
115 passed_vimfx.reset('normal')
116 match = passed_vimfx.consumeKeyEvent(event, {mode: 'normal'})
117 if match.type == 'full'
118 value = try match.command.run() catch then null
119 assert.notEqual(value, nonce)
121 # Test that the new complex command cannot be run.
122 passed_vimfx.reset('ignore')
123 match = passed_vimfx.consumeKeyEvent(event, {mode: 'ignore'})
124 if match.type == 'full'
125 value = try match.command.run() catch then null
126 assert.notEqual(value, nonce)
128 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
130 # Test that the new simple command cannot show up in the help dialog.
131 mode_normal = modes.find((mode) -> mode._name == 'normal')
132 category_misc = mode_normal.categories.find(
133 (category) -> category._name == 'misc'
135 [ ..., { command: last_command } ] = category_misc.commands
136 assert.notEqual(last_command.description(), 'Test command')
138 # Test that the new complex command cannot show up in the help dialog.
139 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
140 [ first_category ] = mode_ignore.categories
141 assert.notEqual(first_category.name, 'New category')
143 # Restore original values.
144 passed_vimfx.options = originalOptions
145 passed_vimfx.options.categories = originalCategories
148 exports['test addCommand order'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
151 description: 'Test command'
153 }, Function.prototype)
154 vimfx.set('custom.mode.normal.test_command', 'ö')
156 modes = passed_vimfx.getGroupedCommands()
157 mode_normal = modes.find((mode) -> mode._name == 'normal')
158 category_misc = mode_normal.categories.find(
159 (category) -> category._name == 'misc'
161 [ { command: first_command } ] = category_misc.commands
162 assert.equal(first_command.description(), 'Test command')
164 delete vimfx.modes.normal.commands.test_command
167 exports['test addOptionOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
168 originalOptions = Object.assign({}, passed_vimfx.options)
169 originalOptionOverrides = Object.assign({}, passed_vimfx.optionOverrides)
171 passed_vimfx.optionOverrides = null
172 passed_vimfx.options.prevent_autofocus = true
174 vimfx.addOptionOverrides(
176 (location) -> location.hostname == 'example.com'
177 {prevent_autofocus: false}
181 assert.equal(passed_vimfx.options.prevent_autofocus, true)
183 passed_vimfx.currentVim =
185 location: {hostname: 'example.com'}
187 assert.equal(passed_vimfx.options.prevent_autofocus, false)
189 passed_vimfx.options = originalOptions
190 passed_vimfx.optionOverrides = originalOptionOverrides
193 exports['test addKeyOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
194 originalOptions = Object.assign({}, passed_vimfx.options)
195 originalKeyOverrides = Object.assign({}, passed_vimfx.keyOverrides)
197 passed_vimfx.options.keyValidator = null
198 passed_vimfx.options.ignore_keyboard_layout = false
199 passed_vimfx.options.translations = {}
201 vimfx.addKeyOverrides(
203 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
207 (location, mode) -> mode == 'ignore' and location.href == 'about:blank'
212 prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j', ->
213 passed_vimfx.reset('normal')
215 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'})
218 passed_vimfx.currentVim =
220 location: {hostname: 'example.co', href: 'about:blank'}
222 match = passed_vimfx.consumeKeyEvent({key: '1'}, {mode: 'normal'})
223 assert.equal(match.type, 'count')
224 assert.equal(match.count, 1)
226 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'})
229 match = passed_vimfx.consumeKeyEvent({key: 'foobar', ctrlKey: true},
233 match = passed_vimfx.consumeKeyEvent({key: 'foobar'}, {mode: 'normal'})
234 assert.equal(match.type, 'partial')
235 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'})
236 assert.equal(match.type, 'full')
237 assert.strictEqual(match.count, undefined)
239 passed_vimfx.reset('ignore')
241 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'})
244 match = passed_vimfx.consumeKeyEvent({key: 'escape'}, {mode: 'ignore'})
248 passed_vimfx.options = originalOptions
249 passed_vimfx.keyOverrides = originalKeyOverrides
252 exports['test vimfx.[gs]et errors'] = (assert) -> getAPI((vimfx) ->
253 throws(assert, /unknown pref/i, 'undefined', ->
257 throws(assert, /unknown pref/i, 'undefined', ->
261 throws(assert, /unknown pref/i, 'unknown_pref', ->
262 vimfx.get('unknown_pref')
265 throws(assert, /unknown pref/i, 'unknown_pref', ->
266 vimfx.set('unknown_pref', 'foo')
269 throws(assert, /boolean, number, string or null/i, 'undefined', ->
270 vimfx.set('hint_chars')
273 throws(assert, /boolean, number, string or null/i, 'object', ->
274 vimfx.set('hint_chars', ['a', 'b', 'c'])
278 exports['test vimfx.addCommand errors'] = (assert) -> getAPI((vimfx) ->
279 throws(assert, /name.+string.+required/i, 'undefined', ->
283 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
284 vimfx.addCommand({name: 'Command'})
287 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
288 vimfx.addCommand({name: 'command-name'})
291 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
292 vimfx.addCommand({name: 'ö'})
295 throws(assert, /non-empty description/i, 'undefined', ->
296 vimfx.addCommand({name: 'test'})
299 throws(assert, /non-empty description/i, '', ->
300 vimfx.addCommand({name: 'test', description: ''})
303 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
304 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
307 throws(assert, /unknown category.+available.+location/i, 'toString', ->
308 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
311 throws(assert, /order.+number/i, 'false', ->
312 vimfx.addCommand({name: 'test', description: 'Test', order: false})
315 throws(assert, /function/i, 'undefined', ->
316 vimfx.addCommand({name: 'test', description: 'Test'})
319 throws(assert, /function/i, 'false', ->
320 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
324 throws = (assert, regex, badValue, fn) ->
327 assert.ok(error.message.startsWith('VimFx:'), 'start with VimFx')
328 assert.ok(error.message.endsWith(": #{ badValue }"), 'show bad value')
329 assert.ok(regex.test(error.message), 'regex match')