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 testUtils = require('./utils')
21 prefs = require('../lib/prefs')
22 utils = require('../lib/utils')
24 { utils: Cu } = Components
26 { getAPI } = Cu.import(
27 Services.prefs.getCharPref('extensions.VimFx.api_url'), {}
30 exports['test exports'] = (assert, passed_vimfx) -> getAPI((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.on, 'function', 'on')
39 assert.equal(typeof vimfx.refresh, 'function', 'refresh')
40 assert.equal(vimfx.modes, passed_vimfx.modes, 'modes')
43 exports['test get'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
44 reset = prefs.tmp('hint_chars', 'abcd')
45 assert.equal(vimfx.get('hint_chars'), 'abcd')
49 exports['test getDefault'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
50 default_hint_chars = passed_vimfx.options.hint_chars
51 reset = prefs.tmp('hint_chars', 'abcd')
52 assert.equal(vimfx.getDefault('hint_chars'), default_hint_chars)
56 exports['test customization'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
57 # Save some values that need to be temporarily changed below.
58 originalOptions = Object.assign({}, passed_vimfx.options)
59 originalCategories = Object.assign({}, passed_vimfx.options.categories)
61 # Setup some settings for testing.
62 passed_vimfx.options.keyValidator = null
63 passed_vimfx.options.ignore_keyboard_layout = true
64 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
67 event = {code: 'KeyQ'}
69 # Add a simple test command.
72 description: 'Test command'
74 vimfx.set('custom.mode.normal.test_command', 'ö')
76 # Add a slightly more complex command.
77 vimfx.get('categories')['new_category'] = {
78 name: -> 'New category'
83 description: 'Test ignore mode command'
85 category: 'new_category'
87 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
89 # Test that the new simple command can be run.
90 passed_vimfx.reset('normal')
91 match = passed_vimfx.consumeKeyEvent(event, {mode: 'normal'}, null)
92 assert.equal(match.type, 'full')
93 assert.equal(match.command.run(), nonce)
95 # Test that the new complex command can be run.
96 passed_vimfx.reset('ignore')
97 match = passed_vimfx.consumeKeyEvent(event, {mode: 'ignore'}, null)
98 assert.equal(match.type, 'full')
99 assert.equal(match.command.run(), nonce)
101 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
103 # Test that the new simple command can show up in the help dialog.
104 mode_normal = modes.find((mode) -> mode._name == 'normal')
105 category_misc = mode_normal.categories.find(
106 (category) -> category._name == 'misc'
108 [ ..., { command: test_command } ] = category_misc.commands
109 assert.equal(test_command.description(), 'Test command')
111 # Test that the new complex command can show up in the help dialog.
112 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
113 [ category_new ] = mode_ignore.categories
114 assert.equal(category_new.name, 'New category')
115 [ test_command ] = category_new.commands
116 assert.equal(test_command.command.description(), 'Test ignore mode command')
117 assert.deepEqual(test_command.enabledSequences, ['ö'])
119 # Remove the added commands.
120 delete vimfx.modes.normal.commands.test_command
121 delete vimfx.modes.ignore.commands.test_command
124 # Test that the new simple command cannot be run.
125 passed_vimfx.reset('normal')
126 match = passed_vimfx.consumeKeyEvent(event, {mode: 'normal'}, null)
127 if match.type == 'full'
128 value = try match.command.run() catch then null
129 assert.notEqual(value, nonce)
131 # Test that the new complex command cannot be run.
132 passed_vimfx.reset('ignore')
133 match = passed_vimfx.consumeKeyEvent(event, {mode: 'ignore'}, null)
134 if match.type == 'full'
135 value = try match.command.run() catch then null
136 assert.notEqual(value, nonce)
138 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
140 # Test that the new simple command cannot show up in the help dialog.
141 mode_normal = modes.find((mode) -> mode._name == 'normal')
142 category_misc = mode_normal.categories.find(
143 (category) -> category._name == 'misc'
145 [ ..., { command: last_command } ] = category_misc.commands
146 assert.notEqual(last_command.description(), 'Test command')
148 # Test that the new complex command cannot show up in the help dialog.
149 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
150 [ first_category ] = mode_ignore.categories
151 assert.notEqual(first_category.name, 'New category')
153 # Restore original values.
154 passed_vimfx.options = originalOptions
155 passed_vimfx.options.categories = originalCategories
158 exports['test addCommand order'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
161 description: 'Test command'
163 }, Function.prototype)
164 vimfx.set('custom.mode.normal.test_command', 'ö')
166 modes = passed_vimfx.getGroupedCommands()
167 mode_normal = modes.find((mode) -> mode._name == 'normal')
168 category_misc = mode_normal.categories.find(
169 (category) -> category._name == 'misc'
171 [ { command: first_command } ] = category_misc.commands
172 assert.equal(first_command.description(), 'Test command')
174 delete vimfx.modes.normal.commands.test_command
177 exports['test addOptionOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
178 originalOptions = Object.assign({}, passed_vimfx.options)
179 originalOptionOverrides = Object.assign({}, passed_vimfx.optionOverrides)
181 passed_vimfx.optionOverrides = null
182 passed_vimfx.options.prevent_autofocus = true
184 vimfx.addOptionOverrides(
186 (location) -> location.hostname == 'example.com'
187 {prevent_autofocus: false}
191 assert.equal(passed_vimfx.options.prevent_autofocus, true)
193 reset = testUtils.stub(utils, 'getCurrentLocation', -> {
194 hostname: 'example.com'
197 assert.equal(passed_vimfx.options.prevent_autofocus, false)
200 passed_vimfx.options = originalOptions
201 passed_vimfx.optionOverrides = originalOptionOverrides
204 exports['test addKeyOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
205 originalOptions = Object.assign({}, passed_vimfx.options)
206 originalKeyOverrides = Object.assign({}, passed_vimfx.keyOverrides)
208 passed_vimfx.options.keyValidator = null
209 passed_vimfx.options.ignore_keyboard_layout = false
210 passed_vimfx.options.translations = {}
212 vimfx.addKeyOverrides(
214 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
218 (location, mode) -> mode == 'ignore' and location.href == 'about:blank'
223 resetScrollToBottom = prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j')
224 passed_vimfx.reset('normal')
226 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'}, null)
229 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
230 hostname: 'example.co'
234 match = passed_vimfx.consumeKeyEvent({key: '1'}, {mode: 'normal'}, null)
235 assert.equal(match.type, 'count')
236 assert.equal(match.count, 1)
238 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'}, null)
241 match = passed_vimfx.consumeKeyEvent({key: 'foobar', ctrlKey: true},
242 {mode: 'normal'}, null)
245 match = passed_vimfx.consumeKeyEvent({key: 'foobar'}, {mode: 'normal'},
247 assert.equal(match.type, 'partial')
248 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'}, null)
249 assert.equal(match.type, 'full')
250 assert.strictEqual(match.count, undefined)
252 passed_vimfx.reset('ignore')
254 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'}, null)
257 match = passed_vimfx.consumeKeyEvent({key: 'escape'}, {mode: 'ignore'},
261 resetScrollToBottom()
262 resetGetCurrentLocation()
263 passed_vimfx.options = originalOptions
264 passed_vimfx.keyOverrides = originalKeyOverrides
267 exports['test vimfx.[gs]et(Default)? errors'] = (assert) -> getAPI((vimfx) ->
268 throws(assert, /unknown pref/i, 'undefined', ->
272 throws(assert, /unknown pref/i, 'undefined', ->
276 throws(assert, /unknown pref/i, 'undefined', ->
280 throws(assert, /unknown pref/i, 'unknown_pref', ->
281 vimfx.get('unknown_pref')
284 throws(assert, /unknown pref/i, 'unknown_pref', ->
285 vimfx.getDefault('unknown_pref')
288 throws(assert, /no default/i, 'custom.mode.normal.foo', ->
289 vimfx.getDefault('custom.mode.normal.foo')
292 throws(assert, /no default/i, 'translations', ->
293 vimfx.getDefault('translations')
296 throws(assert, /unknown pref/i, 'unknown_pref', ->
297 vimfx.set('unknown_pref', 'foo')
300 throws(assert, /boolean, number, string or null/i, 'undefined', ->
301 vimfx.set('hint_chars')
304 throws(assert, /boolean, number, string or null/i, 'object', ->
305 vimfx.set('hint_chars', ['a', 'b', 'c'])
309 exports['test vimfx.addCommand errors'] = (assert) -> getAPI((vimfx) ->
310 throws(assert, /name.+string.+required/i, 'undefined', ->
314 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
315 vimfx.addCommand({name: 'Command'})
318 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
319 vimfx.addCommand({name: 'command-name'})
322 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
323 vimfx.addCommand({name: 'ö'})
326 throws(assert, /non-empty description/i, 'undefined', ->
327 vimfx.addCommand({name: 'test'})
330 throws(assert, /non-empty description/i, '', ->
331 vimfx.addCommand({name: 'test', description: ''})
334 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
335 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
338 throws(assert, /unknown category.+available.+location/i, 'toString', ->
339 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
342 throws(assert, /order.+number/i, 'false', ->
343 vimfx.addCommand({name: 'test', description: 'Test', order: false})
346 throws(assert, /function/i, 'undefined', ->
347 vimfx.addCommand({name: 'test', description: 'Test'})
350 throws(assert, /function/i, 'false', ->
351 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
355 throws = (assert, regex, badValue, fn) ->
358 assert.ok(error.message.startsWith('VimFx:'), 'start with VimFx')
359 assert.ok(error.message.endsWith(": #{ badValue }"), 'show bad value')
360 assert.ok(regex.test(error.message), 'regex match')