]> git.gir.st - VimFx.git/blob - extension/test/test-api.coffee
Merge pull request #512 from akhodakivskiy/multi-process
[VimFx.git] / extension / test / test-api.coffee
1 ###
2 # Copyright Simon Lydell 2015.
3 #
4 # This file is part of VimFx.
5 #
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.
10 #
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.
15 #
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/>.
18 ###
19
20 testUtils = require('./utils')
21 prefs = require('../lib/prefs')
22 utils = require('../lib/utils')
23
24 { utils: Cu } = Components
25
26 { getAPI } = Cu.import(
27 Services.prefs.getCharPref('extensions.VimFx.api_url'), {}
28 )
29
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',
35 'addOptionOverrides')
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')
40 )
41
42 exports['test get'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
43 reset = prefs.tmp('hint_chars', 'abcd')
44 assert.equal(vimfx.get('hint_chars'), 'abcd')
45 reset()
46 )
47
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)
52
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: ['ö', 'Ö']})
57
58 nonce = {}
59 event = {code: 'KeyQ'}
60
61 # Add a simple test command.
62 vimfx.addCommand({
63 name: 'test_command'
64 description: 'Test command'
65 }, -> nonce)
66 vimfx.set('custom.mode.normal.test_command', 'ö')
67
68 # Add a slightly more complex command.
69 vimfx.get('categories')['new_category'] = {
70 name: -> 'New category'
71 order: -100
72 }
73 vimfx.addCommand({
74 name: 'test_command'
75 description: 'Test ignore mode command'
76 mode: 'ignore'
77 category: 'new_category'
78 }, -> nonce)
79 vimfx.set('custom.mode.ignore.test_command', 'ö <ö> <c-c-invalid>')
80
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)
86
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)
92
93 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
94
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'
99 )
100 [ ..., { command: test_command } ] = category_misc.commands
101 assert.equal(test_command.description(), 'Test command')
102
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, ['<ö>'])
110
111 # Remove the added commands.
112 delete vimfx.modes.normal.commands.test_command
113 delete vimfx.modes.ignore.commands.test_command
114 vimfx.refresh()
115
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)
122
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)
129
130 modes = passed_vimfx.getGroupedCommands({enabledOnly: true})
131
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'
136 )
137 [ ..., { command: last_command } ] = category_misc.commands
138 assert.notEqual(last_command.description(), 'Test command')
139
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')
144
145 # Restore original values.
146 passed_vimfx.options = originalOptions
147 passed_vimfx.options.categories = originalCategories
148 )
149
150 exports['test addCommand order'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
151 vimfx.addCommand({
152 name: 'test_command'
153 description: 'Test command'
154 order: 0
155 }, Function.prototype)
156 vimfx.set('custom.mode.normal.test_command', 'ö')
157
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'
162 )
163 [ { command: first_command } ] = category_misc.commands
164 assert.equal(first_command.description(), 'Test command')
165
166 delete vimfx.modes.normal.commands.test_command
167 )
168
169 exports['test addOptionOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
170 originalOptions = Object.assign({}, passed_vimfx.options)
171 originalOptionOverrides = Object.assign({}, passed_vimfx.optionOverrides)
172
173 passed_vimfx.optionOverrides = null
174 passed_vimfx.options.prevent_autofocus = true
175
176 vimfx.addOptionOverrides(
177 [
178 (location) -> location.hostname == 'example.com'
179 {prevent_autofocus: false}
180 ]
181 )
182
183 assert.equal(passed_vimfx.options.prevent_autofocus, true)
184
185 reset = testUtils.stub(utils, 'getCurrentLocation', -> {
186 hostname: 'example.com'
187 })
188
189 assert.equal(passed_vimfx.options.prevent_autofocus, false)
190
191 reset()
192 passed_vimfx.options = originalOptions
193 passed_vimfx.optionOverrides = originalOptionOverrides
194 )
195
196 exports['test addKeyOverrides'] = (assert, passed_vimfx) -> getAPI((vimfx) ->
197 originalOptions = Object.assign({}, passed_vimfx.options)
198 originalKeyOverrides = Object.assign({}, passed_vimfx.keyOverrides)
199
200 passed_vimfx.options.keyValidator = null
201 passed_vimfx.options.ignore_keyboard_layout = false
202 passed_vimfx.options.translations = {}
203
204 vimfx.addKeyOverrides(
205 [
206 (location, mode) -> mode == 'normal' and location.hostname == 'example.co'
207 ['j', '<c-foobar>']
208 ],
209 [
210 (location, mode) -> mode == 'ignore' and location.href == 'about:blank'
211 ['<escape>']
212 ]
213 )
214
215 resetScrollToBottom = prefs.tmp('mode.normal.scroll_to_bottom', '<foobar>j')
216 passed_vimfx.reset('normal')
217
218 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'}, null)
219 assert.ok(match)
220
221 resetGetCurrentLocation = testUtils.stub(utils, 'getCurrentLocation', -> {
222 hostname: 'example.co'
223 href: 'about:blank'
224 })
225
226 match = passed_vimfx.consumeKeyEvent({key: '1'}, {mode: 'normal'}, null)
227 assert.equal(match.type, 'count')
228 assert.equal(match.count, 1)
229
230 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'normal'}, null)
231 assert.ok(not match)
232
233 match = passed_vimfx.consumeKeyEvent({key: 'foobar', ctrlKey: true},
234 {mode: 'normal'}, null)
235 assert.ok(not match)
236
237 match = passed_vimfx.consumeKeyEvent({key: 'foobar'}, {mode: 'normal'},
238 null)
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)
243
244 passed_vimfx.reset('ignore')
245
246 match = passed_vimfx.consumeKeyEvent({key: 'j'}, {mode: 'ignore'}, null)
247 assert.ok(match)
248
249 match = passed_vimfx.consumeKeyEvent({key: 'escape'}, {mode: 'ignore'},
250 null)
251 assert.ok(not match)
252
253 resetScrollToBottom()
254 resetGetCurrentLocation()
255 passed_vimfx.options = originalOptions
256 passed_vimfx.keyOverrides = originalKeyOverrides
257 )
258
259 exports['test vimfx.[gs]et errors'] = (assert) -> getAPI((vimfx) ->
260 throws(assert, /unknown pref/i, 'undefined', ->
261 vimfx.get()
262 )
263
264 throws(assert, /unknown pref/i, 'undefined', ->
265 vimfx.set()
266 )
267
268 throws(assert, /unknown pref/i, 'unknown_pref', ->
269 vimfx.get('unknown_pref')
270 )
271
272 throws(assert, /unknown pref/i, 'unknown_pref', ->
273 vimfx.set('unknown_pref', 'foo')
274 )
275
276 throws(assert, /boolean, number, string or null/i, 'undefined', ->
277 vimfx.set('hint_chars')
278 )
279
280 throws(assert, /boolean, number, string or null/i, 'object', ->
281 vimfx.set('hint_chars', ['a', 'b', 'c'])
282 )
283 )
284
285 exports['test vimfx.addCommand errors'] = (assert) -> getAPI((vimfx) ->
286 throws(assert, /name.+string.+required/i, 'undefined', ->
287 vimfx.addCommand()
288 )
289
290 throws(assert, /name.+a-z.+underscore/i, 'Command', ->
291 vimfx.addCommand({name: 'Command'})
292 )
293
294 throws(assert, /name.+a-z.+underscore/i, 'command-name', ->
295 vimfx.addCommand({name: 'command-name'})
296 )
297
298 throws(assert, /name.+a-z.+underscore/i, 'ö', ->
299 vimfx.addCommand({name: 'ö'})
300 )
301
302 throws(assert, /non-empty description/i, 'undefined', ->
303 vimfx.addCommand({name: 'test'})
304 )
305
306 throws(assert, /non-empty description/i, '', ->
307 vimfx.addCommand({name: 'test', description: ''})
308 )
309
310 throws(assert, /unknown mode.+available.+normal/i, 'toString', ->
311 vimfx.addCommand({name: 'test', description: 'Test', mode: 'toString'})
312 )
313
314 throws(assert, /unknown category.+available.+location/i, 'toString', ->
315 vimfx.addCommand({name: 'test', description: 'Test', category: 'toString'})
316 )
317
318 throws(assert, /order.+number/i, 'false', ->
319 vimfx.addCommand({name: 'test', description: 'Test', order: false})
320 )
321
322 throws(assert, /function/i, 'undefined', ->
323 vimfx.addCommand({name: 'test', description: 'Test'})
324 )
325
326 throws(assert, /function/i, 'false', ->
327 vimfx.addCommand({name: 'test_command', description: 'Test command'}, false)
328 )
329 )
330
331 throws = (assert, regex, badValue, fn) ->
332 assert.throws(fn)
333 try fn() catch error
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')
Imprint / Impressum