Skip to content

Commit

Permalink
various fixes and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon McLean committed Sep 14, 2024
1 parent 6169485 commit 067e413
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 76 deletions.
72 changes: 50 additions & 22 deletions lua/triptych/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local view = require 'triptych.view'
local plenary_path = require 'plenary.path'
local triptych_help = require 'triptych.help'
local autocmds = require 'triptych.autocmds'
local log = require 'triptych.logger'

local Actions = {}

Expand Down Expand Up @@ -44,6 +45,49 @@ local function rename_node_and_publish(from, to)
end
end

---Wraps plenary Path:copy with public events
---Note: It only publishes events for files, not folders. This is probably fine for LSP purposes
---@param target PathDetails
---@param destination string
---@return nil
local function duplicate_node_and_publish(target, destination)
log.debug('duplicate_file_or_dir', { target = target, destination = destination })
if not target.is_dir then
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)

-- Sorting to avoid flakey test
table.sort(files_created)

for _, path in ipairs(files_created) do
autocmds.publish_did_create_node(path)
end
end

--- TODO: Return type
---@param State TriptychState
---@param refresh_view fun(): nil
Expand Down Expand Up @@ -188,25 +232,6 @@ function Actions.new(State, refresh_view)
refresh_view()
end

---@param target PathDetails
---@param destination string
---@param callback? fun(boolean) - Callback indicting whether an item an copied
---@return nil
M.duplicate_file_or_dir = function(target, destination, callback)
local p = plenary_path:new(target.path)
local results = p:copy {
destination = destination,
recursive = true,
override = false,
interactive = true,
}
if callback then
for _, v in pairs(results) do
callback(v)
end
end
end

M.bulk_toggle_copy = function()
local targets = view.get_targets_in_selection(State)
local contains_copy_items = false
Expand Down Expand Up @@ -277,9 +302,9 @@ function Actions.new(State, refresh_view)
return get_copy_path(target_path, i + 1)
end

-- TODO: This function is a mess. Maybe break out into handlers for copy and cut?
---@return nil
M.paste = function()
-- TODO: This function is a mess. Maybe break out into handlers for copy and cut?
local cursor_target = view.get_target_under_cursor(State)
local destination_dir = u.eval(function()
if not cursor_target then
Expand All @@ -305,8 +330,11 @@ function Actions.new(State, refresh_view)
-- Handle copy items
for _, item in ipairs(State.copy_list) do
local destination = get_copy_path(u.path_join(destination_dir, item.display_name))
M.duplicate_file_or_dir(item, destination)
autocmds.publish_did_delete_node(destination)
if item.is_dir then
-- Strip trailing slash
destination = string.sub(destination, 1, #destination - 1)
end
duplicate_node_and_publish(item, destination)
end

view.jump_cursor_to(State, destination_dir)
Expand Down
6 changes: 6 additions & 0 deletions lua/triptych/autocmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,19 @@ end

---@param path string
function M.publish_will_create_node(path)
-- vim.print {
-- will_create = path
-- }
exec_public_autocmd('TriptychWillCreateNode', {
path = path,
})
end

---@param path string
function M.publish_did_create_node(path)
-- vim.print {
-- created = path
-- }
exec_public_autocmd('TriptychDidCreateNode', {
path = path,
})
Expand Down
20 changes: 11 additions & 9 deletions test_framework/queue.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ end
function TestQueue:cleanup()
self.is_running = false
for _, test in ipairs(self.queue) do
test:cleanup()
test:reset()
test.result = nil
end
for _, test in ipairs(self.completed) do
test:cleanup()
test:reset()
test.result = nil
end
self.queue = {}
Expand Down Expand Up @@ -104,13 +104,15 @@ end
---@param fail_message? string
function TestQueue:handle_test_fail(test, fail_message)
test.result = 'failed'
u.print('[FAILED] ' .. test.name)
error(fail_message)
self:cleanup()
if u.is_headless() then
u.exit_status_code 'failed'
else
end
vim.schedule(function()
u.print('[FAILED] ' .. test.name)
error(fail_message)
test:reset()
self:cleanup()
if u.is_headless() then
u.exit_status_code 'failed'
end
end)
end

function TestQueue:run_next()
Expand Down
19 changes: 11 additions & 8 deletions test_framework/test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,31 @@ end
---Run an asyncronous test
---@param callback fun(passed: boolean, fail_message?: string)
function Test:run_async(callback)
local success, err = pcall(self.test_body_async, function(test_callback)
local success, err = pcall(self.test_body_async, function(test_finish)
if self.has_run then
error 'Attempted to invoke test completion more than once. Check that any async callbacks in the test are not firing multiple times.'
end

-- Scheduling this allows cleanup to complete before running the next test
local scheduled_callback = vim.schedule_wrap(callback)

self.has_run = true

if test_callback.cleanup then
local cleanup_successful, cleanup_err = pcall(test_callback.cleanup)
if test_finish.cleanup then
local cleanup_successful, cleanup_err = pcall(test_finish.cleanup)
if not cleanup_successful then
error(cleanup_err)
end
end

if self.is_timed_out then
callback(false, 'Timed out')
scheduled_callback(false, 'Timed out')
else
local passed, fail_message = pcall(test_callback.assertions)
local passed, fail_message = pcall(test_finish.assertions)
if passed then
callback(true, nil)
scheduled_callback(true, nil)
else
callback(false, fail_message)
scheduled_callback(false, fail_message)
end
end
end)
Expand Down Expand Up @@ -123,7 +126,7 @@ function Test:only()
return self
end

function Test:cleanup()
function Test:reset()
self.has_run = false
self.result = nil
end
Expand Down
133 changes: 103 additions & 30 deletions tests/specs/ui_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,7 @@ describe('Triptych UI', {
end)
end),

-- Having trouble with this
-- How to programatically input a selection in vim.ui.select
-- TODO: Having trouble with this. How to programatically input a selection in vim.ui.select?
test('deletes files and folders', function(done)
local expected_lines = {
primary = {
Expand Down Expand Up @@ -291,60 +290,134 @@ describe('Triptych UI', {
end)
end):skip(),

-- TODO: Skipped this because there seems to be a bug with dir pasting!
test('copies file and folders', function(done)
test('copies folders along with their contents', function(done)
local expected_lines = {
primary = {
'level_3/',
'level_4/', -- this is the copied dir, cursor should be over it
'level_2_file_1.lua',
},
child = {
'level_5/',
'level_4_file_1.lua',
},
}
open_triptych(function()
-- Copy directory under cursor
u.press_keys 'c'
u.on_primary_window_updated(function()
-- Move left into the parent directory
u.press_keys 'h'
u.on_all_wins_updated(function()
-- Move down, so that the cursor is not over a directory, then paste the previously copied directory
u.press_keys 'jp'
u.on_all_wins_updated(function()
local state = u.get_state()
close_triptych(function()
done {
assertions = function()
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')
end,
}
end)
end)
end)
end)
end)
end),

test('when copying-pasting, publishes public events for files (not folders)', function(done)
local base_dir = u.join_path(cwd, 'tests/test_playground/level_1/level_2')

local expected_events = {
['TriptychDidCreateNode'] = {
{ path = u.join_path(base_dir, 'level_4/level_4_file_1.lua') },
{ path = u.join_path(base_dir, 'level_4/level_5/level_5_file_1.lua') },
},
}

open_triptych(function()
-- Copy directory under cursor
u.press_keys 'c'
u.on_primary_window_updated(function()
-- Move left into the parent directory
u.press_keys 'h'
u.on_all_wins_updated(function()
-- Move down, so that the cursor is not over a directory, then paste the previously copied directory
u.press_keys 'jp'
u.on_events({
{ name = 'TriptychDidCreateNode', wait_for_n = 2 },
}, function(events)
local state = u.get_state()
close_triptych(function()
done {
assertions = function()
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')
end,
}
end)
end)
end)
end)
end)
end),

test('copies files', function(done)
local expected_lines = {
primary = {
'level_4/',
'level_3_file_1.md',
'level_3_file_1_copy1.md',
},
child = {
'level_4/',
'level_5/',
'level_3_file_1.md',
'level_4_file_1.lua',
},
}

open_triptych(function()
u.press_keys 'c'
-- Move down to the file and copy
u.press_keys 'jc'
u.on_primary_window_updated(function()
-- Paste
u.press_keys 'p'
u.on_primary_window_updated(function()
u.press_keys 'j'
u.press_keys 'c'
-- Copy file again, move up over directory
u.press_keys 'ck'
u.on_primary_window_updated(function()
-- Paste
u.press_keys 'p'
u.on_primary_window_updated(function()
-- Go back to the top, so we can the new dir we've pasted in the the child directory
u.press_keys 'gg'
u.on_child_window_updated(function()
local state = u.get_state()
close_triptych(function()
done {
assertions = function()
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(opening_dir, 'level_3_file_1_copy1.md'))
vim.fn.delete(u.join_path(opening_dir, 'level_4/level_4', 'rf'))
end,
}
end)
u.on_child_window_updated(function()
local state = u.get_state()
close_triptych(function()
done {
assertions = function()
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'))
vim.fn.delete(u.join_path(opening_dir, 'level_4/level_3_file_1.md'))
end,
}
end)
end)
end)
end)
end)
end)
end):skip(),
end),

-- TODO: This once the dir pasting bug has been fixed
-- test('moves files and folders', function (done) end):skip()

-- TODO: This once the dir pasting bug has been fixed
-- test('copies files and folders', function(done) end):skip()

test('renames files and folders', function(done)
local expected_lines = {
primary = {
Expand Down
Loading

0 comments on commit 067e413

Please sign in to comment.