msgpack_functions_spec.lua 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. local helpers = require('test.functional.helpers')(after_each)
  2. local clear = helpers.clear
  3. local funcs = helpers.funcs
  4. local eval, eq = helpers.eval, helpers.eq
  5. local command = helpers.command
  6. local nvim = helpers.nvim
  7. local exc_exec = helpers.exc_exec
  8. describe('msgpack*() functions', function()
  9. before_each(clear)
  10. local obj_test = function(msg, obj)
  11. it(msg, function()
  12. nvim('set_var', 'obj', obj)
  13. eq(obj, eval('msgpackparse(msgpackdump(g:obj))'))
  14. eq(obj, eval('msgpackparse(msgpackdump(g:obj, "B"))'))
  15. end)
  16. end
  17. -- Regression test: msgpack_list_write was failing to write buffer with zero
  18. -- length.
  19. obj_test('are able to dump and restore {"file": ""}', {{file=''}})
  20. -- Regression test: msgpack_list_write was failing to write buffer with NL at
  21. -- the end.
  22. obj_test('are able to dump and restore {0, "echo mpack"}', {{0, 'echo mpack'}})
  23. obj_test('are able to dump and restore "Test\\n"', {'Test\n'})
  24. -- Regression test: msgpack_list_write was failing to write buffer with NL
  25. -- inside.
  26. obj_test('are able to dump and restore "Test\\nTest 2"', {'Test\nTest 2'})
  27. -- Test that big objects (requirement: dump to something that is bigger then
  28. -- IOSIZE) are also fine. This particular object is obtained by concatenating
  29. -- 5 identical shada files.
  30. local big_obj = {
  31. 1, 1436711454, 78, {
  32. encoding="utf-8",
  33. max_kbyte=10,
  34. pid=19269,
  35. version="NVIM 0.0.0-alpha+201507121634"
  36. },
  37. 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  38. 8, 1436711391, 8, { file="" },
  39. 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
  40. 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
  41. 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
  42. 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
  43. 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
  44. 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
  45. 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
  46. 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
  47. 4, 1436708966, 6, { 0, "cq" },
  48. 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
  49. 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
  50. 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
  51. 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
  52. 4, 1436709634, 57, {
  53. 0,
  54. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
  55. },
  56. 4, 1436709651, 67, {
  57. 0,
  58. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
  59. },
  60. 4, 1436709660, 70, {
  61. 0,
  62. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
  63. },
  64. 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
  65. 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
  66. 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
  67. 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
  68. 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
  69. 4, 1436711142, 14, { 0, "echo mpack" },
  70. 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
  71. 4, 1436711206, 16, { 0, "echo lengths" },
  72. 4, 1436711244, 92, {
  73. 0,
  74. ("let sum = len(lengths) - 1 | call map(copy(lengths), "
  75. .. "'extend(g:, {\"sum\": sum + v:val})')")
  76. },
  77. 4, 1436711245, 12, { 0, "echo sum" },
  78. 4, 1436711398, 10, { 0, "echo s" },
  79. 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
  80. 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
  81. 4, 1436711415, 22, { 0, "echo shada_objects" },
  82. 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
  83. 4, 1436711454, 6, { 0, "qa" },
  84. 4, 1436711442, 9, { 1, "test", 47 },
  85. 4, 1436711443, 15, { 1, "aontsuesan", 47 },
  86. 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
  87. 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
  88. 3, 0, 3, { "" },
  89. 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  90. 1, 1436711454, 78, {
  91. encoding="utf-8",
  92. max_kbyte=10,
  93. pid=19269,
  94. version="NVIM 0.0.0-alpha+201507121634"
  95. },
  96. 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  97. 8, 1436711391, 8, { file="" },
  98. 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
  99. 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
  100. 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
  101. 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
  102. 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
  103. 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
  104. 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
  105. 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
  106. 4, 1436708966, 6, { 0, "cq" },
  107. 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
  108. 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
  109. 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
  110. 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
  111. 4, 1436709634, 57, {
  112. 0,
  113. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
  114. },
  115. 4, 1436709651, 67, {
  116. 0,
  117. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
  118. },
  119. 4, 1436709660, 70, {
  120. 0,
  121. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
  122. },
  123. 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
  124. 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
  125. 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
  126. 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
  127. 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
  128. 4, 1436711142, 14, { 0, "echo mpack" },
  129. 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
  130. 4, 1436711206, 16, { 0, "echo lengths" },
  131. 4, 1436711244, 92, {
  132. 0,
  133. ("let sum = len(lengths) - 1 | call map(copy(lengths), "
  134. .. "'extend(g:, {\"sum\": sum + v:val})')")
  135. },
  136. 4, 1436711245, 12, { 0, "echo sum" },
  137. 4, 1436711398, 10, { 0, "echo s" },
  138. 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
  139. 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
  140. 4, 1436711415, 22, { 0, "echo shada_objects" },
  141. 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
  142. 4, 1436711454, 6, { 0, "qa" },
  143. 4, 1436711442, 9, { 1, "test", 47 },
  144. 4, 1436711443, 15, { 1, "aontsuesan", 47 },
  145. 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
  146. 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
  147. 3, 0, 3, { "" },
  148. 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  149. 1, 1436711454, 78, {
  150. encoding="utf-8",
  151. max_kbyte=10,
  152. pid=19269,
  153. version="NVIM 0.0.0-alpha+201507121634"
  154. },
  155. 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  156. 8, 1436711391, 8, { file="" },
  157. 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
  158. 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
  159. 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
  160. 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
  161. 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
  162. 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
  163. 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
  164. 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
  165. 4, 1436708966, 6, { 0, "cq" },
  166. 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
  167. 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
  168. 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
  169. 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
  170. 4, 1436709634, 57, {
  171. 0,
  172. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
  173. },
  174. 4, 1436709651, 67, {
  175. 0,
  176. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
  177. },
  178. 4, 1436709660, 70, {
  179. 0,
  180. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
  181. },
  182. 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
  183. 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
  184. 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
  185. 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
  186. 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
  187. 4, 1436711142, 14, { 0, "echo mpack" },
  188. 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
  189. 4, 1436711206, 16, { 0, "echo lengths" },
  190. 4, 1436711244, 92, {
  191. 0,
  192. ("let sum = len(lengths) - 1 | call map(copy(lengths), "
  193. .. "'extend(g:, {\"sum\": sum + v:val})')")
  194. },
  195. 4, 1436711245, 12, { 0, "echo sum" },
  196. 4, 1436711398, 10, { 0, "echo s" },
  197. 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
  198. 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
  199. 4, 1436711415, 22, { 0, "echo shada_objects" },
  200. 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
  201. 4, 1436711454, 6, { 0, "qa" },
  202. 4, 1436711442, 9, { 1, "test", 47 },
  203. 4, 1436711443, 15, { 1, "aontsuesan", 47 },
  204. 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
  205. 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
  206. 3, 0, 3, { "" },
  207. 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  208. 1, 1436711454, 78, {
  209. encoding="utf-8",
  210. max_kbyte=10,
  211. pid=19269,
  212. version="NVIM 0.0.0-alpha+201507121634"
  213. },
  214. 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  215. 8, 1436711391, 8, { file="" },
  216. 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
  217. 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
  218. 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
  219. 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
  220. 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
  221. 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
  222. 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
  223. 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
  224. 4, 1436708966, 6, { 0, "cq" },
  225. 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
  226. 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
  227. 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
  228. 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
  229. 4, 1436709634, 57, {
  230. 0,
  231. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
  232. },
  233. 4, 1436709651, 67, {
  234. 0,
  235. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
  236. },
  237. 4, 1436709660, 70, {
  238. 0,
  239. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
  240. },
  241. 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
  242. 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
  243. 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
  244. 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
  245. 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
  246. 4, 1436711142, 14, { 0, "echo mpack" },
  247. 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
  248. 4, 1436711206, 16, { 0, "echo lengths" },
  249. 4, 1436711244, 92, {
  250. 0,
  251. ("let sum = len(lengths) - 1 | call map(copy(lengths), "
  252. .. "'extend(g:, {\"sum\": sum + v:val})')")
  253. },
  254. 4, 1436711245, 12, { 0, "echo sum" },
  255. 4, 1436711398, 10, { 0, "echo s" },
  256. 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
  257. 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
  258. 4, 1436711415, 22, { 0, "echo shada_objects" },
  259. 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
  260. 4, 1436711454, 6, { 0, "qa" },
  261. 4, 1436711442, 9, { 1, "test", 47 },
  262. 4, 1436711443, 15, { 1, "aontsuesan", 47 },
  263. 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
  264. 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
  265. 3, 0, 3, { "" },
  266. 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  267. 1, 1436711454, 78, {
  268. encoding="utf-8",
  269. max_kbyte=10,
  270. pid=19269,
  271. version="NVIM 0.0.0-alpha+201507121634"
  272. },
  273. 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
  274. 8, 1436711391, 8, { file="" },
  275. 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
  276. 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
  277. 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
  278. 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
  279. 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
  280. 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
  281. 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
  282. 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
  283. 4, 1436708966, 6, { 0, "cq" },
  284. 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
  285. 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
  286. 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
  287. 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
  288. 4, 1436709634, 57, {
  289. 0,
  290. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
  291. },
  292. 4, 1436709651, 67, {
  293. 0,
  294. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
  295. },
  296. 4, 1436709660, 70, {
  297. 0,
  298. "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
  299. },
  300. 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
  301. 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
  302. 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
  303. 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
  304. 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
  305. 4, 1436711142, 14, { 0, "echo mpack" },
  306. 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
  307. 4, 1436711206, 16, { 0, "echo lengths" },
  308. 4, 1436711244, 92, {
  309. 0,
  310. ("let sum = len(lengths) - 1 | call map(copy(lengths), "
  311. .. "'extend(g:, {\"sum\": sum + v:val})')")
  312. },
  313. 4, 1436711245, 12, { 0, "echo sum" },
  314. 4, 1436711398, 10, { 0, "echo s" },
  315. 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
  316. 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
  317. 4, 1436711415, 22, { 0, "echo shada_objects" },
  318. 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
  319. 4, 1436711454, 6, { 0, "qa" },
  320. 4, 1436711442, 9, { 1, "test", 47 },
  321. 4, 1436711443, 15, { 1, "aontsuesan", 47 },
  322. 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
  323. 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
  324. 3, 0, 3, { "" },
  325. 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" }
  326. }
  327. obj_test('are able to dump and restore rather big object', big_obj)
  328. obj_test('are able to dump and restore floating-point value', {0.125})
  329. it('can restore and dump UINT64_MAX', function()
  330. command('let dumped = ["\\xCF" . repeat("\\xFF", 8)]')
  331. command('let parsed = msgpackparse(dumped)')
  332. command('let dumped2 = msgpackdump(parsed)')
  333. eq(1, eval('type(parsed[0]) == type(0) ' ..
  334. '|| parsed[0]._TYPE is v:msgpack_types.integer'))
  335. if eval('type(parsed[0]) == type(0)') == 1 then
  336. command('call assert_equal(0xFFFFFFFFFFFFFFFF, parsed[0])')
  337. eq({}, eval('v:errors'))
  338. else
  339. eq({_TYPE={}, _VAL={1, 3, 0x7FFFFFFF, 0x7FFFFFFF}}, eval('parsed[0]'))
  340. end
  341. eq(1, eval('dumped ==# dumped2'))
  342. end)
  343. it('can restore and dump INT64_MIN', function()
  344. command('let dumped = ["\\xD3\\x80" . repeat("\\n", 7)]')
  345. command('let parsed = msgpackparse(dumped)')
  346. command('let dumped2 = msgpackdump(parsed)')
  347. eq(1, eval('type(parsed[0]) == type(0) ' ..
  348. '|| parsed[0]._TYPE is v:msgpack_types.integer'))
  349. if eval('type(parsed[0]) == type(0)') == 1 then
  350. command('call assert_equal(-0x7fffffffffffffff - 1, parsed[0])')
  351. eq({}, eval('v:errors'))
  352. else
  353. eq({_TYPE={}, _VAL={-1, 2, 0, 0}}, eval('parsed[0]'))
  354. end
  355. eq(1, eval('dumped ==# dumped2'))
  356. end)
  357. it('can restore and dump BIN string with zero byte', function()
  358. command('let dumped = ["\\xC4\\x01\\n"]')
  359. command('let parsed = msgpackparse(dumped)')
  360. command('let dumped2 = msgpackdump(parsed)')
  361. eq({'\000'}, eval('parsed'))
  362. eq(1, eval('dumped ==# dumped2'))
  363. end)
  364. it('can restore and dump STR string with zero byte', function()
  365. command('let dumped = ["\\xA1\\n"]')
  366. command('let parsed = msgpackparse(dumped)')
  367. command('let dumped2 = msgpackdump(parsed)')
  368. eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed'))
  369. eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string'))
  370. eq(1, eval('dumped ==# dumped2'))
  371. end)
  372. it('can restore and dump BIN string with NL', function()
  373. command('let dumped = ["\\xC4\\x01", ""]')
  374. command('let parsed = msgpackparse(dumped)')
  375. command('let dumped2 = msgpackdump(parsed)')
  376. eq({"\n"}, eval('parsed'))
  377. eq(1, eval('dumped ==# dumped2'))
  378. end)
  379. it('dump and restore special mapping with floating-point value', function()
  380. command('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
  381. eq({0.125}, eval('msgpackparse(msgpackdump([todump]))'))
  382. end)
  383. end)
  384. local blobstr = function(list)
  385. local l = {}
  386. for i,v in ipairs(list) do
  387. l[i] = v:gsub('\n', '\000')
  388. end
  389. return table.concat(l, '\n')
  390. end
  391. -- Test msgpackparse() with a readfile()-style list and a blob argument
  392. local parse_eq = function(expect, list_arg)
  393. local blob_expr = '0z' .. blobstr(list_arg):gsub('(.)', function(c)
  394. return ('%.2x'):format(c:byte())
  395. end)
  396. eq(expect, funcs.msgpackparse(list_arg))
  397. command('let g:parsed = msgpackparse(' .. blob_expr .. ')')
  398. eq(expect, eval('g:parsed'))
  399. end
  400. describe('msgpackparse() function', function()
  401. before_each(clear)
  402. it('restores nil as v:null', function()
  403. parse_eq(eval('[v:null]'), {'\192'})
  404. end)
  405. it('restores boolean false as v:false', function()
  406. parse_eq({false}, {'\194'})
  407. end)
  408. it('restores boolean true as v:true', function()
  409. parse_eq({true}, {'\195'})
  410. end)
  411. it('restores FIXSTR as special dict', function()
  412. parse_eq({{_TYPE={}, _VAL={'ab'}}}, {'\162ab'})
  413. eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string'))
  414. end)
  415. it('restores BIN 8 as string', function()
  416. parse_eq({'ab'}, {'\196\002ab'})
  417. end)
  418. it('restores FIXEXT1 as special dictionary', function()
  419. parse_eq({{_TYPE={}, _VAL={0x10, {"", ""}}}}, {'\212\016', ''})
  420. eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext'))
  421. end)
  422. it('restores MAP with BIN key as special dictionary', function()
  423. parse_eq({{_TYPE={}, _VAL={{'a', ''}}}}, {'\129\196\001a\196\n'})
  424. eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
  425. end)
  426. it('restores MAP with duplicate STR keys as special dictionary', function()
  427. command('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]')
  428. -- FIXME Internal error bug, can't use parse_eq() here
  429. command('silent! let parsed = msgpackparse(dumped)')
  430. eq({{_TYPE={}, _VAL={ {{_TYPE={}, _VAL={'a'}}, ''},
  431. {{_TYPE={}, _VAL={'a'}}, ''}}} }, eval('parsed'))
  432. eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
  433. eq(1, eval('g:parsed[0]._VAL[0][0]._TYPE is v:msgpack_types.string'))
  434. eq(1, eval('g:parsed[0]._VAL[1][0]._TYPE is v:msgpack_types.string'))
  435. end)
  436. it('restores MAP with MAP key as special dictionary', function()
  437. parse_eq({{_TYPE={}, _VAL={{{}, ''}}}}, {'\129\128\196\n'})
  438. eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
  439. end)
  440. it('msgpackparse(systemlist(...)) does not segfault. #3135', function()
  441. local cmd = "sort(keys(msgpackparse(systemlist('"
  442. ..helpers.nvim_prog.." --api-info'))[0]))"
  443. eval(cmd)
  444. eval(cmd) -- do it again (try to force segfault)
  445. local api_info = eval(cmd) -- do it again
  446. eq({'error_types', 'functions', 'types',
  447. 'ui_events', 'ui_options', 'version'}, api_info)
  448. end)
  449. it('fails when called with no arguments', function()
  450. eq('Vim(call):E119: Not enough arguments for function: msgpackparse',
  451. exc_exec('call msgpackparse()'))
  452. end)
  453. it('fails when called with two arguments', function()
  454. eq('Vim(call):E118: Too many arguments for function: msgpackparse',
  455. exc_exec('call msgpackparse(["", ""], 1)'))
  456. end)
  457. it('fails to parse a string', function()
  458. eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
  459. exc_exec('call msgpackparse("abcdefghijklmnopqrstuvwxyz")'))
  460. end)
  461. it('fails to parse a number', function()
  462. eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
  463. exc_exec('call msgpackparse(127)'))
  464. end)
  465. it('fails to parse a dictionary', function()
  466. eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
  467. exc_exec('call msgpackparse({})'))
  468. end)
  469. it('fails to parse a funcref', function()
  470. eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
  471. exc_exec('call msgpackparse(function("tr"))'))
  472. end)
  473. it('fails to parse a partial', function()
  474. command('function T() dict\nendfunction')
  475. eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
  476. exc_exec('call msgpackparse(function("T", [1, 2], {}))'))
  477. end)
  478. it('fails to parse a float', function()
  479. eq('Vim(call):E899: Argument of msgpackparse() must be a List or Blob',
  480. exc_exec('call msgpackparse(0.0)'))
  481. end)
  482. it('fails on incomplete msgpack string', function()
  483. local expected = 'Vim(call):E475: Invalid argument: Incomplete msgpack string'
  484. eq(expected, exc_exec([[call msgpackparse(["\xc4"])]]))
  485. eq(expected, exc_exec([[call msgpackparse(["\xca", "\x02\x03"])]]))
  486. eq(expected, exc_exec('call msgpackparse(0zc4)'))
  487. eq(expected, exc_exec('call msgpackparse(0zca0a0203)'))
  488. end)
  489. it('fails when unable to parse msgpack string', function()
  490. local expected = 'Vim(call):E475: Invalid argument: Failed to parse msgpack string'
  491. eq(expected, exc_exec([[call msgpackparse(["\xc1"])]]))
  492. eq(expected, exc_exec('call msgpackparse(0zc1)'))
  493. end)
  494. end)
  495. describe('msgpackdump() function', function()
  496. before_each(clear)
  497. local dump_eq = function(exp_list, arg_expr)
  498. eq(exp_list, eval('msgpackdump(' .. arg_expr .. ')'))
  499. eq(blobstr(exp_list), eval('msgpackdump(' .. arg_expr .. ', "B")'))
  500. end
  501. it('dumps string as BIN 8', function()
  502. dump_eq({'\196\004Test'}, '["Test"]')
  503. end)
  504. it('dumps blob as BIN 8', function()
  505. dump_eq({'\196\005Bl\nb!'}, '[0z426c006221]')
  506. end)
  507. it('can dump generic mapping with generic mapping keys and values', function()
  508. command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
  509. command('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
  510. command('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
  511. command('call add(todump._VAL, [todumpv1, todumpv2])')
  512. dump_eq({'\129\128\128'}, '[todump]')
  513. end)
  514. it('can dump v:true', function()
  515. dump_eq({'\195'}, '[v:true]')
  516. end)
  517. it('can dump v:false', function()
  518. dump_eq({'\194'}, '[v:false]')
  519. end)
  520. it('can dump v:null', function()
  521. dump_eq({'\192'}, '[v:null]')
  522. end)
  523. it('can dump special bool mapping (true)', function()
  524. command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 1}')
  525. dump_eq({'\195'}, '[todump]')
  526. end)
  527. it('can dump special bool mapping (false)', function()
  528. command('let todump = {"_TYPE": v:msgpack_types.boolean, "_VAL": 0}')
  529. dump_eq({'\194'}, '[todump]')
  530. end)
  531. it('can dump special nil mapping', function()
  532. command('let todump = {"_TYPE": v:msgpack_types.nil, "_VAL": 0}')
  533. dump_eq({'\192'}, '[todump]')
  534. end)
  535. it('can dump special ext mapping', function()
  536. command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
  537. dump_eq({'\212\005', ''}, '[todump]')
  538. end)
  539. it('can dump special array mapping', function()
  540. command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
  541. dump_eq({'\146\005\145\196\n'}, '[todump]')
  542. end)
  543. it('can dump special UINT64_MAX mapping', function()
  544. command('let todump = {"_TYPE": v:msgpack_types.integer}')
  545. command('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
  546. dump_eq({'\207\255\255\255\255\255\255\255\255'}, '[todump]')
  547. end)
  548. it('can dump special INT64_MIN mapping', function()
  549. command('let todump = {"_TYPE": v:msgpack_types.integer}')
  550. command('let todump._VAL = [-1, 2, 0, 0]')
  551. dump_eq({'\211\128\n\n\n\n\n\n\n'}, '[todump]')
  552. end)
  553. it('fails to dump a function reference', function()
  554. command('let Todump = function("tr")')
  555. eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
  556. exc_exec('call msgpackdump([Todump])'))
  557. end)
  558. it('fails to dump a partial', function()
  559. command('function T() dict\nendfunction')
  560. command('let Todump = function("T", [1, 2], {})')
  561. eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, itself: attempt to dump function reference',
  562. exc_exec('call msgpackdump([Todump])'))
  563. end)
  564. it('fails to dump a function reference in a list', function()
  565. command('let todump = [function("tr")]')
  566. eq('Vim(call):E5004: Error while dumping msgpackdump() argument, index 0, index 0: attempt to dump function reference',
  567. exc_exec('call msgpackdump([todump])'))
  568. end)
  569. it('fails to dump a recursive list', function()
  570. command('let todump = [[[]]]')
  571. command('call add(todump[0][0], todump)')
  572. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 0, index 0',
  573. exc_exec('call msgpackdump([todump])'))
  574. end)
  575. it('fails to dump a recursive dict', function()
  576. command('let todump = {"d": {"d": {}}}')
  577. command('call extend(todump.d.d, {"d": todump})')
  578. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key \'d\', key \'d\', key \'d\'',
  579. exc_exec('call msgpackdump([todump])'))
  580. end)
  581. it('can dump dict with two same dicts inside', function()
  582. command('let inter = {}')
  583. command('let todump = {"a": inter, "b": inter}')
  584. dump_eq({"\130\161a\128\161b\128"}, '[todump]')
  585. end)
  586. it('can dump list with two same lists inside', function()
  587. command('let inter = []')
  588. command('let todump = [inter, inter]')
  589. dump_eq({"\146\144\144"}, '[todump]')
  590. end)
  591. it('fails to dump a recursive list in a special dict', function()
  592. command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
  593. command('call add(todump._VAL, todump)')
  594. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0',
  595. exc_exec('call msgpackdump([todump])'))
  596. end)
  597. it('fails to dump a recursive (key) map in a special dict', function()
  598. command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
  599. command('call add(todump._VAL, [todump, 0])')
  600. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0',
  601. exc_exec('call msgpackdump([todump])'))
  602. end)
  603. it('fails to dump a recursive (val) map in a special dict', function()
  604. command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
  605. command('call add(todump._VAL, [0, todump])')
  606. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key 0 at index 0 from special map',
  607. exc_exec('call msgpackdump([todump])'))
  608. end)
  609. it('fails to dump a recursive (key) map in a special dict, _VAL reference', function()
  610. command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
  611. command('call add(todump._VAL[0][0], todump._VAL)')
  612. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [[[[...@0], []]]] at index 0 from special map, index 0',
  613. exc_exec('call msgpackdump([todump])'))
  614. end)
  615. it('fails to dump a recursive (val) map in a special dict, _VAL reference', function()
  616. command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[[], []]]}')
  617. command('call add(todump._VAL[0][1], todump._VAL)')
  618. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in key [] at index 0 from special map, index 0',
  619. exc_exec('call msgpackdump([todump])'))
  620. end)
  621. it('fails to dump a recursive (val) special list in a special dict',
  622. function()
  623. command('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
  624. command('call add(todump._VAL, [0, todump._VAL])')
  625. eq('Vim(call):E5005: Unable to dump msgpackdump() argument, index 0: container references itself in index 0, index 1',
  626. exc_exec('call msgpackdump([todump])'))
  627. end)
  628. it('fails when called with no arguments', function()
  629. eq('Vim(call):E119: Not enough arguments for function: msgpackdump',
  630. exc_exec('call msgpackdump()'))
  631. end)
  632. it('fails when called with three arguments', function()
  633. eq('Vim(call):E118: Too many arguments for function: msgpackdump',
  634. exc_exec('call msgpackdump(["", ""], 1, 2)'))
  635. end)
  636. it('fails to dump a string', function()
  637. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  638. exc_exec('call msgpackdump("abcdefghijklmnopqrstuvwxyz")'))
  639. end)
  640. it('fails to dump a number', function()
  641. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  642. exc_exec('call msgpackdump(127)'))
  643. end)
  644. it('fails to dump a dictionary', function()
  645. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  646. exc_exec('call msgpackdump({})'))
  647. end)
  648. it('fails to dump a funcref', function()
  649. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  650. exc_exec('call msgpackdump(function("tr"))'))
  651. end)
  652. it('fails to dump a partial', function()
  653. command('function T() dict\nendfunction')
  654. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  655. exc_exec('call msgpackdump(function("T", [1, 2], {}))'))
  656. end)
  657. it('fails to dump a float', function()
  658. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  659. exc_exec('call msgpackdump(0.0)'))
  660. end)
  661. it('fails to dump special value', function()
  662. for _, val in ipairs({'v:true', 'v:false', 'v:null'}) do
  663. eq('Vim(call):E686: Argument of msgpackdump() must be a List',
  664. exc_exec('call msgpackdump(' .. val .. ')'))
  665. end
  666. end)
  667. it('can dump NULL string', function()
  668. dump_eq({'\196\n'}, '[$XXX_UNEXISTENT_VAR_XXX]')
  669. dump_eq({'\196\n'}, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
  670. dump_eq({'\160'}, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]')
  671. end)
  672. it('can dump NULL blob', function()
  673. eq({'\196\n'}, eval('msgpackdump([v:_null_blob])'))
  674. end)
  675. it('can dump NULL list', function()
  676. eq({'\144'}, eval('msgpackdump([v:_null_list])'))
  677. end)
  678. it('can dump NULL dictionary', function()
  679. eq({'\128'}, eval('msgpackdump([v:_null_dict])'))
  680. end)
  681. end)