From 34f29ac858d00b9724254a5fa0ca0fda49b1303e Mon Sep 17 00:00:00 2001 From: Christopher Waldon Date: Tue, 21 Jun 2016 20:58:38 -0400 Subject: test/unit: some unit tests for undo.c #4985 --- test/unit/undo_spec.lua | 213 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 test/unit/undo_spec.lua (limited to 'test') diff --git a/test/unit/undo_spec.lua b/test/unit/undo_spec.lua new file mode 100644 index 0000000000..7d21204707 --- /dev/null +++ b/test/unit/undo_spec.lua @@ -0,0 +1,213 @@ +local lfs = require('lfs') +local helpers = require('test.unit.helpers') + +local ffi = helpers.ffi +local cimport = helpers.cimport +local to_cstr = helpers.to_cstr +local neq = helpers.neq +local eq = helpers.eq + +cimport('./src/nvim/ex_cmds_defs.h') +cimport('./src/nvim/buffer_defs.h') +local options = cimport('./src/nvim/option_defs.h') +-- TODO: remove: local vim = cimport('./src/nvim/vim.h') +local undo = cimport('./src/nvim/undo.h') +local buffer = cimport('./src/nvim/buffer.h') + +local old_p_udir = options.p_udir -- save the old value of p_udir (undodir) + +-- Values expected by tests. Set in the setup function and destroyed in teardown +local file_buffer = nil +local buffer_hash = nil + +describe('u_write_undo', function() + setup(function() + lfs.mkdir('unit-test-directory') + lfs.chdir('unit-test-directory') + options.p_udir = to_cstr(lfs.currentdir()) -- set p_udir to be the test dir + end) + + teardown(function() + lfs.chdir('..') + local success, err = lfs.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) + + before_each(function() + -- create a new buffer + local c_file = to_cstr('../test/unit/undo_spec.lua') + 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_u[32]') + undo.u_compute_hash(buffer_hash) + 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 + + it('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) + + it('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) + + it('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) + + it('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 = lfs.attributes(test_file_name).permissions + + -- 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 = lfs.attributes(undo_file_name).permissions + 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) + + it('writes an undofile only readable by the user if the buffer is unnamed', function() + local correct_permissions = "rw-------" + 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 = lfs.attributes(undo_file_name).permissions + 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) + + it('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)) + local text_file, err = io.open(correct_name, "w") + if err then + pending() + end + text_file:write(file_contents) + text_file:close() + + u_write_undo(nil, true, file_buffer, buffer_hash) -- Call with forceit flag enabled + + local undo_file, undo_file_err = io.open(correct_name, "r") + if undo_file_err then + pending() + end + local undo_file_contents = undo_file:read("*a") -- Read all + + 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) + + it('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 = lfs.attributes(correct_name).modification + + os.execute('sleep 1s') -- Ensure there will be some 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 = lfs.attributes(correct_name).modification + + -- 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) + + it('does not overwrite an existing file that is not an undo file', function() + -- TODO: write test + end) + + it('does not overwrite an existing file that has the wrong permissions', function() + -- TODO: write test + end) + + it('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) -- cgit From d6a164026029b942150aeec7e768bc6180bfc50c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 27 Apr 2018 10:07:26 +0200 Subject: test/util: move general functions into global helpers --- test/functional/helpers.lua | 70 +++++---------------------------------------- test/helpers.lua | 67 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 64 deletions(-) (limited to 'test') diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 655200e6f7..9895281773 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -12,15 +12,18 @@ local Paths = require('test.config.paths') local check_cores = global_helpers.check_cores local check_logs = global_helpers.check_logs -local neq = global_helpers.neq +local dedent = global_helpers.dedent local eq = global_helpers.eq local expect_err = global_helpers.expect_err -local ok = global_helpers.ok +local filter = global_helpers.filter local map = global_helpers.map local matches = global_helpers.matches -local filter = global_helpers.filter -local dedent = global_helpers.dedent +local neq = global_helpers.neq +local ok = global_helpers.ok +local read_file = global_helpers.read_file +local sleep = global_helpers.sleep local table_flatten = global_helpers.table_flatten +local write_file = global_helpers.write_file local start_dir = lfs.currentdir() -- XXX: NVIM_PROG takes precedence, QuickBuild sets it. @@ -374,34 +377,6 @@ local function feed_command(...) end end --- Dedent the given text and write it to the file name. -local function write_file(name, text, no_dedent, append) - local file = io.open(name, (append and 'a' or 'w')) - if type(text) == 'table' then - -- Byte blob - local bytes = text - text = '' - for _, char in ipairs(bytes) do - text = ('%s%c'):format(text, char) - end - elseif not no_dedent then - text = dedent(text) - end - file:write(text) - file:flush() - file:close() -end - -local function read_file(name) - local file = io.open(name, 'r') - if not file then - return nil - end - local ret = file:read('*a') - file:close() - return ret -end - local sourced_fnames = {} local function source(code) local fname = tmpname() @@ -466,11 +441,6 @@ local function wait() session:request('nvim_eval', '1') end --- sleeps the test runner (_not_ the nvim instance) -local function sleep(ms) - luv.sleep(ms) -end - local function curbuf_contents() wait() -- Before inspecting the buffer, process all input. return table.concat(curbuf('get_lines', 0, -1, true), '\n') @@ -682,31 +652,6 @@ local function alter_slashes(obj) end end -local function hexdump(str) - local len = string.len(str) - local dump = "" - local hex = "" - local asc = "" - - for i = 1, len do - if 1 == i % 8 then - dump = dump .. hex .. asc .. "\n" - hex = string.format("%04x: ", i - 1) - asc = "" - end - - local ord = string.byte(str, i) - hex = hex .. string.format("%02x ", ord) - if ord >= 32 and ord <= 126 then - asc = asc .. string.char(ord) - else - asc = asc .. "." - end - end - - return dump .. hex .. string.rep(" ", 8 - len % 8) .. asc -end - local module = { NIL = mpack.NIL, alter_slashes = alter_slashes, @@ -737,7 +682,6 @@ local module = { filter = filter, funcs = funcs, get_pathsep = get_pathsep, - hexdump = hexdump, insert = insert, iswin = iswin, map = map, diff --git a/test/helpers.lua b/test/helpers.lua index efc0e911f1..0d3fe1316b 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -1,4 +1,5 @@ local assert = require('luassert') +local luv = require('luv') local lfs = require('lfs') local quote_me = '[^.%w%+%-%@%_%/]' -- complement (needn't quote) @@ -33,6 +34,11 @@ local function popen_w(...) return io.popen(argss_to_cmd(...), 'w') end +-- sleeps the test runner (_not_ the nvim instance) +local function sleep(ms) + luv.sleep(ms) +end + local check_logs_useless_lines = { ['Warning: noted but unhandled ioctl']=1, ['could cause spurious value errors to appear']=2, @@ -612,7 +618,60 @@ local function table_flatten(arr) return result end -return { +local function hexdump(str) + local len = string.len(str) + local dump = "" + local hex = "" + local asc = "" + + for i = 1, len do + if 1 == i % 8 then + dump = dump .. hex .. asc .. "\n" + hex = string.format("%04x: ", i - 1) + asc = "" + end + + local ord = string.byte(str, i) + hex = hex .. string.format("%02x ", ord) + if ord >= 32 and ord <= 126 then + asc = asc .. string.char(ord) + else + asc = asc .. "." + end + end + + return dump .. hex .. string.rep(" ", 8 - len % 8) .. asc +end + +local function read_file(name) + local file = io.open(name, 'r') + if not file then + return nil + end + local ret = file:read('*a') + file:close() + return ret +end + +-- Dedent the given text and write it to the file name. +local function write_file(name, text, no_dedent, append) + local file = io.open(name, (append and 'a' or 'w')) + if type(text) == 'table' then + -- Byte blob + local bytes = text + text = '' + for _, char in ipairs(bytes) do + text = ('%s%c'):format(text, char) + end + elseif not no_dedent then + text = dedent(text) + end + file:write(text) + file:flush() + file:close() +end + +local module = { REMOVE_THIS = REMOVE_THIS, argss_to_cmd = argss_to_cmd, check_cores = check_cores, @@ -630,6 +689,7 @@ return { format_string = format_string, glob = glob, hasenv = hasenv, + hexdump = hexdump, intchar2lua = intchar2lua, map = map, matches = matches, @@ -638,11 +698,16 @@ return { ok = ok, popen_r = popen_r, popen_w = popen_w, + read_file = read_file, repeated_read_cmd = repeated_read_cmd, + sleep = sleep, shallowcopy = shallowcopy, table_flatten = table_flatten, tmpname = tmpname, uname = uname, updated = updated, which = which, + write_file = write_file, } + +return module -- cgit From bd17ef75b34b0ca10b795b705ffa82cc4eb30ee9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 27 Apr 2018 10:06:42 +0200 Subject: test/unit/undo_spec.lua: fixup after rebase #4985 --- test/unit/undo_spec.lua | 111 +++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 54 deletions(-) (limited to 'test') diff --git a/test/unit/undo_spec.lua b/test/unit/undo_spec.lua index 7d21204707..ab172e89f2 100644 --- a/test/unit/undo_spec.lua +++ b/test/unit/undo_spec.lua @@ -1,5 +1,11 @@ +local helpers = require('test.unit.helpers')(after_each) +local itp = helpers.gen_itp(it) local lfs = require('lfs') -local helpers = require('test.unit.helpers') +local child_call_once = helpers.child_call_once + +local global_helpers = require('test.helpers') +local hexdump = global_helpers.hexdump +local sleep = global_helpers.sleep local ffi = helpers.ffi local cimport = helpers.cimport @@ -14,19 +20,38 @@ local options = cimport('./src/nvim/option_defs.h') local undo = cimport('./src/nvim/undo.h') local buffer = cimport('./src/nvim/buffer.h') -local old_p_udir = options.p_udir -- save the old value of p_udir (undodir) +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_u[32]') + undo.u_compute_hash(buffer_hash) +end) + + describe('u_write_undo', function() setup(function() lfs.mkdir('unit-test-directory') lfs.chdir('unit-test-directory') options.p_udir = to_cstr(lfs.currentdir()) -- set p_udir to be the test dir end) - + teardown(function() lfs.chdir('..') local success, err = lfs.rmdir('unit-test-directory') @@ -36,59 +61,45 @@ describe('u_write_undo', function() options.p_udir = old_p_udir --restore old p_udir end) - before_each(function() - -- create a new buffer - local c_file = to_cstr('../test/unit/undo_spec.lua') - 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_u[32]') - undo.u_compute_hash(buffer_hash) - 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 - it('writes an undo file to undodir given a buffer and hash', function() + 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) - - it('writes a correctly-named undo file to undodir given a name, buffer, and hash', function() + + 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) - - it('does not write an undofile when the buffer has no valid undofile name', function() + + 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) - it('writes the undofile with the same permissions as the original file', function() + 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") @@ -102,7 +113,7 @@ describe('u_write_undo', function() 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)) @@ -121,16 +132,16 @@ describe('u_write_undo', function() end end) - it('writes an undofile only readable by the user if the buffer is unnamed', function() + itp('writes an undofile only readable by the user if the buffer is unnamed', function() local correct_permissions = "rw-------" 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 = lfs.attributes(undo_file_name).permissions eq(correct_permissions, permissions) @@ -142,24 +153,16 @@ describe('u_write_undo', function() end end) - it('forces writing undo file for :wundo! command', function() + 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)) - local text_file, err = io.open(correct_name, "w") - if err then - pending() - end - text_file:write(file_contents) - text_file:close() + global_helpers.write_file(correct_name, file_contents, true, false) - u_write_undo(nil, true, file_buffer, buffer_hash) -- Call with forceit flag enabled + -- Call with `forceit`. + u_write_undo(correct_name, true, file_buffer, buffer_hash) - local undo_file, undo_file_err = io.open(correct_name, "r") - if undo_file_err then - pending() - end - local undo_file_contents = undo_file:read("*a") -- Read all + local undo_file_contents = global_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. @@ -168,18 +171,18 @@ describe('u_write_undo', function() end end) - it('overwrites an existing undo file', function() + 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 = lfs.attributes(correct_name).modification - os.execute('sleep 1s') -- Ensure there will be some difference in timestamps + 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 = lfs.attributes(correct_name).modification - + -- 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. @@ -187,16 +190,16 @@ describe('u_write_undo', function() print(err) -- inform tester if undofile fails to delete end end) - - it('does not overwrite an existing file that is not an undo file', function() + + itp('does not overwrite an existing file that is not an undo file', function() -- TODO: write test end) - - it('does not overwrite an existing file that has the wrong permissions', function() + + itp('does not overwrite an existing file that has the wrong permissions', function() -- TODO: write test end) - - it('does not write an undo file if there is no undo information for the buffer', function() + + 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)) @@ -207,7 +210,7 @@ describe('u_write_undo', function() end u_write_undo(nil, false, file_buffer, buffer_hash) local undo_file = io.open(correct_name, "r") - + eq(undo_file, nil) end) end) -- cgit