mirror of
https://github.com/windwp/nvim-ts-autotag.git
synced 2024-12-28 07:19:16 -06:00
test: overhaul test setup and make
commands
This commit is contained in:
parent
802c28e08b
commit
df93be4d2e
1
.gitignore
vendored
1
.gitignore
vendored
@ -0,0 +1 @@
|
||||
tests/.deps
|
8
Makefile
8
Makefile
@ -1,2 +1,8 @@
|
||||
clean:
|
||||
nvim --headless --clean -n -c "lua vim.fn.delete('./tests/.deps', 'rf')" +q
|
||||
test:
|
||||
nvim --headless --noplugin -u tests/minimal.vim -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal.vim'}"
|
||||
nvim --headless --clean -u tests/test.lua "$(FILE)"
|
||||
lint:
|
||||
stylua --check lua/ tests/
|
||||
format:
|
||||
stylua lua/ tests/
|
||||
|
@ -16,6 +16,8 @@ function M.init()
|
||||
end
|
||||
end
|
||||
|
||||
function M.ensure_ts_parsers_installed() end
|
||||
|
||||
function M.setup(opts)
|
||||
internal.setup(opts)
|
||||
vim.cmd([[augroup nvim_ts_xmltag]])
|
||||
|
6
tests/.luarc.json
Normal file
6
tests/.luarc.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"diagnostics.globals": [
|
||||
"it",
|
||||
"describe"
|
||||
]
|
||||
}
|
111
tests/minimal_init.lua
Normal file
111
tests/minimal_init.lua
Normal file
@ -0,0 +1,111 @@
|
||||
local M = {}
|
||||
|
||||
local utils = require("tests.utils.utils")
|
||||
local root = utils.paths.Root:push(".deps/")
|
||||
|
||||
---@class MinPlugin A plugin to download and register on the package path
|
||||
---@alias PluginName string The plugin name, will be used as part of the git clone destination
|
||||
---@alias PluginCloneInfo string | string[] The git url a plugin located at or a table of arguments to be passed to `git clone`
|
||||
---@alias MinPlugins table<PluginName, PluginCloneInfo>
|
||||
|
||||
---Downloads a plugin from a given url and registers it on the 'runtimepath'
|
||||
---@param plugin_name PluginName
|
||||
---@param plugin_clone_args PluginCloneInfo
|
||||
function M.load_plugin(plugin_name, plugin_clone_args)
|
||||
local package_root = root:push("plugins/")
|
||||
local install_destination = package_root:push(plugin_name):get()
|
||||
|
||||
vim.opt.runtimepath:append(install_destination)
|
||||
|
||||
if not vim.loop.fs_stat(package_root:get()) then
|
||||
vim.fn.mkdir(package_root:get(), "p")
|
||||
end
|
||||
|
||||
-- If the plugin install path already exists, we don't need to clone it again.
|
||||
if not vim.loop.fs_stat(install_destination) then
|
||||
print(string.format("[LOAD PLUGIN] Downloading plugin '%s' to '%s'", plugin_name, install_destination))
|
||||
if type(plugin_clone_args) == "table" then
|
||||
plugin_clone_args = table.concat(plugin_clone_args, " ")
|
||||
end
|
||||
vim.fn.system({
|
||||
"git",
|
||||
"clone",
|
||||
"--depth=1",
|
||||
plugin_clone_args,
|
||||
install_destination,
|
||||
})
|
||||
if vim.v.shell_error > 0 then
|
||||
error(
|
||||
string.format("[LOAD PLUGIN] Failed to clone plugin: '%s' to '%s'!", plugin_name, install_destination),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
end
|
||||
end
|
||||
print(("[LOAD PLUGIN] Loaded plugin '%s'"):format(plugin_name))
|
||||
end
|
||||
|
||||
---Do the initial setup. Downloads plugins, ensures the minimal init does not pollute the filesystem by keeping
|
||||
---everything self contained to the CWD of the minimal init file. Run prior to running tests, reproducing issues, etc.
|
||||
---@param plugins? MinPlugins
|
||||
function M.setup(plugins)
|
||||
print("[SETUP] Setting up minimal init")
|
||||
|
||||
-- Instead of disabling swap and a bunch of other stuff, we override default xdg locations for
|
||||
-- Neovim so our test client is as close to a normal client in terms of options as possible
|
||||
local xdg_root = root:push("xdg")
|
||||
local std_paths = {
|
||||
"cache",
|
||||
"data",
|
||||
"config",
|
||||
"state",
|
||||
}
|
||||
for _, std_path in pairs(std_paths) do
|
||||
local xdg_str = "XDG_" .. std_path:upper() .. "_HOME"
|
||||
local xdg_path = xdg_root:push(std_path):get()
|
||||
print(("[SETUP] Set vim.env.%-3s -> %s"):format(xdg_str, xdg_path))
|
||||
vim.env[xdg_str] = xdg_path
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
vim.fn.mkdir(vim.fn.stdpath(std_path), "p")
|
||||
end
|
||||
|
||||
-- Ignore cleanups if specified in the environment
|
||||
-- NOTE: Cleanup the xdg cache on exit so new runs of the minimal init doesn't share any previous state, e.g. shada
|
||||
vim.api.nvim_create_autocmd("VimLeave", {
|
||||
callback = function()
|
||||
if vim.env.TEST_NO_CLEANUP and vim.env.TEST_NO_CLEANUP:lower() == "true" then
|
||||
print("[CLEANUP]: `TEST_NO_CLEANUP` was specified, not removing: " .. xdg_root)
|
||||
else
|
||||
print("[CLEANUP]: `TEST_NO_CLEANUP` not specified, removing " .. xdg_root)
|
||||
vim.fn.delete(xdg_root:get(), "rf")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- Empty the package path so we use only the plugins specified
|
||||
vim.opt.packpath = {}
|
||||
|
||||
-- Install required plugins
|
||||
if plugins ~= nil then
|
||||
for plugin_name, plugin_clone_args in pairs(plugins) do
|
||||
M.load_plugin(plugin_name, plugin_clone_args)
|
||||
end
|
||||
end
|
||||
|
||||
-- Ensure `nvim-ts-autotag` is registed on the runtimepath and set it up
|
||||
utils.rtp_register_ts_autotag()
|
||||
require("nvim-ts-autotag").setup({
|
||||
enable = true,
|
||||
enable_rename = true,
|
||||
enable_close = true,
|
||||
enable_close_on_slash = true,
|
||||
})
|
||||
print("[SETUP] Finished setting up minimal init")
|
||||
end
|
||||
|
||||
M.setup({
|
||||
["plenary.nvim"] = "https://github.com/nvim-lua/plenary.nvim",
|
||||
["popup.nvim"] = "https://github.com/nvim-lua/popup.nvim",
|
||||
["nvim-treesitter"] = "https://github.com/nvim-treesitter/nvim-treesitter",
|
||||
["playground"] = "https://github.com/nvim-treesitter/playground",
|
||||
["nvim-treesitter-rescript"] = "https://github.com/nkrkv/nvim-treesitter-rescript",
|
||||
})
|
@ -1,6 +1,6 @@
|
||||
local ts = require("nvim-treesitter.configs")
|
||||
ts.setup({
|
||||
ensure_installed = _G.ts_filetypes,
|
||||
local helpers = require("tests.utils.helpers")
|
||||
|
||||
helpers.setup_nvim_treesitter({
|
||||
highlight = { enable = true },
|
||||
})
|
||||
|
||||
@ -171,10 +171,10 @@ local data = {
|
||||
|
||||
local autotag = require("nvim-ts-autotag")
|
||||
autotag.test = true
|
||||
local run_data = _G.Test_filter(data)
|
||||
local run_data = helpers.Test_filter(data)
|
||||
|
||||
describe("[close slash tag]", function()
|
||||
_G.Test_withfile(run_data, {
|
||||
helpers.Test_withfile(run_data, {
|
||||
mode = "i",
|
||||
cursor_add = 0,
|
||||
})
|
@ -1,6 +1,6 @@
|
||||
local ts = require("nvim-treesitter.configs")
|
||||
ts.setup({
|
||||
ensure_installed = _G.ts_filetypes,
|
||||
local helpers = require("tests.utils.helpers")
|
||||
|
||||
helpers.setup_nvim_treesitter({
|
||||
highlight = { enable = true },
|
||||
})
|
||||
|
||||
@ -209,12 +209,12 @@ local data = {
|
||||
|
||||
local autotag = require("nvim-ts-autotag")
|
||||
autotag.test = true
|
||||
local run_data = _G.Test_filter(data)
|
||||
local run_data = helpers.Test_filter(data)
|
||||
|
||||
describe("[close tag]", function()
|
||||
_G.Test_withfile(run_data, {
|
||||
helpers.Test_withfile(run_data, {
|
||||
mode = "i",
|
||||
cursor_add = 0,
|
||||
before_each = function(value) end,
|
||||
before_each = function() end,
|
||||
})
|
||||
end)
|
@ -1,6 +1,6 @@
|
||||
local ts = require("nvim-treesitter.configs")
|
||||
ts.setup({
|
||||
ensure_installed = _G.ts_filetypes,
|
||||
local helpers = require("tests.utils.helpers")
|
||||
helpers.setup_nvim_treesitter({
|
||||
|
||||
highlight = {
|
||||
use_languagetree = false,
|
||||
enable = true,
|
||||
@ -315,11 +315,11 @@ local data = {
|
||||
local autotag = require("nvim-ts-autotag")
|
||||
autotag.test = true
|
||||
|
||||
local run_data = _G.Test_filter(data)
|
||||
local run_data = helpers.Test_filter(data)
|
||||
|
||||
describe("[rename tag]", function()
|
||||
_G.Test_withfile(run_data, {
|
||||
helpers.Test_withfile(run_data, {
|
||||
cursor_add = 0,
|
||||
before_each = function(value) end,
|
||||
before_each = function() end,
|
||||
})
|
||||
end)
|
13
tests/test.lua
Normal file
13
tests/test.lua
Normal file
@ -0,0 +1,13 @@
|
||||
require("tests.minimal_init")
|
||||
|
||||
---@type string
|
||||
local test_file = vim.v.argv[#vim.v.argv]
|
||||
if test_file == "" or not test_file:find("tests/specs/", nil, true) then
|
||||
test_file = "tests/specs"
|
||||
end
|
||||
print("[STARTUP] Running all tests in " .. test_file)
|
||||
|
||||
require("plenary.test_harness").test_directory(test_file, {
|
||||
minimal_init = "tests/minimal_init.lua",
|
||||
sequential = true,
|
||||
})
|
@ -1,6 +1,13 @@
|
||||
local test_utils = require("tests.utils.utils")
|
||||
|
||||
-- Some helpers depend on utilities from the main plugin, so we have to register the plugin on the
|
||||
-- path if it isn't already present
|
||||
test_utils.rtp_register_ts_autotag()
|
||||
|
||||
local utils = require("nvim-ts-autotag.utils")
|
||||
local log = require("nvim-ts-autotag._log")
|
||||
local api = vim.api
|
||||
|
||||
local M = {}
|
||||
|
||||
local helpers = {}
|
||||
|
||||
@ -16,21 +23,36 @@ function helpers.insert(text, is_replace)
|
||||
helpers.feed("i" .. text, "x", is_replace)
|
||||
end
|
||||
|
||||
utils.insert_char = function(text)
|
||||
api.nvim_put({ text }, "c", true, true)
|
||||
M.insert_char = function(text)
|
||||
vim.api.nvim_put({ text }, "c", true, true)
|
||||
end
|
||||
|
||||
utils.feed = function(text, num)
|
||||
M.feed = function(text, num)
|
||||
local result = ""
|
||||
for _ = 1, num, 1 do
|
||||
result = result .. text
|
||||
end
|
||||
api.nvim_feedkeys(api.nvim_replace_termcodes(result, true, false, true), "x", true)
|
||||
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(result, true, false, true), "x", true)
|
||||
end
|
||||
|
||||
_G.eq = assert.are.same
|
||||
M.setup_nvim_treesitter = function(opts)
|
||||
opts = vim.tbl_deep_extend("keep", opts or {}, {
|
||||
ensure_installed = {
|
||||
"html",
|
||||
"javascript",
|
||||
"typescript",
|
||||
"svelte",
|
||||
"vue",
|
||||
"tsx",
|
||||
"php",
|
||||
"glimmer",
|
||||
"rescript",
|
||||
"embedded_template",
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
_G.Test_filter = function(data)
|
||||
M.Test_filter = function(data)
|
||||
local run_data = {}
|
||||
for _, value in pairs(data) do
|
||||
if value.only == true then
|
||||
@ -50,34 +72,34 @@ local compare_text = function(linenr, text_after, name, cursor_add, end_cursor)
|
||||
for i = 1, #text_after, 1 do
|
||||
local t = string.gsub(text_after[i], "%|", "")
|
||||
if t and new_text[i] and t:gsub("%s+$", "") ~= new_text[i]:gsub("%s+$", "") then
|
||||
eq(t, new_text[i], "\n\n text error: " .. name .. "\n")
|
||||
assert.are.same(t, new_text[i], "\n\n text error: " .. name .. "\n")
|
||||
end
|
||||
local p_after = string.find(text_after[i], "%|")
|
||||
if p_after then
|
||||
local row, col = utils.get_cursor()
|
||||
if end_cursor then
|
||||
eq(row, linenr + i - 2, "\n\n cursor row error: " .. name .. "\n")
|
||||
eq(col + 1, end_cursor, "\n\n end cursor column error : " .. name .. "\n")
|
||||
assert.are.same(row, linenr + i - 2, "\n\n cursor row error: " .. name .. "\n")
|
||||
assert.are.same(col + 1, end_cursor, "\n\n end cursor column error : " .. name .. "\n")
|
||||
else
|
||||
eq(row, linenr + i - 2, "\n\n cursor row error: " .. name .. "\n")
|
||||
assert.are.same(row, linenr + i - 2, "\n\n cursor row error: " .. name .. "\n")
|
||||
p_after = p_after + cursor_add
|
||||
eq(col, math.max(p_after - 2, 0), "\n\n cursor column error : " .. name .. "\n")
|
||||
assert.are.same(col, math.max(p_after - 2, 0), "\n\n cursor column error : " .. name .. "\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
_G.Test_withfile = function(test_data, cb)
|
||||
M.Test_withfile = function(test_data, cb)
|
||||
for _, value in pairs(test_data) do
|
||||
it("test " .. value.name, function(done)
|
||||
it("test " .. value.name, function()
|
||||
local text_before = {}
|
||||
value.linenr = value.linenr or 1
|
||||
local pos_before = {
|
||||
linenr = value.linenr,
|
||||
colnr = 0,
|
||||
}
|
||||
if not vim.tbl_islist(value.before) then
|
||||
if not vim.islist(value.before) then
|
||||
value.before = { value.before }
|
||||
end
|
||||
for index, text in pairs(value.before) do
|
||||
@ -90,7 +112,7 @@ _G.Test_withfile = function(test_data, cb)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not vim.tbl_islist(value.after) then
|
||||
if not vim.islist(value.after) then
|
||||
value.after = { value.after }
|
||||
end
|
||||
vim.bo.filetype = value.filetype or "text"
|
||||
@ -137,14 +159,14 @@ _G.Test_withfile = function(test_data, cb)
|
||||
end
|
||||
end
|
||||
|
||||
_G.dump_node = function(node)
|
||||
M.dump_node = function(node)
|
||||
local text = utils.get_node_text(node)
|
||||
for _, txt in pairs(text) do
|
||||
log.debug(txt)
|
||||
end
|
||||
end
|
||||
|
||||
_G.dump_node_text = function(target)
|
||||
M.dump_node_text = function(target)
|
||||
for node in target:iter_children() do
|
||||
local node_type = node:type()
|
||||
local text = utils.get_node_text(node)
|
||||
@ -152,3 +174,4 @@ _G.dump_node_text = function(target)
|
||||
log.debug(text)
|
||||
end
|
||||
end
|
||||
return M
|
77
tests/utils/paths.lua
Normal file
77
tests/utils/paths.lua
Normal file
@ -0,0 +1,77 @@
|
||||
local M = {}
|
||||
|
||||
---Search up from the current file until we find the full path of the base `tests/` directory and
|
||||
---return it
|
||||
---@param test_file string Filename to look for in each directory, if it exists then stop the search
|
||||
---@return fun(): string dir A function wrapping the found directory
|
||||
local function search_dir_up(test_file)
|
||||
-- This is the path of the directory of the current file
|
||||
local cur_dir = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":p")
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
while not vim.uv.fs_stat(cur_dir .. "/" .. test_file, nil) and cur_dir ~= "/" do
|
||||
cur_dir = vim.fn.fnamemodify(cur_dir, ":h")
|
||||
end
|
||||
if cur_dir == "/" then
|
||||
error("Failed to locate the base 'tests/' directory!")
|
||||
end
|
||||
-- We return a wrapping function instead of a bare string so its easier to enforce "readonly"
|
||||
-- uses of the searched directory
|
||||
return function()
|
||||
return cur_dir
|
||||
end
|
||||
end
|
||||
|
||||
--- WARN: DO NOT MUTATE THESE VALUES!
|
||||
---
|
||||
--- Table containing useful paths to directories within the plugin
|
||||
M.static = {
|
||||
--- Full path of the `tests/` directory
|
||||
tests_dir = search_dir_up("test.lua"),
|
||||
--- Full base path of the plugin where the `.git` directory resides
|
||||
ts_autotag_dir = search_dir_up(".git"),
|
||||
}
|
||||
|
||||
---@class nvim-ts-autotag.Root
|
||||
---@field package path string
|
||||
local Root = {
|
||||
path = M.static.tests_dir(),
|
||||
}
|
||||
|
||||
---@package
|
||||
---@nodiscard
|
||||
---@return nvim-ts-autotag.Root
|
||||
function Root:new(o)
|
||||
o = o or {}
|
||||
|
||||
setmetatable(o, self)
|
||||
-- The last part of the path must be a "/" to work correctly
|
||||
if self.path:sub(#self.path, #self.path) ~= "/" then
|
||||
self.path = self.path .. "/"
|
||||
end
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
--- Create a new instance, pushing the given path onto it
|
||||
---@nodiscard
|
||||
---@param path string The new path to add
|
||||
---@return nvim-ts-autotag.Root
|
||||
function Root:push(path)
|
||||
local new_root = self:new()
|
||||
-- Since we're extending the path, the current path must be a directory, ensure it ends in a "/"
|
||||
if new_root.path:sub(#new_root.path) ~= "/" then
|
||||
new_root.path = new_root.path .. "/"
|
||||
end
|
||||
new_root.path = new_root.path .. path
|
||||
return new_root
|
||||
end
|
||||
|
||||
--- Get the current path string
|
||||
---@return string path
|
||||
function Root:get()
|
||||
return self.path
|
||||
end
|
||||
|
||||
M.Root = Root:new()
|
||||
|
||||
return M
|
14
tests/utils/utils.lua
Normal file
14
tests/utils/utils.lua
Normal file
@ -0,0 +1,14 @@
|
||||
local path_utils = require("tests.utils.paths")
|
||||
local M = {}
|
||||
|
||||
M.paths = path_utils
|
||||
|
||||
--- Register the main plugin (`nvim-ts-autotag`) on the runtimepath if it hasn't already been
|
||||
--- registered
|
||||
M.rtp_register_ts_autotag = function()
|
||||
if not vim.list_contains(vim.opt.runtimepath, path_utils.static.ts_autotag_dir()) then
|
||||
vim.opt.runtimepath:append(path_utils.static.ts_autotag_dir())
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
Loading…
Reference in New Issue
Block a user