mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-06 12:44:23 +08:00
Add basic Lua ALE functions and test coverage
Ensure that basic ALE functions `ale.var`, `ale.escape`, and `ale.env` are available in Lua. Cover all Lua code so far with busted tests, fixing bugs where ALE variables can be set with Boolean values instead of numbers. Document all functionality so far.
This commit is contained in:
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@@ -30,6 +30,7 @@ jobs:
|
|||||||
- '--vim-90-only'
|
- '--vim-90-only'
|
||||||
- '--neovim-07-only'
|
- '--neovim-07-only'
|
||||||
- '--neovim-08-only'
|
- '--neovim-08-only'
|
||||||
|
- '--lua-only'
|
||||||
- '--linters-only'
|
- '--linters-only'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
19
.luarc.json
Normal file
19
.luarc.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
|
||||||
|
"diagnostics.globals": [
|
||||||
|
"vim"
|
||||||
|
],
|
||||||
|
"workspace.ignoreDir": [
|
||||||
|
"test"
|
||||||
|
],
|
||||||
|
"workspace.library": [
|
||||||
|
"/usr/share/nvim/runtime/lua"
|
||||||
|
],
|
||||||
|
"runtime.pathStrict": true,
|
||||||
|
"runtime.path": [
|
||||||
|
"lua/?.lua",
|
||||||
|
"lua/?/init.lua"
|
||||||
|
],
|
||||||
|
"runtime.version": "LuaJIT",
|
||||||
|
"hint.enable": false
|
||||||
|
}
|
||||||
13
Dockerfile
13
Dockerfile
@@ -2,12 +2,10 @@ ARG TESTBED_VIM_VERSION=24
|
|||||||
|
|
||||||
FROM testbed/vim:${TESTBED_VIM_VERSION}
|
FROM testbed/vim:${TESTBED_VIM_VERSION}
|
||||||
|
|
||||||
RUN install_vim -tag v8.0.0027 -build \
|
|
||||||
-tag v9.0.0297 -build \
|
|
||||||
-tag neovim:v0.7.0 -build \
|
|
||||||
-tag neovim:v0.8.0 -build
|
|
||||||
|
|
||||||
ENV PACKAGES="\
|
ENV PACKAGES="\
|
||||||
|
lua5.1 \
|
||||||
|
lua5.1-dev \
|
||||||
|
lua5.1-busted \
|
||||||
bash \
|
bash \
|
||||||
git \
|
git \
|
||||||
python2 \
|
python2 \
|
||||||
@@ -19,6 +17,11 @@ ENV PACKAGES="\
|
|||||||
RUN apk --update add $PACKAGES && \
|
RUN apk --update add $PACKAGES && \
|
||||||
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
|
rm -rf /var/cache/apk/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
RUN install_vim -tag v8.0.0027 -build \
|
||||||
|
-tag v9.0.0297 -build \
|
||||||
|
-tag neovim:v0.7.0 -build \
|
||||||
|
-tag neovim:v0.8.0 -build
|
||||||
|
|
||||||
RUN pip install vim-vint==0.3.21
|
RUN pip install vim-vint==0.3.21
|
||||||
|
|
||||||
RUN git clone https://github.com/junegunn/vader.vim vader && \
|
RUN git clone https://github.com/junegunn/vader.vim vader && \
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ function! ale#engine#SendResultsToNeovimDiagnostics(buffer, loclist) abort
|
|||||||
|
|
||||||
" Keep the Lua surface area really small in the VimL part of ALE,
|
" Keep the Lua surface area really small in the VimL part of ALE,
|
||||||
" and just require the diagnostics.lua module on demand.
|
" and just require the diagnostics.lua module on demand.
|
||||||
let l:SendDiagnostics = luaeval('require("ale.diagnostics").sendAleResultsToDiagnostics')
|
let l:SendDiagnostics = luaeval('require("ale.diagnostics").send')
|
||||||
call l:SendDiagnostics(a:buffer, a:loclist)
|
call l:SendDiagnostics(a:buffer, a:loclist)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|||||||
29
doc/ale.txt
29
doc/ale.txt
@@ -4453,6 +4453,7 @@ Vim autocmd names `ale#Foo` are available in the Vim context, and functions
|
|||||||
documented with dot names `ale.foo` are available in Lua scripts.
|
documented with dot names `ale.foo` are available in Lua scripts.
|
||||||
|
|
||||||
|
|
||||||
|
ale.env(variable_name, value) *ale.env()*
|
||||||
ale#Env(variable_name, value) *ale#Env()*
|
ale#Env(variable_name, value) *ale#Env()*
|
||||||
|
|
||||||
Given a variable name and a string value, produce a string for including in
|
Given a variable name and a string value, produce a string for including in
|
||||||
@@ -4464,6 +4465,18 @@ ale#Env(variable_name, value) *ale#Env()*
|
|||||||
'set VAR="some value" && command' # On Windows
|
'set VAR="some value" && command' # On Windows
|
||||||
|
|
||||||
|
|
||||||
|
ale.escape(str) *ale.escape()*
|
||||||
|
ale#Escape(str) *ale#Escape()*
|
||||||
|
|
||||||
|
Given a string, escape that string so it is ready for shell execution.
|
||||||
|
|
||||||
|
If the shell is detected to be `cmd.exe`, ALE will apply its own escaping
|
||||||
|
that tries to avoid escaping strings unless absolutely necessary to avoid
|
||||||
|
issues with Windows programs that do not properly handle quoted arguments.
|
||||||
|
|
||||||
|
In all other cases, ALE will call |shellescape|.
|
||||||
|
|
||||||
|
|
||||||
ale#GetFilenameMappings(buffer, name) *ale#GetFilenameMappings()*
|
ale#GetFilenameMappings(buffer, name) *ale#GetFilenameMappings()*
|
||||||
|
|
||||||
Given a `buffer` and the `name` of either a linter for fixer, return a
|
Given a `buffer` and the `name` of either a linter for fixer, return a
|
||||||
@@ -4509,7 +4522,7 @@ ale#Queue(delay, [linting_flag, buffer_number]) *ale#Queue()*
|
|||||||
is broken, or when developing ALE itself.
|
is broken, or when developing ALE itself.
|
||||||
|
|
||||||
|
|
||||||
ale.setup(config) *ale.setup*
|
ale.setup(config) *ale.setup()*
|
||||||
|
|
||||||
Configure ALE global settings, which are documented in |ale-options|. For
|
Configure ALE global settings, which are documented in |ale-options|. For
|
||||||
example: >
|
example: >
|
||||||
@@ -4524,7 +4537,7 @@ ale.setup(config) *ale.setup*
|
|||||||
ALE is being configured in less ambiguous if you like.
|
ALE is being configured in less ambiguous if you like.
|
||||||
|
|
||||||
|
|
||||||
ale.setup.buffer(config) *ale.setup.buffer*
|
ale.setup.buffer(config) *ale.setup.buffer()*
|
||||||
|
|
||||||
Configure ALE buffer-local settings, which are documented in |ale-options|.
|
Configure ALE buffer-local settings, which are documented in |ale-options|.
|
||||||
For example: >
|
For example: >
|
||||||
@@ -4534,6 +4547,18 @@ ale.setup.buffer(config) *ale.setup.buffer*
|
|||||||
})
|
})
|
||||||
<
|
<
|
||||||
|
|
||||||
|
ale.var(buffer, variable_name) *ale.var()*
|
||||||
|
ale#Var(buffer, variable_name) *ale#Var()*
|
||||||
|
|
||||||
|
Given a buffer number and an ALE variable name return the value of that
|
||||||
|
if defined in the buffer, and if not defined in the buffer return the
|
||||||
|
global value. The `ale_` prefix will be added to the Vim variable name.
|
||||||
|
|
||||||
|
The `ale#Var` Vim function will return errors if the variable is not defined
|
||||||
|
in either the buffer or globally. The `ale.var` Lua function will return
|
||||||
|
`nil` if the variable is not defined in either the buffer or globally.
|
||||||
|
|
||||||
|
|
||||||
ale#command#CreateDirectory(buffer) *ale#command#CreateDirectory()*
|
ale#command#CreateDirectory(buffer) *ale#command#CreateDirectory()*
|
||||||
|
|
||||||
Create a new temporary directory with a unique name, and manage that
|
Create a new temporary directory with a unique name, and manage that
|
||||||
|
|||||||
@@ -1,24 +1,30 @@
|
|||||||
|
local ale = require("ale")
|
||||||
|
|
||||||
local module = {}
|
local module = {}
|
||||||
|
|
||||||
local ale_type_to_diagnostic_severity = {
|
local diagnostic_severity_map = {
|
||||||
E = vim.diagnostic.severity.ERROR,
|
E = vim.diagnostic.severity.ERROR,
|
||||||
W = vim.diagnostic.severity.WARN,
|
W = vim.diagnostic.severity.WARN,
|
||||||
I = vim.diagnostic.severity.INFO
|
I = vim.diagnostic.severity.INFO
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Equivalent to ale#Var, only we can't error on missing global keys.
|
-- A map of all possible values that we can consider virtualtext enabled for
|
||||||
module.aleVar = function(buffer, key)
|
-- from ALE's setting.
|
||||||
key = "ale_" .. key
|
local virtualtext_enabled_set = {
|
||||||
local exists, value = pcall(vim.api.nvim_buf_get_var, buffer, key)
|
["all"] = true,
|
||||||
|
["2"] = true,
|
||||||
|
[2] = true,
|
||||||
|
["current"] = true,
|
||||||
|
["1"] = true,
|
||||||
|
[1] = true,
|
||||||
|
[true] = true,
|
||||||
|
}
|
||||||
|
|
||||||
if exists then
|
---Send diagnostics to the Neovim diagnostics API
|
||||||
return value
|
---@param buffer number The buffer number to retreive the variable for.
|
||||||
end
|
---@param loclist table The loclist array to report as diagnostics.
|
||||||
|
---@return nil
|
||||||
return vim.g[key]
|
module.send = function(buffer, loclist)
|
||||||
end
|
|
||||||
|
|
||||||
module.sendAleResultsToDiagnostics = function(buffer, loclist)
|
|
||||||
local diagnostics = {}
|
local diagnostics = {}
|
||||||
|
|
||||||
-- Convert all the ALE loclist items to the shape that Neovim's diagnostic
|
-- Convert all the ALE loclist items to the shape that Neovim's diagnostic
|
||||||
@@ -27,20 +33,20 @@ module.sendAleResultsToDiagnostics = function(buffer, loclist)
|
|||||||
if location.bufnr == buffer then
|
if location.bufnr == buffer then
|
||||||
table.insert(
|
table.insert(
|
||||||
diagnostics,
|
diagnostics,
|
||||||
-- All line numbers from ALE are 1-indexed, but all line numbers
|
-- All line numbers from ALE are 1-indexed, but all line
|
||||||
-- in the diagnostics API are 0-indexed, so we have to subtract 1
|
-- numbers in the diagnostics API are 0-indexed, so we have to
|
||||||
-- to make this work.
|
-- subtract 1 to make this work.
|
||||||
{
|
{
|
||||||
lnum = location.lnum - 1,
|
lnum = location.lnum - 1,
|
||||||
-- Ending line number, or if we don't have one, just make it the same
|
-- Ending line number, or if we don't have one, just make
|
||||||
-- as the starting line number
|
-- it the same as the starting line number
|
||||||
end_lnum = (location.end_lnum or location.lnum) - 1,
|
end_lnum = (location.end_lnum or location.lnum) - 1,
|
||||||
-- Which column does the error start on?
|
-- Which column does the error start on?
|
||||||
col = math.max((location.col or 1) - 1, 0),
|
col = math.max((location.col or 1) - 1, 0),
|
||||||
-- end_col does *not* appear to need 1 subtracted, so we don't.
|
-- end_col does not appear to need 1 subtracted.
|
||||||
end_col = location.end_col,
|
end_col = location.end_col,
|
||||||
-- Which severity: error, warning, or info?
|
-- Which severity: error, warning, or info?
|
||||||
severity = ale_type_to_diagnostic_severity[location.type] or "E",
|
severity = diagnostic_severity_map[location.type] or "E",
|
||||||
-- An error code
|
-- An error code
|
||||||
code = location.code,
|
code = location.code,
|
||||||
-- The error message
|
-- The error message
|
||||||
@@ -52,42 +58,35 @@ module.sendAleResultsToDiagnostics = function(buffer, loclist)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local virtualtext_enabled_set = {
|
local set_signs = ale.var(buffer, "set_signs")
|
||||||
['all'] = true,
|
local sign_priority = ale.var(buffer, "sign_priority")
|
||||||
['2'] = true,
|
|
||||||
[2] = true,
|
|
||||||
['current'] = true,
|
|
||||||
['1'] = true,
|
|
||||||
[1] = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
local set_signs = module.aleVar(buffer, 'set_signs')
|
|
||||||
local sign_priority = module.aleVar(buffer, 'sign_priority')
|
|
||||||
local signs
|
local signs
|
||||||
|
|
||||||
if set_signs == 1 and sign_priority then
|
if (set_signs == 1 or set_signs == true) and sign_priority then
|
||||||
-- If signs are enabled, set the priority for them.
|
-- If signs are enabled, set the priority for them.
|
||||||
local local_cfg = { priority = sign_priority }
|
local local_cfg = { priority = sign_priority }
|
||||||
local global_cfg = vim.diagnostic.config().signs
|
local global_cfg = vim.diagnostic.config().signs
|
||||||
|
|
||||||
if type(global_cfg) == 'boolean' then
|
if type(global_cfg) == "boolean" then
|
||||||
signs = local_cfg
|
signs = local_cfg
|
||||||
elseif type(global_cfg) == 'table' then
|
elseif type(global_cfg) == "table" then
|
||||||
signs = vim.tbl_extend('force', global_cfg, local_cfg)
|
signs = vim.tbl_extend("force", global_cfg, local_cfg)
|
||||||
else
|
else
|
||||||
|
-- If a global function is defined, then define a function
|
||||||
|
-- that calls that function when Neovim calls our function.
|
||||||
signs = function(...)
|
signs = function(...)
|
||||||
local calculated = global_cfg(...)
|
return vim.tbl_extend("force", global_cfg(...), local_cfg)
|
||||||
return vim.tbl_extend('force', calculated, local_cfg)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.diagnostic.set(
|
vim.diagnostic.set(
|
||||||
vim.api.nvim_create_namespace('ale'),
|
vim.api.nvim_create_namespace("ale"),
|
||||||
buffer,
|
buffer,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
{
|
{
|
||||||
virtual_text = virtualtext_enabled_set[vim.g.ale_virtualtext_cursor] ~= nil,
|
virtual_text =
|
||||||
|
virtualtext_enabled_set[vim.g.ale_virtualtext_cursor] ~= nil,
|
||||||
signs = signs,
|
signs = signs,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
local ale = {}
|
local ale = {}
|
||||||
|
|
||||||
local global_settings = setmetatable({}, {
|
local global_settings = setmetatable({}, {
|
||||||
__index = function (_, key)
|
__index = function(_, key)
|
||||||
return vim.g['ale_' .. key]
|
return vim.g['ale_' .. key]
|
||||||
end,
|
end,
|
||||||
__newindex = function (_, key, value)
|
__newindex = function(_, key, value)
|
||||||
vim.g['ale_' .. key] = value
|
vim.g['ale_' .. key] = value
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
local buffer_settings = setmetatable({}, {
|
local buffer_settings = setmetatable({}, {
|
||||||
__index = function (_, key)
|
__index = function(_, key)
|
||||||
return vim.b['ale_' .. key]
|
return vim.b['ale_' .. key]
|
||||||
end,
|
end,
|
||||||
__newindex = function (_, key, value)
|
__newindex = function(_, key, value)
|
||||||
vim.b['ale_' .. key] = value
|
vim.b['ale_' .. key] = value
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
@@ -30,10 +30,22 @@ ale.set_buffer = function(c)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---(when called) Set global ALE settings, just like ale.setup.global.
|
||||||
|
---@class ALESetup
|
||||||
|
---@field global fun(c: table): nil -- Set global ALE settings.
|
||||||
|
---@field buffer fun(c: table): nil -- Set buffer-local ALE settings.
|
||||||
|
---@overload fun(c: table): nil
|
||||||
|
---@type ALESetup
|
||||||
ale.setup = setmetatable({
|
ale.setup = setmetatable({
|
||||||
|
---Set global ALE settings.
|
||||||
|
---@param c table The table of ALE settings to set.
|
||||||
|
---@return nil
|
||||||
global = function(c)
|
global = function(c)
|
||||||
ale.set_global(c)
|
ale.set_global(c)
|
||||||
end,
|
end,
|
||||||
|
---Set buffer-local ALE settings.
|
||||||
|
---@param c table The table of ALE settings to set.
|
||||||
|
---@return nil
|
||||||
buffer = function(c)
|
buffer = function(c)
|
||||||
ale.set_buffer(c)
|
ale.set_buffer(c)
|
||||||
end,
|
end,
|
||||||
@@ -43,4 +55,54 @@ ale.setup = setmetatable({
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
---Get an ALE variable for a buffer (first) or globally (second)
|
||||||
|
---@param buffer number The buffer number to retreive the variable for.
|
||||||
|
---@param variable_name string The variable to retrieve.
|
||||||
|
---@return any value The value for the ALE variable
|
||||||
|
ale.var = function(buffer, variable_name)
|
||||||
|
variable_name = "ale_" .. variable_name
|
||||||
|
local exists, value = pcall(vim.api.nvim_buf_get_var, buffer, variable_name)
|
||||||
|
|
||||||
|
if exists then
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim.g[variable_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
---Escape a string for use in a shell command
|
||||||
|
---@param str string The string to escape.
|
||||||
|
---@return string escaped The escaped string.
|
||||||
|
ale.escape = function(str)
|
||||||
|
local shell = vim.fn.fnamemodify(vim.o.shell, ":t")
|
||||||
|
|
||||||
|
if shell:lower() == "cmd.exe" then
|
||||||
|
local step1
|
||||||
|
|
||||||
|
if str:find(" ") then
|
||||||
|
step1 = '"' .. str:gsub('"', '""') .. '"'
|
||||||
|
else
|
||||||
|
step1 = str:gsub("([&|<>^])", "^%1")
|
||||||
|
end
|
||||||
|
|
||||||
|
local percent_subbed = step1:gsub("%%", "%%%%")
|
||||||
|
|
||||||
|
return percent_subbed
|
||||||
|
end
|
||||||
|
|
||||||
|
return vim.fn.shellescape(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
---Create a prefix for a shell command for adding environment variables.
|
||||||
|
---@param variable_name string The environment variable name.
|
||||||
|
---@param value string The value to set for the environment variable.
|
||||||
|
---@return string prefix The shell code for prefixing a command.
|
||||||
|
ale.env = function(variable_name, value)
|
||||||
|
if vim.fn.has("win32") then
|
||||||
|
return "set " .. ale.escape(variable_name .. "=" .. value) .. " && "
|
||||||
|
end
|
||||||
|
|
||||||
|
return variable_name .. "=" .. ale.escape(value) .. " "
|
||||||
|
end
|
||||||
|
|
||||||
return ale
|
return ale
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ local module = {}
|
|||||||
|
|
||||||
module.start = function(config)
|
module.start = function(config)
|
||||||
-- Neovim's luaeval sometimes adds a Boolean key to table we need to remove.
|
-- Neovim's luaeval sometimes adds a Boolean key to table we need to remove.
|
||||||
if config.init_options[true] ~= nil then
|
if type(config.init_options) == "table"
|
||||||
|
and config.init_options[true] ~= nil
|
||||||
|
then
|
||||||
config.init_options[true] = nil
|
config.init_options[true] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
26
run-tests
26
run-tests
@@ -29,6 +29,7 @@ run_neovim_07_tests=1
|
|||||||
run_neovim_08_tests=1
|
run_neovim_08_tests=1
|
||||||
run_vim_80_tests=1
|
run_vim_80_tests=1
|
||||||
run_vim_90_tests=1
|
run_vim_90_tests=1
|
||||||
|
run_lua_tests=1
|
||||||
run_linters=1
|
run_linters=1
|
||||||
|
|
||||||
while [ $# -ne 0 ]; do
|
while [ $# -ne 0 ]; do
|
||||||
@@ -46,12 +47,14 @@ while [ $# -ne 0 ]; do
|
|||||||
run_vim_90_tests=0
|
run_vim_90_tests=0
|
||||||
run_neovim_07_tests=0
|
run_neovim_07_tests=0
|
||||||
run_neovim_08_tests=0
|
run_neovim_08_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--neovim-only)
|
--neovim-only)
|
||||||
run_vim_80_tests=0
|
run_vim_80_tests=0
|
||||||
run_vim_90_tests=0
|
run_vim_90_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@@ -59,6 +62,7 @@ while [ $# -ne 0 ]; do
|
|||||||
run_neovim_08_tests=0
|
run_neovim_08_tests=0
|
||||||
run_vim_80_tests=0
|
run_vim_80_tests=0
|
||||||
run_vim_90_tests=0
|
run_vim_90_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@@ -66,12 +70,14 @@ while [ $# -ne 0 ]; do
|
|||||||
run_neovim_07_tests=0
|
run_neovim_07_tests=0
|
||||||
run_vim_80_tests=0
|
run_vim_80_tests=0
|
||||||
run_vim_90_tests=0
|
run_vim_90_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--vim-only)
|
--vim-only)
|
||||||
run_neovim_07_tests=0
|
run_neovim_07_tests=0
|
||||||
run_neovim_08_tests=0
|
run_neovim_08_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@@ -79,6 +85,7 @@ while [ $# -ne 0 ]; do
|
|||||||
run_neovim_07_tests=0
|
run_neovim_07_tests=0
|
||||||
run_neovim_08_tests=0
|
run_neovim_08_tests=0
|
||||||
run_vim_90_tests=0
|
run_vim_90_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@@ -86,6 +93,7 @@ while [ $# -ne 0 ]; do
|
|||||||
run_neovim_07_tests=0
|
run_neovim_07_tests=0
|
||||||
run_neovim_08_tests=0
|
run_neovim_08_tests=0
|
||||||
run_vim_80_tests=0
|
run_vim_80_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
run_linters=0
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
@@ -94,6 +102,15 @@ while [ $# -ne 0 ]; do
|
|||||||
run_vim_90_tests=0
|
run_vim_90_tests=0
|
||||||
run_neovim_07_tests=0
|
run_neovim_07_tests=0
|
||||||
run_neovim_08_tests=0
|
run_neovim_08_tests=0
|
||||||
|
run_lua_tests=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--lua-only)
|
||||||
|
run_vim_80_tests=0
|
||||||
|
run_vim_90_tests=0
|
||||||
|
run_neovim_07_tests=0
|
||||||
|
run_neovim_08_tests=0
|
||||||
|
run_linters=0
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
--fast)
|
--fast)
|
||||||
@@ -119,6 +136,7 @@ while [ $# -ne 0 ]; do
|
|||||||
echo ' --vim-only Run tests only for Vim'
|
echo ' --vim-only Run tests only for Vim'
|
||||||
echo ' --vim-80-only Run tests only for Vim 8.2'
|
echo ' --vim-80-only Run tests only for Vim 8.2'
|
||||||
echo ' --vim-90-only Run tests only for Vim 9.0'
|
echo ' --vim-90-only Run tests only for Vim 9.0'
|
||||||
|
echo ' --lua-only Run only Lua tests'
|
||||||
echo ' --linters-only Run only Vint and custom checks'
|
echo ' --linters-only Run only Vint and custom checks'
|
||||||
echo ' --fast Run only the fastest Vim and custom checks'
|
echo ' --fast Run only the fastest Vim and custom checks'
|
||||||
echo ' --help Show this help text'
|
echo ' --help Show this help text'
|
||||||
@@ -147,6 +165,7 @@ if [ $# -ne 0 ]; then
|
|||||||
|
|
||||||
# Don't run other tools when targeting tests.
|
# Don't run other tools when targeting tests.
|
||||||
run_linters=0
|
run_linters=0
|
||||||
|
run_lua_tests=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Delete .swp files in the test directory, which cause Vim 8 to hang.
|
# Delete .swp files in the test directory, which cause Vim 8 to hang.
|
||||||
@@ -250,6 +269,13 @@ for vim in $("$DOCKER" run --rm "$DOCKER_RUN_IMAGE" ls /vim-build/bin | grep '^n
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if ((run_lua_tests)); then
|
||||||
|
echo "Starting Lua tests..."
|
||||||
|
file_number=$((file_number+1))
|
||||||
|
test/script/run-lua-tests $quiet_flag > "$output_dir/$file_number" 2>&1 &
|
||||||
|
pid_list="$pid_list $!"
|
||||||
|
fi
|
||||||
|
|
||||||
if ((run_linters)); then
|
if ((run_linters)); then
|
||||||
echo "Starting Vint..."
|
echo "Starting Vint..."
|
||||||
file_number=$((file_number+1))
|
file_number=$((file_number+1))
|
||||||
|
|||||||
@@ -11,9 +11,30 @@
|
|||||||
"pending",
|
"pending",
|
||||||
"assert"
|
"assert"
|
||||||
],
|
],
|
||||||
|
"workspace.checkThirdParty": false,
|
||||||
"workspace.library": [
|
"workspace.library": [
|
||||||
|
"${3rd}/busted/library",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.4",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.3",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.2",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.1",
|
||||||
"../../lua"
|
"../../lua"
|
||||||
],
|
],
|
||||||
|
"runtime.pathStrict": true,
|
||||||
|
"runtime.path": [
|
||||||
|
"?.lua",
|
||||||
|
"?/init.lua",
|
||||||
|
"../../lua/?.lua",
|
||||||
|
"../../lua/?/init.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.4/?.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.4/?/init.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.3/?.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.3/?/init.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.2/?.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.2/?/init.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.1/?.lua",
|
||||||
|
"${env:HOME}/.luarocks/share/lua/5.1/?/init.lua"
|
||||||
|
],
|
||||||
"runtime.version": "LuaJIT",
|
"runtime.version": "LuaJIT",
|
||||||
"hint.enable": false
|
"hint.enable": false
|
||||||
}
|
}
|
||||||
|
|||||||
232
test/lua/ale_diagnostics_spec.lua
Normal file
232
test/lua/ale_diagnostics_spec.lua
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
local eq = assert.are.same
|
||||||
|
local diagnostics
|
||||||
|
|
||||||
|
describe("ale.diagnostics.send", function()
|
||||||
|
local buffer_map
|
||||||
|
local signs_config
|
||||||
|
local diagnostic_set_calls
|
||||||
|
|
||||||
|
setup(function()
|
||||||
|
_G.vim = {
|
||||||
|
api = {
|
||||||
|
nvim_buf_get_var = function(buffer, key)
|
||||||
|
local buffer_table = buffer_map[buffer] or {}
|
||||||
|
local value = buffer_table[key]
|
||||||
|
|
||||||
|
if value == nil then
|
||||||
|
error(key .. " is missing")
|
||||||
|
end
|
||||||
|
|
||||||
|
return value
|
||||||
|
end,
|
||||||
|
nvim_create_namespace = function()
|
||||||
|
return 42
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
diagnostic = {
|
||||||
|
severity = {ERROR = 1, WARN = 2, INFO = 3},
|
||||||
|
config = function()
|
||||||
|
return {signs = signs_config}
|
||||||
|
end,
|
||||||
|
set = function(namespace, bufnr, _diagnostics, opts)
|
||||||
|
table.insert(diagnostic_set_calls, {
|
||||||
|
namespace = namespace,
|
||||||
|
bufnr = bufnr,
|
||||||
|
diagnostics = _diagnostics,
|
||||||
|
opts = opts,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
tbl_extend = function(behavior, ...)
|
||||||
|
assert(behavior == "force", "We should only use `force`")
|
||||||
|
|
||||||
|
local merged = {}
|
||||||
|
|
||||||
|
for _, arg in ipairs({...}) do
|
||||||
|
for key, value in pairs(arg) do
|
||||||
|
merged[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return merged
|
||||||
|
end,
|
||||||
|
g = {},
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnostics = require("ale.diagnostics")
|
||||||
|
end)
|
||||||
|
|
||||||
|
teardown(function()
|
||||||
|
_G.vim = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
buffer_map = {}
|
||||||
|
diagnostic_set_calls = {}
|
||||||
|
signs_config = false
|
||||||
|
_G.vim.g = {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should set an empty list of diagnostics correctly", function()
|
||||||
|
diagnostics.send(7, {})
|
||||||
|
|
||||||
|
eq(
|
||||||
|
{
|
||||||
|
{
|
||||||
|
namespace = 42,
|
||||||
|
bufnr = 7,
|
||||||
|
diagnostics = {},
|
||||||
|
opts = {virtual_text = false}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
diagnostic_set_calls
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should handle basic case with all fields", function()
|
||||||
|
diagnostics.send(1, {
|
||||||
|
{
|
||||||
|
bufnr = 1,
|
||||||
|
lnum = 2,
|
||||||
|
end_lnum = 3,
|
||||||
|
col = 4,
|
||||||
|
end_col = 5,
|
||||||
|
type = "W",
|
||||||
|
code = "123",
|
||||||
|
text = "Warning message",
|
||||||
|
linter_name = "eslint",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
eq({
|
||||||
|
{
|
||||||
|
lnum = 1,
|
||||||
|
end_lnum = 2,
|
||||||
|
col = 3,
|
||||||
|
end_col = 5,
|
||||||
|
severity = vim.diagnostic.severity.WARN,
|
||||||
|
code = "123",
|
||||||
|
message = "Warning message",
|
||||||
|
source = "eslint",
|
||||||
|
},
|
||||||
|
}, diagnostic_set_calls[1].diagnostics)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should default end_lnum to lnum when missing", function()
|
||||||
|
diagnostics.send(1, {
|
||||||
|
{
|
||||||
|
bufnr = 1,
|
||||||
|
lnum = 5,
|
||||||
|
col = 2,
|
||||||
|
end_col = 8,
|
||||||
|
type = "E",
|
||||||
|
text = "Error message",
|
||||||
|
linter_name = "mylinter",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
eq({
|
||||||
|
{
|
||||||
|
lnum = 4,
|
||||||
|
end_lnum = 4,
|
||||||
|
col = 1,
|
||||||
|
end_col = 8,
|
||||||
|
severity = vim.diagnostic.severity.ERROR,
|
||||||
|
code = nil,
|
||||||
|
message = "Error message",
|
||||||
|
source = "mylinter",
|
||||||
|
},
|
||||||
|
}, diagnostic_set_calls[1].diagnostics)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should default col to 0 when missing", function()
|
||||||
|
diagnostics.send(1, {
|
||||||
|
{
|
||||||
|
bufnr = 1,
|
||||||
|
lnum = 10,
|
||||||
|
end_lnum = 12,
|
||||||
|
end_col = 6,
|
||||||
|
type = "I",
|
||||||
|
text = "Info message",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
eq({
|
||||||
|
{
|
||||||
|
lnum = 9,
|
||||||
|
end_lnum = 11,
|
||||||
|
col = 0,
|
||||||
|
end_col = 6,
|
||||||
|
severity = vim.diagnostic.severity.INFO,
|
||||||
|
code = nil,
|
||||||
|
message = "Info message",
|
||||||
|
source = nil,
|
||||||
|
},
|
||||||
|
}, diagnostic_set_calls[1].diagnostics)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should ignore non-matching buffers", function()
|
||||||
|
diagnostics.send(1, {
|
||||||
|
{
|
||||||
|
bufnr = 2,
|
||||||
|
lnum = 1,
|
||||||
|
end_lnum = 2,
|
||||||
|
col = 1,
|
||||||
|
end_col = 4,
|
||||||
|
type = "W",
|
||||||
|
text = "Message",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
eq({}, diagnostic_set_calls[1].diagnostics)
|
||||||
|
end)
|
||||||
|
|
||||||
|
for _, set_signs_value in ipairs {1, true} do
|
||||||
|
describe("signs with setting set_signs = " .. tostring(set_signs_value), function()
|
||||||
|
before_each(function()
|
||||||
|
_G.vim.g.ale_set_signs = set_signs_value
|
||||||
|
_G.vim.g.ale_sign_priority = 10
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("and global config as `false` should enable signs with the given priority", function()
|
||||||
|
diagnostics.send(7, {})
|
||||||
|
eq({priority = 10}, diagnostic_set_calls[1].opts.signs)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("and global config as a table should enable signs with the given priority", function()
|
||||||
|
signs_config = {foo = "bar", priority = 5}
|
||||||
|
diagnostics.send(7, {})
|
||||||
|
eq(
|
||||||
|
{foo = "bar", priority = 10},
|
||||||
|
diagnostic_set_calls[1].opts.signs
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("and global config as a function should enable signs with the given priority", function()
|
||||||
|
signs_config = function()
|
||||||
|
return {foo = "bar", priority = 5}
|
||||||
|
end
|
||||||
|
diagnostics.send(7, {})
|
||||||
|
|
||||||
|
local local_signs = diagnostic_set_calls[1].opts.signs
|
||||||
|
|
||||||
|
eq("function", type(local_signs))
|
||||||
|
eq({foo = "bar", priority = 10}, local_signs())
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
it("should toggle virtual_text correctly", function()
|
||||||
|
for _, value in ipairs({"all", "2", 2, "current", "1", 1, true}) do
|
||||||
|
diagnostic_set_calls = {}
|
||||||
|
_G.vim.g.ale_virtualtext_cursor = value
|
||||||
|
diagnostics.send(7, {})
|
||||||
|
|
||||||
|
eq({virtual_text = true}, diagnostic_set_calls[1].opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, value in ipairs({"disabled", "0", 0, false, nil}) do
|
||||||
|
diagnostic_set_calls = {}
|
||||||
|
_G.vim.g.ale_virtualtext_cursor = value
|
||||||
|
diagnostics.send(7, {})
|
||||||
|
|
||||||
|
eq({virtual_text = false}, diagnostic_set_calls[1].opts)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end)
|
||||||
56
test/lua/ale_env_spec.lua
Normal file
56
test/lua/ale_env_spec.lua
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
local eq = assert.are.same
|
||||||
|
local ale = require("ale")
|
||||||
|
|
||||||
|
describe("ale.env", function()
|
||||||
|
local is_win32 = false
|
||||||
|
|
||||||
|
setup(function()
|
||||||
|
_G.vim = {
|
||||||
|
o = setmetatable({}, {
|
||||||
|
__index = function(_, key)
|
||||||
|
if key == "shell" then
|
||||||
|
if is_win32 then
|
||||||
|
return "cmd.exe"
|
||||||
|
end
|
||||||
|
|
||||||
|
return "bash"
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
}),
|
||||||
|
fn = {
|
||||||
|
has = function(feature)
|
||||||
|
return feature == "win32" and is_win32
|
||||||
|
end,
|
||||||
|
-- Mock a very poor version of shellescape() for Unix
|
||||||
|
-- This shouldn't be called for Windows
|
||||||
|
shellescape = function(str)
|
||||||
|
return "'" .. str .. "'"
|
||||||
|
end,
|
||||||
|
fnamemodify = function(shell, _)
|
||||||
|
return shell
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
teardown(function()
|
||||||
|
_G.vim = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
is_win32 = false
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should escape values correctly on Unix", function()
|
||||||
|
eq("name='xxx' ", ale.env('name', 'xxx'))
|
||||||
|
eq("name='foo bar' ", ale.env('name', 'foo bar'))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should escape values correctly on Windows", function()
|
||||||
|
is_win32 = true
|
||||||
|
eq('set name=xxx && ', ale.env('name', 'xxx'))
|
||||||
|
eq('set "name=foo bar" && ', ale.env('name', 'foo bar'))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
224
test/lua/ale_lsp_spec.lua
Normal file
224
test/lua/ale_lsp_spec.lua
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
local eq = assert.are.same
|
||||||
|
local lsp = require("ale.lsp")
|
||||||
|
|
||||||
|
describe("ale.lsp.start", function()
|
||||||
|
local start_calls
|
||||||
|
local rpc_connect_calls
|
||||||
|
local vim_fn_calls
|
||||||
|
local defer_calls
|
||||||
|
|
||||||
|
setup(function()
|
||||||
|
_G.vim = {
|
||||||
|
defer_fn = function(func, delay)
|
||||||
|
table.insert(defer_calls, {func, delay})
|
||||||
|
end,
|
||||||
|
fn = setmetatable({}, {
|
||||||
|
__index = function(_, key)
|
||||||
|
return function(...)
|
||||||
|
table.insert(vim_fn_calls, {key, ...})
|
||||||
|
|
||||||
|
if key == "ale#lsp#GetLanguage" then
|
||||||
|
return "python"
|
||||||
|
end
|
||||||
|
|
||||||
|
if key ~= "ale#lsp_linter#HandleLSPResponse"
|
||||||
|
and key ~= "ale#lsp#UpdateCapabilities"
|
||||||
|
and key ~= "ale#lsp#CallInitCallbacks"
|
||||||
|
then
|
||||||
|
assert(false, "Invalid ALE function: " .. key)
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}),
|
||||||
|
lsp = {
|
||||||
|
rpc = {
|
||||||
|
connect = function(host, port)
|
||||||
|
return function(dispatch)
|
||||||
|
table.insert(rpc_connect_calls, {
|
||||||
|
host = host,
|
||||||
|
port = port,
|
||||||
|
dispatch = dispatch,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
start = function(...)
|
||||||
|
table.insert(start_calls, {...})
|
||||||
|
|
||||||
|
return 42
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
teardown(function()
|
||||||
|
_G.vim = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
start_calls = {}
|
||||||
|
rpc_connect_calls = {}
|
||||||
|
vim_fn_calls = {}
|
||||||
|
defer_calls = {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should start lsp programs with the correct arguments", function()
|
||||||
|
lsp.start({
|
||||||
|
name = "server:/code",
|
||||||
|
cmd = "server",
|
||||||
|
root_dir = "/code",
|
||||||
|
-- This Boolean value somehow ends up in Dictionaries from
|
||||||
|
-- Vim for init_options, and we need to remove it.
|
||||||
|
init_options = {[true] = 123},
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Remove arguments with functions we can't apply equality checks
|
||||||
|
-- for easily.
|
||||||
|
for _, args in pairs(start_calls) do
|
||||||
|
args[1].handlers = nil
|
||||||
|
args[1].on_init = nil
|
||||||
|
args[1].get_language_id = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
eq({
|
||||||
|
{
|
||||||
|
{
|
||||||
|
cmd = "server",
|
||||||
|
name = "server:/code",
|
||||||
|
root_dir = "/code",
|
||||||
|
init_options = {},
|
||||||
|
},
|
||||||
|
{attach = false, silent = true}
|
||||||
|
}
|
||||||
|
}, start_calls)
|
||||||
|
eq({}, vim_fn_calls)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should start lsp socket connections with the correct arguments", function()
|
||||||
|
lsp.start({
|
||||||
|
name = "localhost:1234:/code",
|
||||||
|
host = "localhost",
|
||||||
|
port = 1234,
|
||||||
|
root_dir = "/code",
|
||||||
|
init_options = {foo = "bar"},
|
||||||
|
})
|
||||||
|
|
||||||
|
local cmd
|
||||||
|
|
||||||
|
-- Remove arguments with functions we can't apply equality checks
|
||||||
|
-- for easily.
|
||||||
|
for _, args in pairs(start_calls) do
|
||||||
|
cmd = args[1].cmd
|
||||||
|
args[1].cmd = nil
|
||||||
|
args[1].handlers = nil
|
||||||
|
args[1].on_init = nil
|
||||||
|
args[1].get_language_id = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
eq({
|
||||||
|
{
|
||||||
|
{
|
||||||
|
name = "localhost:1234:/code",
|
||||||
|
root_dir = "/code",
|
||||||
|
init_options = {foo = "bar"},
|
||||||
|
},
|
||||||
|
{attach = false, silent = true}
|
||||||
|
}
|
||||||
|
}, start_calls)
|
||||||
|
|
||||||
|
cmd("dispatch_value")
|
||||||
|
|
||||||
|
eq({
|
||||||
|
{dispatch = "dispatch_value", host = "localhost", port = 1234},
|
||||||
|
}, rpc_connect_calls)
|
||||||
|
eq({}, vim_fn_calls)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should return the client_id value from vim.lsp.start", function()
|
||||||
|
eq(42, lsp.start({}))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should implement get_language_id correctly", function()
|
||||||
|
lsp.start({name = "server:/code"})
|
||||||
|
|
||||||
|
eq(1, #start_calls)
|
||||||
|
eq("python", start_calls[1][1].get_language_id(347, "ftype"))
|
||||||
|
eq({{"ale#lsp#GetLanguage", "server:/code", 347}}, vim_fn_calls)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should initialize clients with ALE correctly", function()
|
||||||
|
lsp.start({name = "server:/code"})
|
||||||
|
|
||||||
|
eq(1, #start_calls)
|
||||||
|
|
||||||
|
start_calls[1][1].on_init({server_capabilities = {cap = 1}})
|
||||||
|
|
||||||
|
eq({
|
||||||
|
{"ale#lsp#UpdateCapabilities", "server:/code", {cap = 1}},
|
||||||
|
}, vim_fn_calls)
|
||||||
|
eq(1, #defer_calls)
|
||||||
|
eq(2, #defer_calls[1])
|
||||||
|
eq("function", type(defer_calls[1][1]))
|
||||||
|
eq(0, defer_calls[1][2])
|
||||||
|
|
||||||
|
defer_calls[1][1]()
|
||||||
|
|
||||||
|
eq({
|
||||||
|
{"ale#lsp#UpdateCapabilities", "server:/code", {cap = 1}},
|
||||||
|
{"ale#lsp#CallInitCallbacks", "server:/code"},
|
||||||
|
}, vim_fn_calls)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should configure handlers correctly", function()
|
||||||
|
lsp.start({name = "server:/code"})
|
||||||
|
|
||||||
|
eq(1, #start_calls)
|
||||||
|
|
||||||
|
local handlers = start_calls[1][1].handlers
|
||||||
|
local handler_names = {}
|
||||||
|
|
||||||
|
-- get keys from handlers
|
||||||
|
for key, _ in pairs(handlers) do
|
||||||
|
-- add key to handler_names mapping
|
||||||
|
handler_names[key] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
eq({["textDocument/publishDiagnostics"] = true}, handler_names)
|
||||||
|
|
||||||
|
handlers["textDocument/publishDiagnostics"](nil, {
|
||||||
|
{
|
||||||
|
lnum = 1,
|
||||||
|
end_lnum = 2,
|
||||||
|
col = 3,
|
||||||
|
end_col = 5,
|
||||||
|
severity = 1,
|
||||||
|
code = "123",
|
||||||
|
message = "Warning message",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
eq({
|
||||||
|
{
|
||||||
|
"ale#lsp_linter#HandleLSPResponse",
|
||||||
|
"server:/code",
|
||||||
|
{
|
||||||
|
jsonrpc = "2.0",
|
||||||
|
method = "textDocument/publishDiagnostics",
|
||||||
|
params = {
|
||||||
|
{
|
||||||
|
lnum = 1,
|
||||||
|
end_lnum = 2,
|
||||||
|
col = 3,
|
||||||
|
end_col = 5,
|
||||||
|
severity = 1,
|
||||||
|
code = "123",
|
||||||
|
message = "Warning message",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, vim_fn_calls)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
51
test/lua/ale_var_spec.lua
Normal file
51
test/lua/ale_var_spec.lua
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
local eq = assert.are.same
|
||||||
|
local ale = require("ale")
|
||||||
|
|
||||||
|
describe("ale.var", function()
|
||||||
|
local buffer_map
|
||||||
|
|
||||||
|
setup(function()
|
||||||
|
_G.vim = {
|
||||||
|
api = {
|
||||||
|
nvim_buf_get_var = function(buffer, key)
|
||||||
|
local buffer_table = buffer_map[buffer] or {}
|
||||||
|
local value = buffer_table[key]
|
||||||
|
|
||||||
|
if value == nil then
|
||||||
|
error(key .. " is missing")
|
||||||
|
end
|
||||||
|
|
||||||
|
return value
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
g = {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
teardown(function()
|
||||||
|
_G.vim = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
buffer_map = {}
|
||||||
|
_G.vim.g = {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should return nil for undefined variables", function()
|
||||||
|
eq(nil, ale.var(1, "foo"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should return buffer-local values, if set", function()
|
||||||
|
_G.vim.g.ale_foo = "global-value"
|
||||||
|
buffer_map[1] = {ale_foo = "buffer-value"}
|
||||||
|
|
||||||
|
eq("buffer-value", ale.var(1, "foo"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should return global values, if set", function()
|
||||||
|
_G.vim.g.ale_foo = "global-value"
|
||||||
|
|
||||||
|
eq("global-value", ale.var(1, "foo"))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
61
test/lua/windows_escaping_spec.lua
Normal file
61
test/lua/windows_escaping_spec.lua
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
local eq = assert.are.same
|
||||||
|
local ale = require("ale")
|
||||||
|
|
||||||
|
describe("ale.escape for cmd.exe", function()
|
||||||
|
setup(function()
|
||||||
|
_G.vim = {
|
||||||
|
o = {
|
||||||
|
shell = "cmd.exe"
|
||||||
|
},
|
||||||
|
fn = {
|
||||||
|
fnamemodify = function(shell, _)
|
||||||
|
return shell
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
teardown(function()
|
||||||
|
_G.vim = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should allow not escape paths without special characters", function()
|
||||||
|
eq("C:", ale.escape("C:"))
|
||||||
|
eq("C:\\", ale.escape("C:\\"))
|
||||||
|
eq("python", ale.escape("python"))
|
||||||
|
eq("C:\\foo\\bar", ale.escape("C:\\foo\\bar"))
|
||||||
|
eq("/bar/baz", ale.escape("/bar/baz"))
|
||||||
|
eq("nul", ale.escape("nul"))
|
||||||
|
eq("'foo'", ale.escape("'foo'"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should escape Windows paths with spaces appropriately", function()
|
||||||
|
eq('"C:\\foo bar\\baz"', ale.escape('C:\\foo bar\\baz'))
|
||||||
|
eq('"^foo bar^"', ale.escape('^foo bar^'))
|
||||||
|
eq('"&foo bar&"', ale.escape('&foo bar&'))
|
||||||
|
eq('"|foo bar|"', ale.escape('|foo bar|'))
|
||||||
|
eq('"<foo bar<"', ale.escape('<foo bar<'))
|
||||||
|
eq('">foo bar>"', ale.escape('>foo bar>'))
|
||||||
|
eq('"^foo bar^"', ale.escape('^foo bar^'))
|
||||||
|
eq('"\'foo\' \'bar\'"', ale.escape('\'foo\' \'bar\''))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should use caret escapes on special characters", function()
|
||||||
|
eq('^^foo^^', ale.escape('^foo^'))
|
||||||
|
eq('^&foo^&', ale.escape('&foo&'))
|
||||||
|
eq('^|foo^|', ale.escape('|foo|'))
|
||||||
|
eq('^<foo^<', ale.escape('<foo<'))
|
||||||
|
eq('^>foo^>', ale.escape('>foo>'))
|
||||||
|
eq('^^foo^^', ale.escape('^foo^'))
|
||||||
|
eq('\'foo\'^^\'bar\'', ale.escape('\'foo\'^\'bar\''))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("should escape percent characters", function()
|
||||||
|
eq('%%foo%%', ale.escape('%foo%'))
|
||||||
|
eq('C:\foo%%\bar\baz%%', ale.escape('C:\foo%\bar\baz%'))
|
||||||
|
eq('"C:\foo bar%%\baz%%"', ale.escape('C:\foo bar%\baz%'))
|
||||||
|
eq('^^%%foo%%', ale.escape('^%foo%'))
|
||||||
|
eq('"^%%foo%% %%bar%%"', ale.escape('^%foo% %bar%'))
|
||||||
|
eq('"^%%foo%% %%bar%% """""', ale.escape('^%foo% %bar% ""'))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
57
test/script/run-lua-tests
Executable file
57
test/script/run-lua-tests
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
docker_flags=(--rm -v "$PWD:/testplugin" -v "$PWD/test:/home" -w /testplugin/test/lua "$DOCKER_RUN_IMAGE")
|
||||||
|
|
||||||
|
quiet=0
|
||||||
|
|
||||||
|
while [ $# -ne 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
-q)
|
||||||
|
quiet=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-?*)
|
||||||
|
echo "Invalid argument: $1" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
function filter-busted-output() {
|
||||||
|
local hit_failure_line=0
|
||||||
|
|
||||||
|
while read -r; do
|
||||||
|
if ((quiet)); then
|
||||||
|
# If we're using the quiet flag, the filter out lines until we hit
|
||||||
|
# the first line with "Failure" and then print the rest.
|
||||||
|
if ((hit_failure_line)); then
|
||||||
|
echo "$REPLY"
|
||||||
|
elif [[ "$REPLY" = *'Failure'* ]]; then
|
||||||
|
hit_failure_line=1
|
||||||
|
echo "$REPLY"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "$REPLY"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_code=0
|
||||||
|
|
||||||
|
set -o pipefail
|
||||||
|
"$DOCKER" run -a stdout "${docker_flags[@]}" /usr/bin/busted-5.1 \
|
||||||
|
-m '../../lua/?.lua;../../lua/?/init.lua' . \
|
||||||
|
--output utfTerminal | filter-busted-output || exit_code=$?
|
||||||
|
set +o pipefail
|
||||||
|
|
||||||
|
exit "$exit_code"
|
||||||
Reference in New Issue
Block a user