diff --git a/lua/ivy/vim_mock.lua b/lua/ivy/vim_mock.lua index 98f03fd..8f07472 100644 --- a/lua/ivy/vim_mock.lua +++ b/lua/ivy/vim_mock.lua @@ -1,30 +1,72 @@ local mock = { commands = {}, + lines = {}, + cursors = {}, } mock.reset = function() mock.commands = {} + mock.lines = {} + mock.cursors = {} _G.vim = { notify = function() end, cmd = function(cmd) table.insert(mock.commands, cmd) end, api = { nvim_echo = function() end, nvim_get_current_win = function() return 10 end, nvim_command = function() end, nvim_win_get_buf = function() return 10 end, nvim_win_set_option = function() end, nvim_buf_set_option = function() end, nvim_buf_set_var = function() end, nvim_buf_set_keymap = function() end, + nvim_buf_delete = function() end, + nvim_buf_set_lines = function(buffer_number, state_index, end_index, _, items) + local new_lines = {} + + for index = 1, state_index do + if mock.lines[buffer_number][index] == nil then + table.insert(new_lines, "") + else + table.insert(new_lines, mock.lines[buffer_number][index]) + end + end + + for index = 1, #items do + table.insert(new_lines, items[index]) + end + + if end_index ~= -1 then + error("Mock of nvim_buf_set_lines dose not support a end_index grater than -1 found " .. end_index) + end + + mock.lines[buffer_number] = new_lines + end, + nvim_win_set_height = function() end, + nvim_win_set_cursor = function(window_number, position) + mock.cursors[window_number] = position + end, + nvim_buf_get_lines = function(buffer_number, start_index, end_index) + local lines = {} + for index = start_index, end_index do + table.insert(lines, mock.lines[buffer_number][index + 1]) + end + + if #lines == 0 then + return nil + end + + return lines + end, }, } end return mock diff --git a/lua/ivy/window_test.lua b/lua/ivy/window_test.lua index 75b9698..c42b380 100644 --- a/lua/ivy/window_test.lua +++ b/lua/ivy/window_test.lua @@ -1,14 +1,23 @@ local vim_mock = require "ivy.vim_mock" local window = require "ivy.window" before_each(function() vim_mock.reset() end) -it("can initialize", function(t) +it("can initialize and destroy the window", function(t) window.initialize() - if window.get_buffer() ~= 10 then - t.error("The windows buffer should be 10 found " .. window.get_buffer()) - end + t.assert_equal(10, window.get_buffer()) + t.assert_equal(10, window.buffer) + + window.destroy() + t.assert_equal(nil, window.buffer) +end) + +it("can set items", function(t) + window.initialize() + + window.set_items { { content = "Line one" } } + t.assert_equal("Line one", window.get_current_selection()) end) diff --git a/plugin/ivy.lua b/plugin/ivy.lua index dcf5322..671d289 100644 --- a/plugin/ivy.lua +++ b/plugin/ivy.lua @@ -1,73 +1,73 @@ local controller = require "ivy.controller" local utils = require "ivy.utils" local libivy = require "ivy.libivy" -- Put the controller in to the vim global so we can access it in mappings -- better without requires. You can call controller commands like `vim.ivy.xxx`. -- luacheck: ignore vim.ivy = controller vim.api.nvim_create_user_command("IvyAg", function() vim.ivy.run("AG", utils.command_finder "ag", utils.vimgrep_action()) end, { bang = true, desc = "Run ag to search for content in files" }) vim.api.nvim_create_user_command("IvyFd", function() vim.ivy.run("Files", function(term) return libivy.ivy_files(term, vim.fn.getcwd()) end, utils.file_action()) end, { bang = true, desc = "Find files in the project" }) vim.api.nvim_create_user_command("IvyBuffers", function() vim.ivy.run("Buffers", function(input) local list = {} local buffers = vim.api.nvim_list_bufs() for index = 1, #buffers do local buffer = buffers[index] -- Get the relative path from the current working directory. We need to -- substring +2 to remove the `/` from the start of the path to give us a -- true relative path local buffer_name = vim.api.nvim_buf_get_name(buffer):sub(#vim.fn.getcwd() + 2, -1) local file_type = vim.api.nvim_buf_get_option(buffer, "filetype") if vim.api.nvim_buf_is_loaded(buffer) and file_type ~= "ivy" and #buffer_name > 0 then local score = libivy.ivy_match(input, buffer_name) if score > -200 or #input == 0 then table.insert(list, { score = score, content = buffer_name }) end end end table.sort(list, function(a, b) return a.score < b.score end) return list end, utils.file_action()) end, { bang = true, desc = "List all of the current open buffers" }) vim.api.nvim_create_user_command("IvyLines", function() vim.ivy.run("Lines", function(input) local list = {} local lines = vim.api.nvim_buf_get_lines(vim.ivy.origin(), 0, -1, false) for index = 1, #lines do local line = lines[index] local score = libivy.ivy_match(input, line) if score > -200 then local prefix = string.rep(" ", 4 - #tostring(index)) .. index .. ": " - table.insert(list, { score, prefix .. line }) + table.insert(list, { score = score, content = prefix .. line }) end end table.sort(list, function(a, b) - return a[1] < b[1] + return a.score < b.score end) return list end, utils.line_action()) end, { bang = true, desc = "List all of the current open buffers" }) vim.api.nvim_set_keymap("n", "b", "IvyBuffers", { nowait = true, silent = true }) vim.api.nvim_set_keymap("n", "p", "IvyFd", { nowait = true, silent = true }) vim.api.nvim_set_keymap("n", "/", "IvyAg", { nowait = true, silent = true }) vim.cmd "highlight IvyMatch cterm=bold gui=bold" diff --git a/scripts/test.lua b/scripts/test.lua index 8b69506..0574c55 100644 --- a/scripts/test.lua +++ b/scripts/test.lua @@ -1,101 +1,106 @@ package.path = "lua/?.lua;" .. package.path local global_context = { current_test_name = "", before = {}, after = {}, before_each = {}, after_each = {}, total = 0, pass = 0, fail = 0, } local call_hook = function(hook_name) for index = 1, #global_context[hook_name] do global_context[hook_name][index]() end end _G.before_each = function(callback) table.insert(global_context.before_each, callback) end _G.after_each = function(callback) table.insert(global_context.after_each, callback) end _G.before = function(callback) -- currently before functions just get called because we only have a context -- of a test file. If we ever need to have more contexts then this will be to -- be differed. callback() end _G.after = function(callback) table.insert(global_context.after, callback) end _G.it = function(name, callback) local context = { name = name, error = function(message) error(message, 2) end, + assert_equal = function(expected, actual) + if expected ~= actual then + error("Failed to assert that '" .. expected .. "' matches '" .. actual .. "'", 2) + end + end, } call_hook "before_each" local time = os.clock() * 1000 local status, err = pcall(callback, context) local elapsed = (os.clock() * 1000) - time call_hook "before_each" local prefix = "\x1B[42mPASS" global_context.total = global_context.total + 1 if status then global_context.pass = global_context.pass + 1 else global_context.fail = global_context.fail + 1 prefix = "\x1B[41mFAIL" end print(string.format("%s\x1B[0m %s - %s (%.3f ms)", prefix, global_context.current_test_name, name, elapsed)) if err then print(" " .. err) end end local start_time = os.clock() for _, name in ipairs(arg) do -- Turn the file name in to a lau module name that we can require local module = name:gsub("^lua/", "") module, _ = module:gsub("/init.lua$", "") module, _ = module:gsub(".lua$", "") module = module:gsub("/", ".") global_context.current_test_name = module:gsub("_test", "") require(module) call_hook "after" global_context.before_each = {} global_context.after_each = {} global_context.before = {} global_context.after = {} end print(string.format( [[ Tests: %d passed, %d total Time: %.3f seconds]], global_context.pass, global_context.total, (os.clock()) - start_time )) if global_context.fail > 0 then os.exit(1, true) end