1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
|
local helpers = require('test.unit.helpers')(after_each)
local itp = helpers.gen_itp(it)
local luv = require('luv')
local child_call_once = helpers.child_call_once
local sleep = helpers.sleep
local ffi = helpers.ffi
local cimport = helpers.cimport
local to_cstr = helpers.to_cstr
local neq = helpers.neq
local eq = helpers.eq
local mkdir = helpers.mkdir
local options = cimport('./src/nvim/option_vars.h')
local undo = cimport('./src/nvim/undo.h')
local buffer = cimport('./src/nvim/buffer.h')
local old_p_udir = nil
-- Values expected by tests. Set in the setup function and destroyed in teardown
local file_buffer = nil
local buffer_hash = nil
child_call_once(function()
if old_p_udir == nil then
old_p_udir = options.p_udir -- save the old value of p_udir (undodir)
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
buffer_hash = ffi.new('char[32]')
undo.u_compute_hash(file_buffer, buffer_hash)
end)
describe('u_write_undo', function()
setup(function()
mkdir('unit-test-directory')
luv.chdir('unit-test-directory')
options.p_udir = to_cstr(luv.cwd()) -- set p_udir to be the test dir
end)
teardown(function()
luv.chdir('..')
local success, err = luv.fs_rmdir('unit-test-directory')
if not success then
print(err) -- inform tester if directory fails to delete
end
options.p_udir = old_p_udir --restore old p_udir
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
return undo.u_write_undo(name, forceit, buf, buf_hash)
end
itp('writes an undo file to undodir given a buffer and hash', function()
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))
local undo_file = io.open(correct_name, "r")
neq(undo_file, nil)
local success, err = os.remove(correct_name) -- delete the file now that we're done with it.
if not success then
print(err) -- inform tester if undofile fails to delete
end
end)
itp('writes a correctly-named undo file to undodir given a name, buffer, and hash', function()
local correct_name = "undofile.test"
u_write_undo(correct_name, false, file_buffer, buffer_hash)
local undo_file = io.open(correct_name, "r")
neq(undo_file, nil)
local success, err = os.remove(correct_name) -- delete the file now that we're done with it.
if not success then
print(err) -- inform tester if undofile fails to delete
end
end)
itp('does not write an undofile when the buffer has no valid undofile name', function()
-- 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)
itp('writes the undofile with the same permissions as the original file', function()
-- Create Test file and set permissions
local test_file_name = "./test.file"
local test_permission_file = io.open(test_file_name, "w")
test_permission_file:write("testing permissions")
test_permission_file:close()
local test_permissions = luv.fs_stat(test_file_name).mode
-- 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)
-- 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
local permissions = luv.fs_stat(undo_file_name).mode
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
print(err) -- inform tester if undofile fails to delete
end
success, err = os.remove(undo_file_name)
if not success then
print(err) -- inform tester if undofile fails to delete
end
end)
itp('writes an undofile only readable by the user if the buffer is unnamed', function()
local correct_permissions = 33152
local undo_file_name = "test.undo"
-- 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)
-- Find out the permissions of the new file
local permissions = luv.fs_stat(undo_file_name).mode
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
print(err) -- inform tester if undofile fails to delete
end
end)
itp('forces writing undo file for :wundo! command', function()
local file_contents = "testing permissions"
-- 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))
helpers.write_file(correct_name, file_contents, true, false)
-- Call with `forceit`.
u_write_undo(correct_name, true, file_buffer, buffer_hash)
local undo_file_contents = helpers.read_file(correct_name)
neq(file_contents, undo_file_contents)
local success, deletion_err = os.remove(correct_name) -- delete the file now that we're done with it.
if not success then
print(deletion_err) -- inform tester if undofile fails to delete
end
end)
itp('overwrites an existing undo file', function()
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))
local file_last_modified = luv.fs_stat(correct_name).mtime.sec
sleep(1000) -- Ensure difference in timestamps.
file_buffer.b_u_numhead = 1 -- Mark it as if there are changes
u_write_undo(nil, false, file_buffer, buffer_hash)
local file_last_modified_2 = luv.fs_stat(correct_name).mtime.sec
-- print(file_last_modified, file_last_modified_2)
neq(file_last_modified, file_last_modified_2)
local success, err = os.remove(correct_name) -- delete the file now that we're done with it.
if not success then
print(err) -- inform tester if undofile fails to delete
end
end)
itp('does not overwrite an existing file that is not an undo file', function()
-- TODO: write test
end)
itp('does not overwrite an existing file that has the wrong permissions', function()
-- TODO: write test
end)
itp('does not write an undo file if there is no undo information for the buffer', function()
file_buffer.b_u_numhead = 0 -- Mark it as if there is no undo information
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
local existing_file = io.open(correct_name,"r")
if existing_file then
existing_file:close()
os.remove(correct_name)
end
u_write_undo(nil, false, file_buffer, buffer_hash)
local undo_file = io.open(correct_name, "r")
eq(undo_file, nil)
end)
end)
|