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.set, 'function', 'set')
33 assert.equal(typeof vimfx.addCommand, 'function', 'addCommand')
34 assert.equal(typeof vimfx.addOptionOverrides, 'function',
36 assert.equal(typeof vimfx.addKeyOverrides, 'function', 'addKeyOverrides')
37 assert.equal(typeof vimfx.on, 'function', 'on')
38 assert.equal(typeof vimfx.refresh, 'function', 'refresh')
39 assert.equal(vimfx.modes, passed_vimfx.modes, 'modes')
42 exports['test get'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
43 reset = prefs.tmp('hint_chars', 'abcd')
44 assert.equal(vimfx.get('hint_chars'), 'abcd')
48 exports['test customization'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
49 # Save some values that need to be temporarily changed below.
50 originalOptions = Object.assign({}, passed_vimfx.options)
51 originalCategories = Object.assign({}, passed_vimfx.options.categories)
53 # Setup some settings for testing.
54 passed_vimfx.options.keyValidator = null
55 passed_vimfx.options.ignore_keyboard_layout = true
56 vimfx.set('translations', {KeyQ: ['ö', 'Ö']})
59 event = {code: 'KeyQ'}
61 # Add a simple test command.
64 description: 'Test command'
66 vimfx.set('custom.mode.normal.test_command', 'ö')
68 # Add a slightly more complex command.
69 vimfx.get('categories')['new_category'] = {
70 name: -> 'New category'
75 description: 'Test ignore mode command'
77 category: 'new_category'
79 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
81 # Test that the new simple command can be run.
82 passed_vimfx.reset('normal')
83 match = passed_vimfx.consumeKeyEvent(event, {mode: 'normal'}, null)
84 assert.equal(match.type, 'full')
85 assert.equal(match.command.run(), nonce)
87 # Test that the new complex command can be run.
88 passed_vimfx.reset('ignore')
89 match = passed_vimfx.consumeKeyEvent(event, {mode: 'ignore'}, null)
90 assert.equal(match.type, 'full')
91 assert.equal(match.command.run(), nonce)
93 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
95 # Test that the new simple command can show up in the help dialog.
96 mode_normal = modes.find((mode) -> mode._name == 'normal')
97 category_misc = mode_normal.categories.find(
98 (category) -> category._name == 'misc'
100 [ ..., { command: test_command } ] = category_misc.commands
101 assert.equal(test_command.description(), 'Test command')
103 # Test that the new complex command can show up in the help dialog.
104 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
105 [ category_new ] = mode_ignore.categories
106 assert.equal(category_new.name, 'New category')
107 [ test_command ] = category_new.commands
108 assert.equal(test_command.command.description(), 'Test ignore mode command')
109 assert.deepEqual(test_command.enabledSequences, ['ö'])
111 # Remove the added commands.
112 delete vimfx.modes.normal.commands.test_command
113 delete vimfx.modes.ignore.commands.test_command
116 # Test that the new simple command cannot be run.
117 passed_vimfx.reset('normal')
118 match = passed_vimfx.consumeKeyEvent(event, {mode: 'normal'}, null)
119 if match.type == 'full'
120 value = try match.command.run() catch then null
121 assert.notEqual(value, nonce)
123 # Test that the new complex command cannot be run.
124 passed_vimfx.reset('ignore')
125 match = passed_vimfx.consumeKeyEvent(event, {mode: 'ignore'}, null)
126 if match.type == 'full'
127 value = try match.command.run() catch then null
128 assert.notEqual(value, nonce)
130 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
132 # Test that the new simple command cannot show up in the help dialog.
133 mode_normal = modes.find((mode) -> mode._name == 'normal')
134 category_misc = mode_normal.categories.find(
135 (category) -> category._name == 'misc'
137 [ ..., { command: last_command } ] = category_misc.commands
138 assert.notEqual(last_command.description(), 'Test command')
140 # Test that the new complex command cannot show up in the help dialog.
141 mode_ignore = modes.find((mode) -> mode._name == 'ignore')
142 [ first_category ] = mode_ignore.categories
143 assert.notEqual(first_category.name, 'New category')
145 # Restore original values.
146 passed_vimfx.options = originalOptions
147 passed_vimfx.options.categories = originalCategories
150 exports['test addCommand order'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
153 description: 'Test command'
155 }, Function.prototype)
156 vimfx.set('custom.mode.normal.test_command', 'ö')
158 modes = passed_vimfx.getGroupedCommands()
159 mode_normal = modes.find((mode) -> mode._name == 'normal')
160 category_misc = mode_normal.categories.find(
161 (category) -> category._name == 'misc'
163 [ { command: first_command } ] = category_misc.commands
164 assert.equal(first_command.description(), 'Test command')
166 delete vimfx.modes.normal.commands.test_command
169 exports['test addOptionOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
170 originalOptions = Object.assign({}, passed_vimfx.options)
171 originalOptionOverrides = Object.assign({}, passed_vimfx.optionOverrides)
173 passed_vimfx.optionOverrides = null
174 passed_vimfx.options.prevent_autofocus = true
176 vimfx.addOptionOverrides(
178 (location) -> location.hostname == 'example.com'
179 {prevent_autofocus: false}
183 assert.equal(passed_vimfx.options.prevent_autofocus, true)
185 reset = testUtils.stub(utils, 'getCurrentLocation', -> {
186 hostname: 'example.com'
189 assert.equal(passed_vimfx.options.prevent_autofocus, false)
192 passed_vimfx.options = originalOptions
193 passed_vimfx.optionOverrides = originalOptionOverrides
196 exports['test addKeyOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
197 originalOptions = Object.assign({}, passed_vimfx.options)
198 originalKeyOverrides = Object.assign({}, passed_vimfx.keyOverrides)
200 passed_vimfx.options.keyValidator = null
201 passed_vimfx.options.ignore_keyboard_layout = false
202 passed_vimfx.options.translations = {}
204 vimfx.addKeyOverrides(
206 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
210 (location, mode) -> mode == 'ignore' and location.href == 'about:blank'
215 resetScrollToBottom = prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j')
216 passed_vimfx.reset('normal')
218 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'}, null)
221 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
222 hostname: 'example.co'
226 match = passed_vimfx.consumeKeyEvent({key: '1'}, {mode: 'normal'}, null)
227 assert.equal(match.type, 'count')
228 assert.equal(match.count, 1)
230 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'}, null)
233 match = passed_vimfx.consumeKeyEvent({key: 'foobar', ctrlKey: true},
234 {mode: 'normal'}, null)
237 match = passed_vimfx.consumeKeyEvent({key: 'foobar'}, {mode: 'normal'},
239 assert.equal(match.type, 'partial')
240 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'}, null)
241 assert.equal(match.type, 'full')
242 assert.strictEqual(match.count, undefined)
244 passed_vimfx.reset('ignore')
246 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'}, null)
249 match = passed_vimfx.consumeKeyEvent({key: 'escape'}, {mode: 'ignore'},
253 resetScrollToBottom()
254 resetGetCurrentLocation()
255 passed_vimfx.options = originalOptions
256 passed_vimfx.keyOverrides = originalKeyOverrides
259 exports['test vimfx.[gs]et errors'] = (assert) -> getAPI((vimfx) ->
260 throws(assert, /unknown pref/i, 'undefined', ->
264 throws(assert, /unknown pref/i, 'undefined', ->
268 throws(assert, /unknown pref/i, 'unknown_pref', ->
269 vimfx.get('unknown_pref')
272 throws(assert, /unknown pref/i, 'unknown_pref', ->
273 vimfx.set('unknown_pref', 'foo')
276 throws(assert, /boolean, number, string or null/i, 'undefined', ->
277 vimfx.set('hint_chars')
280 throws(assert, /boolean, number, string or null/i, 'object', ->
281 vimfx.set('hint_chars', ['a', 'b', 'c'])
285 exports['test vimfx.addCommand errors'] = (assert) -> getAPI((vimfx) ->
286 throws(assert, /name.+string.+required/i, 'undefined', ->
290 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
291 vimfx.addCommand({name: 'Command'})
294 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
295 vimfx.addCommand({name: 'command-name'})
298 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
299 vimfx.addCommand({name: 'ö'})
302 throws(assert, /non-empty description/i, 'undefined', ->
303 vimfx.addCommand({name: 'test'})
306 throws(assert, /non-empty description/i, '', ->
307 vimfx.addCommand({name: 'test', description: ''})
310 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
311 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
314 throws(assert, /unknown category.+available.+location/i, 'toString', ->
315 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
318 throws(assert, /order.+number/i, 'false', ->
319 vimfx.addCommand({name: 'test', description: 'Test', order: false})
322 throws(assert, /function/i, 'undefined', ->
323 vimfx.addCommand({name: 'test', description: 'Test'})
326 throws(assert, /function/i, 'false', ->
327 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
331 throws = (assert, regex, badValue, fn) ->
334 assert.ok(error.message.startsWith('VimFx:'), 'start with VimFx')
335 assert.ok(error.message.endsWith(": #{ badValue }"), 'show bad value')
336 assert.ok(regex.test(error.message), 'regex match')