msgpack_spec.lua 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local clear = n.clear
  4. local api = n.api
  5. local eq = t.eq
  6. local nvim_eval = n.eval
  7. local nvim_command = n.command
  8. local exc_exec = n.exc_exec
  9. local ok = t.ok
  10. local NIL = vim.NIL
  11. describe('autoload/msgpack.vim', function()
  12. before_each(function()
  13. clear { args = { '-u', 'NORC' } }
  14. end)
  15. local sp = function(typ, val)
  16. return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
  17. end
  18. local mapsp = function(...)
  19. local val = ''
  20. for i = 1, (select('#', ...) / 2) do
  21. val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...), select(i * 2, ...))
  22. end
  23. return sp('map', '[' .. val .. ']')
  24. end
  25. local nan = -(1.0 / 0.0 - 1.0 / 0.0)
  26. local inf = 1.0 / 0.0
  27. local minus_inf = -(1.0 / 0.0)
  28. describe('function msgpack#equal', function()
  29. local msgpack_eq = function(expected, a, b)
  30. eq(expected, nvim_eval(('msgpack#equal(%s, %s)'):format(a, b)))
  31. if a ~= b then
  32. eq(expected, nvim_eval(('msgpack#equal(%s, %s)'):format(b, a)))
  33. end
  34. end
  35. it('compares raw integers correctly', function()
  36. msgpack_eq(1, '1', '1')
  37. msgpack_eq(0, '1', '0')
  38. end)
  39. it('compares integer specials correctly', function()
  40. msgpack_eq(1, sp('integer', '[-1, 1, 0, 0]'), sp('integer', '[-1, 1, 0, 0]'))
  41. msgpack_eq(0, sp('integer', '[-1, 1, 0, 0]'), sp('integer', '[ 1, 1, 0, 0]'))
  42. end)
  43. it('compares integer specials with raw integer correctly', function()
  44. msgpack_eq(1, sp('integer', '[-1, 0, 0, 1]'), '-1')
  45. msgpack_eq(0, sp('integer', '[-1, 0, 0, 1]'), '1')
  46. msgpack_eq(0, sp('integer', '[ 1, 0, 0, 1]'), '-1')
  47. msgpack_eq(1, sp('integer', '[ 1, 0, 0, 1]'), '1')
  48. end)
  49. it('compares integer with float correctly', function()
  50. msgpack_eq(0, '0', '0.0')
  51. end)
  52. it('compares raw binaries correctly', function()
  53. msgpack_eq(1, '"abc\\ndef"', '"abc\\ndef"')
  54. msgpack_eq(0, '"abc\\ndef"', '"abc\\nghi"')
  55. end)
  56. it('compares string specials correctly', function()
  57. msgpack_eq(1, sp('string', '["abc\\n", "def"]'), sp('string', '["abc\\n", "def"]'))
  58. msgpack_eq(0, sp('string', '["abc", "def"]'), sp('string', '["abc\\n", "def"]'))
  59. msgpack_eq(1, sp('string', '["abc", "def"]'), '"abc\\ndef"')
  60. msgpack_eq(1, '"abc\\ndef"', sp('string', '["abc", "def"]'))
  61. end)
  62. it('compares ext specials correctly', function()
  63. msgpack_eq(1, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
  64. msgpack_eq(0, sp('ext', '[2, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
  65. msgpack_eq(0, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "abc"]]'))
  66. end)
  67. it('compares raw maps correctly', function()
  68. msgpack_eq(1, '{"a": 1, "b": 2}', '{"b": 2, "a": 1}')
  69. msgpack_eq(1, '{}', '{}')
  70. msgpack_eq(0, '{}', '{"a": 1}')
  71. msgpack_eq(0, '{"a": 2}', '{"a": 1}')
  72. msgpack_eq(0, '{"a": 1}', '{"b": 1}')
  73. msgpack_eq(0, '{"a": 1}', '{"a": 1, "b": 1}')
  74. msgpack_eq(0, '{"a": 1, "b": 1}', '{"b": 1}')
  75. end)
  76. it('compares map specials correctly', function()
  77. msgpack_eq(1, mapsp(), mapsp())
  78. msgpack_eq(
  79. 1,
  80. mapsp(mapsp('1', '1'), mapsp('1', '1')),
  81. mapsp(mapsp('1', '1'), mapsp('1', '1'))
  82. )
  83. msgpack_eq(0, mapsp(), mapsp('1', '1'))
  84. msgpack_eq(
  85. 0,
  86. mapsp(mapsp('1', '1'), mapsp('1', '1')),
  87. mapsp(sp('string', '[""]'), mapsp('1', '1'))
  88. )
  89. msgpack_eq(
  90. 0,
  91. mapsp(mapsp('1', '1'), mapsp('1', '1')),
  92. mapsp(mapsp('2', '1'), mapsp('1', '1'))
  93. )
  94. msgpack_eq(
  95. 0,
  96. mapsp(mapsp('1', '1'), mapsp('1', '1')),
  97. mapsp(mapsp('1', '2'), mapsp('1', '1'))
  98. )
  99. msgpack_eq(
  100. 0,
  101. mapsp(mapsp('1', '1'), mapsp('1', '1')),
  102. mapsp(mapsp('1', '1'), mapsp('2', '1'))
  103. )
  104. msgpack_eq(
  105. 0,
  106. mapsp(mapsp('1', '1'), mapsp('1', '1')),
  107. mapsp(mapsp('1', '1'), mapsp('1', '2'))
  108. )
  109. msgpack_eq(
  110. 1,
  111. mapsp(mapsp('2', '1'), mapsp('1', '1'), mapsp('1', '1'), mapsp('1', '1')),
  112. mapsp(mapsp('1', '1'), mapsp('1', '1'), mapsp('2', '1'), mapsp('1', '1'))
  113. )
  114. end)
  115. it('compares map specials with raw maps correctly', function()
  116. msgpack_eq(1, mapsp(), '{}')
  117. msgpack_eq(1, mapsp(sp('string', '["1"]'), '1'), '{"1": 1}')
  118. msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
  119. msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')), '{1: "1"}')
  120. msgpack_eq(1, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')), '{"1": 1}')
  121. msgpack_eq(0, mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'), '{"1": 1}')
  122. msgpack_eq(0, mapsp(sp('string', '["1"]'), '1'), '{"1": 1, "2": 2}')
  123. end)
  124. it('compares raw arrays correctly', function()
  125. msgpack_eq(1, '[]', '[]')
  126. msgpack_eq(0, '[]', '[1]')
  127. msgpack_eq(1, '[1]', '[1]')
  128. msgpack_eq(1, '[[[1]]]', '[[[1]]]')
  129. msgpack_eq(0, '[[[2]]]', '[[[1]]]')
  130. end)
  131. it('compares array specials correctly', function()
  132. msgpack_eq(1, sp('array', '[]'), sp('array', '[]'))
  133. msgpack_eq(0, sp('array', '[]'), sp('array', '[1]'))
  134. msgpack_eq(1, sp('array', '[1]'), sp('array', '[1]'))
  135. msgpack_eq(1, sp('array', '[[[1]]]'), sp('array', '[[[1]]]'))
  136. msgpack_eq(0, sp('array', '[[[1]]]'), sp('array', '[[[2]]]'))
  137. end)
  138. it('compares array specials with raw arrays correctly', function()
  139. msgpack_eq(1, sp('array', '[]'), '[]')
  140. msgpack_eq(0, sp('array', '[]'), '[1]')
  141. msgpack_eq(1, sp('array', '[1]'), '[1]')
  142. msgpack_eq(1, sp('array', '[[[1]]]'), '[[[1]]]')
  143. msgpack_eq(0, sp('array', '[[[1]]]'), '[[[2]]]')
  144. end)
  145. it('compares raw floats correctly', function()
  146. msgpack_eq(1, '0.0', '0.0')
  147. msgpack_eq(1, '(1.0/0.0-1.0/0.0)', '(1.0/0.0-1.0/0.0)')
  148. -- both (1.0/0.0-1.0/0.0) and -(1.0/0.0-1.0/0.0) now return
  149. -- str2float('nan'). ref: @18d1ba3422d
  150. msgpack_eq(1, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
  151. msgpack_eq(1, '-(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
  152. msgpack_eq(1, '1.0/0.0', '1.0/0.0')
  153. msgpack_eq(1, '-(1.0/0.0)', '-(1.0/0.0)')
  154. msgpack_eq(1, '0.0', '0.0')
  155. msgpack_eq(0, '0.0', '1.0')
  156. msgpack_eq(0, '0.0', '(1.0/0.0-1.0/0.0)')
  157. msgpack_eq(0, '0.0', '1.0/0.0')
  158. msgpack_eq(0, '0.0', '-(1.0/0.0)')
  159. msgpack_eq(0, '1.0/0.0', '-(1.0/0.0)')
  160. msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0)')
  161. msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '1.0/0.0')
  162. end)
  163. it('compares float specials with raw floats correctly', function()
  164. msgpack_eq(1, sp('float', '0.0'), '0.0')
  165. msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), '(1.0/0.0-1.0/0.0)')
  166. msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), '-(1.0/0.0-1.0/0.0)')
  167. msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), '(1.0/0.0-1.0/0.0)')
  168. msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), '-(1.0/0.0-1.0/0.0)')
  169. msgpack_eq(1, sp('float', '1.0/0.0'), '1.0/0.0')
  170. msgpack_eq(1, sp('float', '-(1.0/0.0)'), '-(1.0/0.0)')
  171. msgpack_eq(1, sp('float', '0.0'), '0.0')
  172. msgpack_eq(0, sp('float', '0.0'), '1.0')
  173. msgpack_eq(0, sp('float', '0.0'), '(1.0/0.0-1.0/0.0)')
  174. msgpack_eq(0, sp('float', '0.0'), '1.0/0.0')
  175. msgpack_eq(0, sp('float', '0.0'), '-(1.0/0.0)')
  176. msgpack_eq(0, sp('float', '1.0/0.0'), '-(1.0/0.0)')
  177. msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '-(1.0/0.0)')
  178. msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '1.0/0.0')
  179. end)
  180. it('compares float specials correctly', function()
  181. msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0'))
  182. msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '(1.0/0.0-1.0/0.0)'))
  183. msgpack_eq(1, sp('float', '1.0/0.0'), sp('float', '1.0/0.0'))
  184. msgpack_eq(1, sp('float', '-(1.0/0.0)'), sp('float', '-(1.0/0.0)'))
  185. msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0'))
  186. msgpack_eq(0, sp('float', '0.0'), sp('float', '1.0'))
  187. msgpack_eq(0, sp('float', '0.0'), sp('float', '(1.0/0.0-1.0/0.0)'))
  188. msgpack_eq(0, sp('float', '0.0'), sp('float', '1.0/0.0'))
  189. msgpack_eq(0, sp('float', '0.0'), sp('float', '-(1.0/0.0)'))
  190. msgpack_eq(0, sp('float', '1.0/0.0'), sp('float', '-(1.0/0.0)'))
  191. msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0)'))
  192. msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0-1.0/0.0)'))
  193. msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0-1.0/0.0)'))
  194. msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '1.0/0.0'))
  195. end)
  196. it('compares boolean specials correctly', function()
  197. msgpack_eq(1, sp('boolean', '1'), sp('boolean', '1'))
  198. msgpack_eq(0, sp('boolean', '1'), sp('boolean', '0'))
  199. end)
  200. it('compares nil specials correctly', function()
  201. msgpack_eq(1, sp('nil', '1'), sp('nil', '0'))
  202. end)
  203. it('compares nil, boolean and integer values with each other correctly', function()
  204. msgpack_eq(0, sp('boolean', '1'), '1')
  205. msgpack_eq(0, sp('boolean', '1'), sp('nil', '0'))
  206. msgpack_eq(0, sp('boolean', '1'), sp('nil', '1'))
  207. msgpack_eq(0, sp('boolean', '0'), sp('nil', '0'))
  208. msgpack_eq(0, sp('boolean', '0'), '0')
  209. msgpack_eq(0, sp('boolean', '0'), sp('integer', '[1, 0, 0, 0]'))
  210. msgpack_eq(0, sp('boolean', '0'), sp('integer', '[1, 0, 0, 1]'))
  211. msgpack_eq(0, sp('boolean', '1'), sp('integer', '[1, 0, 0, 1]'))
  212. msgpack_eq(0, sp('nil', '0'), sp('integer', '[1, 0, 0, 0]'))
  213. msgpack_eq(0, sp('nil', '0'), '0')
  214. end)
  215. end)
  216. describe('function msgpack#is_int', function()
  217. it('works', function()
  218. eq(1, nvim_eval('msgpack#is_int(1)'))
  219. eq(1, nvim_eval('msgpack#is_int(-1)'))
  220. eq(1, nvim_eval(('msgpack#is_int(%s)'):format(sp('integer', '[1, 0, 0, 1]'))))
  221. eq(1, nvim_eval(('msgpack#is_int(%s)'):format(sp('integer', '[-1, 0, 0, 1]'))))
  222. eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('float', '0.0'))))
  223. eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('boolean', '0'))))
  224. eq(0, nvim_eval(('msgpack#is_int(%s)'):format(sp('nil', '0'))))
  225. eq(0, nvim_eval('msgpack#is_int("")'))
  226. end)
  227. end)
  228. describe('function msgpack#is_uint', function()
  229. it('works', function()
  230. eq(1, nvim_eval('msgpack#is_uint(1)'))
  231. eq(0, nvim_eval('msgpack#is_uint(-1)'))
  232. eq(1, nvim_eval(('msgpack#is_uint(%s)'):format(sp('integer', '[1, 0, 0, 1]'))))
  233. eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('integer', '[-1, 0, 0, 1]'))))
  234. eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('float', '0.0'))))
  235. eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('boolean', '0'))))
  236. eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(sp('nil', '0'))))
  237. eq(0, nvim_eval('msgpack#is_uint("")'))
  238. end)
  239. end)
  240. describe('function msgpack#strftime', function()
  241. it('works', function()
  242. local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
  243. eq(epoch, nvim_eval('msgpack#strftime("%Y-%m-%dT%H:%M:%S", 0)'))
  244. eq(
  245. epoch,
  246. nvim_eval(
  247. ('msgpack#strftime("%%Y-%%m-%%dT%%H:%%M:%%S", %s)'):format(sp('integer', '[1, 0, 0, 0]'))
  248. )
  249. )
  250. end)
  251. end)
  252. describe('function msgpack#strptime', function()
  253. it('works', function()
  254. for _, v in ipairs({ 0, 10, 100000, 204, 1000000000 }) do
  255. local time = os.date('%Y-%m-%dT%H:%M:%S', v)
  256. eq(v, nvim_eval('msgpack#strptime("%Y-%m-%dT%H:%M:%S", ' .. '"' .. time .. '")'))
  257. end
  258. end)
  259. end)
  260. describe('function msgpack#type', function()
  261. local type_eq = function(expected, val)
  262. eq(expected, nvim_eval(('msgpack#type(%s)'):format(val)))
  263. end
  264. it('works for special dictionaries', function()
  265. type_eq('string', sp('string', '[""]'))
  266. type_eq('ext', sp('ext', '[1, [""]]'))
  267. type_eq('array', sp('array', '[]'))
  268. type_eq('map', sp('map', '[]'))
  269. type_eq('integer', sp('integer', '[1, 0, 0, 0]'))
  270. type_eq('float', sp('float', '0.0'))
  271. type_eq('boolean', sp('boolean', '0'))
  272. type_eq('nil', sp('nil', '0'))
  273. end)
  274. it('works for regular values', function()
  275. type_eq('string', '""')
  276. type_eq('array', '[]')
  277. type_eq('map', '{}')
  278. type_eq('integer', '1')
  279. type_eq('float', '0.0')
  280. type_eq('float', '(1.0/0.0)')
  281. type_eq('float', '-(1.0/0.0)')
  282. type_eq('float', '(1.0/0.0-1.0/0.0)')
  283. end)
  284. end)
  285. describe('function msgpack#special_type', function()
  286. local sp_type_eq = function(expected, val)
  287. eq(expected, nvim_eval(('msgpack#special_type(%s)'):format(val)))
  288. end
  289. it('works for special dictionaries', function()
  290. sp_type_eq('string', sp('string', '[""]'))
  291. sp_type_eq('ext', sp('ext', '[1, [""]]'))
  292. sp_type_eq('array', sp('array', '[]'))
  293. sp_type_eq('map', sp('map', '[]'))
  294. sp_type_eq('integer', sp('integer', '[1, 0, 0, 0]'))
  295. sp_type_eq('float', sp('float', '0.0'))
  296. sp_type_eq('boolean', sp('boolean', '0'))
  297. sp_type_eq('nil', sp('nil', '0'))
  298. end)
  299. it('works for regular values', function()
  300. sp_type_eq(0, '""')
  301. sp_type_eq(0, '[]')
  302. sp_type_eq(0, '{}')
  303. sp_type_eq(0, '1')
  304. sp_type_eq(0, '0.0')
  305. sp_type_eq(0, '(1.0/0.0)')
  306. sp_type_eq(0, '-(1.0/0.0)')
  307. sp_type_eq(0, '(1.0/0.0-1.0/0.0)')
  308. end)
  309. end)
  310. describe('function msgpack#string', function()
  311. local string_eq = function(expected, val)
  312. eq(expected, nvim_eval(('msgpack#string(%s)'):format(val)))
  313. end
  314. it('works for special dictionaries', function()
  315. string_eq('""', sp('string', '[""]'))
  316. string_eq('"\\n"', sp('string', '["", ""]'))
  317. string_eq('"ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
  318. string_eq('+(2)""', sp('ext', '[2, [""]]'))
  319. string_eq('+(2)"\\n"', sp('ext', '[2, ["", ""]]'))
  320. string_eq('+(2)"ab\\0c\\nde"', sp('ext', '[2, ["ab\\nc", "de"]]'))
  321. string_eq('[]', sp('array', '[]'))
  322. string_eq('[[[[{}]]]]', sp('array', '[[[[{}]]]]'))
  323. string_eq('{}', sp('map', '[]'))
  324. string_eq('{2: 10}', sp('map', '[[2, 10]]'))
  325. string_eq(
  326. '{{1: 1}: {1: 1}, {2: 1}: {1: 1}}',
  327. mapsp(mapsp('2', '1'), mapsp('1', '1'), mapsp('1', '1'), mapsp('1', '1'))
  328. )
  329. string_eq(
  330. '{{1: 1}: {1: 1}, {2: 1}: {1: 1}}',
  331. mapsp(mapsp('1', '1'), mapsp('1', '1'), mapsp('2', '1'), mapsp('1', '1'))
  332. )
  333. string_eq(
  334. '{[1, 2, {{1: 2}: 1}]: [1, 2, {{1: 2}: 1}]}',
  335. mapsp(
  336. ('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')),
  337. ('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1'))
  338. )
  339. )
  340. string_eq('0x0000000000000000', sp('integer', '[1, 0, 0, 0]'))
  341. string_eq('-0x0000000100000000', sp('integer', '[-1, 0, 2, 0]'))
  342. string_eq('0x123456789abcdef0', sp('integer', '[ 1, 0, 610839793, 448585456]'))
  343. string_eq('-0x123456789abcdef0', sp('integer', '[-1, 0, 610839793, 448585456]'))
  344. string_eq('0xf23456789abcdef0', sp('integer', '[ 1, 3, 1684581617, 448585456]'))
  345. string_eq('-0x723456789abcdef0', sp('integer', '[-1, 1, 1684581617, 448585456]'))
  346. string_eq('0.0', sp('float', '0.0'))
  347. string_eq('inf', sp('float', '(1.0/0.0)'))
  348. string_eq('-inf', sp('float', '-(1.0/0.0)'))
  349. string_eq('nan', sp('float', '(1.0/0.0-1.0/0.0)'))
  350. string_eq('nan', sp('float', '-(1.0/0.0-1.0/0.0)'))
  351. string_eq('FALSE', sp('boolean', '0'))
  352. string_eq('TRUE', sp('boolean', '1'))
  353. string_eq('NIL', sp('nil', '0'))
  354. end)
  355. it('works for regular values', function()
  356. string_eq('""', '""')
  357. string_eq('"\\n"', '"\\n"')
  358. string_eq('[]', '[]')
  359. string_eq('[[[{}]]]', '[[[{}]]]')
  360. string_eq('{}', '{}')
  361. string_eq('{"2": 10}', '{2: 10}')
  362. string_eq('{"2": [{}]}', '{2: [{}]}')
  363. string_eq('1', '1')
  364. string_eq('0.0', '0.0')
  365. string_eq('inf', '(1.0/0.0)')
  366. string_eq('-inf', '-(1.0/0.0)')
  367. string_eq('nan', '(1.0/0.0-1.0/0.0)')
  368. string_eq('nan', '-(1.0/0.0-1.0/0.0)')
  369. end)
  370. it('works for special v: values like v:true', function()
  371. string_eq('TRUE', 'v:true')
  372. string_eq('FALSE', 'v:false')
  373. string_eq('NIL', 'v:null')
  374. end)
  375. end)
  376. describe('function msgpack#deepcopy', function()
  377. it('works for special dictionaries', function()
  378. nvim_command('let sparr = ' .. sp('array', '[[[]]]'))
  379. nvim_command('let spmap = ' .. mapsp('"abc"', '[[]]'))
  380. nvim_command('let spint = ' .. sp('integer', '[1, 0, 0, 0]'))
  381. nvim_command('let spflt = ' .. sp('float', '1.0'))
  382. nvim_command('let spext = ' .. sp('ext', '[2, ["abc", "def"]]'))
  383. nvim_command('let spstr = ' .. sp('string', '["abc", "def"]'))
  384. nvim_command('let spbln = ' .. sp('boolean', '0'))
  385. nvim_command('let spnil = ' .. sp('nil', '0'))
  386. nvim_command('let sparr2 = msgpack#deepcopy(sparr)')
  387. nvim_command('let spmap2 = msgpack#deepcopy(spmap)')
  388. nvim_command('let spint2 = msgpack#deepcopy(spint)')
  389. nvim_command('let spflt2 = msgpack#deepcopy(spflt)')
  390. nvim_command('let spext2 = msgpack#deepcopy(spext)')
  391. nvim_command('let spstr2 = msgpack#deepcopy(spstr)')
  392. nvim_command('let spbln2 = msgpack#deepcopy(spbln)')
  393. nvim_command('let spnil2 = msgpack#deepcopy(spnil)')
  394. eq('array', nvim_eval('msgpack#type(sparr2)'))
  395. eq('map', nvim_eval('msgpack#type(spmap2)'))
  396. eq('integer', nvim_eval('msgpack#type(spint2)'))
  397. eq('float', nvim_eval('msgpack#type(spflt2)'))
  398. eq('ext', nvim_eval('msgpack#type(spext2)'))
  399. eq('string', nvim_eval('msgpack#type(spstr2)'))
  400. eq('boolean', nvim_eval('msgpack#type(spbln2)'))
  401. eq('nil', nvim_eval('msgpack#type(spnil2)'))
  402. nvim_command('call add(sparr._VAL, 0)')
  403. nvim_command('call add(sparr._VAL[0], 0)')
  404. nvim_command('call add(sparr._VAL[0][0], 0)')
  405. nvim_command('call add(spmap._VAL, [0, 0])')
  406. nvim_command('call add(spmap._VAL[0][1], 0)')
  407. nvim_command('call add(spmap._VAL[0][1][0], 0)')
  408. nvim_command('let spint._VAL[1] = 1')
  409. nvim_command('let spflt._VAL = 0.0')
  410. nvim_command('let spext._VAL[0] = 3')
  411. nvim_command('let spext._VAL[1][0] = "gh"')
  412. nvim_command('let spstr._VAL[0] = "gh"')
  413. nvim_command('let spbln._VAL = 1')
  414. nvim_command('let spnil._VAL = 1')
  415. eq({ _TYPE = {}, _VAL = { { {} } } }, nvim_eval('sparr2'))
  416. eq({ _TYPE = {}, _VAL = { { 'abc', { {} } } } }, nvim_eval('spmap2'))
  417. eq({ _TYPE = {}, _VAL = { 1, 0, 0, 0 } }, nvim_eval('spint2'))
  418. eq({ _TYPE = {}, _VAL = 1.0 }, nvim_eval('spflt2'))
  419. eq({ _TYPE = {}, _VAL = { 2, { 'abc', 'def' } } }, nvim_eval('spext2'))
  420. eq({ _TYPE = {}, _VAL = { 'abc', 'def' } }, nvim_eval('spstr2'))
  421. eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spbln2'))
  422. eq({ _TYPE = {}, _VAL = 0 }, nvim_eval('spnil2'))
  423. nvim_command('let sparr._TYPE = []')
  424. nvim_command('let spmap._TYPE = []')
  425. nvim_command('let spint._TYPE = []')
  426. nvim_command('let spflt._TYPE = []')
  427. nvim_command('let spext._TYPE = []')
  428. nvim_command('let spstr._TYPE = []')
  429. nvim_command('let spbln._TYPE = []')
  430. nvim_command('let spnil._TYPE = []')
  431. eq('array', nvim_eval('msgpack#special_type(sparr2)'))
  432. eq('map', nvim_eval('msgpack#special_type(spmap2)'))
  433. eq('integer', nvim_eval('msgpack#special_type(spint2)'))
  434. eq('float', nvim_eval('msgpack#special_type(spflt2)'))
  435. eq('ext', nvim_eval('msgpack#special_type(spext2)'))
  436. eq('string', nvim_eval('msgpack#special_type(spstr2)'))
  437. eq('boolean', nvim_eval('msgpack#special_type(spbln2)'))
  438. eq('nil', nvim_eval('msgpack#special_type(spnil2)'))
  439. end)
  440. it('works for regular values', function()
  441. nvim_command('let arr = [[[]]]')
  442. nvim_command('let map = {1: {}}')
  443. nvim_command('let int = 1')
  444. nvim_command('let flt = 2.0')
  445. nvim_command('let bin = "abc"')
  446. nvim_command('let arr2 = msgpack#deepcopy(arr)')
  447. nvim_command('let map2 = msgpack#deepcopy(map)')
  448. nvim_command('let int2 = msgpack#deepcopy(int)')
  449. nvim_command('let flt2 = msgpack#deepcopy(flt)')
  450. nvim_command('let bin2 = msgpack#deepcopy(bin)')
  451. eq('array', nvim_eval('msgpack#type(arr2)'))
  452. eq('map', nvim_eval('msgpack#type(map2)'))
  453. eq('integer', nvim_eval('msgpack#type(int2)'))
  454. eq('float', nvim_eval('msgpack#type(flt2)'))
  455. eq('string', nvim_eval('msgpack#type(bin2)'))
  456. nvim_command('call add(arr, 0)')
  457. nvim_command('call add(arr[0], 0)')
  458. nvim_command('call add(arr[0][0], 0)')
  459. nvim_command('let map.a = 1')
  460. nvim_command('let map.1.a = 1')
  461. nvim_command('let int = 2')
  462. nvim_command('let flt = 3.0')
  463. nvim_command('let bin = ""')
  464. eq({ { {} } }, nvim_eval('arr2'))
  465. eq({ ['1'] = {} }, nvim_eval('map2'))
  466. eq(1, nvim_eval('int2'))
  467. eq(2.0, nvim_eval('flt2'))
  468. eq('abc', nvim_eval('bin2'))
  469. end)
  470. it('works for special v: values like v:true', function()
  471. api.nvim_set_var('true', true)
  472. api.nvim_set_var('false', false)
  473. api.nvim_set_var('nil', NIL)
  474. nvim_command('let true2 = msgpack#deepcopy(true)')
  475. nvim_command('let false2 = msgpack#deepcopy(false)')
  476. nvim_command('let nil2 = msgpack#deepcopy(nil)')
  477. eq(true, api.nvim_get_var('true'))
  478. eq(false, api.nvim_get_var('false'))
  479. eq(NIL, api.nvim_get_var('nil'))
  480. end)
  481. end)
  482. describe('function msgpack#eval', function()
  483. local eval_eq = function(expected_type, expected_val, str, ...)
  484. nvim_command(
  485. ("let g:__val = msgpack#eval('%s', %s)"):format(str:gsub("'", "''"), select(1, ...) or '{}')
  486. )
  487. eq(expected_type, nvim_eval('msgpack#type(g:__val)'))
  488. local expected_val_full = expected_val
  489. if
  490. not (({ float = true, integer = true })[expected_type] and type(expected_val) ~= 'table')
  491. and expected_type ~= 'array'
  492. then
  493. expected_val_full = { _TYPE = {}, _VAL = expected_val_full }
  494. end
  495. if expected_val_full == expected_val_full then
  496. eq(expected_val_full, nvim_eval('g:__val'))
  497. else -- NaN
  498. local nvim_nan = tostring(nvim_eval('g:__val'))
  499. -- -NaN is a hardware-specific detail, there's no need to test for it.
  500. -- Accept ether 'nan' or '-nan' as the response.
  501. ok(nvim_nan == 'nan' or nvim_nan == '-nan')
  502. end
  503. nvim_command('unlet g:__val')
  504. end
  505. it('correctly loads strings', function()
  506. eval_eq('string', { 'abcdef' }, '="abcdef"')
  507. eval_eq('string', { 'abc', 'def' }, '="abc\\ndef"')
  508. eval_eq('string', { 'abc\ndef' }, '="abc\\0def"')
  509. eval_eq('string', { '\nabc\ndef\n' }, '="\\0abc\\0def\\0"')
  510. eval_eq('string', { 'abc\n\n\ndef' }, '="abc\\0\\0\\0def"')
  511. eval_eq('string', { 'abc\n', '\ndef' }, '="abc\\0\\n\\0def"')
  512. eval_eq('string', { 'abc', '', '', 'def' }, '="abc\\n\\n\\ndef"')
  513. eval_eq('string', { 'abc', '', '', 'def', '' }, '="abc\\n\\n\\ndef\\n"')
  514. eval_eq('string', { '', 'abc', '', '', 'def' }, '="\\nabc\\n\\n\\ndef"')
  515. eval_eq('string', { '' }, '=""')
  516. eval_eq('string', { '"' }, '="\\""')
  517. eval_eq('string', { 'py3 print(sys.version_info)' }, '="py3 print(sys.version_info)"')
  518. end)
  519. it('correctly loads ext values', function()
  520. eval_eq('ext', { 0, { 'abcdef' } }, '+(0)"abcdef"')
  521. eval_eq('ext', { 0, { 'abc', 'def' } }, '+(0)"abc\\ndef"')
  522. eval_eq('ext', { 0, { 'abc\ndef' } }, '+(0)"abc\\0def"')
  523. eval_eq('ext', { 0, { '\nabc\ndef\n' } }, '+(0)"\\0abc\\0def\\0"')
  524. eval_eq('ext', { 0, { 'abc\n\n\ndef' } }, '+(0)"abc\\0\\0\\0def"')
  525. eval_eq('ext', { 0, { 'abc\n', '\ndef' } }, '+(0)"abc\\0\\n\\0def"')
  526. eval_eq('ext', { 0, { 'abc', '', '', 'def' } }, '+(0)"abc\\n\\n\\ndef"')
  527. eval_eq('ext', { 0, { 'abc', '', '', 'def', '' } }, '+(0)"abc\\n\\n\\ndef\\n"')
  528. eval_eq('ext', { 0, { '', 'abc', '', '', 'def' } }, '+(0)"\\nabc\\n\\n\\ndef"')
  529. eval_eq('ext', { 0, { '' } }, '+(0)""')
  530. eval_eq('ext', { 0, { '"' } }, '+(0)"\\""')
  531. eval_eq('ext', { -1, { 'abcdef' } }, '+(-1)"abcdef"')
  532. eval_eq('ext', { -1, { 'abc', 'def' } }, '+(-1)"abc\\ndef"')
  533. eval_eq('ext', { -1, { 'abc\ndef' } }, '+(-1)"abc\\0def"')
  534. eval_eq('ext', { -1, { '\nabc\ndef\n' } }, '+(-1)"\\0abc\\0def\\0"')
  535. eval_eq('ext', { -1, { 'abc\n\n\ndef' } }, '+(-1)"abc\\0\\0\\0def"')
  536. eval_eq('ext', { -1, { 'abc\n', '\ndef' } }, '+(-1)"abc\\0\\n\\0def"')
  537. eval_eq('ext', { -1, { 'abc', '', '', 'def' } }, '+(-1)"abc\\n\\n\\ndef"')
  538. eval_eq('ext', { -1, { 'abc', '', '', 'def', '' } }, '+(-1)"abc\\n\\n\\ndef\\n"')
  539. eval_eq('ext', { -1, { '', 'abc', '', '', 'def' } }, '+(-1)"\\nabc\\n\\n\\ndef"')
  540. eval_eq('ext', { -1, { '' } }, '+(-1)""')
  541. eval_eq('ext', { -1, { '"' } }, '+(-1)"\\""')
  542. eval_eq(
  543. 'ext',
  544. { 42, { 'py3 print(sys.version_info)' } },
  545. '+(42)"py3 print(sys.version_info)"'
  546. )
  547. end)
  548. it('correctly loads floats', function()
  549. eval_eq('float', inf, 'inf')
  550. eval_eq('float', minus_inf, '-inf')
  551. eval_eq('float', nan, 'nan')
  552. eval_eq('float', 1.0e10, '1.0e10')
  553. eval_eq('float', 1.0e10, '1.0e+10')
  554. eval_eq('float', -1.0e10, '-1.0e+10')
  555. eval_eq('float', 1.0, '1.0')
  556. eval_eq('float', -1.0, '-1.0')
  557. eval_eq('float', 1.0e-10, '1.0e-10')
  558. eval_eq('float', -1.0e-10, '-1.0e-10')
  559. end)
  560. it('correctly loads integers', function()
  561. eval_eq('integer', 10, '10')
  562. eval_eq('integer', -10, '-10')
  563. eval_eq('integer', { 1, 0, 610839793, 448585456 }, ' 0x123456789ABCDEF0')
  564. eval_eq('integer', { -1, 0, 610839793, 448585456 }, '-0x123456789ABCDEF0')
  565. eval_eq('integer', { 1, 3, 1684581617, 448585456 }, ' 0xF23456789ABCDEF0')
  566. eval_eq('integer', { -1, 1, 1684581617, 448585456 }, '-0x723456789ABCDEF0')
  567. eval_eq('integer', { 1, 0, 0, 0x100 }, '0x100')
  568. eval_eq('integer', { -1, 0, 0, 0x100 }, '-0x100')
  569. eval_eq('integer', ('a'):byte(), "'a'")
  570. eval_eq('integer', 0xAB, "'«'")
  571. eval_eq('integer', 0, "'\\0'")
  572. eval_eq('integer', 10246567, "'\\10246567'")
  573. end)
  574. it('correctly loads constants', function()
  575. eval_eq('boolean', 1, 'TRUE')
  576. eval_eq('boolean', 0, 'FALSE')
  577. eval_eq('nil', 0, 'NIL')
  578. eval_eq('nil', 0, 'NIL', '{"NIL": 1, "nan": 2, "T": 3}')
  579. eval_eq('float', nan, 'nan', '{"NIL": "1", "nan": "2", "T": "3"}')
  580. eval_eq('integer', 3, 'T', '{"NIL": "1", "nan": "2", "T": "3"}')
  581. eval_eq(
  582. 'integer',
  583. { 1, 0, 0, 0 },
  584. 'T',
  585. ('{"NIL": "1", "nan": "2", "T": \'%s\'}'):format(sp('integer', '[1, 0, 0, 0]'))
  586. )
  587. end)
  588. it('correctly loads maps', function()
  589. eval_eq('map', {}, '{}')
  590. eval_eq(
  591. 'map',
  592. { { { _TYPE = {}, _VAL = { { 1, 2 } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } } },
  593. '{{1: 2}: {3: 4}}'
  594. )
  595. eval_eq(
  596. 'map',
  597. { { { _TYPE = {}, _VAL = { { 1, 2 } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } }, { 1, 2 } },
  598. '{{1: 2}: {3: 4}, 1: 2}'
  599. )
  600. eval_eq('map', {
  601. {
  602. {
  603. _TYPE = {},
  604. _VAL = {
  605. { { _TYPE = {}, _VAL = { 'py3 print(sys.version_info)' } }, 2 },
  606. },
  607. },
  608. { _TYPE = {}, _VAL = { { 3, 4 } } },
  609. },
  610. { 1, 2 },
  611. }, '{{"py3 print(sys.version_info)": 2}: {3: 4}, 1: 2}')
  612. end)
  613. it('correctly loads arrays', function()
  614. eval_eq('array', {}, '[]')
  615. eval_eq('array', { 1 }, '[1]')
  616. eval_eq('array', { { _TYPE = {}, _VAL = 1 } }, '[TRUE]')
  617. eval_eq(
  618. 'array',
  619. { { { _TYPE = {}, _VAL = { { 1, 2 } } } }, { _TYPE = {}, _VAL = { { 3, 4 } } } },
  620. '[[{1: 2}], {3: 4}]'
  621. )
  622. eval_eq(
  623. 'array',
  624. { { _TYPE = {}, _VAL = { 'py3 print(sys.version_info)' } } },
  625. '["py3 print(sys.version_info)"]'
  626. )
  627. end)
  628. it('errors out when needed', function()
  629. eq('empty:Parsed string is empty', exc_exec('call msgpack#eval("", {})'))
  630. eq('unknown:Invalid non-space character: ^', exc_exec('call msgpack#eval("^", {})'))
  631. eq(
  632. "char-invalid:Invalid integer character literal format: ''",
  633. exc_exec('call msgpack#eval("\'\'", {})')
  634. )
  635. eq(
  636. "char-invalid:Invalid integer character literal format: 'ab'",
  637. exc_exec('call msgpack#eval("\'ab\'", {})')
  638. )
  639. eq(
  640. "char-invalid:Invalid integer character literal format: '",
  641. exc_exec('call msgpack#eval("\'", {})')
  642. )
  643. eq('"-invalid:Invalid string: "', exc_exec('call msgpack#eval("\\"", {})'))
  644. eq('"-invalid:Invalid string: ="', exc_exec('call msgpack#eval("=\\"", {})'))
  645. eq('"-invalid:Invalid string: +(0)"', exc_exec('call msgpack#eval("+(0)\\"", {})'))
  646. eq(
  647. '0.-nodigits:Decimal dot must be followed by digit(s): .e1',
  648. exc_exec('call msgpack#eval("0.e1", {})')
  649. )
  650. eq(
  651. '0x-long:Must have at most 16 hex digits: FEDCBA98765432100',
  652. exc_exec('call msgpack#eval("0xFEDCBA98765432100", {})')
  653. )
  654. eq('0x-empty:Must have number after 0x: ', exc_exec('call msgpack#eval("0x", {})'))
  655. eq('name-unknown:Unknown name FOO: FOO', exc_exec('call msgpack#eval("FOO", {})'))
  656. eq(
  657. 'name-unknown:Unknown name py3: py3 print(sys.version_info)',
  658. exc_exec('call msgpack#eval("py3 print(sys.version_info)", {})')
  659. )
  660. eq('name-unknown:Unknown name o: o', exc_exec('call msgpack#eval("-info", {})'))
  661. end)
  662. end)
  663. end)