shada_spec.lua 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. -- Other ShaDa tests
  2. local helpers = require('test.functional.helpers')(after_each)
  3. local meths, nvim_command, funcs, eq =
  4. helpers.meths, helpers.command, helpers.funcs, helpers.eq
  5. local write_file, spawn, set_session, nvim_prog, exc_exec =
  6. helpers.write_file, helpers.spawn, helpers.set_session, helpers.nvim_prog,
  7. helpers.exc_exec
  8. local lfs = require('lfs')
  9. local paths = require('test.config.paths')
  10. local mpack = require('mpack')
  11. local shada_helpers = require('test.functional.shada.helpers')
  12. local reset, clear, get_shada_rw =
  13. shada_helpers.reset, shada_helpers.clear, shada_helpers.get_shada_rw
  14. local read_shada_file = shada_helpers.read_shada_file
  15. local wshada, _, shada_fname, clean =
  16. get_shada_rw('Xtest-functional-shada-shada.shada')
  17. local dirname = 'Xtest-functional-shada-shada.d'
  18. local dirshada = dirname .. '/main.shada'
  19. describe('ShaDa support code', function()
  20. before_each(reset)
  21. after_each(function()
  22. clear()
  23. clean()
  24. lfs.rmdir(dirname)
  25. end)
  26. it('preserves `s` item size limit with unknown entries', function()
  27. wshada('\100\000\207\000\000\000\000\000\000\004\000\218\003\253' .. ('-'):rep(1024 - 3)
  28. .. '\100\000\207\000\000\000\000\000\000\004\001\218\003\254' .. ('-'):rep(1025 - 3))
  29. eq(0, exc_exec('wshada ' .. shada_fname))
  30. local found = 0
  31. for _, v in ipairs(read_shada_file(shada_fname)) do
  32. if v.type == 100 then
  33. found = found + 1
  34. end
  35. end
  36. eq(2, found)
  37. eq(0, exc_exec('set shada-=s10 shada+=s1'))
  38. eq(0, exc_exec('wshada ' .. shada_fname))
  39. found = 0
  40. for _, v in ipairs(read_shada_file(shada_fname)) do
  41. if v.type == 100 then
  42. found = found + 1
  43. end
  44. end
  45. eq(1, found)
  46. end)
  47. it('preserves `s` item size limit with instance history entries', function()
  48. local hist1 = ('-'):rep(1024 - 5)
  49. local hist2 = ('-'):rep(1025 - 5)
  50. nvim_command('set shada-=s10 shada+=s1')
  51. funcs.histadd(':', hist1)
  52. funcs.histadd(':', hist2)
  53. eq(0, exc_exec('wshada ' .. shada_fname))
  54. local found = 0
  55. for _, v in ipairs(read_shada_file(shada_fname)) do
  56. if v.type == 4 then
  57. found = found + 1
  58. eq(hist1, v.value[2])
  59. end
  60. end
  61. eq(1, found)
  62. end)
  63. it('leaves .tmp.a in-place when there is error in original ShaDa', function()
  64. wshada('Some text file')
  65. eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname))
  66. eq(1, read_shada_file(shada_fname .. '.tmp.a')[1].type)
  67. end)
  68. it('does not leave .tmp.a in-place when there is error in original ShaDa, but writing with bang', function()
  69. wshada('Some text file')
  70. eq(0, exc_exec('wshada! ' .. shada_fname))
  71. eq(1, read_shada_file(shada_fname)[1].type)
  72. eq(nil, lfs.attributes(shada_fname .. '.tmp.a'))
  73. end)
  74. it('leaves .tmp.b in-place when there is error in original ShaDa and it has .tmp.a', function()
  75. wshada('Some text file')
  76. eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname))
  77. eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname))
  78. eq(1, read_shada_file(shada_fname .. '.tmp.a')[1].type)
  79. eq(1, read_shada_file(shada_fname .. '.tmp.b')[1].type)
  80. end)
  81. it('leaves .tmp.z in-place when there is error in original ShaDa and it has .tmp.a … .tmp.x', function()
  82. wshada('Some text file')
  83. local i = ('a'):byte()
  84. while i < ('z'):byte() do
  85. write_file(shada_fname .. ('.tmp.%c'):format(i), 'Some text file', true)
  86. i = i + 1
  87. end
  88. eq('Vim(wshada):E576: Error while reading ShaDa file: last entry specified that it occupies 109 bytes, but file ended earlier', exc_exec('wshada ' .. shada_fname))
  89. eq(1, read_shada_file(shada_fname .. '.tmp.z')[1].type)
  90. end)
  91. it('errors out when there are .tmp.a … .tmp.z ShaDa files', function()
  92. wshada('')
  93. local i = ('a'):byte()
  94. while i <= ('z'):byte() do
  95. write_file(shada_fname .. ('.tmp.%c'):format(i), '', true)
  96. i = i + 1
  97. end
  98. eq('Vim(wshada):E138: All Xtest-functional-shada-shada.shada.tmp.X files exist, cannot write ShaDa file!', exc_exec('wshada ' .. shada_fname))
  99. end)
  100. it('reads correctly various timestamps', function()
  101. local msgpack = {
  102. '\100', -- Positive fixnum 100
  103. '\204\255', -- uint 8 255
  104. '\205\010\003', -- uint 16 2563
  105. '\206\255\010\030\004', -- uint 32 4278853124
  106. '\207\005\100\060\250\255\010\030\004', -- uint 64 388502516579048964
  107. }
  108. local s = '\100'
  109. local e = '\001\192'
  110. wshada(s .. table.concat(msgpack, e .. s) .. e)
  111. eq(0, exc_exec('wshada ' .. shada_fname))
  112. local found = 0
  113. local typ = mpack.unpack(s)
  114. for _, v in ipairs(read_shada_file(shada_fname)) do
  115. if v.type == typ then
  116. found = found + 1
  117. eq(mpack.unpack(msgpack[found]), v.timestamp)
  118. end
  119. end
  120. eq(#msgpack, found)
  121. end)
  122. it('does not write NONE file', function()
  123. local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed',
  124. '--headless', '--cmd', 'qall'}, true)
  125. session:close()
  126. eq(nil, lfs.attributes('NONE'))
  127. eq(nil, lfs.attributes('NONE.tmp.a'))
  128. end)
  129. it('does not read NONE file', function()
  130. write_file('NONE', '\005\001\015\131\161na\162rX\194\162rc\145\196\001-')
  131. local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed',
  132. '--headless'}, true)
  133. set_session(session)
  134. eq('', funcs.getreg('a'))
  135. session:close()
  136. os.remove('NONE')
  137. end)
  138. local marklike = {[7]=true, [8]=true, [10]=true, [11]=true}
  139. local find_file = function(fname)
  140. local found = {}
  141. for _, v in ipairs(read_shada_file(shada_fname)) do
  142. if marklike[v.type] and v.value.f == fname then
  143. found[v.type] = (found[v.type] or 0) + 1
  144. elseif v.type == 9 then
  145. for _, b in ipairs(v.value) do
  146. if b.f == fname then
  147. found[v.type] = (found[v.type] or 0) + 1
  148. end
  149. end
  150. end
  151. end
  152. return found
  153. end
  154. it('correctly uses shada-r option', function()
  155. nvim_command('set shellslash')
  156. meths.set_var('__home', paths.test_source_path)
  157. nvim_command('let $HOME = __home')
  158. nvim_command('unlet __home')
  159. nvim_command('edit ~/README.md')
  160. nvim_command('normal! GmAggmaAabc')
  161. nvim_command('undo')
  162. nvim_command('set shada+=%')
  163. nvim_command('wshada! ' .. shada_fname)
  164. local readme_fname = funcs.resolve(paths.test_source_path) .. '/README.md'
  165. eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname))
  166. nvim_command('set shada+=r~')
  167. nvim_command('wshada! ' .. shada_fname)
  168. eq({}, find_file(readme_fname))
  169. nvim_command('set shada-=r~')
  170. nvim_command('wshada! ' .. shada_fname)
  171. eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname))
  172. nvim_command('set shada+=r' .. funcs.escape(
  173. funcs.escape(paths.test_source_path, '$~'), ' "\\,'))
  174. nvim_command('wshada! ' .. shada_fname)
  175. eq({}, find_file(readme_fname))
  176. end)
  177. it('correctly ignores case with shada-r option', function()
  178. nvim_command('set shellslash')
  179. local pwd = funcs.getcwd()
  180. local relfname = 'абв/test'
  181. local fname = pwd .. '/' .. relfname
  182. meths.set_var('__fname', fname)
  183. nvim_command('silent! edit `=__fname`')
  184. funcs.setline(1, {'a', 'b', 'c', 'd'})
  185. nvim_command('normal! GmAggmaAabc')
  186. nvim_command('undo')
  187. nvim_command('set shada+=%')
  188. nvim_command('wshada! ' .. shada_fname)
  189. eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=2}, find_file(fname))
  190. nvim_command('set shada+=r' .. pwd .. '/АБВ')
  191. nvim_command('wshada! ' .. shada_fname)
  192. eq({}, find_file(fname))
  193. end)
  194. it('is able to set &shada after &viminfo', function()
  195. meths.set_option('viminfo', '\'10')
  196. eq('\'10', meths.get_option('viminfo'))
  197. eq('\'10', meths.get_option('shada'))
  198. meths.set_option('shada', '')
  199. eq('', meths.get_option('viminfo'))
  200. eq('', meths.get_option('shada'))
  201. end)
  202. it('is able to set all& after setting &shada', function()
  203. meths.set_option('shada', '\'10')
  204. eq('\'10', meths.get_option('viminfo'))
  205. eq('\'10', meths.get_option('shada'))
  206. nvim_command('set all&')
  207. eq('!,\'100,<50,s10,h', meths.get_option('viminfo'))
  208. eq('!,\'100,<50,s10,h', meths.get_option('shada'))
  209. end)
  210. it('is able to set &shada after &viminfo using :set', function()
  211. nvim_command('set viminfo=\'10')
  212. eq('\'10', meths.get_option('viminfo'))
  213. eq('\'10', meths.get_option('shada'))
  214. nvim_command('set shada=')
  215. eq('', meths.get_option('viminfo'))
  216. eq('', meths.get_option('shada'))
  217. end)
  218. it('does not crash when ShaDa file directory is not writable', function()
  219. if helpers.pending_win32(pending) then return end
  220. funcs.mkdir(dirname, '', 0)
  221. eq(0, funcs.filewritable(dirname))
  222. reset{shadafile=dirshada, args={'--cmd', 'set shada='}}
  223. meths.set_option('shada', '\'10')
  224. eq('Vim(wshada):E886: System error while opening ShaDa file '
  225. .. 'Xtest-functional-shada-shada.d/main.shada for reading to merge '
  226. .. 'before writing it: permission denied',
  227. exc_exec('wshada'))
  228. meths.set_option('shada', '')
  229. end)
  230. end)