write_spec.lua 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local eq, eval, clear, write_file, source, insert =
  4. t.eq, n.eval, n.clear, t.write_file, n.source, n.insert
  5. local pcall_err = t.pcall_err
  6. local command = n.command
  7. local feed_command = n.feed_command
  8. local fn = n.fn
  9. local api = n.api
  10. local skip = t.skip
  11. local is_os = t.is_os
  12. local is_ci = t.is_ci
  13. local fname = 'Xtest-functional-ex_cmds-write'
  14. local fname_bak = fname .. '~'
  15. local fname_broken = fname_bak .. 'broken'
  16. describe(':write', function()
  17. local function cleanup()
  18. os.remove('test_bkc_file.txt')
  19. os.remove('test_bkc_link.txt')
  20. os.remove('test_fifo')
  21. os.remove('test/write/p_opt.txt')
  22. os.remove('test/write')
  23. os.remove('test')
  24. os.remove(fname)
  25. os.remove(fname_bak)
  26. os.remove(fname_broken)
  27. end
  28. before_each(function()
  29. clear()
  30. cleanup()
  31. end)
  32. after_each(function()
  33. cleanup()
  34. end)
  35. it('&backupcopy=auto preserves symlinks', function()
  36. command('set backupcopy=auto')
  37. write_file('test_bkc_file.txt', 'content0')
  38. if is_os('win') then
  39. command('silent !mklink test_bkc_link.txt test_bkc_file.txt')
  40. else
  41. command('silent !ln -s test_bkc_file.txt test_bkc_link.txt')
  42. end
  43. if eval('v:shell_error') ~= 0 then
  44. pending('Cannot create symlink')
  45. end
  46. source([[
  47. edit test_bkc_link.txt
  48. call setline(1, ['content1'])
  49. write
  50. ]])
  51. eq(eval("['content1']"), eval("readfile('test_bkc_file.txt')"))
  52. eq(eval("['content1']"), eval("readfile('test_bkc_link.txt')"))
  53. end)
  54. it('&backupcopy=no replaces symlink with new file', function()
  55. skip(is_ci('cirrus'))
  56. command('set backupcopy=no')
  57. write_file('test_bkc_file.txt', 'content0')
  58. if is_os('win') then
  59. command('silent !mklink test_bkc_link.txt test_bkc_file.txt')
  60. else
  61. command('silent !ln -s test_bkc_file.txt test_bkc_link.txt')
  62. end
  63. if eval('v:shell_error') ~= 0 then
  64. pending('Cannot create symlink')
  65. end
  66. source([[
  67. edit test_bkc_link.txt
  68. call setline(1, ['content1'])
  69. write
  70. ]])
  71. eq(eval("['content0']"), eval("readfile('test_bkc_file.txt')"))
  72. eq(eval("['content1']"), eval("readfile('test_bkc_link.txt')"))
  73. end)
  74. it('appends FIFO file', function()
  75. -- mkfifo creates read-only .lnk files on Windows
  76. if is_os('win') or eval("executable('mkfifo')") == 0 then
  77. pending('missing "mkfifo" command')
  78. end
  79. local text = 'some fifo text from write_spec'
  80. assert(os.execute('mkfifo test_fifo'))
  81. insert(text)
  82. -- Blocks until a consumer reads the FIFO.
  83. feed_command('write >> test_fifo')
  84. -- Read the FIFO, this will unblock the :write above.
  85. local fifo = assert(io.open('test_fifo'))
  86. eq(text .. '\n', fifo:read('*all'))
  87. fifo:close()
  88. end)
  89. it('++p creates missing parent directories', function()
  90. eq(0, eval("filereadable('p_opt.txt')"))
  91. command('write ++p p_opt.txt')
  92. eq(1, eval("filereadable('p_opt.txt')"))
  93. os.remove('p_opt.txt')
  94. eq(0, eval("filereadable('p_opt.txt')"))
  95. command('write ++p ./p_opt.txt')
  96. eq(1, eval("filereadable('p_opt.txt')"))
  97. os.remove('p_opt.txt')
  98. eq(0, eval("filereadable('test/write/p_opt.txt')"))
  99. command('write ++p test/write/p_opt.txt')
  100. eq(1, eval("filereadable('test/write/p_opt.txt')"))
  101. eq('Vim(write):E32: No file name', pcall_err(command, 'write ++p test_write/'))
  102. if not is_os('win') then
  103. eq(
  104. ('Vim(write):E17: "' .. fn.fnamemodify('.', ':p:h') .. '" is a directory'),
  105. pcall_err(command, 'write ++p .')
  106. )
  107. eq(
  108. ('Vim(write):E17: "' .. fn.fnamemodify('.', ':p:h') .. '" is a directory'),
  109. pcall_err(command, 'write ++p ./')
  110. )
  111. end
  112. end)
  113. it('errors out correctly', function()
  114. skip(is_ci('cirrus'))
  115. command('let $HOME=""')
  116. eq(fn.fnamemodify('.', ':p:h'), fn.fnamemodify('.', ':p:h:~'))
  117. -- Message from check_overwrite
  118. if not is_os('win') then
  119. eq(
  120. ('Vim(write):E17: "' .. fn.fnamemodify('.', ':p:h') .. '" is a directory'),
  121. pcall_err(command, 'write .')
  122. )
  123. end
  124. api.nvim_set_option_value('writeany', true, {})
  125. -- Message from buf_write
  126. eq('Vim(write):E502: "." is a directory', pcall_err(command, 'write .'))
  127. fn.mkdir(fname_bak)
  128. api.nvim_set_option_value('backupdir', '.', {})
  129. api.nvim_set_option_value('backup', true, {})
  130. write_file(fname, 'content0')
  131. command('edit ' .. fname)
  132. fn.setline(1, 'TTY')
  133. eq("Vim(write):E510: Can't make backup file (add ! to override)", pcall_err(command, 'write'))
  134. api.nvim_set_option_value('backup', false, {})
  135. fn.setfperm(fname, 'r--------')
  136. eq(
  137. 'Vim(write):E505: "Xtest-functional-ex_cmds-write" is read-only (add ! to override)',
  138. pcall_err(command, 'write')
  139. )
  140. if is_os('win') then
  141. eq(0, os.execute('del /q/f ' .. fname))
  142. eq(0, os.execute('rd /q/s ' .. fname_bak))
  143. else
  144. eq(true, os.remove(fname))
  145. eq(true, os.remove(fname_bak))
  146. end
  147. write_file(fname_bak, 'TTYX')
  148. skip(is_os('win'), [[FIXME: exc_exec('write!') outputs 0 in Windows]])
  149. vim.uv.fs_symlink(fname_bak .. ('/xxxxx'):rep(20), fname)
  150. eq("Vim(write):E166: Can't open linked file for writing", pcall_err(command, 'write!'))
  151. end)
  152. end)