Meh I'll figure out submodules later
This commit is contained in:
parent
4ca9d44a90
commit
8cb281f436
352 changed files with 66107 additions and 0 deletions
13
.config/nvim/pack/tree/start/neo-tree.nvim/tests/mininit.lua
Normal file
13
.config/nvim/pack/tree/start/neo-tree.nvim/tests/mininit.lua
Normal file
|
@ -0,0 +1,13 @@
|
|||
local root_dir = vim.fs.find("neo-tree.nvim", { upward = true, limit = 1 })[1]
|
||||
assert(root_dir, "no neo-tree found")
|
||||
|
||||
package.path = ("%s;%s/?.lua;%s/?/init.lua"):format(package.path, root_dir, root_dir)
|
||||
vim.opt.packpath:prepend(root_dir .. "/.dependencies")
|
||||
|
||||
vim.opt.rtp = {
|
||||
root_dir,
|
||||
vim.env.VIMRUNTIME,
|
||||
}
|
||||
|
||||
-- need this for tests to work
|
||||
vim.cmd.source(root_dir .. "/plugin/neo-tree.lua")
|
|
@ -0,0 +1,107 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local Path = require("plenary.path")
|
||||
local u = require("tests.utils")
|
||||
local verify = require("tests.utils.verify")
|
||||
|
||||
local run_in_current_command = function(command, expected_tree_node)
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
|
||||
vim.cmd(command)
|
||||
verify.window_handle_is(winid)
|
||||
verify.buf_name_endswith(string.format("neo-tree filesystem [%s]", winid), 1000)
|
||||
if expected_tree_node then
|
||||
verify.filesystem_tree_node_is(expected_tree_node, winid)
|
||||
end
|
||||
end
|
||||
|
||||
local run_close_command = function(command)
|
||||
vim.cmd(command)
|
||||
u.wait_for(function() end, { interval = 200, timeout = 200 })
|
||||
end
|
||||
|
||||
describe("Command", function()
|
||||
local test = u.fs.init_test({
|
||||
items = {
|
||||
{
|
||||
name = "foo",
|
||||
type = "dir",
|
||||
items = {
|
||||
{
|
||||
name = "bar",
|
||||
type = "dir",
|
||||
items = {
|
||||
{ name = "baz1.txt", type = "file" },
|
||||
{ name = "baz2.txt", type = "file", id = "deepfile2" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ name = "topfile1.txt", type = "file", id = "topfile1" },
|
||||
{ name = "topfile2.txt", type = "file", id = "topfile2" },
|
||||
},
|
||||
})
|
||||
|
||||
test.setup()
|
||||
|
||||
local fs_tree = test.fs_tree
|
||||
|
||||
after_each(function()
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
describe("netrw style:", function()
|
||||
it("`:Neotree current` should show neo-tree in current window", function()
|
||||
local cmd = "Neotree current"
|
||||
run_in_current_command(cmd)
|
||||
end)
|
||||
|
||||
it(
|
||||
"`:Neotree current reveal` should show neo-tree and reveal file in current window",
|
||||
function()
|
||||
local cmd = "Neotree current reveal"
|
||||
local testfile = fs_tree.lookup["topfile1"].abspath
|
||||
u.editfile(testfile)
|
||||
run_in_current_command(cmd, testfile)
|
||||
end
|
||||
)
|
||||
|
||||
it("`:Neotree current reveal toggle` should toggle neo-tree in current window", function()
|
||||
local cmd = "Neotree current reveal toggle"
|
||||
local testfile = fs_tree.lookup["topfile1"].abspath
|
||||
u.editfile(testfile)
|
||||
local tree_winid = vim.api.nvim_get_current_win()
|
||||
|
||||
-- toggle OPEN
|
||||
run_in_current_command(cmd, testfile)
|
||||
|
||||
-- toggle CLOSE
|
||||
run_close_command(cmd)
|
||||
verify.window_handle_is(tree_winid)
|
||||
verify.buf_name_is(testfile)
|
||||
end)
|
||||
|
||||
it(
|
||||
"`:Neotree current reveal_force_cwd reveal_file=xyz` should reveal file current window if cwd is not a parent of file",
|
||||
function()
|
||||
vim.cmd("cd ~")
|
||||
local testfile = fs_tree.lookup["deepfile2"].abspath
|
||||
local cmd = "Neotree current reveal_force_cwd reveal_file=" .. testfile
|
||||
run_in_current_command(cmd, testfile)
|
||||
end
|
||||
)
|
||||
|
||||
it(
|
||||
"`:Neotree current reveal_force_cwd reveal_file=xyz` should reveal file current window if cwd is a parent of file",
|
||||
function()
|
||||
local testfile = fs_tree.lookup["deepfile2"].abspath
|
||||
local testfile_dir = Path:new(testfile):parent().filename
|
||||
vim.cmd(string.format("cd %s", testfile_dir))
|
||||
local cmd = "Neotree current reveal_force_cwd reveal_file=" .. testfile
|
||||
run_in_current_command(cmd, testfile)
|
||||
end
|
||||
)
|
||||
end)
|
||||
|
||||
test.teardown()
|
||||
end)
|
|
@ -0,0 +1,214 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local u = require("tests.utils")
|
||||
local verify = require("tests.utils.verify")
|
||||
|
||||
local run_focus_command = function(command, expected_tree_node)
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
|
||||
vim.cmd(command)
|
||||
u.wait_for_neo_tree({ interval = 10, timeout = 200 })
|
||||
--u.wait_for_neo_tree()
|
||||
verify.window_handle_is_not(winid)
|
||||
verify.buf_name_endswith("neo-tree filesystem [1]")
|
||||
if expected_tree_node then
|
||||
verify.filesystem_tree_node_is(expected_tree_node)
|
||||
end
|
||||
end
|
||||
|
||||
local run_show_command = function(command, expected_tree_node)
|
||||
local starting_winid = vim.api.nvim_get_current_win()
|
||||
local starting_bufname = vim.api.nvim_buf_get_name(0)
|
||||
local expected_num_windows = #vim.api.nvim_list_wins() + 1
|
||||
|
||||
vim.cmd(command)
|
||||
verify.eventually(500, function()
|
||||
if #vim.api.nvim_list_wins() ~= expected_num_windows then
|
||||
return false
|
||||
end
|
||||
if vim.api.nvim_get_current_win() ~= starting_winid then
|
||||
return false
|
||||
end
|
||||
if vim.api.nvim_buf_get_name(0) ~= starting_bufname then
|
||||
return false
|
||||
end
|
||||
if expected_tree_node then
|
||||
verify.filesystem_tree_node_is(expected_tree_node)
|
||||
end
|
||||
return true
|
||||
end, "Expected to see a new window without focusing it.")
|
||||
end
|
||||
|
||||
local run_close_command = function(command)
|
||||
vim.cmd(command)
|
||||
u.wait_for(function() end, { interval = 200, timeout = 200 })
|
||||
end
|
||||
|
||||
describe("Command", function()
|
||||
local test = u.fs.init_test({
|
||||
items = {
|
||||
{
|
||||
name = "foo",
|
||||
type = "dir",
|
||||
items = {
|
||||
{
|
||||
name = "bar",
|
||||
type = "dir",
|
||||
items = {
|
||||
{ name = "baz1.txt", type = "file" },
|
||||
{ name = "baz2.txt", type = "file", id = "deepfile2" },
|
||||
},
|
||||
},
|
||||
{ name = "foofile1.txt", type = "file" },
|
||||
},
|
||||
},
|
||||
{ name = "topfile1.txt", type = "file", id = "topfile1" },
|
||||
},
|
||||
})
|
||||
|
||||
test.setup()
|
||||
|
||||
local fs_tree = test.fs_tree
|
||||
|
||||
after_each(function()
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
describe("with reveal:", function()
|
||||
it("`:Neotree float reveal` should reveal the current file in the floating window", function()
|
||||
local cmd = "Neotree float reveal"
|
||||
local testfile = fs_tree.lookup["./foo/bar/baz1.txt"].abspath
|
||||
u.editfile(testfile)
|
||||
run_focus_command(cmd, testfile)
|
||||
end)
|
||||
|
||||
it("`:Neotree reveal toggle` should toggle the reveal-state of the tree", function()
|
||||
local cmd = "Neotree reveal toggle"
|
||||
local testfile = fs_tree.lookup["./foo/foofile1.txt"].abspath
|
||||
u.editfile(testfile)
|
||||
|
||||
-- toggle OPEN
|
||||
run_focus_command(cmd, testfile)
|
||||
local tree_winid = vim.api.nvim_get_current_win()
|
||||
|
||||
-- toggle CLOSE
|
||||
run_close_command(cmd)
|
||||
verify.window_handle_is_not(tree_winid)
|
||||
verify.buf_name_is(testfile)
|
||||
|
||||
-- toggle OPEN with a different file
|
||||
testfile = fs_tree.lookup["./foo/bar/baz1.txt"].abspath
|
||||
u.editfile(testfile)
|
||||
run_focus_command(cmd, testfile)
|
||||
end)
|
||||
|
||||
it(
|
||||
"`:Neotree float reveal toggle` should toggle the reveal-state of the floating window",
|
||||
function()
|
||||
local cmd = "Neotree float reveal toggle"
|
||||
local testfile = fs_tree.lookup["./foo/foofile1.txt"].abspath
|
||||
u.editfile(testfile)
|
||||
|
||||
-- toggle OPEN
|
||||
run_focus_command(cmd, testfile)
|
||||
local tree_winid = vim.api.nvim_get_current_win()
|
||||
|
||||
-- toggle CLOSE
|
||||
run_close_command("Neotree float reveal toggle")
|
||||
verify.window_handle_is_not(tree_winid)
|
||||
verify.buf_name_is(testfile)
|
||||
|
||||
-- toggle OPEN
|
||||
testfile = fs_tree.lookup["./foo/bar/baz2.txt"].abspath
|
||||
u.editfile(testfile)
|
||||
run_focus_command(cmd, testfile)
|
||||
end
|
||||
)
|
||||
|
||||
it("`:Neotree reveal` should reveal the current file in the sidebar", function()
|
||||
local cmd = "Neotree reveal"
|
||||
local testfile = fs_tree.lookup["topfile1"].abspath
|
||||
u.editfile(testfile)
|
||||
run_focus_command(cmd, testfile)
|
||||
end)
|
||||
end)
|
||||
|
||||
for _, follow_current_file in ipairs({ true, false }) do
|
||||
require("neo-tree").setup({
|
||||
filesystem = {
|
||||
follow_current_file = {
|
||||
enabled = follow_current_file,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
describe(string.format("w/ follow_current_file.enabled=%s", follow_current_file), function()
|
||||
describe("with show :", function()
|
||||
it("`:Neotree show` should show the window without focusing", function()
|
||||
local cmd = "Neotree show"
|
||||
local testfile = fs_tree.lookup["topfile1"].abspath
|
||||
u.editfile(testfile)
|
||||
run_show_command(cmd)
|
||||
end)
|
||||
|
||||
it("`:Neotree show toggle` should retain the focused node on next show", function()
|
||||
local cmd = "Neotree show toggle"
|
||||
local topfile = fs_tree.lookup["topfile1"].abspath
|
||||
local baz = fs_tree.lookup["./foo/bar/baz1.txt"].abspath
|
||||
|
||||
-- focus a sub node to see if state is retained
|
||||
u.editfile(baz)
|
||||
run_focus_command(":Neotree reveal", baz)
|
||||
local expected_tree_node = baz
|
||||
|
||||
verify.after(500, function()
|
||||
-- toggle CLOSE
|
||||
run_close_command(cmd)
|
||||
|
||||
-- toggle OPEN
|
||||
u.editfile(topfile)
|
||||
if follow_current_file then
|
||||
expected_tree_node = topfile
|
||||
end
|
||||
run_show_command(cmd, expected_tree_node)
|
||||
return true
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("with focus :", function()
|
||||
it("`:Neotree focus` should show the window and focus it", function()
|
||||
local cmd = "Neotree focus"
|
||||
local testfile = fs_tree.lookup["topfile1"].abspath
|
||||
u.editfile(testfile)
|
||||
run_focus_command(cmd)
|
||||
end)
|
||||
|
||||
it("`:Neotree focus toggle` should retain the focused node on next focus", function()
|
||||
local cmd = "Neotree focus toggle"
|
||||
local topfile = fs_tree.lookup["topfile1"].abspath
|
||||
local baz = fs_tree.lookup["./foo/bar/baz1.txt"].abspath
|
||||
|
||||
-- focus a sub node to see if state is retained
|
||||
u.editfile(baz)
|
||||
run_focus_command("Neotree reveal", baz)
|
||||
local expected_tree_node = baz
|
||||
-- toggle CLOSE
|
||||
run_close_command(cmd)
|
||||
|
||||
verify.after(500, function()
|
||||
-- toggle OPEN
|
||||
u.editfile(topfile)
|
||||
if follow_current_file then
|
||||
expected_tree_node = topfile
|
||||
end
|
||||
run_focus_command(cmd, expected_tree_node)
|
||||
return true
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
test.teardown()
|
||||
end)
|
|
@ -0,0 +1,28 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
describe("Event queue", function()
|
||||
it("should return data when handled = true", function()
|
||||
local events = require("neo-tree.events")
|
||||
events.subscribe({
|
||||
event = "test",
|
||||
handler = function()
|
||||
return { data = "first" }
|
||||
end,
|
||||
})
|
||||
events.subscribe({
|
||||
event = "test",
|
||||
handler = function()
|
||||
return { handled = true, data = "second" }
|
||||
end,
|
||||
})
|
||||
events.subscribe({
|
||||
event = "test",
|
||||
handler = function()
|
||||
return { data = "third" }
|
||||
end,
|
||||
})
|
||||
local result = events.fire_event("test") or {}
|
||||
local data = result.data
|
||||
assert.are.same("second", data)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,33 @@
|
|||
local u = require("tests.utils")
|
||||
local verify = require("tests.utils.verify")
|
||||
describe("Opening buffers in neo-tree window", function()
|
||||
-- Just make sure we start all tests in the expected state
|
||||
before_each(function()
|
||||
u.eq(1, #vim.api.nvim_list_wins())
|
||||
u.eq(1, #vim.api.nvim_list_tabpages())
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
local width = 33
|
||||
describe("should automatically redirect to other buffers", function()
|
||||
it("without changing our own width", function()
|
||||
require("neo-tree").setup({
|
||||
window = {
|
||||
width = width,
|
||||
},
|
||||
})
|
||||
vim.cmd("e test.txt")
|
||||
vim.cmd("Neotree")
|
||||
local neotree = vim.api.nvim_get_current_win()
|
||||
assert.are.equal(width, vim.api.nvim_win_get_width(neotree))
|
||||
|
||||
vim.cmd("bnext")
|
||||
verify.schedule(function()
|
||||
return assert.are.equal(width, vim.api.nvim_win_get_width(neotree))
|
||||
end, nil, "width should remain 33")
|
||||
end)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,43 @@
|
|||
local helper = require("neo-tree.setup.mapping-helper")
|
||||
describe("keymap normalization", function()
|
||||
it("passes basic tests", function()
|
||||
local tests = {
|
||||
{ "<BS>", "<bs>" },
|
||||
{ "<Backspace>", "<bs>" },
|
||||
{ "<Enter>", "<cr>" },
|
||||
{ "<C-W>", "<c-W>" },
|
||||
{ "<A-q>", "<m-q>" },
|
||||
{ "<C-Left>", "<c-left>" },
|
||||
{ "<C-Right>", "<c-right>" },
|
||||
{ "<C-Up>", "<c-up>" },
|
||||
}
|
||||
for _, test in ipairs(tests) do
|
||||
local key = helper.normalize_map_key(test[1])
|
||||
assert(key == test[2], string.format("%s != %s", key, test[2]))
|
||||
end
|
||||
end)
|
||||
it("allows for proper merging", function()
|
||||
local defaults = helper.normalize_mappings({
|
||||
["n"] = "n",
|
||||
["<Esc>"] = "escape",
|
||||
["<C-j>"] = "j",
|
||||
["<c-J>"] = "capital_j",
|
||||
["a"] = "keep_this",
|
||||
})
|
||||
local new = helper.normalize_mappings({
|
||||
["n"] = "n",
|
||||
["<ESC>"] = "escape",
|
||||
["<c-j>"] = "j",
|
||||
["b"] = "override_this",
|
||||
})
|
||||
local merged = vim.tbl_deep_extend("force", defaults, new)
|
||||
assert.are.same({
|
||||
["n"] = "n",
|
||||
["<esc>"] = "escape",
|
||||
["<c-j>"] = "j",
|
||||
["<c-J>"] = "capital_j",
|
||||
["a"] = "keep_this",
|
||||
["b"] = "override_this",
|
||||
}, merged)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,8 @@
|
|||
describe("manager state", function()
|
||||
it("can be retrieved at startup", function()
|
||||
local fs_state = require("neo-tree.sources.manager").get_state("filesystem")
|
||||
local buffers_state = require("neo-tree.sources.manager").get_state("buffers")
|
||||
assert.are_equal(type(fs_state), "table")
|
||||
assert.are_equal(type(buffers_state), "table")
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,25 @@
|
|||
local u = require("tests.utils")
|
||||
local verify = require("tests.utils.verify")
|
||||
describe("Neo-tree should be able to track previous windows", function()
|
||||
-- Just make sure we start all tests in the expected state
|
||||
before_each(function()
|
||||
u.eq(1, #vim.api.nvim_list_wins())
|
||||
u.eq(1, #vim.api.nvim_list_tabpages())
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
it("before opening", function()
|
||||
vim.cmd.vsplit()
|
||||
vim.cmd.split()
|
||||
vim.cmd.wincmd("l")
|
||||
local win = vim.api.nvim_get_current_win()
|
||||
verify.schedule(function()
|
||||
local prior_windows =
|
||||
require("neo-tree.utils").prior_windows[vim.api.nvim_get_current_tabpage()]
|
||||
return assert.are.same(win, prior_windows[#prior_windows])
|
||||
end)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,146 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local ns_id = require("neo-tree.ui.highlights").ns_id
|
||||
local u = require("tests.utils")
|
||||
|
||||
local config = {
|
||||
renderers = {
|
||||
directory = {
|
||||
{
|
||||
"container",
|
||||
content = {
|
||||
{ "indent", zindex = 10 },
|
||||
{ "icon", zindex = 10 },
|
||||
{ "name", zindex = 10 },
|
||||
{ "name", zindex = 5, align = "right" },
|
||||
},
|
||||
},
|
||||
},
|
||||
file = {
|
||||
{
|
||||
"container",
|
||||
content = {
|
||||
{ "indent", zindex = 10 },
|
||||
{ "icon", zindex = 10 },
|
||||
{ "name", zindex = 10 },
|
||||
{ "name", zindex = 20, align = "right" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
window = {
|
||||
width = 40,
|
||||
},
|
||||
}
|
||||
|
||||
local config_right = {
|
||||
renderers = {
|
||||
directory = {
|
||||
{
|
||||
"container",
|
||||
enable_character_fade = false,
|
||||
content = {
|
||||
{ "indent", zindex = 10, align = "right" },
|
||||
{ "icon", zindex = 10, align = "right" },
|
||||
{ "name", zindex = 10, align = "right" },
|
||||
},
|
||||
},
|
||||
},
|
||||
file = {
|
||||
{
|
||||
"container",
|
||||
enable_character_fade = false,
|
||||
content = {
|
||||
{ "indent", zindex = 10, align = "right" },
|
||||
{ "icon", zindex = 10, align = "right" },
|
||||
{ "name", zindex = 10, align = "right" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
window = {
|
||||
width = 40,
|
||||
},
|
||||
}
|
||||
|
||||
local test_dir = {
|
||||
items = {
|
||||
{
|
||||
name = "foo",
|
||||
type = "dir",
|
||||
items = {
|
||||
{
|
||||
name = "bar",
|
||||
type = "dir",
|
||||
items = {
|
||||
{ name = "bar1.txt", type = "file" },
|
||||
{ name = "bar2.txt", type = "file" },
|
||||
},
|
||||
},
|
||||
{ name = "foo1.lua", type = "file" },
|
||||
},
|
||||
},
|
||||
{ name = "bazbazbazbazbazbazbazbazbazbazbazbazbazbazbazbazbaz", type = "dir" },
|
||||
{ name = "1.md", type = "file" },
|
||||
},
|
||||
}
|
||||
|
||||
describe("sources/components/container", function()
|
||||
local req_switch = u.get_require_switch()
|
||||
|
||||
local test = u.fs.init_test(test_dir)
|
||||
test.setup()
|
||||
|
||||
after_each(function()
|
||||
if req_switch then
|
||||
req_switch.restore()
|
||||
end
|
||||
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
describe("should expand to width", function()
|
||||
for pow = 4, 8 do
|
||||
it(2 ^ pow, function()
|
||||
config.window.width = 2 ^ pow
|
||||
require("neo-tree").setup(config)
|
||||
vim.cmd([[Neotree focus]])
|
||||
u.wait_for(function()
|
||||
return vim.bo.filetype == "neo-tree"
|
||||
end)
|
||||
|
||||
assert.equals(vim.bo.filetype, "neo-tree")
|
||||
|
||||
local width = vim.api.nvim_win_get_width(0)
|
||||
local lines = vim.api.nvim_buf_get_lines(0, 2, -1, false)
|
||||
for _, line in ipairs(lines) do
|
||||
assert.is_true(#line >= width)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
describe("right-align should matches width", function()
|
||||
for pow = 4, 8 do
|
||||
it(2 ^ pow, function()
|
||||
config_right.window.width = 2 ^ pow
|
||||
require("neo-tree").setup(config_right)
|
||||
vim.cmd([[Neotree focus]])
|
||||
u.wait_for(function()
|
||||
return vim.bo.filetype == "neo-tree"
|
||||
end)
|
||||
|
||||
assert.equals(vim.bo.filetype, "neo-tree")
|
||||
|
||||
local width = vim.api.nvim_win_get_width(0)
|
||||
local lines = vim.api.nvim_buf_get_lines(0, 1, -1, false)
|
||||
for _, line in ipairs(lines) do
|
||||
line = vim.fn.trim(line, " ", 2)
|
||||
assert.equals(width, vim.fn.strchars(line))
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
test.teardown()
|
||||
end)
|
|
@ -0,0 +1,89 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local u = require("tests.utils")
|
||||
local verify = require("tests.utils.verify")
|
||||
|
||||
describe("Filesystem netrw hijack", function()
|
||||
after_each(function()
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
it("does not interfere with netrw when disabled", function()
|
||||
require("neo-tree").setup({
|
||||
filesystem = {
|
||||
hijack_netrw_behavior = "disabled",
|
||||
window = {
|
||||
position = "left",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.cmd("edit .")
|
||||
|
||||
assert(#vim.api.nvim_list_wins() == 1, "there should only be one window")
|
||||
|
||||
verify.after(100, function()
|
||||
local name = vim.api.nvim_buf_get_name(0)
|
||||
return name ~= "neo-tree filesystem [1]"
|
||||
end, "the buffer should not be neo-tree")
|
||||
end)
|
||||
|
||||
it("opens in sidebar when behavior is open_default", function()
|
||||
local file = "Makefile"
|
||||
vim.cmd("edit " .. file)
|
||||
|
||||
require("neo-tree").setup({
|
||||
filesystem = {
|
||||
hijack_netrw_behavior = "open_default",
|
||||
window = {
|
||||
position = "left",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
vim.cmd("edit .")
|
||||
|
||||
verify.eventually(200, function()
|
||||
return #vim.api.nvim_list_wins() == 2
|
||||
end, "there should be two windows")
|
||||
|
||||
verify.buf_name_endswith("neo-tree filesystem [1]")
|
||||
|
||||
verify.eventually(100, function()
|
||||
local expected_buf_name = "Makefile"
|
||||
local buf_at_2 = vim.api.nvim_win_get_buf(vim.fn.win_getid(2))
|
||||
local name_at_2 = vim.api.nvim_buf_get_name(buf_at_2)
|
||||
if name_at_2:sub(-#expected_buf_name) == expected_buf_name then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end, file .. " is not at window 2")
|
||||
end)
|
||||
|
||||
-- This test is flaky and usually fails in github actions but not always
|
||||
-- so I'm disabling it for now.
|
||||
-- TODO: fix this test
|
||||
--
|
||||
--it("opens in in splits when behavior is open_current", function()
|
||||
-- local file = "Makefile"
|
||||
-- vim.cmd("edit " .. file)
|
||||
|
||||
-- require("neo-tree").setup({
|
||||
-- filesystem = {
|
||||
-- hijack_netrw_behavior = "open_current",
|
||||
-- },
|
||||
-- })
|
||||
|
||||
-- assert(#vim.api.nvim_list_wins() == 1, "Test should start with one window")
|
||||
|
||||
-- vim.cmd("split .")
|
||||
|
||||
-- verify.eventually(200, function()
|
||||
-- if #vim.api.nvim_list_wins() ~= 2 then
|
||||
-- return false
|
||||
-- end
|
||||
-- return vim.bo[0].filetype == "neo-tree"
|
||||
-- end, "neotree is not in the second window")
|
||||
--end)
|
||||
end)
|
|
@ -0,0 +1,124 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local u = require("tests.utils")
|
||||
local verify = require("tests.utils.verify")
|
||||
|
||||
local manager = require("neo-tree.sources.manager")
|
||||
|
||||
local get_dirs = function(winid)
|
||||
winid = winid or vim.api.nvim_get_current_win()
|
||||
local tabnr = vim.api.nvim_tabpage_get_number(vim.api.nvim_win_get_tabpage(winid))
|
||||
local winnr = vim.api.nvim_win_get_number(winid)
|
||||
return {
|
||||
win = vim.fn.getcwd(winnr),
|
||||
tab = vim.fn.getcwd(-1, tabnr),
|
||||
global = vim.fn.getcwd(-1, -1),
|
||||
}
|
||||
end
|
||||
|
||||
local get_state_for_tab = function(tabid)
|
||||
for _, state in ipairs(manager._get_all_states()) do
|
||||
if state.tabid == tabid then
|
||||
return state
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local get_tabnr = function(tabid)
|
||||
return vim.api.nvim_tabpage_get_number(tabid or vim.api.nvim_get_current_tabpage())
|
||||
end
|
||||
|
||||
describe("Manager", function()
|
||||
local test = u.fs.init_test({
|
||||
items = {
|
||||
{
|
||||
name = "foo",
|
||||
type = "dir",
|
||||
items = {
|
||||
{ name = "foofile1.txt", type = "file" },
|
||||
},
|
||||
},
|
||||
{ name = "topfile1.txt", type = "file", id = "topfile1" },
|
||||
},
|
||||
})
|
||||
|
||||
test.setup()
|
||||
|
||||
local fs_tree = test.fs_tree
|
||||
|
||||
-- Just make sure we start all tests in the expected state
|
||||
before_each(function()
|
||||
u.eq(1, #vim.api.nvim_list_wins())
|
||||
u.eq(1, #vim.api.nvim_list_tabpages())
|
||||
vim.cmd.lcd(fs_tree.abspath)
|
||||
vim.cmd.tcd(fs_tree.abspath)
|
||||
vim.cmd.cd(fs_tree.abspath)
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
local setup_2_tabs = function()
|
||||
-- create 2 tabs
|
||||
local tab1 = vim.api.nvim_get_current_tabpage()
|
||||
local win1 = vim.api.nvim_get_current_win()
|
||||
vim.cmd.tabnew()
|
||||
local tab2 = vim.api.nvim_get_current_tabpage()
|
||||
local win2 = vim.api.nvim_get_current_win()
|
||||
u.neq(tab2, tab1)
|
||||
u.neq(win2, win1)
|
||||
|
||||
-- set different directories
|
||||
vim.api.nvim_set_current_tabpage(tab2)
|
||||
local base_dir = vim.fn.getcwd()
|
||||
vim.cmd.tcd("foo")
|
||||
local new_dir = vim.fn.getcwd()
|
||||
|
||||
-- open neo-tree
|
||||
vim.api.nvim_set_current_tabpage(tab1)
|
||||
vim.cmd.Neotree("show")
|
||||
vim.api.nvim_set_current_tabpage(tab2)
|
||||
vim.cmd.Neotree("show")
|
||||
|
||||
return {
|
||||
tab1 = tab1,
|
||||
tab2 = tab2,
|
||||
win1 = win1,
|
||||
win2 = win2,
|
||||
tab1_dir = base_dir,
|
||||
tab2_dir = new_dir,
|
||||
}
|
||||
end
|
||||
|
||||
it("should respect changed tab cwd", function()
|
||||
local ctx = setup_2_tabs()
|
||||
|
||||
local state1 = get_state_for_tab(ctx.tab1)
|
||||
local state2 = get_state_for_tab(ctx.tab2)
|
||||
u.eq(ctx.tab1_dir, manager.get_cwd(state1))
|
||||
u.eq(ctx.tab2_dir, manager.get_cwd(state2))
|
||||
end)
|
||||
|
||||
it("should have correct tab cwd after tabs order is changed", function()
|
||||
local ctx = setup_2_tabs()
|
||||
|
||||
-- tab numbers should be the same as ids
|
||||
u.eq(1, get_tabnr(ctx.tab1))
|
||||
u.eq(2, get_tabnr(ctx.tab2))
|
||||
|
||||
-- swap tabs
|
||||
vim.cmd.tabfirst()
|
||||
vim.cmd.tabmove("+1")
|
||||
|
||||
-- make sure tabs have been swapped
|
||||
u.eq(2, get_tabnr(ctx.tab1))
|
||||
u.eq(1, get_tabnr(ctx.tab2))
|
||||
|
||||
-- verify that tab dirs are the same as nvim tab cwd
|
||||
local state1 = get_state_for_tab(ctx.tab1)
|
||||
local state2 = get_state_for_tab(ctx.tab2)
|
||||
u.eq(get_dirs(ctx.win1).tab, manager.get_cwd(state1))
|
||||
u.eq(get_dirs(ctx.win2).tab, manager.get_cwd(state2))
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,51 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
|
||||
---Return all sources inside "lua/neo-tree/sources"
|
||||
---@return string[] # name of sources found
|
||||
local function find_all_sources()
|
||||
local base_dir = "lua/neo-tree/sources"
|
||||
local result = {}
|
||||
local fd = uv.fs_scandir(base_dir)
|
||||
while fd do
|
||||
local name, typ = uv.fs_scandir_next(fd)
|
||||
if not name then
|
||||
break
|
||||
end
|
||||
if typ == "directory" then
|
||||
local ok, mod = pcall(require, "neo-tree.sources." .. name)
|
||||
if ok and mod.name then
|
||||
result[#result + 1] = name
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
describe("sources.navigate(...: #<nparams>)", function()
|
||||
it("neo-tree.sources.filesystem.navigate exists", function()
|
||||
local ok, mod = pcall(require, "neo-tree.sources.filesystem")
|
||||
assert.is_true(ok)
|
||||
assert.not_nil(mod.navigate)
|
||||
end)
|
||||
local filesystem_navigate_nparams =
|
||||
debug.getinfo(require("neo-tree.sources.filesystem").navigate).nparams
|
||||
it("neo-tree.sources.filesystem.navigate is a func and has args", function()
|
||||
assert.not_nil(filesystem_navigate_nparams)
|
||||
assert.is_true(filesystem_navigate_nparams > 0)
|
||||
end)
|
||||
for _, source in ipairs(find_all_sources()) do
|
||||
describe(string.format("Test: %s.navigate", source), function()
|
||||
it(source .. ".navigate is able to require and exists", function()
|
||||
local ok, mod = pcall(require, "neo-tree.sources." .. source)
|
||||
assert.is_true(ok)
|
||||
assert.not_nil(mod.navigate)
|
||||
end)
|
||||
it(source .. ".navigate has same num of args as filesystem", function()
|
||||
local nparams = debug.getinfo(require("neo-tree.sources." .. source).navigate).nparams
|
||||
assert.are.equal(filesystem_navigate_nparams, nparams)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,227 @@
|
|||
pcall(require, "luacov")
|
||||
|
||||
local ns_id = require("neo-tree.ui.highlights").ns_id
|
||||
local u = require("tests.utils")
|
||||
|
||||
describe("ui/icons", function()
|
||||
local req_switch = u.get_require_switch()
|
||||
|
||||
local test = u.fs.init_test({
|
||||
items = {
|
||||
{
|
||||
name = "foo",
|
||||
type = "dir",
|
||||
items = {
|
||||
{
|
||||
name = "bar",
|
||||
type = "dir",
|
||||
items = {
|
||||
{ name = "bar1.txt", type = "file" },
|
||||
{ name = "bar2.txt", type = "file" },
|
||||
},
|
||||
},
|
||||
{ name = "foo1.lua", type = "file" },
|
||||
},
|
||||
},
|
||||
{ name = "baz", type = "dir" },
|
||||
{ name = "1.md", type = "file" },
|
||||
},
|
||||
})
|
||||
|
||||
test.setup()
|
||||
|
||||
local fs_tree = test.fs_tree
|
||||
|
||||
after_each(function()
|
||||
if req_switch then
|
||||
req_switch.restore()
|
||||
end
|
||||
|
||||
u.clear_environment()
|
||||
end)
|
||||
|
||||
describe("w/ default_config", function()
|
||||
before_each(function()
|
||||
require("neo-tree").setup({})
|
||||
end)
|
||||
|
||||
it("works w/o nvim-web-devicons", function()
|
||||
req_switch.disable_package("nvim-web-devicons")
|
||||
|
||||
vim.cmd([[:Neotree focus]])
|
||||
u.wait_for_neo_tree()
|
||||
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
local bufnr = vim.api.nvim_win_get_buf(winid)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
string.format(" %s", fs_tree.abspath):sub(1, 42),
|
||||
" baz",
|
||||
" foo",
|
||||
" * 1.md",
|
||||
})
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 2, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 3, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.wait(100)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
string.format(" %s", fs_tree.abspath):sub(1, 42),
|
||||
" baz",
|
||||
" foo",
|
||||
" │ bar",
|
||||
" └ * foo1.lua",
|
||||
" * 1.md",
|
||||
})
|
||||
|
||||
u.assert_highlight(bufnr, ns_id, 1, " ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 2, " ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 4, " ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 5, "* ", "NeoTreeFileIcon")
|
||||
end)
|
||||
|
||||
it("works w/ nvim-web-devicons", function()
|
||||
vim.cmd([[:Neotree focus]])
|
||||
u.wait_for_neo_tree()
|
||||
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
local bufnr = vim.api.nvim_win_get_buf(winid)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
vim.fn.strcharpart(string.format(" %s", fs_tree.abspath), 0, 40),
|
||||
" baz",
|
||||
" foo",
|
||||
" 1.md",
|
||||
})
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 2, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 3, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.wait(100)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
vim.fn.strcharpart(string.format(" %s", fs_tree.abspath), 0, 40),
|
||||
" baz",
|
||||
" foo",
|
||||
" │ bar",
|
||||
" └ foo1.lua",
|
||||
" 1.md",
|
||||
})
|
||||
|
||||
u.assert_highlight(bufnr, ns_id, 1, " ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 2, " ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 4, " ", "NeoTreeDirectoryIcon")
|
||||
|
||||
local extmarks = u.get_text_extmarks(bufnr, ns_id, 5, " ")
|
||||
u.eq(#extmarks, 1)
|
||||
u.neq(extmarks[1][4].hl_group, "NeoTreeFileIcon")
|
||||
end)
|
||||
end)
|
||||
|
||||
describe("custom config", function()
|
||||
local config
|
||||
before_each(function()
|
||||
config = {
|
||||
default_component_configs = {
|
||||
icon = {
|
||||
folder_closed = "c",
|
||||
folder_open = "o",
|
||||
folder_empty = "e",
|
||||
default = "f",
|
||||
highlight = "TestNeoTreeFileIcon",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require("neo-tree").setup(config)
|
||||
end)
|
||||
|
||||
it("works w/o nvim-web-devicons", function()
|
||||
req_switch.disable_package("nvim-web-devicons")
|
||||
|
||||
vim.cmd([[:Neotree focus]])
|
||||
u.wait_for_neo_tree()
|
||||
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
local bufnr = vim.api.nvim_win_get_buf(winid)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
string.format(" o %s", fs_tree.abspath):sub(1, 40),
|
||||
" c baz",
|
||||
" c foo",
|
||||
" f 1.md",
|
||||
})
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 2, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 3, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.wait(100)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
string.format(" o %s", fs_tree.abspath):sub(1, 40),
|
||||
" e baz",
|
||||
" o foo",
|
||||
" │ c bar",
|
||||
" └ f foo1.lua",
|
||||
" f 1.md",
|
||||
})
|
||||
|
||||
u.assert_highlight(bufnr, ns_id, 1, "o ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 2, "e ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 4, "c ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 5, "f ", config.default_component_configs.icon.highlight)
|
||||
end)
|
||||
|
||||
it("works w/ nvim-web-devicons", function()
|
||||
vim.cmd([[:Neotree focus]])
|
||||
u.wait_for_neo_tree()
|
||||
|
||||
local winid = vim.api.nvim_get_current_win()
|
||||
local bufnr = vim.api.nvim_win_get_buf(winid)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
vim.fn.strcharpart(string.format(" o %s", fs_tree.abspath), 0, 40),
|
||||
" c baz",
|
||||
" c foo",
|
||||
" 1.md",
|
||||
})
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 2, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.api.nvim_win_set_cursor(winid, { 3, 0 })
|
||||
u.feedkeys("<CR>")
|
||||
|
||||
vim.wait(100)
|
||||
|
||||
u.assert_buf_lines(bufnr, {
|
||||
vim.fn.strcharpart(string.format(" o %s", fs_tree.abspath), 0, 40),
|
||||
" e baz",
|
||||
" o foo",
|
||||
" │ c bar",
|
||||
" └ foo1.lua",
|
||||
" 1.md",
|
||||
})
|
||||
|
||||
u.assert_highlight(bufnr, ns_id, 1, "o ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 2, "e ", "NeoTreeDirectoryIcon")
|
||||
u.assert_highlight(bufnr, ns_id, 4, "c ", "NeoTreeDirectoryIcon")
|
||||
|
||||
local extmarks = u.get_text_extmarks(bufnr, ns_id, 5, " ")
|
||||
u.eq(#extmarks, 1)
|
||||
u.neq(extmarks[1][4].hl_group, config.default_component_configs.icon.highlight)
|
||||
end)
|
||||
end)
|
||||
|
||||
test.teardown()
|
||||
end)
|
|
@ -0,0 +1,66 @@
|
|||
pcall(require, "luacov")
|
||||
local utils = require("neo-tree.utils")
|
||||
|
||||
describe("is_subpath", function()
|
||||
local common_tests = function()
|
||||
-- Relative paths
|
||||
assert.are.same(true, utils.is_subpath("a", "a/subpath"))
|
||||
assert.are.same(false, utils.is_subpath("a", "b/c"))
|
||||
assert.are.same(false, utils.is_subpath("a", "b"))
|
||||
end
|
||||
it("should work with unix paths", function()
|
||||
local old = utils.is_windows
|
||||
utils.is_windows = false
|
||||
common_tests()
|
||||
assert.are.same(true, utils.is_subpath("/a", "/a/subpath"))
|
||||
assert.are.same(false, utils.is_subpath("/a", "/b/c"))
|
||||
|
||||
-- Edge cases
|
||||
assert.are.same(false, utils.is_subpath("", ""))
|
||||
assert.are.same(true, utils.is_subpath("/", "/"))
|
||||
|
||||
-- Paths with trailing slashes
|
||||
assert.are.same(true, utils.is_subpath("/a/", "/a/subpath"))
|
||||
assert.are.same(true, utils.is_subpath("/a/", "/a/subpath/"))
|
||||
assert.are.same(true, utils.is_subpath("/a", "/a/subpath"))
|
||||
assert.are.same(true, utils.is_subpath("/a", "/a/subpath/"))
|
||||
|
||||
-- Paths with different casing
|
||||
assert.are.same(true, utils.is_subpath("/TeSt", "/TeSt/subpath"))
|
||||
assert.are.same(false, utils.is_subpath("/A", "/a/subpath"))
|
||||
assert.are.same(false, utils.is_subpath("/A", "/a/subpath"))
|
||||
utils.is_windows = old
|
||||
end)
|
||||
it("should work on windows paths", function()
|
||||
local old = utils.is_windows
|
||||
utils.is_windows = true
|
||||
common_tests()
|
||||
assert.are.same(true, utils.is_subpath("C:", "C:"))
|
||||
assert.are.same(false, utils.is_subpath("C:", "D:"))
|
||||
assert.are.same(true, utils.is_subpath("C:/A", [[C:\A]]))
|
||||
|
||||
-- Test Windows paths with backslashes
|
||||
assert.are.same(true, utils.is_subpath([[C:\Users\user]], [[C:\Users\user\Documents]]))
|
||||
assert.are.same(false, utils.is_subpath([[C:\Users\user]], [[D:\Users\user]]))
|
||||
assert.are.same(false, utils.is_subpath([[C:\Users\user]], [[C:\Users\usera]]))
|
||||
|
||||
-- Test Windows paths with forward slashes
|
||||
assert.are.same(true, utils.is_subpath("C:/Users/user", "C:/Users/user/Documents"))
|
||||
assert.are.same(false, utils.is_subpath("C:/Users/user", "D:/Users/user"))
|
||||
assert.are.same(false, utils.is_subpath("C:/Users/user", "C:/Users/usera"))
|
||||
|
||||
-- Test Windows paths with drive letters
|
||||
assert.are.same(true, utils.is_subpath("C:", "C:/Users/user"))
|
||||
assert.are.same(false, utils.is_subpath("C:", "D:/Users/user"))
|
||||
|
||||
-- Test Windows paths with UNC paths
|
||||
assert.are.same(true, utils.is_subpath([[\\server\share]], [[\\server\share\folder]]))
|
||||
assert.are.same(false, utils.is_subpath([[\\server\share]], [[\\server2\share]]))
|
||||
|
||||
-- Test Windows paths with trailing backslashes
|
||||
assert.are.same(true, utils.is_subpath([[C:\Users\user\]], [[C:\Users\user\Documents]]))
|
||||
assert.are.same(true, utils.is_subpath("C:/Users/user/", "C:/Users/user/Documents"))
|
||||
|
||||
utils.is_windows = old
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,94 @@
|
|||
local Path = require("plenary.path")
|
||||
|
||||
local fs = {}
|
||||
|
||||
function fs.create_temp_dir()
|
||||
-- Resolve for two reasons.
|
||||
-- 1. Follow any symlinks which make comparing paths fail. (on macOS, TMPDIR can be under /var which is symlinked to
|
||||
-- /private/var)
|
||||
-- 2. Remove any double separators (on macOS TMPDIR can end in a trailing / which absolute doesn't remove, this should
|
||||
-- be coverted by https://github.com/nvim-lua/plenary.nvim/issues/330).
|
||||
local temp_dir = vim.fn.resolve(
|
||||
Path:new(
|
||||
vim.fn.fnamemodify(vim.fn.tempname(), ":h"),
|
||||
string.format("neo-tree-test-%s", vim.fn.rand())
|
||||
):absolute()
|
||||
)
|
||||
vim.fn.mkdir(temp_dir, "p")
|
||||
return temp_dir
|
||||
end
|
||||
|
||||
function fs.create_dir(path)
|
||||
local abspath = Path:new(path):absolute()
|
||||
vim.fn.mkdir(abspath, "p")
|
||||
end
|
||||
|
||||
function fs.remove_dir(dir, recursive)
|
||||
if vim.fn.isdirectory(dir) == 1 then
|
||||
return vim.fn.delete(dir, recursive and "rf" or "d") == 0
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function fs.write_file(path, content)
|
||||
local abspath = Path:new(path):absolute()
|
||||
fs.create_dir(vim.fn.fnamemodify(abspath, ":h"))
|
||||
vim.fn.writefile(content or {}, abspath)
|
||||
end
|
||||
|
||||
function fs.create_fs_tree(fs_tree)
|
||||
local function create_items(items, basedir, relative_root_path)
|
||||
relative_root_path = relative_root_path or "."
|
||||
|
||||
for _, item in ipairs(items) do
|
||||
local relative_path = relative_root_path .. "/" .. item.name
|
||||
|
||||
-- create lookups
|
||||
fs_tree.lookup[relative_path] = item
|
||||
if item.id then
|
||||
fs_tree.lookup[item.id] = item
|
||||
end
|
||||
|
||||
-- create actual files and directories
|
||||
if item.type == "dir" then
|
||||
item.abspath = Path:new(basedir, item.name):absolute()
|
||||
fs.create_dir(item.abspath)
|
||||
if item.items then
|
||||
create_items(item.items, item.abspath, relative_path)
|
||||
end
|
||||
elseif item.type == "file" then
|
||||
item.abspath = Path:new(basedir, item.name):absolute()
|
||||
fs.write_file(item.abspath)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
create_items(fs_tree.items, fs_tree.abspath)
|
||||
|
||||
return fs_tree
|
||||
end
|
||||
|
||||
function fs.init_test(fs_tree)
|
||||
fs_tree.lookup = {}
|
||||
if not fs_tree.abspath then
|
||||
fs_tree.abspath = fs.create_temp_dir()
|
||||
end
|
||||
|
||||
local function setup()
|
||||
fs.remove_dir(fs_tree.abspath, true)
|
||||
fs.create_fs_tree(fs_tree)
|
||||
vim.cmd("tcd " .. fs_tree.abspath)
|
||||
end
|
||||
|
||||
local function teardown()
|
||||
fs.remove_dir(fs_tree.abspath, true)
|
||||
end
|
||||
|
||||
return {
|
||||
fs_tree = fs_tree,
|
||||
setup = setup,
|
||||
teardown = teardown,
|
||||
}
|
||||
end
|
||||
|
||||
return fs
|
191
.config/nvim/pack/tree/start/neo-tree.nvim/tests/utils/init.lua
Normal file
191
.config/nvim/pack/tree/start/neo-tree.nvim/tests/utils/init.lua
Normal file
|
@ -0,0 +1,191 @@
|
|||
local mod = {
|
||||
fs = require("tests.utils.fs"),
|
||||
}
|
||||
|
||||
function mod.clear_environment()
|
||||
-- Create fresh window
|
||||
vim.cmd("top new | wincmd o")
|
||||
local keepbufnr = vim.api.nvim_get_current_buf()
|
||||
-- Clear ALL neo-tree state
|
||||
require("neo-tree.sources.manager")._clear_state()
|
||||
-- Cleanup any remaining buffers
|
||||
for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if bufnr ~= keepbufnr then
|
||||
vim.api.nvim_buf_delete(bufnr, { force = true })
|
||||
end
|
||||
end
|
||||
assert(#vim.api.nvim_tabpage_list_wins(0) == 1, "Failed to properly clear tab")
|
||||
assert(#vim.api.nvim_list_bufs() == 1, "Failed to properly clear buffers")
|
||||
end
|
||||
|
||||
mod.editfile = function(testfile)
|
||||
vim.cmd("e " .. testfile)
|
||||
assert.are.same(
|
||||
vim.fn.fnamemodify(vim.api.nvim_buf_get_name(0), ":p"),
|
||||
vim.fn.fnamemodify(testfile, ":p")
|
||||
)
|
||||
end
|
||||
|
||||
function mod.eq(...)
|
||||
return assert.are.same(...)
|
||||
end
|
||||
|
||||
function mod.neq(...)
|
||||
return assert["not"].are.same(...)
|
||||
end
|
||||
|
||||
---@param keys string
|
||||
---@param mode? string
|
||||
function mod.feedkeys(keys, mode)
|
||||
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(keys, true, false, true), mode or "x", true)
|
||||
end
|
||||
|
||||
---@param tbl table
|
||||
---@param keys string[]
|
||||
function mod.tbl_pick(tbl, keys)
|
||||
if not keys or #keys == 0 then
|
||||
return tbl
|
||||
end
|
||||
|
||||
local new_tbl = {}
|
||||
for _, key in ipairs(keys) do
|
||||
new_tbl[key] = tbl[key]
|
||||
end
|
||||
return new_tbl
|
||||
end
|
||||
|
||||
local orig_require = _G.require
|
||||
-- can be used to enable/disable package
|
||||
-- for specific tests
|
||||
function mod.get_require_switch()
|
||||
local disabled_packages = {}
|
||||
|
||||
local function fake_require(name)
|
||||
if vim.tbl_contains(disabled_packages, name) then
|
||||
return error("test: package disabled")
|
||||
end
|
||||
|
||||
return orig_require(name)
|
||||
end
|
||||
|
||||
return {
|
||||
disable_package = function(name)
|
||||
_G.require = fake_require
|
||||
package.loaded[name] = nil
|
||||
table.insert(disabled_packages, name)
|
||||
end,
|
||||
enable_package = function(name)
|
||||
_G.require = fake_require
|
||||
disabled_packages = vim.tbl_filter(function(package_name)
|
||||
return package_name ~= name
|
||||
end, disabled_packages)
|
||||
end,
|
||||
restore = function()
|
||||
disabled_packages = {}
|
||||
_G.require = orig_require
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
---@param bufnr number
|
||||
---@param lines string[]
|
||||
---@param linenr_start? integer (1-indexed)
|
||||
---@param linenr_end? integer (1-indexed, inclusive)
|
||||
function mod.assert_buf_lines(bufnr, lines, linenr_start, linenr_end)
|
||||
mod.eq(
|
||||
lines,
|
||||
vim.api.nvim_buf_get_lines(
|
||||
bufnr,
|
||||
linenr_start and linenr_start - 1 or 0,
|
||||
linenr_end or -1,
|
||||
false
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
---@param bufnr number
|
||||
---@param ns_id integer
|
||||
---@param linenr integer (1-indexed)
|
||||
---@param byte_start? integer (0-indexed)
|
||||
---@param byte_end? integer (0-indexed, inclusive)
|
||||
function mod.get_line_extmarks(bufnr, ns_id, linenr, byte_start, byte_end)
|
||||
return vim.api.nvim_buf_get_extmarks(
|
||||
bufnr,
|
||||
ns_id,
|
||||
{ linenr - 1, byte_start or 0 },
|
||||
{ linenr - 1, byte_end and byte_end + 1 or -1 },
|
||||
{ details = true }
|
||||
)
|
||||
end
|
||||
|
||||
---@param bufnr number
|
||||
---@param ns_id integer
|
||||
---@param linenr integer (1-indexed)
|
||||
---@param text string
|
||||
---@return table[]
|
||||
---@return { byte_start: integer, byte_end: integer } info (byte range: 0-indexed, inclusive)
|
||||
function mod.get_text_extmarks(bufnr, ns_id, linenr, text)
|
||||
local line = vim.api.nvim_buf_get_lines(bufnr, linenr - 1, linenr, false)[1]
|
||||
|
||||
local byte_start = string.find(line, text) -- 1-indexed
|
||||
byte_start = byte_start - 1 -- 0-indexed
|
||||
local byte_end = byte_start + #text - 1 -- inclusive
|
||||
|
||||
local extmarks = vim.api.nvim_buf_get_extmarks(
|
||||
bufnr,
|
||||
ns_id,
|
||||
{ linenr - 1, byte_start },
|
||||
{ linenr - 1, byte_end },
|
||||
{ details = true }
|
||||
)
|
||||
|
||||
return extmarks, { byte_start = byte_start, byte_end = byte_end }
|
||||
end
|
||||
|
||||
---@param extmark table
|
||||
---@param linenr number (1-indexed)
|
||||
---@param text string
|
||||
---@param hl_group string
|
||||
function mod.assert_extmark(extmark, linenr, text, hl_group)
|
||||
mod.eq(extmark[2], linenr - 1)
|
||||
|
||||
if text then
|
||||
local start_col = extmark[3]
|
||||
mod.eq(extmark[4].end_col - start_col, #text)
|
||||
end
|
||||
|
||||
mod.eq(mod.tbl_pick(extmark[4], { "end_row", "hl_group" }), {
|
||||
end_row = linenr - 1,
|
||||
hl_group = hl_group,
|
||||
})
|
||||
end
|
||||
|
||||
---@param bufnr number
|
||||
---@param ns_id integer
|
||||
---@param linenr integer (1-indexed)
|
||||
---@param text string
|
||||
---@param hl_group string
|
||||
function mod.assert_highlight(bufnr, ns_id, linenr, text, hl_group)
|
||||
local extmarks, info = mod.get_text_extmarks(bufnr, ns_id, linenr, text)
|
||||
|
||||
mod.eq(#extmarks, 1)
|
||||
mod.eq(extmarks[1][3], info.byte_start)
|
||||
mod.assert_extmark(extmarks[1], linenr, text, hl_group)
|
||||
end
|
||||
|
||||
---@param callback fun(): boolean
|
||||
---@param options? { interval?: integer, timeout?: integer }
|
||||
function mod.wait_for(callback, options)
|
||||
options = options or {}
|
||||
vim.wait(options.timeout or 1000, callback, options.interval or 100)
|
||||
end
|
||||
|
||||
---@param options? { interval?: integer, timeout?: integer }
|
||||
function mod.wait_for_neo_tree(options)
|
||||
local verify = require("tests.utils.verify")
|
||||
mod.wait_for(function()
|
||||
return verify.get_state() ~= nil
|
||||
end, options)
|
||||
end
|
||||
|
||||
return mod
|
|
@ -0,0 +1,145 @@
|
|||
local verify = {}
|
||||
|
||||
verify.eventually = function(timeout, assertfunc, failmsg, ...)
|
||||
local success, args = false, { ... }
|
||||
vim.wait(timeout or 1000, function()
|
||||
success = assertfunc(unpack(args))
|
||||
return success
|
||||
end)
|
||||
assert(success, failmsg)
|
||||
end
|
||||
|
||||
local id = 0
|
||||
---Waits until the next vim.schedule before running assertfunc
|
||||
verify.schedule = function(assertfunc, timeout, failmsg)
|
||||
id = id + 1
|
||||
local scheduled_func_ran = false
|
||||
local success = false
|
||||
local args
|
||||
vim.schedule(function()
|
||||
args = { assertfunc() }
|
||||
success = args[1]
|
||||
scheduled_func_ran = true
|
||||
end)
|
||||
local notimeout, errcode = vim.wait(timeout or 1000, function()
|
||||
return scheduled_func_ran
|
||||
end)
|
||||
assert(success, failmsg)
|
||||
end
|
||||
|
||||
verify.after = function(timeout, assertfunc, failmsg)
|
||||
vim.wait(timeout, function()
|
||||
return false
|
||||
end)
|
||||
assert(assertfunc(), failmsg)
|
||||
end
|
||||
|
||||
verify.bufnr_is = function(bufnr, timeout)
|
||||
verify.eventually(timeout or 500, function()
|
||||
return bufnr == vim.api.nvim_get_current_buf()
|
||||
end, string.format("Current buffer is expected to be '%s' but is not", bufnr))
|
||||
end
|
||||
|
||||
verify.bufnr_is_not = function(bufnr, timeout)
|
||||
verify.eventually(timeout or 500, function()
|
||||
return bufnr ~= vim.api.nvim_get_current_buf()
|
||||
end, string.format("Current buffer is '%s' when expected to not be", bufnr))
|
||||
end
|
||||
|
||||
verify.buf_name_endswith = function(buf_name, timeout)
|
||||
verify.eventually(
|
||||
timeout or 500,
|
||||
function()
|
||||
if buf_name == "" then
|
||||
return true
|
||||
end
|
||||
local n = vim.api.nvim_buf_get_name(0)
|
||||
if n:sub(-#buf_name) == buf_name then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end,
|
||||
string.format("Current buffer name is expected to be end with '%s' but it does not", buf_name)
|
||||
)
|
||||
end
|
||||
|
||||
verify.buf_name_is = function(buf_name, timeout)
|
||||
verify.eventually(timeout or 500, function()
|
||||
return buf_name == vim.api.nvim_buf_get_name(0)
|
||||
end, string.format("Current buffer name is expected to be '%s' but is not", buf_name))
|
||||
end
|
||||
|
||||
verify.tree_focused = function(timeout)
|
||||
verify.eventually(timeout or 1000, function()
|
||||
if not verify.get_state() then
|
||||
return false
|
||||
end
|
||||
return vim.bo[0].filetype == "neo-tree"
|
||||
end, "Current buffer is not a 'neo-tree' filetype")
|
||||
end
|
||||
|
||||
verify.get_state = function(source_name, winid)
|
||||
if source_name == nil then
|
||||
local success
|
||||
success, source_name = pcall(vim.api.nvim_buf_get_var, 0, "neo_tree_source")
|
||||
if not success then
|
||||
return nil
|
||||
end
|
||||
end
|
||||
local state = require("neo-tree.sources.manager").get_state(source_name, nil, winid)
|
||||
if not state.tree then
|
||||
return nil
|
||||
end
|
||||
if not state._ready then
|
||||
return nil
|
||||
end
|
||||
return state
|
||||
end
|
||||
|
||||
verify.tree_node_is = function(source_name, expected_node_id, winid, timeout)
|
||||
verify.eventually(timeout or 500, function()
|
||||
local state = verify.get_state(source_name, winid)
|
||||
if not state then
|
||||
return false
|
||||
end
|
||||
local success, node = pcall(state.tree.get_node, state.tree)
|
||||
if not success then
|
||||
return false
|
||||
end
|
||||
if not node then
|
||||
return false
|
||||
end
|
||||
local node_id = node:get_id()
|
||||
if node_id == expected_node_id then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end, string.format("Tree node '%s' not focused", expected_node_id))
|
||||
end
|
||||
|
||||
verify.filesystem_tree_node_is = function(expected_node_id, winid, timeout)
|
||||
verify.tree_node_is("filesystem", expected_node_id, winid, timeout)
|
||||
end
|
||||
|
||||
verify.buffers_tree_node_is = function(expected_node_id, winid, timeout)
|
||||
verify.tree_node_is("buffers", expected_node_id, winid, timeout)
|
||||
end
|
||||
|
||||
verify.git_status_tree_node_is = function(expected_node_id, winid, timeout)
|
||||
verify.tree_node_is("git_status", expected_node_id, winid, timeout)
|
||||
end
|
||||
|
||||
verify.window_handle_is = function(winid, timeout)
|
||||
verify.eventually(timeout or 500, function()
|
||||
return winid == vim.api.nvim_get_current_win()
|
||||
end, string.format("Current window handle is expected to be '%s' but is not", winid))
|
||||
end
|
||||
|
||||
verify.window_handle_is_not = function(winid, timeout)
|
||||
verify.eventually(timeout or 500, function()
|
||||
return winid ~= vim.api.nvim_get_current_win()
|
||||
end, string.format("Current window handle is not expected to be '%s' but it is", winid))
|
||||
end
|
||||
|
||||
return verify
|
Loading…
Add table
Add a link
Reference in a new issue