msgpack_spec.lua 32 KB

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