define_spec.lua 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim
  3. local eq, run, stop = helpers.eq, helpers.run, helpers.stop
  4. local clear = helpers.clear
  5. local function get_prefix(sync)
  6. if sync then
  7. return 'sync'
  8. end
  9. return 'async'
  10. end
  11. local function call(fn, arguments)
  12. command('call '..fn..'('..arguments..')')
  13. end
  14. local function clear_and_init(init)
  15. return function()
  16. clear()
  17. if init then
  18. init()
  19. end
  20. end
  21. end
  22. local function runx(sync, handler, on_setup)
  23. local function setup_cb(...)
  24. on_setup(...)
  25. -- need to stop on setup callback because there's two session:request
  26. -- calls in `request/helpers.lua`. The second call will always return
  27. -- after pending notification/request callbacks are processed
  28. stop()
  29. end
  30. local function handler_cb(...)
  31. return handler(...)
  32. end
  33. if sync then
  34. run(handler_cb, nil, setup_cb)
  35. else
  36. run(nil, handler_cb, setup_cb)
  37. end
  38. end
  39. local function command_specs_for(fn, sync, first_arg_factory, init)
  40. local prefix = get_prefix(sync)
  41. describe(prefix..' command created by', function()
  42. before_each(clear_and_init(init))
  43. describe(fn, function()
  44. local args
  45. before_each(function()
  46. args = first_arg_factory()..', "test-handler", '
  47. if sync then
  48. args = args .. '1'
  49. else
  50. args = args .. '0'
  51. end
  52. args = args..', "RpcCommand"'
  53. end)
  54. it('without options', function()
  55. call(fn, args..', {}')
  56. local function on_setup()
  57. command('RpcCommand')
  58. end
  59. local function handler(method)
  60. eq('test-handler', method)
  61. return ''
  62. end
  63. runx(sync, handler, on_setup)
  64. end)
  65. it('with nargs', function()
  66. call(fn, args..', {"nargs": "*"}')
  67. local function on_setup()
  68. command('RpcCommand arg1 arg2 arg3')
  69. end
  70. local function handler(method, arguments)
  71. eq('test-handler', method)
  72. eq({'arg1', 'arg2', 'arg3'}, arguments[1])
  73. return ''
  74. end
  75. runx(sync, handler, on_setup)
  76. end)
  77. it('with nargs/double-quote', function()
  78. call(fn, args..', {"nargs": "*"}')
  79. local function on_setup()
  80. command('RpcCommand "arg1" "arg2" "arg3"')
  81. end
  82. local function handler(method, arguments)
  83. eq('test-handler', method)
  84. eq({'"arg1"', '"arg2"', '"arg3"'}, arguments[1])
  85. return ''
  86. end
  87. runx(sync, handler, on_setup)
  88. end)
  89. it('with range', function()
  90. call(fn,args..', {"range": ""}')
  91. local function on_setup()
  92. command('1,1RpcCommand')
  93. end
  94. local function handler(method, arguments)
  95. eq('test-handler', method)
  96. eq({1, 1}, arguments[1])
  97. return ''
  98. end
  99. runx(sync, handler, on_setup)
  100. end)
  101. it('with nargs/range', function()
  102. call(fn, args..', {"nargs": "1", "range": ""}')
  103. local function on_setup()
  104. command('1,1RpcCommand arg')
  105. end
  106. local function handler(method, arguments)
  107. eq('test-handler', method)
  108. eq({'arg'}, arguments[1])
  109. eq({1, 1}, arguments[2])
  110. return ''
  111. end
  112. runx(sync, handler, on_setup)
  113. end)
  114. it('with nargs/count', function()
  115. call(fn, args..', {"nargs": "1", "count": "5"}')
  116. local function on_setup()
  117. command('5RpcCommand arg')
  118. end
  119. local function handler(method, arguments)
  120. eq('test-handler', method)
  121. eq({'arg'}, arguments[1])
  122. eq(5, arguments[2])
  123. return ''
  124. end
  125. runx(sync, handler, on_setup)
  126. end)
  127. it('with nargs/count/bang', function()
  128. call(fn, args..', {"nargs": "1", "count": "5", "bang": ""}')
  129. local function on_setup()
  130. command('5RpcCommand! arg')
  131. end
  132. local function handler(method, arguments)
  133. eq('test-handler', method)
  134. eq({'arg'}, arguments[1])
  135. eq(5, arguments[2])
  136. eq(1, arguments[3])
  137. return ''
  138. end
  139. runx(sync, handler, on_setup)
  140. end)
  141. it('with nargs/count/bang/register', function()
  142. call(fn, args..', {"nargs": "1", "count": "5", "bang": "",'..
  143. ' "register": ""}')
  144. local function on_setup()
  145. command('5RpcCommand! b arg')
  146. end
  147. local function handler(method, arguments)
  148. eq('test-handler', method)
  149. eq({'arg'}, arguments[1])
  150. eq(5, arguments[2])
  151. eq(1, arguments[3])
  152. eq('b', arguments[4])
  153. return ''
  154. end
  155. runx(sync, handler, on_setup)
  156. end)
  157. it('with nargs/count/bang/register/eval', function()
  158. call(fn, args..', {"nargs": "1", "count": "5", "bang": "",'..
  159. ' "register": "", "eval": "@<reg>"}')
  160. local function on_setup()
  161. command('let @b = "regb"')
  162. command('5RpcCommand! b arg')
  163. end
  164. local function handler(method, arguments)
  165. eq('test-handler', method)
  166. eq({'arg'}, arguments[1])
  167. eq(5, arguments[2])
  168. eq(1, arguments[3])
  169. eq('b', arguments[4])
  170. eq('regb', arguments[5])
  171. return ''
  172. end
  173. runx(sync, handler, on_setup)
  174. end)
  175. end)
  176. end)
  177. end
  178. local function autocmd_specs_for(fn, sync, first_arg_factory, init)
  179. local prefix = get_prefix(sync)
  180. describe(prefix..' autocmd created by', function()
  181. before_each(clear_and_init(init))
  182. describe(fn, function()
  183. local args
  184. before_each(function()
  185. args = first_arg_factory()..', "test-handler", '
  186. if sync then
  187. args = args .. '1'
  188. else
  189. args = args .. '0'
  190. end
  191. args = args..', "BufEnter"'
  192. end)
  193. it('without options', function()
  194. call(fn, args..', {}')
  195. local function on_setup()
  196. command('doautocmd BufEnter x.c')
  197. end
  198. local function handler(method)
  199. eq('test-handler', method)
  200. return ''
  201. end
  202. runx(sync, handler, on_setup)
  203. end)
  204. it('with eval', function()
  205. call(fn, args..[[, {'eval': 'expand("<afile>")'}]])
  206. local function on_setup()
  207. command('doautocmd BufEnter x.c')
  208. end
  209. local function handler(method, arguments)
  210. eq('test-handler', method)
  211. eq('x.c', arguments[1])
  212. return ''
  213. end
  214. runx(sync, handler, on_setup)
  215. end)
  216. end)
  217. end)
  218. end
  219. local function function_specs_for(fn, sync, first_arg_factory, init)
  220. local prefix = get_prefix(sync)
  221. describe(prefix..' function created by', function()
  222. before_each(clear_and_init(init))
  223. describe(fn, function()
  224. local args
  225. before_each(function()
  226. args = first_arg_factory()..', "test-handler", '
  227. if sync then
  228. args = args .. '1'
  229. else
  230. args = args .. '0'
  231. end
  232. args = args..', "TestFunction"'
  233. end)
  234. it('without options', function()
  235. call(fn, args..', {}')
  236. local function on_setup()
  237. if sync then
  238. eq('rv', eval('TestFunction(1, "a", ["b", "c"])'))
  239. else
  240. eq(1, eval('TestFunction(1, "a", ["b", "c"])'))
  241. end
  242. end
  243. local function handler(method, arguments)
  244. eq('test-handler', method)
  245. eq({{1, 'a', {'b', 'c'}}}, arguments)
  246. return 'rv'
  247. end
  248. runx(sync, handler, on_setup)
  249. end)
  250. it('with eval', function()
  251. call(fn, args..[[, {'eval': '2 + 2'}]])
  252. local function on_setup()
  253. if sync then
  254. eq('rv', eval('TestFunction(1, "a", ["b", "c"])'))
  255. else
  256. eq(1, eval('TestFunction(1, "a", ["b", "c"])'))
  257. end
  258. end
  259. local function handler(method, arguments)
  260. eq('test-handler', method)
  261. eq({{1, 'a', {'b', 'c'}}, 4}, arguments)
  262. return 'rv'
  263. end
  264. runx(sync, handler, on_setup)
  265. end)
  266. it('with range', function()
  267. helpers.insert([[
  268. foo
  269. bar
  270. baz
  271. zub]])
  272. call(fn, args..[[, {'range': ''}]])
  273. local function on_setup()
  274. command('2,3call TestFunction(1, "a", ["b", "c"])')
  275. end
  276. local function handler(method, arguments)
  277. eq('test-handler', method)
  278. eq({{1, 'a', {'b', 'c'}}, {2, 3}}, arguments)
  279. return 'rv'
  280. end
  281. runx(sync, handler, on_setup)
  282. end)
  283. it('with eval/range', function()
  284. call(fn, args..[[, {'eval': '4', 'range': ''}]])
  285. local function on_setup()
  286. command('%call TestFunction(1, "a", ["b", "c"])')
  287. end
  288. local function handler(method, arguments)
  289. eq('test-handler', method)
  290. eq({{1, 'a', {'b', 'c'}}, {1, 1}, 4}, arguments)
  291. return 'rv'
  292. end
  293. runx(sync, handler, on_setup)
  294. end)
  295. end)
  296. end)
  297. end
  298. local function channel()
  299. return nvim('get_api_info')[1]
  300. end
  301. local function host()
  302. return '"busted"'
  303. end
  304. local function register()
  305. eval('remote#host#Register("busted", "busted", '..channel()..')')
  306. end
  307. command_specs_for('remote#define#CommandOnChannel', true, channel)
  308. command_specs_for('remote#define#CommandOnChannel', false, channel)
  309. command_specs_for('remote#define#CommandOnHost', true, host, register)
  310. command_specs_for('remote#define#CommandOnHost', false, host, register)
  311. autocmd_specs_for('remote#define#AutocmdOnChannel', true, channel)
  312. autocmd_specs_for('remote#define#AutocmdOnChannel', false, channel)
  313. autocmd_specs_for('remote#define#AutocmdOnHost', true, host, register)
  314. autocmd_specs_for('remote#define#AutocmdOnHost', false, host, register)
  315. function_specs_for('remote#define#FunctionOnChannel', true, channel)
  316. function_specs_for('remote#define#FunctionOnChannel', false, channel)
  317. function_specs_for('remote#define#FunctionOnHost', true, host, register)
  318. function_specs_for('remote#define#FunctionOnHost', false, host, register)