2024-04-09 04:26:16 -07:00
|
|
|
local t = require('test.unit.testutil')
|
2024-04-08 02:03:20 -07:00
|
|
|
local itp = t.gen_itp(it)
|
2024-01-12 04:41:09 -07:00
|
|
|
local uv = vim.uv
|
2024-04-08 02:03:20 -07:00
|
|
|
local child_call_once = t.child_call_once
|
2024-01-12 04:41:09 -07:00
|
|
|
local sleep = uv.sleep
|
2016-06-21 17:58:38 -07:00
|
|
|
|
2024-04-08 02:03:20 -07:00
|
|
|
local ffi = t.ffi
|
|
|
|
local cimport = t.cimport
|
|
|
|
local to_cstr = t.to_cstr
|
|
|
|
local neq = t.neq
|
|
|
|
local eq = t.eq
|
|
|
|
local mkdir = t.mkdir
|
2016-06-21 17:58:38 -07:00
|
|
|
|
2023-09-29 23:41:34 -07:00
|
|
|
local options = cimport('./src/nvim/option_vars.h')
|
2016-06-21 17:58:38 -07:00
|
|
|
local undo = cimport('./src/nvim/undo.h')
|
|
|
|
local buffer = cimport('./src/nvim/buffer.h')
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
local old_p_udir = nil
|
2016-06-21 17:58:38 -07:00
|
|
|
|
|
|
|
-- Values expected by tests. Set in the setup function and destroyed in teardown
|
|
|
|
local file_buffer = nil
|
|
|
|
local buffer_hash = nil
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
child_call_once(function()
|
|
|
|
if old_p_udir == nil then
|
2023-12-04 15:32:39 -07:00
|
|
|
old_p_udir = options.p_udir -- save the old value of p_udir (undodir)
|
2018-04-27 01:06:42 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
-- create a new buffer
|
|
|
|
local c_file = to_cstr('Xtest-unit-undo')
|
|
|
|
file_buffer = buffer.buflist_new(c_file, c_file, 1, buffer.BLN_LISTED)
|
|
|
|
file_buffer.b_u_numhead = 1 -- Pretend that the buffer has been changed
|
|
|
|
|
|
|
|
-- TODO(christopher.waldon.dev@gmail.com): replace the 32 with UNDO_HASH_SIZE
|
|
|
|
-- requires refactor of UNDO_HASH_SIZE into constant/enum for ffi
|
|
|
|
--
|
|
|
|
-- compute a hash for this undofile
|
2023-04-02 01:11:42 -07:00
|
|
|
buffer_hash = ffi.new('char[32]')
|
2021-07-09 06:10:49 -07:00
|
|
|
undo.u_compute_hash(file_buffer, buffer_hash)
|
2018-04-27 01:06:42 -07:00
|
|
|
end)
|
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
describe('u_write_undo', function()
|
|
|
|
setup(function()
|
2023-04-04 12:59:06 -07:00
|
|
|
mkdir('unit-test-directory')
|
2024-01-12 04:41:09 -07:00
|
|
|
uv.chdir('unit-test-directory')
|
|
|
|
options.p_udir = to_cstr(uv.cwd()) -- set p_udir to be the test dir
|
2016-06-21 17:58:38 -07:00
|
|
|
end)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
teardown(function()
|
2024-01-12 04:41:09 -07:00
|
|
|
uv.chdir('..')
|
|
|
|
local success, err = uv.fs_rmdir('unit-test-directory')
|
2016-06-21 17:58:38 -07:00
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if directory fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
2023-12-04 15:32:39 -07:00
|
|
|
options.p_udir = old_p_udir --restore old p_udir
|
2016-06-21 17:58:38 -07:00
|
|
|
end)
|
|
|
|
|
|
|
|
-- Lua wrapper for u_write_undo
|
|
|
|
local function u_write_undo(name, forceit, buf, buf_hash)
|
|
|
|
if name ~= nil then
|
|
|
|
name = to_cstr(name)
|
|
|
|
end
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
return undo.u_write_undo(name, forceit, buf, buf_hash)
|
|
|
|
end
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
itp('writes an undo file to undodir given a buffer and hash', function()
|
2016-06-21 17:58:38 -07:00
|
|
|
u_write_undo(nil, false, file_buffer, buffer_hash)
|
|
|
|
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
|
2023-12-04 15:32:39 -07:00
|
|
|
local undo_file = io.open(correct_name, 'r')
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
neq(undo_file, nil)
|
2023-12-04 15:32:39 -07:00
|
|
|
local success, err = os.remove(correct_name) -- delete the file now that we're done with it.
|
2016-06-21 17:58:38 -07:00
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
end)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
|
|
|
itp('writes a correctly-named undo file to undodir given a name, buffer, and hash', function()
|
2023-12-04 15:32:39 -07:00
|
|
|
local correct_name = 'undofile.test'
|
2016-06-21 17:58:38 -07:00
|
|
|
u_write_undo(correct_name, false, file_buffer, buffer_hash)
|
2023-12-04 15:32:39 -07:00
|
|
|
local undo_file = io.open(correct_name, 'r')
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
neq(undo_file, nil)
|
2023-12-04 15:32:39 -07:00
|
|
|
local success, err = os.remove(correct_name) -- delete the file now that we're done with it.
|
2016-06-21 17:58:38 -07:00
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
end)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
|
|
|
itp('does not write an undofile when the buffer has no valid undofile name', function()
|
2016-06-21 17:58:38 -07:00
|
|
|
-- TODO(christopher.waldon.dev@gmail.com): Figure out how to test this.
|
|
|
|
-- it's hard because u_get_undo_file_name() would need to return null
|
|
|
|
end)
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
itp('writes the undofile with the same permissions as the original file', function()
|
2016-06-21 17:58:38 -07:00
|
|
|
-- Create Test file and set permissions
|
2023-12-04 15:32:39 -07:00
|
|
|
local test_file_name = './test.file'
|
|
|
|
local test_permission_file = io.open(test_file_name, 'w')
|
|
|
|
test_permission_file:write('testing permissions')
|
2016-06-21 17:58:38 -07:00
|
|
|
test_permission_file:close()
|
2024-01-12 04:41:09 -07:00
|
|
|
local test_permissions = uv.fs_stat(test_file_name).mode
|
2016-06-21 17:58:38 -07:00
|
|
|
|
|
|
|
-- Create vim buffer
|
|
|
|
local c_file = to_cstr(test_file_name)
|
|
|
|
file_buffer = buffer.buflist_new(c_file, c_file, 1, buffer.BLN_LISTED)
|
|
|
|
file_buffer.b_u_numhead = 1 -- Pretend that the buffer has been changed
|
|
|
|
|
|
|
|
u_write_undo(nil, false, file_buffer, buffer_hash)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
-- Find out the correct name of the undofile
|
|
|
|
local undo_file_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
|
|
|
|
|
|
|
|
-- Find out the permissions of the new file
|
2024-01-12 04:41:09 -07:00
|
|
|
local permissions = uv.fs_stat(undo_file_name).mode
|
2016-06-21 17:58:38 -07:00
|
|
|
eq(test_permissions, permissions)
|
|
|
|
|
|
|
|
-- delete the file now that we're done with it.
|
|
|
|
local success, err = os.remove(test_file_name)
|
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
success, err = os.remove(undo_file_name)
|
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
itp('writes an undofile only readable by the user if the buffer is unnamed', function()
|
2023-04-04 12:59:06 -07:00
|
|
|
local correct_permissions = 33152
|
2023-12-04 15:32:39 -07:00
|
|
|
local undo_file_name = 'test.undo'
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
-- Create vim buffer
|
|
|
|
file_buffer = buffer.buflist_new(nil, nil, 1, buffer.BLN_LISTED)
|
|
|
|
file_buffer.b_u_numhead = 1 -- Pretend that the buffer has been changed
|
|
|
|
|
|
|
|
u_write_undo(undo_file_name, false, file_buffer, buffer_hash)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
-- Find out the permissions of the new file
|
2024-01-12 04:41:09 -07:00
|
|
|
local permissions = uv.fs_stat(undo_file_name).mode
|
2016-06-21 17:58:38 -07:00
|
|
|
eq(correct_permissions, permissions)
|
|
|
|
|
|
|
|
-- delete the file now that we're done with it.
|
|
|
|
local success, err = os.remove(undo_file_name)
|
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
itp('forces writing undo file for :wundo! command', function()
|
2023-12-04 15:32:39 -07:00
|
|
|
local file_contents = 'testing permissions'
|
2016-06-21 17:58:38 -07:00
|
|
|
-- Write a text file where the undofile should go
|
|
|
|
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
|
2024-04-08 02:03:20 -07:00
|
|
|
t.write_file(correct_name, file_contents, true, false)
|
2016-06-21 17:58:38 -07:00
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
-- Call with `forceit`.
|
|
|
|
u_write_undo(correct_name, true, file_buffer, buffer_hash)
|
2016-06-21 17:58:38 -07:00
|
|
|
|
2024-04-08 02:03:20 -07:00
|
|
|
local undo_file_contents = t.read_file(correct_name)
|
2016-06-21 17:58:38 -07:00
|
|
|
|
|
|
|
neq(file_contents, undo_file_contents)
|
2023-12-04 15:32:39 -07:00
|
|
|
local success, deletion_err = os.remove(correct_name) -- delete the file now that we're done with it.
|
2016-06-21 17:58:38 -07:00
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(deletion_err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2018-04-27 01:06:42 -07:00
|
|
|
itp('overwrites an existing undo file', function()
|
2016-06-21 17:58:38 -07:00
|
|
|
u_write_undo(nil, false, file_buffer, buffer_hash)
|
|
|
|
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2024-01-12 04:41:09 -07:00
|
|
|
local file_last_modified = uv.fs_stat(correct_name).mtime.sec
|
2016-06-21 17:58:38 -07:00
|
|
|
|
2023-12-04 15:32:39 -07:00
|
|
|
sleep(1000) -- Ensure difference in timestamps.
|
|
|
|
file_buffer.b_u_numhead = 1 -- Mark it as if there are changes
|
2016-06-21 17:58:38 -07:00
|
|
|
u_write_undo(nil, false, file_buffer, buffer_hash)
|
|
|
|
|
2024-01-12 04:41:09 -07:00
|
|
|
local file_last_modified_2 = uv.fs_stat(correct_name).mtime.sec
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
-- print(file_last_modified, file_last_modified_2)
|
|
|
|
neq(file_last_modified, file_last_modified_2)
|
2023-12-04 15:32:39 -07:00
|
|
|
local success, err = os.remove(correct_name) -- delete the file now that we're done with it.
|
2016-06-21 17:58:38 -07:00
|
|
|
if not success then
|
2023-12-04 15:32:39 -07:00
|
|
|
print(err) -- inform tester if undofile fails to delete
|
2016-06-21 17:58:38 -07:00
|
|
|
end
|
|
|
|
end)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
|
|
|
itp('does not overwrite an existing file that is not an undo file', function()
|
2016-06-21 17:58:38 -07:00
|
|
|
-- TODO: write test
|
|
|
|
end)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
|
|
|
itp('does not overwrite an existing file that has the wrong permissions', function()
|
2016-06-21 17:58:38 -07:00
|
|
|
-- TODO: write test
|
|
|
|
end)
|
2018-04-27 01:06:42 -07:00
|
|
|
|
|
|
|
itp('does not write an undo file if there is no undo information for the buffer', function()
|
2023-12-04 15:32:39 -07:00
|
|
|
file_buffer.b_u_numhead = 0 -- Mark it as if there is no undo information
|
2016-06-21 17:58:38 -07:00
|
|
|
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
|
|
|
|
|
2023-12-04 15:32:39 -07:00
|
|
|
local existing_file = io.open(correct_name, 'r')
|
2016-06-21 17:58:38 -07:00
|
|
|
if existing_file then
|
|
|
|
existing_file:close()
|
|
|
|
os.remove(correct_name)
|
|
|
|
end
|
|
|
|
u_write_undo(nil, false, file_buffer, buffer_hash)
|
2023-12-04 15:32:39 -07:00
|
|
|
local undo_file = io.open(correct_name, 'r')
|
2018-04-27 01:06:42 -07:00
|
|
|
|
2016-06-21 17:58:38 -07:00
|
|
|
eq(undo_file, nil)
|
|
|
|
end)
|
|
|
|
end)
|