diff --git a/lua/unclutter/buffer_spec.lua b/lua/unclutter/buffer_spec.lua new file mode 100644 index 0000000..dbd03c6 --- /dev/null +++ b/lua/unclutter/buffer_spec.lua @@ -0,0 +1,127 @@ +local M = require "unclutter.buffer" + +local CURRENT_BUFNAME = "test.lua" +local CURRENT_BUFNR = 42 +local NO_FILE_BUF = 5 + +describe("Buffer functions", function() + before_each(function() + -- Setting up mocks before each test + ---@diagnostic disable-next-line: duplicate-set-field + vim.api.nvim_get_current_buf = function() + return CURRENT_BUFNR + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.fn.bufnr = function(file_path) + if file_path == CURRENT_BUFNAME then + return CURRENT_BUFNR + end + return -1 + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.api.nvim_buf_get_name = function(buf) + if buf == CURRENT_BUFNR then + return CURRENT_BUFNAME + end + return "" + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.api.nvim_get_option_value = function(option, opts) + if option == "buftype" then + if opts.buf == NO_FILE_BUF then + return "nofile" + elseif opts.buf == CURRENT_BUFNR then + return "" + end + return "nofile" + end + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.fn.win_findbuf = function(buf) + if buf == CURRENT_BUFNR then + return { 1, 2 } -- Example buffer is open in two windows + end + return {} + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.fn.tabpagebuflist = function() + return { 3, CURRENT_BUFNR, 7 } -- Example buffers in current tab + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.api.nvim_buf_is_valid = function(buf) + return buf == CURRENT_BUFNR -- Only CURRENT_BUF is considered valid in this mock + end + ---@diagnostic disable-next-line: duplicate-set-field + vim.api.nvim_buf_is_loaded = function(buf) + return buf == CURRENT_BUFNR -- Only CURRENT_BUF is considered loaded in this mock + end + vim.bo = setmetatable({}, { + __index = function(_, buf) + if buf == CURRENT_BUFNR then + return { buflisted = true } + end + return { buflisted = false } + end, + }) + ---@diagnostic disable-next-line: duplicate-set-field + vim.api.nvim_list_bufs = function() + return { 3, 7 } -- Example of all buffers + end + end) + + it("gets the current buffer number", function() + local buf = M.current() + assert.is.equal(CURRENT_BUFNR, buf) + end) + + it("gets the buffer number for a file path", function() + local buf = M.number(CURRENT_BUFNAME) + assert.is.equal(CURRENT_BUFNR, buf) + end) + + it("gets the name of a buffer", function() + local name = M.name(CURRENT_BUFNR) + assert.is.equal(CURRENT_BUFNAME, name) + end) + + it("gets the buffer type", function() + local buftype = M.type(NO_FILE_BUF) + assert.is.equal("nofile", buftype) + end) + + it("checks if buffer is a file", function() + local isFile = M.is_file(CURRENT_BUFNR) + assert.is_true(isFile) + end) + + it("gets the number of windows a buffer is open in", function() + local windows = M.windows(CURRENT_BUFNR) + assert.is.equal(2, windows) + end) + + it("checks if buffer is visible in current tab", function() + local isVisible = M.is_visible(CURRENT_BUFNR) + assert.is_true(isVisible) + end) + + it("checks if buffer is valid", function() + local isValid = M.is_valid(CURRENT_BUFNR) + assert.is_true(isValid) + end) + + it("checks if buffer is loaded", function() + local isLoaded = M.is_loaded(CURRENT_BUFNR) + assert.is_true(isLoaded) + end) + + it("checks if a buffer is listed", function() + local isListed = M.listed(CURRENT_BUFNR) + assert.is_true(isListed) + end) + + it("returns the current buffer in .all()", function() + local all = M.all() + local current = M.current() + assert.is_true(vim.tbl_contains(all, current)) + end) +end) diff --git a/lua/unclutter/config_spec.lua b/lua/unclutter/config_spec.lua new file mode 100644 index 0000000..7f2f8f7 --- /dev/null +++ b/lua/unclutter/config_spec.lua @@ -0,0 +1,37 @@ +local M = require "unclutter.config" + +describe("Config module", function() + before_each(function() + -- Reset config to default values before each test + M.set { + clean_after = 3, + tabline = true, + } + end) + + it("sets configuration values", function() + local newConfig = { + clean_after = 5, + tabline = false, + } + M.set(newConfig) + + assert.is.equal(5, M.clean_after) + assert.is_false(M.tabline) + end) + + it("handles nil options by keeping default values", function() + ---@diagnostic disable-next-line: param-type-mismatch + M.set(nil) + + assert.is.equal(3, M.clean_after) + assert.is_true(M.tabline) + end) + + it("only updates provided fields", function() + M.set { clean_after = 7 } + + assert.is.equal(7, M.clean_after) + assert.is_true(M.tabline) -- should remain unchanged + end) +end) diff --git a/lua/unclutter/tabline_spec.lua b/lua/unclutter/tabline_spec.lua index eda58ca..09028a9 100644 --- a/lua/unclutter/tabline_spec.lua +++ b/lua/unclutter/tabline_spec.lua @@ -1,22 +1,24 @@ local M = require "unclutter.tabline" describe("Tabpage section", function() - it("creates tabpage section for multiple tabpages", function() + before_each(function() -- Mock vim.fn.tabpagenr ---@diagnostic disable-next-line: duplicate-set-field vim.fn.tabpagenr = function(arg) if arg == "$" then - return 3 - end -- total tabpages - return 2 -- current tabpage + return 3 -- total tabpages for the first test, 1 for the second + end + return 2 -- current tabpage for the first test, 1 for the second end + end) + it("creates tabpage section for multiple tabpages", function() M.make_tabpage_section() assert.are.equal(" Tab 2/3 ", M.tabpage_section) end) it("creates no tabpage section for a single tabpage", function() - -- Mock vim.fn.tabpagenr + -- Change the mock for a single tabpage scenario ---@diagnostic disable-next-line: duplicate-set-field vim.fn.tabpagenr = function(arg) if arg == "$" then diff --git a/lua/unclutter/unclutter_spec.lua b/lua/unclutter/unclutter_spec.lua new file mode 100644 index 0000000..1eba894 --- /dev/null +++ b/lua/unclutter/unclutter_spec.lua @@ -0,0 +1,103 @@ +local mock = require "luassert.mock" +local M = require "unclutter.unclutter" +local config = require "unclutter.config" + +local autocmds, buffer, tabline + +describe("Unclutter", function() + before_each(function() + M.enabled = false + M.buf_just_left = nil + + autocmds = mock(require "unclutter.autocmds", true) + buffer = mock(require "unclutter.buffer", true) + tabline = mock(require "unclutter.tabline", true) + + config.set { + clean_after = 3, + tabline = true, + } + end) + + after_each(function() + mock.clear(autocmds) + mock.clear(buffer) + mock.clear(tabline) + end) + + describe("enable", function() + it("enables the plugin with tabline enabled", function() + M.enable { tabline = true } + assert.is_true(M.enabled) + assert.stub(tabline.enable).was_called() + assert.stub(tabline.disable).was_not_called() + end) + + it("enables the plugin with tabline disabled", function() + M.enable { tabline = false } + assert.is_true(M.enabled) + assert.stub(tabline.enable).was_not_called() + assert.stub(tabline.disable).was_called() + end) + + it("enables the plugin with default settings when no options are provided", function() + M.enable {} + assert.is_true(M.enabled) + assert.are.equal(3, config.clean_after) -- Default value + assert.are.equal(true, config.tabline) -- Default value + end) + + it("partially updates settings when partial options are provided", function() + M.enable { tabline = false } -- Only providing tabline option + assert.is_true(M.enabled) + assert.are.equal(3, config.clean_after) -- Default value + assert.are.equal(false, config.tabline) -- Updated value + end) + end) + + describe("disable", function() + it("disables the plugin", function() + M.enabled = true + M.disable() + assert.is_false(M.enabled) + assert.stub(autocmds.remove_augroup).was_called() + assert.stub(tabline.disable).was_called() + end) + end) + + describe("buffer_should_be_hidden_on_leave", function() + it("checks if buffer should be hidden on leave", function() + buffer.current.returns(2) + buffer.is_file.returns(true) + buffer.is_visible.returns(false) + buffer.windows.returns(0) + tabline.is_buffer_kept.returns(false) + + local result = M.buffer_should_be_hidden_on_leave(1) + assert.is_true(result) + end) + it("does not hide the buffer if it is kept", function() + buffer.current.returns(2) + buffer.is_file.returns(true) + buffer.is_visible.returns(false) + buffer.windows.returns(0) + tabline.is_buffer_kept.returns(true) -- Buffer is kept + + local result = M.buffer_should_be_hidden_on_leave(1) + assert.is_false(result) + end) + end) + + describe("keep_all_buffers", function() + it("keeps all buffers", function() + buffer.all.returns { 1, 2, 3 } + M.keep_all_buffers() + assert.stub(tabline.keep_buffer).was_called(3) + end) + it("does nothing when there are no buffers", function() + buffer.all.returns {} + M.keep_all_buffers() + assert.stub(tabline.keep_buffer).was_not_called() + end) + end) +end)