From 73ec27fb79463050c5b49835fe9e782bb0eb1e36 Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 18:28:03 +0100 Subject: [PATCH 1/9] remove plenary --- .github/workflows/ci.yml | 3 +- README.md | 2 - doc/tags | 9 ++++ doc/triptych.nvim.txt | 2 - lua/triptych/actions.lua | 73 ++++++++++++++++++---------- lua/triptych/fs.lua | 52 ++++++++++++++------ lua/triptych/init.lua | 6 --- lua/triptych/syntax_highlighting.lua | 5 +- lua/triptych/view.lua | 17 ++++--- 9 files changed, 107 insertions(+), 62 deletions(-) create mode 100644 doc/tags diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffc3050..e0426d8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,7 @@ name: CI env: TRIPTYCH_DIR: .local/share/nvim/site/pack/simonmclean/start/triptych LUA_LS_LOG_PATH: /home/runner/lua-language-server/logs - LATEST_NVIM_VERSION: "0.11.3" + LATEST_NVIM_VERSION: "0.12.1" on: workflow_dispatch: @@ -42,7 +42,6 @@ jobs: - name: install neovim plugins run: | git config --global advice.detachedHead false - git clone https://github.com/nvim-lua/plenary.nvim.git $HOME/.local/share/nvim/site/pack/plenary/start/plenary git clone https://github.com/nvim-tree/nvim-web-devicons $HOME/.local/share/nvim/site/pack/nvim-tree/start/nvim-web-devicons git clone --recurse-submodules https://github.com/$GITHUB_REPOSITORY $HOME/$TRIPTYCH_DIR cd $HOME/$TRIPTYCH_DIR diff --git a/README.md b/README.md index 22e3fcf..d260299 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,6 @@ You only ever control or focus the middle window. ## ⚡️ Requirements - Neovim >= 0.9.0 -- [nvim-lua/plenary.nvim](https://github.com/nvim-lua/plenary.nvim) - Optional, if you want fancy icons - [nvim-tree/nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) - A [Nerd Font](https://www.nerdfonts.com/) @@ -54,7 +53,6 @@ Example using [Lazy](https://github.com/folke/lazy.nvim). { 'simonmclean/triptych.nvim', dependencies = { - 'nvim-lua/plenary.nvim', -- required 'nvim-tree/nvim-web-devicons', -- optional for icons 'antosha417/nvim-lsp-file-operations' -- optional LSP integration }, diff --git a/doc/tags b/doc/tags new file mode 100644 index 0000000..7756474 --- /dev/null +++ b/doc/tags @@ -0,0 +1,9 @@ +triptych.nvim-configuration triptych.nvim.txt /*triptych.nvim-configuration* +triptych.nvim-extending-functionality triptych.nvim.txt /*triptych.nvim-extending-functionality* +triptych.nvim-features triptych.nvim.txt /*triptych.nvim-features* +triptych.nvim-how-it-works triptych.nvim.txt /*triptych.nvim-how-it-works* +triptych.nvim-installation triptych.nvim.txt /*triptych.nvim-installation* +triptych.nvim-lsp-integration triptych.nvim.txt /*triptych.nvim-lsp-integration* +triptych.nvim-requirements triptych.nvim.txt /*triptych.nvim-requirements* +triptych.nvim-table-of-contents triptych.nvim.txt /*triptych.nvim-table-of-contents* +triptych.nvim.txt triptych.nvim.txt /*triptych.nvim.txt* diff --git a/doc/triptych.nvim.txt b/doc/triptych.nvim.txt index 96bf20e..892c14d 100644 --- a/doc/triptych.nvim.txt +++ b/doc/triptych.nvim.txt @@ -44,7 +44,6 @@ FEATURES *triptych.nvim-features* REQUIREMENTS *triptych.nvim-requirements* - Neovim >= 0.9.0 -- nvim-lua/plenary.nvim - Optional, if you want fancy icons - nvim-tree/nvim-web-devicons - A Nerd Font @@ -60,7 +59,6 @@ Example using Lazy . { 'simonmclean/triptych.nvim', dependencies = { - 'nvim-lua/plenary.nvim', -- required 'nvim-tree/nvim-web-devicons', -- optional for icons 'antosha417/nvim-lsp-file-operations' -- optional LSP integration }, diff --git a/lua/triptych/actions.lua b/lua/triptych/actions.lua index 459f133..b77de09 100644 --- a/lua/triptych/actions.lua +++ b/lua/triptych/actions.lua @@ -1,7 +1,6 @@ local u = require 'triptych.utils' -local float = require 'triptych.float' local view = require 'triptych.view' -local plenary_path = require 'plenary.path' +local float = require 'triptych.float' local triptych_help = require 'triptych.help' local autocmds = require 'triptych.autocmds' local log = require 'triptych.logger' @@ -45,7 +44,51 @@ local function rename_node_and_publish(from, to) end end ----Wraps plenary Path:copy with public events +---Recursively copy a file or directory to a destination path. +---Returns a flat list of all file paths that were created. +---@param src string +---@param dest string +---@return string[] created_files +local function copy_recursive(src, dest) + local created = {} + local src_type = vim.fn.getftype(src) + + if src_type == 'dir' then + vim.fn.mkdir(dest, 'p') + local handle = vim.loop.fs_scandir(src) + if handle then + while true do + local name, _ = vim.loop.fs_scandir_next(handle) + if not name then + break + end + local sub_created = copy_recursive(src .. '/' .. name, dest .. '/' .. name) + for _, p in ipairs(sub_created) do + table.insert(created, p) + end + end + end + else + -- Read source file and write to destination + local f_in = io.open(src, 'rb') + if f_in then + local data = f_in:read '*a' + f_in:close() + local dest_dir = vim.fn.fnamemodify(dest, ':h') + vim.fn.mkdir(dest_dir, 'p') + local f_out = io.open(dest, 'wb') + if f_out then + f_out:write(data) + f_out:close() + table.insert(created, dest) + end + end + end + + return created +end + +---Copy a node (file or directory) to destination, publishing events for created files. ---Note: It only publishes events for files, not folders. This is probably fine for LSP purposes ---@param target PathDetails ---@param destination string @@ -56,29 +99,7 @@ local function duplicate_node_and_publish(target, destination) autocmds.publish_will_create_node(destination) end - local p = plenary_path:new(target.path) - -- Note: Plenary has a bug whereby a copying a directory into itself creates hundreds of nested copies - -- https://github.com/nvim-lua/plenary.nvim/pull/358 - local results = p:copy { - destination = destination, - recursive = true, - override = false, - interactive = true, - } - - local files_created = {} - - local function handle_results(results) - for key, value in pairs(results) do - if type(value) == 'table' then - handle_results(value) - elseif value then - table.insert(files_created, key.filename) - end - end - end - - handle_results(results) + local files_created = copy_recursive(target.path, destination) -- Sorting to avoid flakey test table.sort(files_created) diff --git a/lua/triptych/fs.lua b/lua/triptych/fs.lua index e0b2f88..b89ff22 100644 --- a/lua/triptych/fs.lua +++ b/lua/triptych/fs.lua @@ -1,7 +1,4 @@ local u = require 'triptych.utils' -local plenary_filetype = require 'plenary.filetype' -local plenary_path = require 'plenary.path' -local plenary_async = require 'plenary.async' local M = {} @@ -15,28 +12,53 @@ end ---@param path string ---@return string? function M.get_filetype_from_path(path) - -- plenary locks up when trying to read a fifo file, so we're sniffing this out first + -- Bail out early for fifo files to avoid hangs if vim.fn.getftype(path) == 'fifo' then return 'fifo' end - -- We still want to use plenary though, because it has more advanced filetype detection - local success, result = pcall(plenary_filetype.detect, path) - if success then + local success, result = pcall(vim.filetype.match, { filename = path }) + if success and result then return result end + -- Fallback: read a small chunk to sniff the filetype by content + local f = io.open(path, 'r') + if f then + local sample = f:read(512) or '' + f:close() + local ok, ft = pcall(vim.filetype.match, { filename = path, contents = vim.split(sample, '\n') }) + if ok and ft then + return ft + end + end end -M.read_file_async = plenary_async.wrap(function(file_path, callback) - local file = plenary_path:new(file_path) +---Read a file asynchronously and call callback(err, lines) +---@param file_path string +---@param callback fun(err: string|nil, lines: string[]|nil) +function M.read_file_async(file_path, callback) + local uv = vim.uv or vim.loop - if not file:exists() then - return callback('File does not exist', nil) - end + uv.fs_open(file_path, 'r', 438, function(open_err, fd) + if open_err or not fd then + return callback('Could not open file: ' .. (open_err or 'unknown error'), nil) + end - file:read(function(content) - callback(nil, u.multiline_str_to_table(content)) + uv.fs_fstat(fd, function(stat_err, stat) + if stat_err or not stat then + uv.fs_close(fd, function() end) + return callback('Could not stat file: ' .. (stat_err or 'unknown error'), nil) + end + + uv.fs_read(fd, stat.size, 0, function(read_err, data) + uv.fs_close(fd, function() end) + if read_err then + return callback('Could not read file: ' .. read_err, nil) + end + callback(nil, u.multiline_str_to_table(data)) + end) + end) end) -end, 2) +end ---Keep recursively reading into sub-directories, so long as each sub-directory contains only a single directory and no files ---@param path string diff --git a/lua/triptych/init.lua b/lua/triptych/init.lua index d1d5978..0da1c91 100644 --- a/lua/triptych/init.lua +++ b/lua/triptych/init.lua @@ -149,12 +149,6 @@ local function setup(user_config) return warn 'triptych.nvim requires Neovim >= 0.9.0' end - local plenary_installed, _ = pcall(require, 'plenary') - - if not plenary_installed then - return warn 'triptych.nvim requires plenary.nvim' - end - vim.g.triptych_is_open = false vim.api.nvim_create_user_command('Triptych', function(opts) diff --git a/lua/triptych/syntax_highlighting.lua b/lua/triptych/syntax_highlighting.lua index caf173b..767911c 100644 --- a/lua/triptych/syntax_highlighting.lua +++ b/lua/triptych/syntax_highlighting.lua @@ -13,6 +13,7 @@ end ---@param filetype? string ---@return nil M.start = function(buf, filetype) + vim.print 'HELLO!' -- Because this function will be debounced we need to check that the buffer still exists if not vim.api.nvim_buf_is_valid(buf) then return @@ -28,8 +29,8 @@ M.start = function(buf, filetype) if lang then local success, _ = pcall(vim.treesitter.get_parser, buf, lang) if success then - vim.treesitter.start(buf, lang) - treesitter_applied = true + local start_success, _ = pcall(vim.treesitter.start, buf, lang) + treesitter_applied = start_success end end if not treesitter_applied then diff --git a/lua/triptych/view.lua b/lua/triptych/view.lua index dd2fcc5..59d1094 100644 --- a/lua/triptych/view.lua +++ b/lua/triptych/view.lua @@ -5,7 +5,6 @@ local fs = require 'triptych.fs' local git = require 'triptych.git' local diagnostics = require 'triptych.diagnostics' local autocmds = require 'triptych.autocmds' -local plenary_async = require 'plenary.async' local syntax_highlighting = require 'triptych.syntax_highlighting' local M = {} @@ -54,14 +53,18 @@ end ---@param child_win_buf number ---@param path string local function read_file_and_publish(child_win_buf, path) - plenary_async.run(function() - fs.read_file_async(path, function(err, lines) - if err then + fs.read_file_async(path, function(err, lines) + if err then + vim.schedule(function() vim.notify(err, vim.log.levels.ERROR) - else - autocmds.send_file_read(child_win_buf, path, lines) + end) + else + if lines then + vim.schedule(function() + autocmds.send_file_read(child_win_buf, path, lines) + end) end - end) + end end) end From 1ca33459cd7573bfa5c03234843dcf1e17835f34 Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 18:32:21 +0100 Subject: [PATCH 2/9] debugging --- lua/triptych/init.lua | 1 + lua/triptych/syntax_highlighting.lua | 1 + 2 files changed, 2 insertions(+) diff --git a/lua/triptych/init.lua b/lua/triptych/init.lua index 0da1c91..82538b5 100644 --- a/lua/triptych/init.lua +++ b/lua/triptych/init.lua @@ -18,6 +18,7 @@ end ---@param dir? string Path of directory to open. If omitted will be the directory containing the current buffer ---@return fun()|nil local function toggle_triptych(dir) + vim.print(dir) if dir and vim.fn.isdirectory(dir) == 0 then return warn(tostring(dir) .. ' is not a directory') end diff --git a/lua/triptych/syntax_highlighting.lua b/lua/triptych/syntax_highlighting.lua index 767911c..54f9ed4 100644 --- a/lua/triptych/syntax_highlighting.lua +++ b/lua/triptych/syntax_highlighting.lua @@ -30,6 +30,7 @@ M.start = function(buf, filetype) local success, _ = pcall(vim.treesitter.get_parser, buf, lang) if success then local start_success, _ = pcall(vim.treesitter.start, buf, lang) + vim.print('start_success', start_success) treesitter_applied = start_success end end From bf6e7e2c2f15ee2b1ac930f93f46efb0345be8a7 Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 18:36:28 +0100 Subject: [PATCH 3/9] Revert "debugging" This reverts commit 1ca33459cd7573bfa5c03234843dcf1e17835f34. --- lua/triptych/init.lua | 1 - lua/triptych/syntax_highlighting.lua | 1 - 2 files changed, 2 deletions(-) diff --git a/lua/triptych/init.lua b/lua/triptych/init.lua index 82538b5..0da1c91 100644 --- a/lua/triptych/init.lua +++ b/lua/triptych/init.lua @@ -18,7 +18,6 @@ end ---@param dir? string Path of directory to open. If omitted will be the directory containing the current buffer ---@return fun()|nil local function toggle_triptych(dir) - vim.print(dir) if dir and vim.fn.isdirectory(dir) == 0 then return warn(tostring(dir) .. ' is not a directory') end diff --git a/lua/triptych/syntax_highlighting.lua b/lua/triptych/syntax_highlighting.lua index 54f9ed4..767911c 100644 --- a/lua/triptych/syntax_highlighting.lua +++ b/lua/triptych/syntax_highlighting.lua @@ -30,7 +30,6 @@ M.start = function(buf, filetype) local success, _ = pcall(vim.treesitter.get_parser, buf, lang) if success then local start_success, _ = pcall(vim.treesitter.start, buf, lang) - vim.print('start_success', start_success) treesitter_applied = start_success end end From 0c314fb2f6838b54ef7327cfe1d43a3df00003c0 Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 18:38:03 +0100 Subject: [PATCH 4/9] delete tags --- doc/tags | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 doc/tags diff --git a/doc/tags b/doc/tags deleted file mode 100644 index 7756474..0000000 --- a/doc/tags +++ /dev/null @@ -1,9 +0,0 @@ -triptych.nvim-configuration triptych.nvim.txt /*triptych.nvim-configuration* -triptych.nvim-extending-functionality triptych.nvim.txt /*triptych.nvim-extending-functionality* -triptych.nvim-features triptych.nvim.txt /*triptych.nvim-features* -triptych.nvim-how-it-works triptych.nvim.txt /*triptych.nvim-how-it-works* -triptych.nvim-installation triptych.nvim.txt /*triptych.nvim-installation* -triptych.nvim-lsp-integration triptych.nvim.txt /*triptych.nvim-lsp-integration* -triptych.nvim-requirements triptych.nvim.txt /*triptych.nvim-requirements* -triptych.nvim-table-of-contents triptych.nvim.txt /*triptych.nvim-table-of-contents* -triptych.nvim.txt triptych.nvim.txt /*triptych.nvim.txt* From 04e008f2bc5867379bcbaf9cff3a964dd82b9b0b Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 18:38:58 +0100 Subject: [PATCH 5/9] remove debug line --- lua/triptych/syntax_highlighting.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/triptych/syntax_highlighting.lua b/lua/triptych/syntax_highlighting.lua index 767911c..316d2bf 100644 --- a/lua/triptych/syntax_highlighting.lua +++ b/lua/triptych/syntax_highlighting.lua @@ -13,7 +13,6 @@ end ---@param filetype? string ---@return nil M.start = function(buf, filetype) - vim.print 'HELLO!' -- Because this function will be debounced we need to check that the buffer still exists if not vim.api.nvim_buf_is_valid(buf) then return From 748eb8612d1144d258fd5c608469db3ca3c4fe05 Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 18:52:58 +0100 Subject: [PATCH 6/9] fix tests --- test_framework/luassert.lua | 57 +++++++++++++++++++++++++++++++++++++ tests/run_specs.lua | 5 ++++ 2 files changed, 62 insertions(+) create mode 100644 test_framework/luassert.lua diff --git a/test_framework/luassert.lua b/test_framework/luassert.lua new file mode 100644 index 0000000..40c0d03 --- /dev/null +++ b/test_framework/luassert.lua @@ -0,0 +1,57 @@ +--- Minimal luassert shim used by the test specs. +--- Only implements the subset of the luassert API that is actually used. + +local M = {} + +---Deep-equality check that mirrors luassert's assert.same behaviour. +---Raises an error (via Lua's built-in assert) when the values differ. +---@param expected any +---@param actual any +---@param msg? string +function M.same(expected, actual, msg) + local function deep_eq(a, b) + if type(a) ~= type(b) then + return false + end + if type(a) ~= 'table' then + return a == b + end + -- Check all keys in a exist and match in b + for k, v in pairs(a) do + if not deep_eq(v, b[k]) then + return false + end + end + -- Check b has no extra keys + for k in pairs(b) do + if a[k] == nil then + return false + end + end + return true + end + + if not deep_eq(expected, actual) then + local lines = {} + if msg then + table.insert(lines, msg) + end + table.insert(lines, 'Expected:') + table.insert(lines, vim.inspect(expected)) + table.insert(lines, 'Got:') + table.insert(lines, vim.inspect(actual)) + error(table.concat(lines, '\n'), 2) + end +end + +-- Make the module itself callable so that bare assert(cond, msg) calls work +-- even after `local assert = require 'luassert'` shadows the built-in. +setmetatable(M, { + __call = function(_, cond, msg) + if not cond then + error(msg or 'assertion failed', 2) + end + end, +}) + +return M diff --git a/tests/run_specs.lua b/tests/run_specs.lua index 8e8dac0..4e14f09 100644 --- a/tests/run_specs.lua +++ b/tests/run_specs.lua @@ -1,6 +1,11 @@ local u = require 'test_framework.utils' local uv = vim.loop +-- Register a built-in luassert shim so that specs don't need an external dependency +package.preload['luassert'] = function() + return require 'test_framework.luassert' +end + local function get_files_in_dir(dir) local files = {} local handle = uv.fs_scandir(dir) From 0d831253dba1fc78f51eb04bf0a0eb0c53f3718c Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 19:34:32 +0100 Subject: [PATCH 7/9] fix tests --- lua/triptych/config.lua | 2 +- test_framework/luassert.lua | 57 ------------------------------ test_framework/queue.lua | 4 ++- test_framework/utils.lua | 2 +- tests/run_specs.lua | 5 --- tests/specs/config_spec.lua | 5 ++- tests/specs/help_spec.lua | 4 +-- tests/specs/ui_spec.lua | 69 ++++++++++++++++++------------------- tests/specs/utils_spec.lua | 22 ++++++------ tests/utils.lua | 38 ++++++++++++++++++++ validate.sh | 2 ++ 11 files changed, 94 insertions(+), 116 deletions(-) delete mode 100644 test_framework/luassert.lua diff --git a/lua/triptych/config.lua b/lua/triptych/config.lua index faca0c0..b76c665 100644 --- a/lua/triptych/config.lua +++ b/lua/triptych/config.lua @@ -101,7 +101,7 @@ local function default_config() debug = false, mappings = { -- Everything below is buffer-local, meaning it will only apply to Triptych windows - show_help = 'g?', + show_help = '?', jump_to_cwd = '.', nav_left = 'h', nav_right = { 'l', '' }, diff --git a/test_framework/luassert.lua b/test_framework/luassert.lua deleted file mode 100644 index 40c0d03..0000000 --- a/test_framework/luassert.lua +++ /dev/null @@ -1,57 +0,0 @@ ---- Minimal luassert shim used by the test specs. ---- Only implements the subset of the luassert API that is actually used. - -local M = {} - ----Deep-equality check that mirrors luassert's assert.same behaviour. ----Raises an error (via Lua's built-in assert) when the values differ. ----@param expected any ----@param actual any ----@param msg? string -function M.same(expected, actual, msg) - local function deep_eq(a, b) - if type(a) ~= type(b) then - return false - end - if type(a) ~= 'table' then - return a == b - end - -- Check all keys in a exist and match in b - for k, v in pairs(a) do - if not deep_eq(v, b[k]) then - return false - end - end - -- Check b has no extra keys - for k in pairs(b) do - if a[k] == nil then - return false - end - end - return true - end - - if not deep_eq(expected, actual) then - local lines = {} - if msg then - table.insert(lines, msg) - end - table.insert(lines, 'Expected:') - table.insert(lines, vim.inspect(expected)) - table.insert(lines, 'Got:') - table.insert(lines, vim.inspect(actual)) - error(table.concat(lines, '\n'), 2) - end -end - --- Make the module itself callable so that bare assert(cond, msg) calls work --- even after `local assert = require 'luassert'` shadows the built-in. -setmetatable(M, { - __call = function(_, cond, msg) - if not cond then - error(msg or 'assertion failed', 2) - end - end, -}) - -return M diff --git a/test_framework/queue.lua b/test_framework/queue.lua index b276722..21ce6e9 100644 --- a/test_framework/queue.lua +++ b/test_framework/queue.lua @@ -91,7 +91,9 @@ function TestQueue:handle_all_tests_succeeded() .. result_count.skipped .. ' skipped, ' .. result_count.passed - .. ' passed, 0 failed' + .. ' passed, ' + .. result_count.failed + .. ' failed' ) self:cleanup() diff --git a/test_framework/utils.lua b/test_framework/utils.lua index 28ae017..01e660c 100644 --- a/test_framework/utils.lua +++ b/test_framework/utils.lua @@ -63,7 +63,7 @@ function M.raise_error(error_message) if M.is_headless() then M.print(error_message) else - error(error_message) + vim.notify(error_message, vim.log.levels.ERROR) end end diff --git a/tests/run_specs.lua b/tests/run_specs.lua index 4e14f09..8e8dac0 100644 --- a/tests/run_specs.lua +++ b/tests/run_specs.lua @@ -1,11 +1,6 @@ local u = require 'test_framework.utils' local uv = vim.loop --- Register a built-in luassert shim so that specs don't need an external dependency -package.preload['luassert'] = function() - return require 'test_framework.luassert' -end - local function get_files_in_dir(dir) local files = {} local handle = uv.fs_scandir(dir) diff --git a/tests/specs/config_spec.lua b/tests/specs/config_spec.lua index 000eef9..8ed1988 100644 --- a/tests/specs/config_spec.lua +++ b/tests/specs/config_spec.lua @@ -1,4 +1,3 @@ -local assert = require 'luassert' local u = require 'tests.utils' local config = require 'triptych.config' local framework = require 'test_framework.test' @@ -80,7 +79,7 @@ end describe('create_merged_config', { it('returns the default config when user config is empty', function() - assert.same(expected_default_config(), config.create_merged_config {}) + u.assert_same(expected_default_config(), config.create_merged_config {}) end), it('merges partial user config with the default', function() @@ -99,6 +98,6 @@ describe('create_merged_config', { result.git_signs.enabled = false return result end) - assert.same(expected, config.create_merged_config(user_config)) + u.assert_same(expected, config.create_merged_config(user_config)) end), }) diff --git a/tests/specs/help_spec.lua b/tests/specs/help_spec.lua index efb94c2..65e4646 100644 --- a/tests/specs/help_spec.lua +++ b/tests/specs/help_spec.lua @@ -1,5 +1,5 @@ local help = require 'triptych.help' -local assert = require 'luassert' +local u = require 'tests.utils' local framework = require 'test_framework.test' local it = framework.test local describe = framework.describe @@ -8,7 +8,7 @@ describe('help_lines', { it('returns key bindings', function() local result = help.help_lines() - assert.same({ + u.assert_same({ ' Triptych key bindings', ' ', ' add : a', diff --git a/tests/specs/ui_spec.lua b/tests/specs/ui_spec.lua index 33e398e..cf57250 100644 --- a/tests/specs/ui_spec.lua +++ b/tests/specs/ui_spec.lua @@ -1,4 +1,3 @@ -local assert = require 'luassert' local u = require 'tests.utils' local framework = require 'test_framework.test' local describe = framework.describe @@ -29,7 +28,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(is_open, true) + u.assert_same(is_open, true) -- This is kinda janky, but basically this test could be called from one of 2 places assert(current_line == 'run_specs.lua' or current_line == 'ui_spec.lua', 'got ' .. tostring(current_line)) end, @@ -43,7 +42,7 @@ describe('Triptych UI', { u.on_event('TriptychDidClose', function() done { assertions = function() - assert.same(vim.g.triptych_is_open, false) + u.assert_same(vim.g.triptych_is_open, false) end, } end) @@ -71,8 +70,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines, result.lines) - assert.same(expected_winbars, result.winbars) + u.assert_same(expected_lines, result.lines) + u.assert_same(expected_winbars, result.winbars) end, } end) @@ -99,8 +98,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines, result.lines) - assert.same(expected_winbars, result.winbars) + u.assert_same(expected_lines, result.lines) + u.assert_same(expected_winbars, result.winbars) end, } end) @@ -128,8 +127,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines, result.lines) - assert.same(expected_winbars, result.winbars) + u.assert_same(expected_lines, result.lines) + u.assert_same(expected_winbars, result.winbars) end, } end) @@ -145,7 +144,7 @@ describe('Triptych UI', { u.on_event('TriptychDidClose', function() done { assertions = function() - assert.same(vim.g.triptych_is_open, false) + u.assert_same(vim.g.triptych_is_open, false) end, cleanup = function() vim.api.nvim_set_current_buf(current_buf) @@ -173,7 +172,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_file_preview, state.lines.child) + u.assert_same(expected_file_preview, state.lines.child) end, } end) @@ -206,8 +205,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines.primary, state.lines.primary) - assert.same(expected_lines.child, state.lines.child) + u.assert_same(expected_lines.primary, state.lines.primary) + u.assert_same(expected_lines.child, state.lines.child) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'a_new_dir'), 'rf') @@ -243,7 +242,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_events, events) + u.assert_same(expected_events, events) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'a_new_dir'), 'rf') @@ -282,8 +281,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines.primary, state.lines.primary) - assert.same(expected_lines.child, state.lines.child) + u.assert_same(expected_lines.primary, state.lines.primary) + u.assert_same(expected_lines.child, state.lines.child) end, } end) @@ -318,8 +317,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines.child, state.lines.child) - assert.same(expected_lines.primary, state.lines.primary) + u.assert_same(expected_lines.child, state.lines.child) + u.assert_same(expected_lines.primary, state.lines.primary) end, cleanup = function() vim.fn.delete(u.join_path(cwd, 'tests/test_playground/level_1/level_2/level_4'), 'rf') @@ -357,7 +356,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_events, events) + u.assert_same(expected_events, events) end, cleanup = function() vim.fn.delete(u.join_path(cwd, 'tests/test_playground/level_1/level_2/level_4'), 'rf') @@ -393,7 +392,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_events, events) + u.assert_same(expected_events, events) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'level_3_file_1_copy1.md')) @@ -437,8 +436,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines.primary, state.lines.primary) - assert.same(expected_lines.child, state.lines.child) + u.assert_same(expected_lines.primary, state.lines.primary) + u.assert_same(expected_lines.child, state.lines.child) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'level_3_file_1_copy1.md')) @@ -476,7 +475,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines.primary, state.lines.primary) + u.assert_same(expected_lines.primary, state.lines.primary) end, cleanup = function() vim.fn.rename(u.join_path(opening_dir, 'renamed_dir'), u.join_path(opening_dir, 'level_4')) @@ -521,7 +520,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_events, events) + u.assert_same(expected_events, events) end, cleanup = function() vim.fn.rename(u.join_path(opening_dir, 'renamed_dir'), u.join_path(opening_dir, 'level_4')) @@ -566,9 +565,9 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_lines_without_hidden.primary, first_state.lines.primary) - assert.same(expected_lines_with_hidden.primary, second_state.lines.primary) - assert.same(expected_lines_without_hidden.primary, third_state.lines.primary) + u.assert_same(expected_lines_without_hidden.primary, first_state.lines.primary) + u.assert_same(expected_lines_with_hidden.primary, second_state.lines.primary) + u.assert_same(expected_lines_without_hidden.primary, third_state.lines.primary) end, cleanup = function() vim.fn.delete(git_ignored_file) @@ -600,8 +599,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_winbar_after_first_jump, winbar_after_first_jump) - assert.same(expected_winbar_after_second_jump, winbar_after_second_jump) + u.assert_same(expected_winbar_after_first_jump, winbar_after_first_jump) + u.assert_same(expected_winbar_after_second_jump, winbar_after_second_jump) end, } end) @@ -632,10 +631,10 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - assert.same(expected_collapsed_lines.primary, state_collapsed.lines.primary) - assert.same(expected_collapsed_lines.child, state_collapsed.lines.child) - assert.same(expected_uncollapsed_lines.primary, state_uncollapsed.lines.primary) - assert.same(expected_uncollapsed_lines.child, state_uncollapsed.lines.child) + u.assert_same(expected_collapsed_lines.primary, state_collapsed.lines.primary) + u.assert_same(expected_collapsed_lines.child, state_collapsed.lines.child) + u.assert_same(expected_uncollapsed_lines.primary, state_uncollapsed.lines.primary) + u.assert_same(expected_uncollapsed_lines.child, state_uncollapsed.lines.child) end, cleanup = function() os.execute('rm -rf ' .. opening_dir .. '/a') @@ -678,8 +677,8 @@ describe('Triptych config', { close_triptych(function() done { assertions = function() - assert.same(expected_data, resulting_callback_params[1]) - assert.same('function', type(resulting_callback_params[2])) + u.assert_same(expected_data, resulting_callback_params[1]) + u.assert_same('function', type(resulting_callback_params[2])) end, } end) diff --git a/tests/specs/utils_spec.lua b/tests/specs/utils_spec.lua index 105f978..9aa89dc 100644 --- a/tests/specs/utils_spec.lua +++ b/tests/specs/utils_spec.lua @@ -1,4 +1,4 @@ -local assert = require 'luassert' +local test_u = require 'tests.utils' local u = require 'triptych.utils' local framework = require 'test_framework.test' local it = framework.test @@ -11,7 +11,7 @@ describe('set', { bar = 2, } local result = u.set(tbl, 'foo', 3) - assert.same(3, result.foo) + test_u.assert_same(3, result.foo) end), }) @@ -37,7 +37,7 @@ describe('merge_tables', { }, } local result = u.merge_tables(a, b) - assert.same(expected, result) + test_u.assert_same(expected, result) end), it('merges tables - first one is empty', function() @@ -53,7 +53,7 @@ describe('merge_tables', { }, } local result = u.merge_tables(a, b) - assert.same(expected, result) + test_u.assert_same(expected, result) end), it('merges tables - second one empty', function() @@ -71,17 +71,17 @@ describe('merge_tables', { }, } local result = u.merge_tables(a, b) - assert.same(expected, result) + test_u.assert_same(expected, result) end), }) describe('round', { it('rounds to x decimal places', function() - assert.same(0.33, u.round(0.333, 2)) - assert.same(0.333, u.round(0.333, 3)) - assert.same(1.2, u.round(1.16, 1)) - assert.same(1.1, u.round(1.11, 1)) - assert.same(1, u.round(1.16, 0)) - assert.same(200.99, u.round(200.99, 3)) + test_u.assert_same(0.33, u.round(0.333, 2)) + test_u.assert_same(0.333, u.round(0.333, 3)) + test_u.assert_same(1.2, u.round(1.16, 1)) + test_u.assert_same(1.1, u.round(1.11, 1)) + test_u.assert_same(1, u.round(1.16, 0)) + test_u.assert_same(200.99, u.round(200.99, 3)) end), }) diff --git a/tests/utils.lua b/tests/utils.lua index 9428c40..d984328 100644 --- a/tests/utils.lua +++ b/tests/utils.lua @@ -232,4 +232,42 @@ function M.eval(fn) return fn() end +---Deep-equality assertion. +---@param expected any +---@param actual any +---@param msg? string +function M.assert_same(expected, actual, msg) + local function deep_eq(a, b) + if type(a) ~= type(b) then + return false + end + if type(a) ~= 'table' then + return a == b + end + for k, v in pairs(a) do + if not deep_eq(v, b[k]) then + return false + end + end + for k in pairs(b) do + if a[k] == nil then + return false + end + end + return true + end + + if not deep_eq(expected, actual) then + local lines = {} + if msg then + table.insert(lines, msg) + end + table.insert(lines, 'Expected:') + table.insert(lines, vim.inspect(expected)) + table.insert(lines, 'Got:') + table.insert(lines, vim.inspect(actual)) + error(table.concat(lines, '\n'), 2) + end +end + return M diff --git a/validate.sh b/validate.sh index c20ecde..5ff8b43 100755 --- a/validate.sh +++ b/validate.sh @@ -20,6 +20,7 @@ diagnostics_exit_code=$? if [ $diagnostics_exit_code -ne 0 ]; then echo "❌ 1 or more diagnostic problems found"; + exit 1; else echo "✅ Diagnostics passed"; fi @@ -30,6 +31,7 @@ tests_exit_code=$? if [ $tests_exit_code -ne 0 ]; then echo "❌ 1 or more tests failed"; + exit 1; else echo "✅ Tests passed"; fi From 8cd2c273b5447342735d467c752f9eec1b43e246 Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 19:49:31 +0100 Subject: [PATCH 8/9] fix tests --- test_framework/test.lua | 38 ++++++++++++++++++++ tests/specs/config_spec.lua | 5 +-- tests/specs/help_spec.lua | 4 +-- tests/specs/ui_spec.lua | 69 +++++++++++++++++++------------------ tests/specs/utils_spec.lua | 22 ++++++------ tests/utils.lua | 38 -------------------- 6 files changed, 89 insertions(+), 87 deletions(-) diff --git a/test_framework/test.lua b/test_framework/test.lua index e916008..2dd668d 100644 --- a/test_framework/test.lua +++ b/test_framework/test.lua @@ -154,4 +154,42 @@ M.describe = function(description, tests) end end +---Deep-equality assertion. +---@param expected any +---@param actual any +---@param msg? string +M.assert_same = function(expected, actual, msg) + local function deep_eq(a, b) + if type(a) ~= type(b) then + return false + end + if type(a) ~= 'table' then + return a == b + end + for k, v in pairs(a) do + if not deep_eq(v, b[k]) then + return false + end + end + for k in pairs(b) do + if a[k] == nil then + return false + end + end + return true + end + + if not deep_eq(expected, actual) then + local lines = {} + if msg then + table.insert(lines, msg) + end + table.insert(lines, 'Expected:') + table.insert(lines, vim.inspect(expected)) + table.insert(lines, 'Got:') + table.insert(lines, vim.inspect(actual)) + error(table.concat(lines, '\n'), 2) + end +end + return M diff --git a/tests/specs/config_spec.lua b/tests/specs/config_spec.lua index 8ed1988..9444363 100644 --- a/tests/specs/config_spec.lua +++ b/tests/specs/config_spec.lua @@ -3,6 +3,7 @@ local config = require 'triptych.config' local framework = require 'test_framework.test' local it = framework.test local describe = framework.describe +local assert_same = framework.assert_same local function expected_default_config() return { @@ -79,7 +80,7 @@ end describe('create_merged_config', { it('returns the default config when user config is empty', function() - u.assert_same(expected_default_config(), config.create_merged_config {}) + assert_same(expected_default_config(), config.create_merged_config {}) end), it('merges partial user config with the default', function() @@ -98,6 +99,6 @@ describe('create_merged_config', { result.git_signs.enabled = false return result end) - u.assert_same(expected, config.create_merged_config(user_config)) + assert_same(expected, config.create_merged_config(user_config)) end), }) diff --git a/tests/specs/help_spec.lua b/tests/specs/help_spec.lua index 65e4646..db4a9a1 100644 --- a/tests/specs/help_spec.lua +++ b/tests/specs/help_spec.lua @@ -1,14 +1,14 @@ local help = require 'triptych.help' -local u = require 'tests.utils' local framework = require 'test_framework.test' local it = framework.test local describe = framework.describe +local assert_same = framework.assert_same describe('help_lines', { it('returns key bindings', function() local result = help.help_lines() - u.assert_same({ + assert_same({ ' Triptych key bindings', ' ', ' add : a', diff --git a/tests/specs/ui_spec.lua b/tests/specs/ui_spec.lua index cf57250..31d397e 100644 --- a/tests/specs/ui_spec.lua +++ b/tests/specs/ui_spec.lua @@ -2,6 +2,7 @@ local u = require 'tests.utils' local framework = require 'test_framework.test' local describe = framework.describe local test = framework.test_async +local assert_same = framework.assert_same local cwd = vim.fn.getcwd() local opening_dir = u.join_path(cwd, 'tests/test_playground/level_1/level_2/level_3') @@ -28,7 +29,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(is_open, true) + assert_same(is_open, true) -- This is kinda janky, but basically this test could be called from one of 2 places assert(current_line == 'run_specs.lua' or current_line == 'ui_spec.lua', 'got ' .. tostring(current_line)) end, @@ -42,7 +43,7 @@ describe('Triptych UI', { u.on_event('TriptychDidClose', function() done { assertions = function() - u.assert_same(vim.g.triptych_is_open, false) + assert_same(vim.g.triptych_is_open, false) end, } end) @@ -70,8 +71,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines, result.lines) - u.assert_same(expected_winbars, result.winbars) + assert_same(expected_lines, result.lines) + assert_same(expected_winbars, result.winbars) end, } end) @@ -98,8 +99,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines, result.lines) - u.assert_same(expected_winbars, result.winbars) + assert_same(expected_lines, result.lines) + assert_same(expected_winbars, result.winbars) end, } end) @@ -127,8 +128,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines, result.lines) - u.assert_same(expected_winbars, result.winbars) + assert_same(expected_lines, result.lines) + assert_same(expected_winbars, result.winbars) end, } end) @@ -144,7 +145,7 @@ describe('Triptych UI', { u.on_event('TriptychDidClose', function() done { assertions = function() - u.assert_same(vim.g.triptych_is_open, false) + assert_same(vim.g.triptych_is_open, false) end, cleanup = function() vim.api.nvim_set_current_buf(current_buf) @@ -172,7 +173,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_file_preview, state.lines.child) + assert_same(expected_file_preview, state.lines.child) end, } end) @@ -205,8 +206,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines.primary, state.lines.primary) - u.assert_same(expected_lines.child, state.lines.child) + assert_same(expected_lines.primary, state.lines.primary) + assert_same(expected_lines.child, state.lines.child) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'a_new_dir'), 'rf') @@ -242,7 +243,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_events, events) + assert_same(expected_events, events) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'a_new_dir'), 'rf') @@ -281,8 +282,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines.primary, state.lines.primary) - u.assert_same(expected_lines.child, state.lines.child) + assert_same(expected_lines.primary, state.lines.primary) + assert_same(expected_lines.child, state.lines.child) end, } end) @@ -317,8 +318,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines.child, state.lines.child) - u.assert_same(expected_lines.primary, state.lines.primary) + assert_same(expected_lines.child, state.lines.child) + assert_same(expected_lines.primary, state.lines.primary) end, cleanup = function() vim.fn.delete(u.join_path(cwd, 'tests/test_playground/level_1/level_2/level_4'), 'rf') @@ -356,7 +357,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_events, events) + assert_same(expected_events, events) end, cleanup = function() vim.fn.delete(u.join_path(cwd, 'tests/test_playground/level_1/level_2/level_4'), 'rf') @@ -392,7 +393,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_events, events) + assert_same(expected_events, events) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'level_3_file_1_copy1.md')) @@ -436,8 +437,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines.primary, state.lines.primary) - u.assert_same(expected_lines.child, state.lines.child) + assert_same(expected_lines.primary, state.lines.primary) + assert_same(expected_lines.child, state.lines.child) end, cleanup = function() vim.fn.delete(u.join_path(opening_dir, 'level_3_file_1_copy1.md')) @@ -475,7 +476,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines.primary, state.lines.primary) + assert_same(expected_lines.primary, state.lines.primary) end, cleanup = function() vim.fn.rename(u.join_path(opening_dir, 'renamed_dir'), u.join_path(opening_dir, 'level_4')) @@ -520,7 +521,7 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_events, events) + assert_same(expected_events, events) end, cleanup = function() vim.fn.rename(u.join_path(opening_dir, 'renamed_dir'), u.join_path(opening_dir, 'level_4')) @@ -565,9 +566,9 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_lines_without_hidden.primary, first_state.lines.primary) - u.assert_same(expected_lines_with_hidden.primary, second_state.lines.primary) - u.assert_same(expected_lines_without_hidden.primary, third_state.lines.primary) + assert_same(expected_lines_without_hidden.primary, first_state.lines.primary) + assert_same(expected_lines_with_hidden.primary, second_state.lines.primary) + assert_same(expected_lines_without_hidden.primary, third_state.lines.primary) end, cleanup = function() vim.fn.delete(git_ignored_file) @@ -599,8 +600,8 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_winbar_after_first_jump, winbar_after_first_jump) - u.assert_same(expected_winbar_after_second_jump, winbar_after_second_jump) + assert_same(expected_winbar_after_first_jump, winbar_after_first_jump) + assert_same(expected_winbar_after_second_jump, winbar_after_second_jump) end, } end) @@ -631,10 +632,10 @@ describe('Triptych UI', { close_triptych(function() done { assertions = function() - u.assert_same(expected_collapsed_lines.primary, state_collapsed.lines.primary) - u.assert_same(expected_collapsed_lines.child, state_collapsed.lines.child) - u.assert_same(expected_uncollapsed_lines.primary, state_uncollapsed.lines.primary) - u.assert_same(expected_uncollapsed_lines.child, state_uncollapsed.lines.child) + assert_same(expected_collapsed_lines.primary, state_collapsed.lines.primary) + assert_same(expected_collapsed_lines.child, state_collapsed.lines.child) + assert_same(expected_uncollapsed_lines.primary, state_uncollapsed.lines.primary) + assert_same(expected_uncollapsed_lines.child, state_uncollapsed.lines.child) end, cleanup = function() os.execute('rm -rf ' .. opening_dir .. '/a') @@ -677,8 +678,8 @@ describe('Triptych config', { close_triptych(function() done { assertions = function() - u.assert_same(expected_data, resulting_callback_params[1]) - u.assert_same('function', type(resulting_callback_params[2])) + assert_same(expected_data, resulting_callback_params[1]) + assert_same('function', type(resulting_callback_params[2])) end, } end) diff --git a/tests/specs/utils_spec.lua b/tests/specs/utils_spec.lua index 9aa89dc..04f44cd 100644 --- a/tests/specs/utils_spec.lua +++ b/tests/specs/utils_spec.lua @@ -1,8 +1,8 @@ -local test_u = require 'tests.utils' local u = require 'triptych.utils' local framework = require 'test_framework.test' local it = framework.test local describe = framework.describe +local assert_same = framework.assert_same describe('set', { it('returns a copy of the table with the specified value changed', function() @@ -11,7 +11,7 @@ describe('set', { bar = 2, } local result = u.set(tbl, 'foo', 3) - test_u.assert_same(3, result.foo) + assert_same(3, result.foo) end), }) @@ -37,7 +37,7 @@ describe('merge_tables', { }, } local result = u.merge_tables(a, b) - test_u.assert_same(expected, result) + assert_same(expected, result) end), it('merges tables - first one is empty', function() @@ -53,7 +53,7 @@ describe('merge_tables', { }, } local result = u.merge_tables(a, b) - test_u.assert_same(expected, result) + assert_same(expected, result) end), it('merges tables - second one empty', function() @@ -71,17 +71,17 @@ describe('merge_tables', { }, } local result = u.merge_tables(a, b) - test_u.assert_same(expected, result) + assert_same(expected, result) end), }) describe('round', { it('rounds to x decimal places', function() - test_u.assert_same(0.33, u.round(0.333, 2)) - test_u.assert_same(0.333, u.round(0.333, 3)) - test_u.assert_same(1.2, u.round(1.16, 1)) - test_u.assert_same(1.1, u.round(1.11, 1)) - test_u.assert_same(1, u.round(1.16, 0)) - test_u.assert_same(200.99, u.round(200.99, 3)) + assert_same(0.33, u.round(0.333, 2)) + assert_same(0.333, u.round(0.333, 3)) + assert_same(1.2, u.round(1.16, 1)) + assert_same(1.1, u.round(1.11, 1)) + assert_same(1, u.round(1.16, 0)) + assert_same(200.99, u.round(200.99, 3)) end), }) diff --git a/tests/utils.lua b/tests/utils.lua index d984328..9428c40 100644 --- a/tests/utils.lua +++ b/tests/utils.lua @@ -232,42 +232,4 @@ function M.eval(fn) return fn() end ----Deep-equality assertion. ----@param expected any ----@param actual any ----@param msg? string -function M.assert_same(expected, actual, msg) - local function deep_eq(a, b) - if type(a) ~= type(b) then - return false - end - if type(a) ~= 'table' then - return a == b - end - for k, v in pairs(a) do - if not deep_eq(v, b[k]) then - return false - end - end - for k in pairs(b) do - if a[k] == nil then - return false - end - end - return true - end - - if not deep_eq(expected, actual) then - local lines = {} - if msg then - table.insert(lines, msg) - end - table.insert(lines, 'Expected:') - table.insert(lines, vim.inspect(expected)) - table.insert(lines, 'Got:') - table.insert(lines, vim.inspect(actual)) - error(table.concat(lines, '\n'), 2) - end -end - return M From 7a80de7979c1313659a27971aaf16cf6dfbf89bd Mon Sep 17 00:00:00 2001 From: Simon McLean Date: Tue, 14 Apr 2026 19:52:35 +0100 Subject: [PATCH 9/9] fix tests --- lua/triptych/config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/triptych/config.lua b/lua/triptych/config.lua index b76c665..faca0c0 100644 --- a/lua/triptych/config.lua +++ b/lua/triptych/config.lua @@ -101,7 +101,7 @@ local function default_config() debug = false, mappings = { -- Everything below is buffer-local, meaning it will only apply to Triptych windows - show_help = '?', + show_help = 'g?', jump_to_cwd = '.', nav_left = 'h', nav_right = { 'l', '' },