Regenerate nvim config
This commit is contained in:
@ -0,0 +1,30 @@
|
||||
describe('linter.ansible_lint', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.ansible_lint').parser
|
||||
local result = parser([[
|
||||
WARNING Listing 4 violation(s) that are fatal
|
||||
playbooks/roles/vim/tasks/common.yml:14: git-latest Git checkouts must contain explicit version
|
||||
playbooks/roles/vim/tasks/common.yml:39: git-latest Git checkouts must contain explicit version
|
||||
playbooks/roles/vim/tasks/common.yml:52: git-latest Git checkouts must contain explicit version
|
||||
playbooks/roles/vim/tasks/common.yml:65: no-changed-when Commands should not change things if nothing needs doing
|
||||
You can skip specific rules or tags by adding them to your configuration file:
|
||||
# .ansible-lint
|
||||
warn_list: # or 'skip_list' to silence them completely
|
||||
- git-latest # Git checkouts must contain explicit version
|
||||
- no-changed-when # Commands should not change things if nothing needs doing
|
||||
|
||||
Finished with 4 failure(s), 0 warning(s) on 1 files.
|
||||
]])
|
||||
assert.are.same(4, #result)
|
||||
local expected = {
|
||||
source = 'ansible-lint',
|
||||
message = 'git-latest Git checkouts must contain explicit version',
|
||||
lnum = 13,
|
||||
col = 0,
|
||||
end_lnum = 13,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
end)
|
||||
6
config/neovim/store/lazy-plugins/nvim-lint/tests/both.py
Executable file
6
config/neovim/store/lazy-plugins/nvim-lint/tests/both.py
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
sys.stdout.write('tests/both.py:10: foo\n')
|
||||
sys.stderr.write('tests/both.py:20: bar\n')
|
||||
@ -0,0 +1,47 @@
|
||||
describe('linter.checkpatch', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.checkpatch').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.c')
|
||||
local result = parser([[
|
||||
/foo.c:6: CHECK: Please don't use multiple blank lines
|
||||
/foo.c:8: WARNING: Missing a blank line after declarations
|
||||
/foo.c:10: ERROR: switch and case should be at the same indent
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(3, #result)
|
||||
|
||||
local expected_info = {
|
||||
source = 'checkpatch',
|
||||
message = 'Please don\'t use multiple blank lines',
|
||||
lnum = 5,
|
||||
col = 0,
|
||||
end_lnum = 5,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected_info, result[1])
|
||||
|
||||
local expected_warning = {
|
||||
source = 'checkpatch',
|
||||
message = 'Missing a blank line after declarations',
|
||||
lnum = 7,
|
||||
col = 0,
|
||||
end_lnum = 7,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
assert.are.same(expected_warning, result[2])
|
||||
|
||||
local expected_error = {
|
||||
source = 'checkpatch',
|
||||
message = 'switch and case should be at the same indent',
|
||||
lnum = 9,
|
||||
col = 0,
|
||||
end_lnum = 9,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected_error, result[3])
|
||||
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,44 @@
|
||||
describe('linter.checkstyle', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.checkstyle').parser
|
||||
local result = parser([[
|
||||
Starting audit...
|
||||
[WARN] src/main/java/com/foo/bar/ApiClient.java:75:1: 'member def modifier' has incorrect indentation level 0, expected level should be 2. [Indentation]
|
||||
[ERROR] src/main/java/com/foo/bar/ApiClient.java:187: Line is longer than 120 characters (found 143). [LineLength]
|
||||
[ERROR] src/main/java/com/foo/bar/ApiClient.java:6:3: 'method def' child has incorrect indentation level 2, expected level should be 4. [Indentation]
|
||||
Audit done.
|
||||
Checkstyle ends with 1 errors.
|
||||
]])
|
||||
assert.are.same(3, #result)
|
||||
local expected = {
|
||||
source = 'checkstyle',
|
||||
message = "'method def' child has incorrect indentation level 2, expected level should be 4. [Indentation]",
|
||||
lnum = 5,
|
||||
col = 2,
|
||||
end_lnum = 5,
|
||||
end_col = 2,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected, result[3])
|
||||
expected = {
|
||||
source = 'checkstyle',
|
||||
message = "Line is longer than 120 characters (found 143). [LineLength]",
|
||||
lnum = 186,
|
||||
col = 0,
|
||||
end_lnum = 186,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected, result[2])
|
||||
expected = {
|
||||
source = 'checkstyle',
|
||||
message = "'member def modifier' has incorrect indentation level 0, expected level should be 2. [Indentation]",
|
||||
lnum = 74,
|
||||
col = 0,
|
||||
end_lnum = 74,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,21 @@
|
||||
describe("linter.commitlint", function()
|
||||
it("can parse the output", function()
|
||||
local parser = require("lint.linters.commitlint").parser
|
||||
local result = parser([[
|
||||
⧗ input: foo: commitlint parser
|
||||
✖ type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
|
||||
|
||||
✖ found 1 problems, 0 warnings
|
||||
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
|
||||
]])
|
||||
assert.are.same(1, #result)
|
||||
local expected = {
|
||||
source = "commitlint",
|
||||
message = "type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]",
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,50 @@
|
||||
local function get_num_handles()
|
||||
local pid = vim.fn.getpid()
|
||||
local output = vim.fn.system({"lsof", "-p"}, tostring(pid))
|
||||
local lines = vim.split(output, "\n", { plain = true })
|
||||
return #lines
|
||||
end
|
||||
|
||||
describe('compiler', function()
|
||||
it('reads errors from both stdout and stderr', function()
|
||||
local a = vim.api
|
||||
local bufnr = a.nvim_create_buf(true, true)
|
||||
a.nvim_buf_set_name(bufnr, "tests/both.py")
|
||||
a.nvim_set_current_buf(bufnr)
|
||||
a.nvim_buf_set_option(bufnr, 'errorformat', '%f:%l: %m')
|
||||
a.nvim_buf_set_option(bufnr, 'makeprg', 'python tests/both.py')
|
||||
|
||||
local handles = get_num_handles()
|
||||
require('lint').try_lint('compiler')
|
||||
|
||||
vim.wait(5000, function() return next(vim.diagnostic.get(bufnr)) ~= nil end)
|
||||
|
||||
assert.are.same(handles, get_num_handles(), "shouldn't leak any handles")
|
||||
|
||||
local result = vim.diagnostic.get(bufnr)
|
||||
for _, d in pairs(result) do
|
||||
d.namespace = nil
|
||||
end
|
||||
local expected = {
|
||||
{
|
||||
bufnr = bufnr,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
lnum = 9,
|
||||
end_lnum = 9,
|
||||
message = 'foo',
|
||||
severity = 1,
|
||||
},
|
||||
{
|
||||
bufnr = bufnr,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
end_lnum = 19,
|
||||
lnum = 19,
|
||||
message = 'bar',
|
||||
severity = 1,
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,41 @@
|
||||
describe('linter.cppcheck', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.cppcheck').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.cpp')
|
||||
local result = parser([[
|
||||
/foo.cpp:46:7: [unusedVariable] style: Unused variable: fd
|
||||
/foo.cpp:366:3: [postfixOperator] performance: Prefer prefix ++/-- operators for non-primitive types.
|
||||
/foo.cpp:46:{column}: [unusedVariable] style: Unused variable: fd
|
||||
/foo.cpp:366:{column}: [postfixOperator] performance: Prefer prefix ++/-- operators for non-primitive types.
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(4, #result)
|
||||
|
||||
local expected_1_88 = {
|
||||
code = 'unusedVariable',
|
||||
source = 'cppcheck',
|
||||
message = 'Unused variable: fd',
|
||||
lnum = 45,
|
||||
col = 6,
|
||||
end_lnum = 45,
|
||||
end_col = 6,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
user_data = { lsp = { code = 'unusedVariable' } },
|
||||
}
|
||||
assert.are.same(expected_1_88, result[1])
|
||||
|
||||
local expected_1_34 = {
|
||||
code = 'unusedVariable',
|
||||
source = 'cppcheck',
|
||||
user_data = { lsp = { code = 'unusedVariable' } },
|
||||
message = 'Unused variable: fd',
|
||||
lnum = 45,
|
||||
col = 0,
|
||||
end_lnum = 45,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected_1_34, result[3])
|
||||
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,37 @@
|
||||
describe('linter.credo', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.credo').parser
|
||||
-- taken from example screenshot from credo's documentation https://hexdocs.pm/credo/overview.html
|
||||
-- 3rd record shouldn't get picked up because there is no file/line information
|
||||
local result = parser([[
|
||||
[R] → stdin:1:11 Unless conditions should avoid having an `else` block.
|
||||
[W] ↗ stdin:9:5 Use `reraise` inside a rescue block to preserve the original stacktrace.
|
||||
[W] ↗ Exception modules should be named consistently. It seems your strategy is to have `Error` ....
|
||||
]])
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_error = {
|
||||
col = 10,
|
||||
end_col = 10,
|
||||
lnum = 0,
|
||||
end_lnum = 0,
|
||||
severity = 1,
|
||||
message = 'Unless conditions should avoid having an `else` block.',
|
||||
source = 'credo',
|
||||
}
|
||||
|
||||
assert.are.same(expected_error, result[1])
|
||||
|
||||
expected_error = {
|
||||
col = 4,
|
||||
end_col = 4,
|
||||
lnum = 8,
|
||||
end_lnum = 8,
|
||||
severity = 2,
|
||||
message = 'Use `reraise` inside a rescue block to preserve the original stacktrace.',
|
||||
source = 'credo',
|
||||
}
|
||||
|
||||
assert.are.same(expected_error, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,58 @@
|
||||
describe('linter.cspell', function()
|
||||
it('can parse cspell output', function()
|
||||
local parser = require('lint.linters.cspell').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.txt')
|
||||
local result = parser([[
|
||||
/:259:8 - Unknown word (langserver)
|
||||
/:272:19 - Unknown word (noplugin)
|
||||
/:278:19 - Unknown word (noplugin)
|
||||
/:321:2 - Unknown word (checkstyle)
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(4, #result)
|
||||
|
||||
local expected_1 = {
|
||||
source = 'cspell',
|
||||
message = 'Unknown word (langserver)',
|
||||
lnum = 258,
|
||||
col = 7,
|
||||
end_lnum = 258,
|
||||
end_col = 17,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected_1, result[1])
|
||||
|
||||
local expected_2 = {
|
||||
source = 'cspell',
|
||||
message = 'Unknown word (noplugin)',
|
||||
lnum = 271,
|
||||
col = 18,
|
||||
end_lnum = 271,
|
||||
end_col = 26,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected_2, result[2])
|
||||
|
||||
local expected_3 = {
|
||||
source = 'cspell',
|
||||
message = 'Unknown word (noplugin)',
|
||||
lnum = 277,
|
||||
col = 18,
|
||||
end_lnum = 277,
|
||||
end_col = 26,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected_3, result[3])
|
||||
|
||||
local expected_4 = {
|
||||
source = 'cspell',
|
||||
message = 'Unknown word (checkstyle)',
|
||||
lnum = 320,
|
||||
col = 1,
|
||||
end_lnum = 320,
|
||||
end_col = 11,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected_4, result[4])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,23 @@
|
||||
describe("linter.deadnix", function()
|
||||
it("can parse the output", function()
|
||||
local parser = require("lint.linters.deadnix").parser
|
||||
local result = parser(
|
||||
[[
|
||||
{"file":"flake.nix","results":[{"column":17,"endColumn":21,"line":25,"message":"Unused lambda argument: prev"}]}
|
||||
]],
|
||||
vim.api.nvim_get_current_buf()
|
||||
)
|
||||
assert.are.same(1, #result)
|
||||
|
||||
local expected_diagnostics = {
|
||||
lnum = 24,
|
||||
end_lnum = 24,
|
||||
col = 16,
|
||||
end_col = 21,
|
||||
message = "Unused lambda argument: prev",
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
|
||||
assert.are.same(expected_diagnostics, result[1])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,175 @@
|
||||
describe("linter.eslint_d", function()
|
||||
it("should ignore empty output", function()
|
||||
local parser = require("lint.linters.eslint_d").parser
|
||||
|
||||
assert.are.same({}, parser("", vim.api.nvim_get_current_buf()))
|
||||
assert.are.same({}, parser(" ", vim.api.nvim_get_current_buf()))
|
||||
end)
|
||||
|
||||
it('should gracefully handle invalid JSON', function()
|
||||
local parser = require("lint.linters.eslint_d").parser
|
||||
|
||||
local json = '{]'
|
||||
local result = parser(json)
|
||||
local expected = {
|
||||
{
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
message = "Could not parse linter output due to: Expected object key string but found T_ARR_END at character 2\noutput: {]",
|
||||
source = "eslint_d",
|
||||
}
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
|
||||
it('uses 0 defaults for missing line/column', function()
|
||||
local parser = require("lint.linters.eslint_d").parser
|
||||
local json = '[{ "messages": [' ..
|
||||
-- Valid JSON diagnostic.
|
||||
[[
|
||||
{
|
||||
"column": 4,
|
||||
"endColumn": 8,
|
||||
"line": 1,
|
||||
"endLine": 1,
|
||||
"message": "foo message",
|
||||
"ruleId": "foo",
|
||||
"severity": 2
|
||||
},
|
||||
]] ..
|
||||
-- JSON diagnostic with missing line.
|
||||
[[
|
||||
{
|
||||
"column": 4,
|
||||
"endColumn": 8,
|
||||
"endLine": 1,
|
||||
"message": "bar message",
|
||||
"ruleId": "bar",
|
||||
"severity": 2
|
||||
},
|
||||
]] ..
|
||||
-- JSON diagnostic with missing column.
|
||||
[[
|
||||
{
|
||||
"endColumn": 8,
|
||||
"line": 1,
|
||||
"endLine": 1,
|
||||
"message": "baz message",
|
||||
"ruleId": "baz",
|
||||
"severity": 2
|
||||
}
|
||||
]] .. ']}]'
|
||||
local result = parser(json)
|
||||
|
||||
assert.are.same(3, #result)
|
||||
assert.are.same(0, result[2].lnum)
|
||||
assert.are.same(0, result[3].col)
|
||||
end)
|
||||
|
||||
it('should show fatal diagnostics on the first line', function()
|
||||
local parser = require("lint.linters.eslint_d").parser
|
||||
|
||||
local json = '[{ "messages": [ { "fatal": true, "message": "fatal", "severity": 2 } ]}]'
|
||||
local result = parser(json)
|
||||
|
||||
assert.are.same(1, #result)
|
||||
assert.are.same({
|
||||
col = 0,
|
||||
lnum = 0,
|
||||
message = "fatal",
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "eslint_d"
|
||||
}, result[1])
|
||||
end)
|
||||
|
||||
it('should parse valid diagnostics', function()
|
||||
local parser = require("lint.linters.eslint_d").parser
|
||||
|
||||
local json = '[{ "messages": [' ..
|
||||
-- JSON diagnostic with warn severity.
|
||||
[[
|
||||
{
|
||||
"column": 4,
|
||||
"endColumn": 8,
|
||||
"line": 12,
|
||||
"endLine": 14,
|
||||
"message": "foo message",
|
||||
"ruleId": "foo",
|
||||
"severity": 1
|
||||
},
|
||||
]] ..
|
||||
-- JSON diagnostic with error serverity.
|
||||
[[
|
||||
{
|
||||
"column": 16,
|
||||
"endColumn": 78,
|
||||
"line": 8,
|
||||
"endLine": 8,
|
||||
"message": "bar message",
|
||||
"ruleId": "bar",
|
||||
"severity": 2
|
||||
},
|
||||
]] ..
|
||||
-- JSON diagnostic without ruleId.
|
||||
[[
|
||||
{
|
||||
"column": 40,
|
||||
"endColumn": 78,
|
||||
"line": 122,
|
||||
"endLine": 124,
|
||||
"message": "baz message",
|
||||
"severity": 2
|
||||
},
|
||||
]] ..
|
||||
-- JSON diagnostic without end values,
|
||||
[[
|
||||
{
|
||||
"column": 36,
|
||||
"line": 92,
|
||||
"message": "qux message",
|
||||
"ruleId": "qux",
|
||||
"severity": 2
|
||||
}
|
||||
]] .. ']}]'
|
||||
local result = parser(json)
|
||||
|
||||
assert.are.same(4, #result)
|
||||
assert.are.same({
|
||||
code = "foo",
|
||||
col = 3,
|
||||
end_col = 7,
|
||||
end_lnum = 13,
|
||||
lnum = 11,
|
||||
message = "foo message",
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
source = "eslint_d"
|
||||
}, result[1])
|
||||
assert.are.same({
|
||||
code = "bar",
|
||||
col = 15,
|
||||
end_col = 77,
|
||||
end_lnum = 7,
|
||||
lnum = 7,
|
||||
message = "bar message",
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "eslint_d"
|
||||
}, result[2])
|
||||
assert.are.same({
|
||||
col = 39,
|
||||
end_col = 77,
|
||||
end_lnum = 123,
|
||||
lnum = 121,
|
||||
message = "baz message",
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "eslint_d"
|
||||
}, result[3])
|
||||
assert.are.same({
|
||||
code = "qux",
|
||||
col = 35,
|
||||
lnum = 91,
|
||||
message = "qux message",
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "eslint_d"
|
||||
}, result[4])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,47 @@
|
||||
describe("linter.hlint", function()
|
||||
it("can parse an error", function()
|
||||
-- Main.hs
|
||||
--
|
||||
-- (first
|
||||
--
|
||||
-- hlint Main.hs --json
|
||||
local parser = require("lint.linters.hlint").parser
|
||||
local result = parser([[
|
||||
[{"module":[],"decl":[],"severity":"Error","hint":"Parse error: possibly incorrect indentation or mismatched brackets","file":"Main.hs","startLine":2,"startColumn":1,"endLine":2,"endColumn":1,"from":" (first\n> \n","to":null,"note":[],"refactorings":"[]"}]
|
||||
]])
|
||||
assert.are.same(#result, 1)
|
||||
local expected = {
|
||||
lnum = 2,
|
||||
col = 1,
|
||||
end_lnum = 2,
|
||||
end_col = 1,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "hlint",
|
||||
message = "Parse error: possibly incorrect indentation or mismatched brackets",
|
||||
}
|
||||
assert.are.same(result[1], expected)
|
||||
end)
|
||||
|
||||
it("can parse a warning", function()
|
||||
-- Main.hs
|
||||
--
|
||||
-- concat (map f x)
|
||||
--
|
||||
-- hlint Main.hs --json
|
||||
local parser = require("lint.linters.hlint").parser
|
||||
local result = parser([[
|
||||
[{"module":["Main"],"decl":[],"severity":"Warning","hint":"Use concatMap","file":"Main.hs","startLine":1,"startColumn":1,"endLine":1,"endColumn":17,"from":"concat (map f x)","to":"concatMap f x","note":[],"refactorings":"[Replace {rtype = Expr, pos = SrcSpan {startLine = 1, startCol = 1, endLine = 1, endCol = 17}, subts = [(\"f\",SrcSpan {startLine = 1, startCol = 13, endLine = 1, endCol = 14}),(\"x\",SrcSpan {startLine = 1, startCol = 15, endLine = 1, endCol = 16})], orig = \"concatMap f x\"}]"}]
|
||||
]])
|
||||
assert.are.same(#result, 1)
|
||||
local expected = {
|
||||
lnum = 1,
|
||||
col = 1,
|
||||
end_lnum = 1,
|
||||
end_col = 17,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
source = "hlint",
|
||||
message = "Use concatMap: concatMap f x",
|
||||
}
|
||||
assert.are.same(result[1], expected)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,32 @@
|
||||
describe('linter.jsonlint', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.jsonlint').parser
|
||||
local result = parser([[
|
||||
/some/folder/test.json: line 3, col 7, found: 'INVALID' - expected: 'EOF', '}', ':', ',', ']'.
|
||||
test.json: line 5003, col 11, found: 'INVALID' - expected: 'STRING'.
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 2,
|
||||
end_lnum = 2,
|
||||
col = 6,
|
||||
end_col = 6,
|
||||
message = "found: 'INVALID' - expected: 'EOF', '}', ':', ',', ']'.",
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "jsonlint",
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
lnum = 5002,
|
||||
end_lnum = 5002,
|
||||
col = 10,
|
||||
end_col = 10,
|
||||
message = "found: 'INVALID' - expected: 'STRING'.",
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = "jsonlint",
|
||||
}
|
||||
assert.are.same(expected, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,55 @@
|
||||
describe('lint', function()
|
||||
local a = vim.api
|
||||
local bufnr = a.nvim_create_buf(true, true)
|
||||
a.nvim_buf_set_option(bufnr, 'filetype', 'ansible.yaml')
|
||||
local lint = require('lint')
|
||||
|
||||
it('resolves all linters for compound filetypes', function()
|
||||
lint.linters_by_ft = {
|
||||
ansible = {'ansible-lint'},
|
||||
yaml = {'yamllint'},
|
||||
}
|
||||
local names = lint._resolve_linter_by_ft('ansible.yaml')
|
||||
local expected = {'ansible-lint', 'yamllint'}
|
||||
table.sort(names, function(x, y) return x < y end)
|
||||
assert.are.same(expected, names)
|
||||
end)
|
||||
it('deduplicates linters for compound filetypes', function()
|
||||
lint.linters_by_ft = {
|
||||
ansible = {'ansible-lint','yamllint'},
|
||||
yaml = {'yamllint'},
|
||||
}
|
||||
local names = lint._resolve_linter_by_ft('ansible.yaml')
|
||||
local expected = {'ansible-lint', 'yamllint'}
|
||||
table.sort(names, function(x, y) return x < y end)
|
||||
assert.are.same(expected, names)
|
||||
end)
|
||||
|
||||
|
||||
it("get_running returns running linter", function()
|
||||
local linter = {
|
||||
name = "dummy",
|
||||
cmd = "python",
|
||||
args = {"tests/loop.py"},
|
||||
parser = require("lint.parser").from_errorformat("%f:%l: %m")
|
||||
}
|
||||
lint.linters.dummy = linter
|
||||
local orig_lint = lint.lint
|
||||
---@type lint.LintProc
|
||||
local captured_proc
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
lint.lint = function(...)
|
||||
captured_proc = assert(orig_lint(...))
|
||||
return captured_proc
|
||||
end
|
||||
lint.try_lint("dummy")
|
||||
assert.are.same({"dummy"}, lint.get_running())
|
||||
|
||||
assert(captured_proc)
|
||||
captured_proc:cancel()
|
||||
|
||||
vim.wait(500, function() return #lint.get_running() == 0 end)
|
||||
assert.are.same({}, lint.get_running())
|
||||
assert.is_false(captured_proc.handle:is_active())
|
||||
end)
|
||||
end)
|
||||
8
config/neovim/store/lazy-plugins/nvim-lint/tests/loop.py
Normal file
8
config/neovim/store/lazy-plugins/nvim-lint/tests/loop.py
Normal file
@ -0,0 +1,8 @@
|
||||
import asyncio
|
||||
|
||||
|
||||
async def sleep():
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
asyncio.run(sleep())
|
||||
@ -0,0 +1,33 @@
|
||||
describe('linter.markdownlint', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.markdownlint').parser
|
||||
local result = parser([[
|
||||
README.md:35 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## What's in this repo?"]
|
||||
README.md:36 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- `dotfiles`"]
|
||||
README.md:47:81 MD013/line-length Line length [Expected: 80; Actual: 114]
|
||||
README.md:55:81 MD013/line-length Line length [Expected: 80; Actual: 244]
|
||||
]])
|
||||
assert.are.same(4, #result)
|
||||
local expected = {
|
||||
source = 'markdownlint',
|
||||
message = 'MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## What\'s in this repo?"]',
|
||||
lnum = 34,
|
||||
col = 0,
|
||||
end_lnum = 34,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
source = 'markdownlint',
|
||||
message = 'MD013/line-length Line length [Expected: 80; Actual: 114]',
|
||||
lnum = 46,
|
||||
col = 80,
|
||||
end_lnum = 46,
|
||||
end_col = 80,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
assert.are.same(expected, result[3])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,50 @@
|
||||
describe("linter.markuplint", function()
|
||||
it("can parse the output", function()
|
||||
local parser = require("lint.linters.markuplint").parser
|
||||
local output = [[
|
||||
[
|
||||
{
|
||||
"severity": "error",
|
||||
"message": "The value of the \"id\" attribute is duplicated",
|
||||
"line": 12,
|
||||
"col": 8,
|
||||
"raw": "id=\"root\"",
|
||||
"ruleId": "id-duplication",
|
||||
"filePath": "/test/index.html"
|
||||
},
|
||||
{
|
||||
"severity": "warning",
|
||||
"message": "Require the \"h1\" element",
|
||||
"line": 1,
|
||||
"col": 1,
|
||||
"raw": "<",
|
||||
"ruleId": "required-h1",
|
||||
"filePath": "/test/index.html"
|
||||
}
|
||||
]
|
||||
]]
|
||||
|
||||
local result = parser(output)
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 11,
|
||||
col = 7,
|
||||
message = 'The value of the "id" attribute is duplicated',
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
code = "id-duplication",
|
||||
source = "markuplint",
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
message = 'Require the "h1" element',
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
code = "required-h1",
|
||||
source = "markuplint",
|
||||
}
|
||||
assert.are.same(expected, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,2 @@
|
||||
set rtp=.,../plenary.nvim,$VIMRUNTIME
|
||||
runtime! plugin/plenary.vim
|
||||
@ -0,0 +1,47 @@
|
||||
describe('linter.mlint', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.mlint').parser
|
||||
local result = parser([[
|
||||
L 1 (C 1): SCABE: ML5: The McCabe cyclomatic complexity is 2.
|
||||
L 1 (C 7-9): CLALL: ML0: Using 'clear' with the 'all' option usually decreases code performance and is often unnecessary.
|
||||
L 7 (C 18): ACABE: ML5: The McCabe cyclomatic complexity of the anonymous function on line 7 is 1.
|
||||
L 10 (C 48-51): SYNER: ML3: Parse error at recs: usage might be invalid MATLAB syntax.
|
||||
L 13 (C 1-3): RESWD: ML3: Invalid use of a reserved word.
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(5, #result)
|
||||
|
||||
local expected = {
|
||||
source = 'mlint',
|
||||
message = 'The McCabe cyclomatic complexity is 2.',
|
||||
severity = vim.diagnostic.severity.HINT,
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 0,
|
||||
code = 'SCABE',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'SCABE',
|
||||
}
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
source = 'mlint',
|
||||
message = 'Parse error at recs: usage might be invalid MATLAB syntax.',
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
lnum = 9,
|
||||
col = 47,
|
||||
end_lnum = 9,
|
||||
end_col = 50,
|
||||
code = 'SYNER',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'SYNER',
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result[4])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,35 @@
|
||||
describe('linter.mypy', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.mypy').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.py')
|
||||
local output = [[
|
||||
/foo.py:10:15:10:20: error: Incompatible return value type (got "str", expected "bool")
|
||||
/foo.py:20:25:20:30: error: Argument 1 to "foo" has incompatible type "str"; expected "int"
|
||||
]]
|
||||
local result = parser(output, bufnr)
|
||||
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_error = {
|
||||
source = 'mypy',
|
||||
message = 'Incompatible return value type (got "str", expected "bool")',
|
||||
lnum = 9,
|
||||
col = 14,
|
||||
end_lnum = 9,
|
||||
end_col = 20,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected_error, result[1])
|
||||
|
||||
local expected_warning = {
|
||||
source = 'mypy',
|
||||
message = 'Argument 1 to "foo" has incompatible type "str"; expected "int"',
|
||||
lnum = 19,
|
||||
col = 24,
|
||||
end_lnum = 19,
|
||||
end_col = 30,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected_warning, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,53 @@
|
||||
describe('linter.oelint-adv', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.oelint-adv').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.bb')
|
||||
local result = parser([[
|
||||
/foo.bb:1:error:oelint.var.mandatoryvar.HOMEPAGE:Variable 'HOMEPAGE' should be set
|
||||
/foo.bb:1:info:oelint.var.suggestedvar.CVE_PRODUCT:Variable 'CVE_PRODUCT' should be set
|
||||
/foo.bb:2:warning:oelint.vars.spacesassignment:Suggest spaces around variable assignment. E.g. 'FOO = "BAR"'
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(3, #result)
|
||||
|
||||
local expected_error = {
|
||||
code = 'oelint.var.mandatoryvar.HOMEPAGE',
|
||||
source = 'oelint-adv',
|
||||
message = 'Variable \'HOMEPAGE\' should be set',
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
user_data = { lsp = { code = 'oelint.var.mandatoryvar.HOMEPAGE' } },
|
||||
}
|
||||
assert.are.same(expected_error, result[1])
|
||||
|
||||
local expected_info = {
|
||||
code = 'oelint.var.suggestedvar.CVE_PRODUCT',
|
||||
source = 'oelint-adv',
|
||||
message = 'Variable \'CVE_PRODUCT\' should be set',
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
user_data = { lsp = { code = 'oelint.var.suggestedvar.CVE_PRODUCT' } },
|
||||
}
|
||||
assert.are.same(expected_info, result[2])
|
||||
|
||||
local expected_warning = {
|
||||
code = 'oelint.vars.spacesassignment',
|
||||
source = 'oelint-adv',
|
||||
message = 'Suggest spaces around variable assignment. E.g. \'FOO = "BAR"\'',
|
||||
lnum = 1,
|
||||
col = 0,
|
||||
end_lnum = 1,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
user_data = { lsp = { code = 'oelint.vars.spacesassignment' } },
|
||||
}
|
||||
assert.are.same(expected_warning, result[3])
|
||||
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,76 @@
|
||||
describe('from_errorformat', function()
|
||||
it('Parses single-line errorformat', function()
|
||||
local efm = '%f:%l:%c:%t:%n:%m'
|
||||
local skeleton = { source = 'test_case' }
|
||||
local parser = require('lint.parser').from_errorformat(efm, skeleton)
|
||||
local output = [[
|
||||
dir1/file1.txt:10:15:E:200:Big mistake
|
||||
dir2/file2.txt:20:25:W:300:Bigger mistake
|
||||
]]
|
||||
local result = parser(output)
|
||||
local expected = {
|
||||
{
|
||||
message = 'Big mistake',
|
||||
lnum = 9,
|
||||
col = 14,
|
||||
end_lnum = 9,
|
||||
end_col = 14,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = 'test_case',
|
||||
},
|
||||
{
|
||||
message = 'Bigger mistake',
|
||||
lnum = 19,
|
||||
col = 24,
|
||||
end_lnum = 19,
|
||||
end_col = 24,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
source = 'test_case',
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
|
||||
it('Strips newlines and whitespace from error message', function()
|
||||
-- NOTE: %m on subsequent line of multi-line emf will include a starting
|
||||
-- newline character
|
||||
local parser = require('lint.parser').from_errorformat('%W%l,%Z%m')
|
||||
assert.equals('Big Mistake', parser('10\n \t Big Mistake \t \n')[1].message)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('from_pattern', function()
|
||||
it('Uses source from defaults', function()
|
||||
local pattern = '(.*):(%d+):(%d+) (.*)'
|
||||
local groups = { '_', 'lnum', 'col', 'message' }
|
||||
local defaults = { source = 'test_case' }
|
||||
local severity_map = nil
|
||||
local parser = require('lint.parser').from_pattern(pattern, groups, severity_map, defaults)
|
||||
local output = [[
|
||||
foo:10:13 Big mistake
|
||||
bar:209:14 Bigger mistake
|
||||
]]
|
||||
local result = parser(output, 0)
|
||||
local expected = {
|
||||
{
|
||||
message = 'Big mistake',
|
||||
lnum = 9,
|
||||
col = 12,
|
||||
end_lnum = 9,
|
||||
end_col = 12,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = 'test_case',
|
||||
},
|
||||
{
|
||||
message = 'Bigger mistake',
|
||||
lnum = 208,
|
||||
col = 13,
|
||||
end_lnum = 208,
|
||||
end_col = 13,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = 'test_case',
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
end)
|
||||
116
config/neovim/store/lazy-plugins/nvim-lint/tests/php_spec.lua
Normal file
116
config/neovim/store/lazy-plugins/nvim-lint/tests/php_spec.lua
Normal file
@ -0,0 +1,116 @@
|
||||
describe('linter.php', function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require('lint.linters.php').parser
|
||||
parser('')
|
||||
parser(' ')
|
||||
end)
|
||||
|
||||
it("handles the default output when there are no errors or warnings", function()
|
||||
local parser = require('lint.linters.php').parser
|
||||
local result = parser('No syntax errors detected in Standard input code')
|
||||
assert.are.same(0, #result)
|
||||
end)
|
||||
|
||||
it("handles warnings in the output", function()
|
||||
local parser = require('lint.linters.php').parser
|
||||
local result = parser([[
|
||||
|
||||
Warning: The use statement with non-compound name 'Foo' has no effect in Standard input code on line 3
|
||||
|
||||
|
||||
Warning: The use statement with non-compound name 'Bar' has no effect in Standard input code on line 4
|
||||
|
||||
No syntax errors detected in Standard input code
|
||||
]])
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 2,
|
||||
end_lnum = 2,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'The use statement with non-compound name \'Foo\' has no effect',
|
||||
source = 'php',
|
||||
severity = vim.diagnostic.severity.WARN
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
lnum = 3,
|
||||
end_lnum = 3,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'The use statement with non-compound name \'Bar\' has no effect',
|
||||
source = 'php',
|
||||
severity = vim.diagnostic.severity.WARN
|
||||
}
|
||||
assert.are.same(expected, result[2])
|
||||
end)
|
||||
|
||||
it("handles a parse error in the output", function()
|
||||
local parser = require('lint.linters.php').parser
|
||||
local result = parser([[
|
||||
|
||||
Parse error: syntax error, unexpected token "function", expecting "," or ";" in Standard input code on line 9
|
||||
|
||||
Errors parsing Standard input code
|
||||
]])
|
||||
assert.are.same(1, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 8,
|
||||
end_lnum = 8,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'syntax error, unexpected token "function", expecting "," or ";"',
|
||||
source = 'php',
|
||||
severity = vim.diagnostic.severity.ERROR
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
|
||||
it("handles a fatal error in the output", function()
|
||||
local parser = require('lint.linters.php').parser
|
||||
local result = parser([[
|
||||
|
||||
Fatal error: Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in Standard input code on line 3
|
||||
|
||||
Errors parsing Standard input code
|
||||
]])
|
||||
assert.are.same(1, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 2,
|
||||
end_lnum = 2,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)`',
|
||||
source = 'php',
|
||||
severity = vim.diagnostic.severity.ERROR
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
|
||||
it("handles a deprecation notices in the output", function()
|
||||
local parser = require('lint.linters.php').parser
|
||||
local result = parser([[
|
||||
|
||||
Deprecated: Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter in Standard input code on line 3
|
||||
|
||||
No syntax errors detected in Standard input code
|
||||
]])
|
||||
assert.are.same(1, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 2,
|
||||
end_lnum = 2,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter',
|
||||
source = 'php',
|
||||
severity = vim.diagnostic.severity.INFO
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
|
||||
end)
|
||||
101
config/neovim/store/lazy-plugins/nvim-lint/tests/phpcs_spec.lua
Normal file
101
config/neovim/store/lazy-plugins/nvim-lint/tests/phpcs_spec.lua
Normal file
@ -0,0 +1,101 @@
|
||||
describe('linter.phpcs', function()
|
||||
it('ignores empty output', function()
|
||||
local parser = require('lint.linters.phpcs').parser
|
||||
|
||||
assert.are.same({}, parser('', vim.api.nvim_get_current_buf()))
|
||||
assert.are.same({}, parser(' ', vim.api.nvim_get_current_buf()))
|
||||
end)
|
||||
|
||||
it('parses json output correctly', function()
|
||||
local parser = require('lint.linters.phpcs').parser
|
||||
-- json sourced from sample here: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Reporting#printing-a-json-report
|
||||
-- slightly modified for STDIN result format
|
||||
local result = parser([[
|
||||
{
|
||||
"totals": {
|
||||
"errors": 4,
|
||||
"warnings": 1,
|
||||
"fixable": 3
|
||||
},
|
||||
"files": {
|
||||
"STDIN": {
|
||||
"errors": 4,
|
||||
"warnings": 1,
|
||||
"messages": [
|
||||
{
|
||||
"message": "Missing file doc comment",
|
||||
"source": "PEAR.Commenting.FileComment.Missing",
|
||||
"severity": 5,
|
||||
"type": "ERROR",
|
||||
"line": 2,
|
||||
"column": 1,
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"message": "TRUE, FALSE and NULL must be lowercase; expected \"false\" but found \"FALSE\"",
|
||||
"source": "Generic.PHP.LowerCaseConstant.Found",
|
||||
"severity": 5,
|
||||
"type": "ERROR",
|
||||
"line": 4,
|
||||
"column": 12,
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"message": "Line indented incorrectly; expected at least 4 spaces, found 1",
|
||||
"source": "PEAR.WhiteSpace.ScopeIndent.Incorrect",
|
||||
"severity": 5,
|
||||
"type": "ERROR",
|
||||
"line": 6,
|
||||
"column": 2,
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"message": "Missing function doc comment",
|
||||
"source": "PEAR.Commenting.FunctionComment.Missing",
|
||||
"severity": 5,
|
||||
"type": "ERROR",
|
||||
"line": 9,
|
||||
"column": 1,
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"message": "Inline control structures are discouraged",
|
||||
"source": "Generic.ControlStructures.InlineControlStructure.Discouraged",
|
||||
"severity": 5,
|
||||
"type": "WARNING",
|
||||
"line": 11,
|
||||
"column": 5,
|
||||
"fixable": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(5, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 1,
|
||||
end_lnum = 1,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'Missing file doc comment',
|
||||
code = 'PEAR.Commenting.FileComment.Missing',
|
||||
source = 'phpcs',
|
||||
severity = vim.diagnostic.severity.ERROR
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
lnum = 10,
|
||||
end_lnum = 10,
|
||||
col = 4,
|
||||
end_col = 4,
|
||||
message = 'Inline control structures are discouraged',
|
||||
code = 'Generic.ControlStructures.InlineControlStructure.Discouraged',
|
||||
source = 'phpcs',
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
assert.are.same(expected, result[5])
|
||||
end)
|
||||
end)
|
||||
114
config/neovim/store/lazy-plugins/nvim-lint/tests/phpmd_spec.lua
Normal file
114
config/neovim/store/lazy-plugins/nvim-lint/tests/phpmd_spec.lua
Normal file
@ -0,0 +1,114 @@
|
||||
describe('linter.phpmd', function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require('lint.linters.phpmd').parser
|
||||
parser('')
|
||||
parser(' ')
|
||||
end)
|
||||
|
||||
it("handles the default JSON output when there are no coding violations", function()
|
||||
local parser = require('lint.linters.phpmd').parser
|
||||
local result = parser([[
|
||||
{
|
||||
"version": "@package_version@",
|
||||
"package": "phpmd",
|
||||
"timestamp": "2023-07-12T20:09:31+01:00",
|
||||
"files": []
|
||||
}
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(0, #result)
|
||||
end)
|
||||
|
||||
it('parses json output correctly', function()
|
||||
local parser = require('lint.linters.phpmd').parser
|
||||
local result = parser([[
|
||||
{
|
||||
"version": "@package_version@",
|
||||
"package": "phpmd",
|
||||
"timestamp": "2023-07-12T19:28:55+01:00",
|
||||
"files": [
|
||||
{
|
||||
"file": "php:\/\/stdin",
|
||||
"violations": [
|
||||
{
|
||||
"beginLine": 11,
|
||||
"endLine": 326,
|
||||
"package": "Acme\\Example",
|
||||
"function": null,
|
||||
"class": "MyClass",
|
||||
"method": null,
|
||||
"description": "The class MyClass has an overall complexity of 61 which is very high. The configured complexity threshold is 50.",
|
||||
"rule": "ExcessiveClassComplexity",
|
||||
"ruleSet": "Code Size Rules",
|
||||
"externalInfoUrl": "https:\/\/phpmd.org\/rules\/codesize.html#excessiveclasscomplexity",
|
||||
"priority": 3
|
||||
},
|
||||
{
|
||||
"beginLine": 125,
|
||||
"endLine": 152,
|
||||
"package": "Acme\\Example",
|
||||
"function": null,
|
||||
"class": "MyClass",
|
||||
"method": "myMethod",
|
||||
"description": "The method myMethod() has a Cyclomatic Complexity of 10. The configured cyclomatic complexity threshold is 10.",
|
||||
"rule": "CyclomaticComplexity",
|
||||
"ruleSet": "Code Size Rules",
|
||||
"externalInfoUrl": "https:\/\/phpmd.org\/rules\/codesize.html#cyclomaticcomplexity",
|
||||
"priority": 3
|
||||
},
|
||||
{
|
||||
"beginLine": 146,
|
||||
"endLine": 146,
|
||||
"package": null,
|
||||
"function": null,
|
||||
"class": null,
|
||||
"method": null,
|
||||
"description": "Avoid excessively long variable names like $thisIsAVeryLongVariableName. Keep variable name length under 20.",
|
||||
"rule": "LongVariable",
|
||||
"ruleSet": "Naming Rules",
|
||||
"externalInfoUrl": "https:\/\/phpmd.org\/rules\/naming.html#longvariable",
|
||||
"priority": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(3, #result)
|
||||
|
||||
local expected = {
|
||||
lnum = 10,
|
||||
end_lnum = 325,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'The class MyClass has an overall complexity of 61 which is very high. The configured complexity threshold is 50.',
|
||||
code = 'ExcessiveClassComplexity',
|
||||
source = 'phpmd',
|
||||
severity = vim.diagnostic.severity.INFO
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
lnum = 124,
|
||||
end_lnum = 151,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'The method myMethod() has a Cyclomatic Complexity of 10. The configured cyclomatic complexity threshold is 10.',
|
||||
code = 'CyclomaticComplexity',
|
||||
source = 'phpmd',
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected, result[2])
|
||||
|
||||
expected = {
|
||||
lnum = 145,
|
||||
end_lnum = 145,
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
message = 'Avoid excessively long variable names like $thisIsAVeryLongVariableName. Keep variable name length under 20.',
|
||||
code = 'LongVariable',
|
||||
source = 'phpmd',
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
}
|
||||
assert.are.same(expected, result[3])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,60 @@
|
||||
local bufnr = vim.uri_to_bufnr('file:///test.php')
|
||||
|
||||
describe('linter.phpstan', function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require('lint.linters.phpstan').parser
|
||||
parser('')
|
||||
parser(' ')
|
||||
end)
|
||||
|
||||
it('parses json output correctly', function()
|
||||
local parser = require('lint.linters.phpstan').parser
|
||||
local result = parser(
|
||||
[[
|
||||
{
|
||||
"totals": {
|
||||
"errors": 0,
|
||||
"file_errors": 2
|
||||
},
|
||||
"files": {
|
||||
"/test.php": {
|
||||
"errors": 2,
|
||||
"messages": [
|
||||
{
|
||||
"message": "Ignored error pattern",
|
||||
"line": null,
|
||||
"ignorable": false
|
||||
},
|
||||
{
|
||||
"message": "Property never read, only written.",
|
||||
"line": 6,
|
||||
"ignorable": true,
|
||||
"tip": "See: https://phpstan.org/developing-extensions/always-read-written-properties"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"errors": []
|
||||
}
|
||||
]],
|
||||
bufnr
|
||||
)
|
||||
|
||||
local expected = {
|
||||
{
|
||||
col = 0,
|
||||
lnum = 0,
|
||||
message = 'Ignored error pattern',
|
||||
source = 'phpstan',
|
||||
},
|
||||
{
|
||||
col = 0,
|
||||
lnum = 5,
|
||||
message = 'Property never read, only written.',
|
||||
source = 'phpstan',
|
||||
},
|
||||
}
|
||||
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,85 @@
|
||||
describe('linter.prisma-lint', function()
|
||||
it('can parse prisma-lint output', function()
|
||||
local parser = require('lint.linters.prisma-lint').parser
|
||||
local result = parser([[
|
||||
{
|
||||
"violations": [
|
||||
{
|
||||
"ruleName": "model-name-mapping-snake-case",
|
||||
"message": "Model name must be mapped to \"user\".",
|
||||
"fileName": "/example/invalid-simple.prisma",
|
||||
"location": {
|
||||
"startLine": 1,
|
||||
"startColumn": 1,
|
||||
"endLine": 1,
|
||||
"endColumn": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"ruleName": "require-field",
|
||||
"message": "Missing required fields: \"createdAt\".",
|
||||
"fileName": "/example/invalid-simple.prisma",
|
||||
"location": {
|
||||
"startLine": 1,
|
||||
"startColumn": 1,
|
||||
"endLine": 1,
|
||||
"endColumn": 12
|
||||
}
|
||||
},
|
||||
{
|
||||
"ruleName": "field-name-mapping-snake-case",
|
||||
"message": "Field name must be mapped to snake case.",
|
||||
"fileName": "/example/invalid-simple.prisma",
|
||||
"location": {
|
||||
"startLine": 3,
|
||||
"startColumn": 3,
|
||||
"endLine": 3,
|
||||
"endColumn": 8
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]])
|
||||
|
||||
assert.are.same(3, #result)
|
||||
|
||||
local expected_1 = {
|
||||
source = 'prisma-lint',
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 12,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
message = 'Model name must be mapped to "user".',
|
||||
code = 'model-name-mapping-snake-case',
|
||||
}
|
||||
|
||||
assert.are.same(expected_1, result[1])
|
||||
|
||||
local expected_2 = {
|
||||
source = 'prisma-lint',
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 12,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
message = 'Missing required fields: "createdAt".',
|
||||
code = 'require-field',
|
||||
}
|
||||
|
||||
assert.are.same(expected_2, result[2])
|
||||
|
||||
local expected_3 = {
|
||||
source = 'prisma-lint',
|
||||
lnum = 2,
|
||||
col = 2,
|
||||
end_lnum = 2,
|
||||
end_col = 8,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
message = 'Field name must be mapped to snake case.',
|
||||
code = 'field-name-mapping-snake-case',
|
||||
}
|
||||
|
||||
assert.are.same(expected_3, result[3])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,50 @@
|
||||
describe('linter.pycodestyle', function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require('lint.linters.pycodestyle').parser
|
||||
parser('', vim.api.nvim_get_current_buf())
|
||||
parser(' ', vim.api.nvim_get_current_buf())
|
||||
end)
|
||||
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.pycodestyle').parser
|
||||
local result = parser([[
|
||||
test.py:26:1:E302:expected 2 blank lines, found 1
|
||||
test.py:37:80:E501:line too long (88 > 79 characters)
|
||||
test.py:69:48:W291:trailing whitespace
|
||||
test.py:411:13:E128:continuation line under-indented for visual indent
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(4, #result)
|
||||
local expected_error = {
|
||||
code = 'E302',
|
||||
source = 'pycodestyle',
|
||||
message = 'expected 2 blank lines, found 1',
|
||||
lnum = 25,
|
||||
col = 0,
|
||||
end_lnum = 25,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'E302',
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.are.same(expected_error, result[1])
|
||||
local expected_warning = {
|
||||
code = 'W291',
|
||||
source = 'pycodestyle',
|
||||
message = 'trailing whitespace',
|
||||
lnum = 68,
|
||||
end_lnum = 68,
|
||||
col = 47,
|
||||
end_col = 47,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'W291',
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.are.same(expected_warning, result[3])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,41 @@
|
||||
describe('linter.pydocstyle', function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require('lint.linters.pydocstyle').parser
|
||||
parser('')
|
||||
parser(' ')
|
||||
end)
|
||||
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.pydocstyle').parser
|
||||
local result = parser([[
|
||||
test.py:10 in public class `Foo`:
|
||||
D200: One-line docstring should fit on one line with quotes (found 3)
|
||||
test.py:20 in public class `Bar`:
|
||||
D208: Docstring is over-indented
|
||||
]]
|
||||
)
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_error = {
|
||||
source = 'pydocstyle',
|
||||
message = 'One-line docstring should fit on one line with quotes (found 3)',
|
||||
lnum = 9,
|
||||
col = 0,
|
||||
end_lnum = 9,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.HINT,
|
||||
}
|
||||
assert.are.same(expected_error, result[1])
|
||||
|
||||
local expected_warning = {
|
||||
source = 'pydocstyle',
|
||||
message = 'Docstring is over-indented',
|
||||
lnum = 19,
|
||||
col = 0,
|
||||
end_lnum = 19,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.HINT,
|
||||
}
|
||||
assert.are.same(expected_warning, result[2])
|
||||
end)
|
||||
end)
|
||||
130
config/neovim/store/lazy-plugins/nvim-lint/tests/pylint_spec.lua
Normal file
130
config/neovim/store/lazy-plugins/nvim-lint/tests/pylint_spec.lua
Normal file
@ -0,0 +1,130 @@
|
||||
describe('linter.pylint', function()
|
||||
it('can parse pylint output', function()
|
||||
local parser = require('lint.linters.pylint').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///two.py')
|
||||
local result = parser([[
|
||||
[
|
||||
{
|
||||
"type": "warning",
|
||||
"module": "two",
|
||||
"obj": "",
|
||||
"line": 4,
|
||||
"column": 0,
|
||||
"path": "/two.py",
|
||||
"symbol": "bad-indentation",
|
||||
"message": "Bad indentation. Found 2 spaces, expected 4",
|
||||
"message-id": "W0311"
|
||||
},
|
||||
{
|
||||
"type": "convention",
|
||||
"module": "two",
|
||||
"obj": "",
|
||||
"line": 1,
|
||||
"column": 0,
|
||||
"path": "/two.py",
|
||||
"symbol": "missing-module-docstring",
|
||||
"message": "Missing module docstring",
|
||||
"message-id": "C0114"
|
||||
},
|
||||
{
|
||||
"type": "refactor",
|
||||
"module": "two",
|
||||
"obj": "",
|
||||
"line": 3,
|
||||
"column": 3,
|
||||
"path": "/two.py",
|
||||
"symbol": "comparison-with-itself",
|
||||
"message": "Redundant comparison - 1 == 1",
|
||||
"message-id": "R0124"
|
||||
},
|
||||
{
|
||||
"type": "warning",
|
||||
"module": "two",
|
||||
"obj": "",
|
||||
"line": 5,
|
||||
"column": 4,
|
||||
"endLine": 5,
|
||||
"endColumn": 8,
|
||||
"path": "/two.py",
|
||||
"symbol": "unused-variable",
|
||||
"message": "Unused variable 'test'",
|
||||
"message-id": "W0612"
|
||||
}
|
||||
]
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(4, #result)
|
||||
|
||||
local expected_1 = {
|
||||
source = 'pylint',
|
||||
message = 'Bad indentation. Found 2 spaces, expected 4 (bad-indentation)',
|
||||
lnum = 3,
|
||||
col = 0,
|
||||
end_lnum = 3,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
code = 'W0311',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'W0311',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.are.same(expected_1, result[1])
|
||||
|
||||
local expected_2 = {
|
||||
source = 'pylint',
|
||||
message = 'Missing module docstring (missing-module-docstring)',
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.HINT,
|
||||
code = 'C0114',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'C0114',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.are.same(expected_2, result[2])
|
||||
|
||||
local expected_3 = {
|
||||
source = 'pylint',
|
||||
message = 'Redundant comparison - 1 == 1 (comparison-with-itself)',
|
||||
lnum = 2,
|
||||
col = 3,
|
||||
end_lnum = 2,
|
||||
end_col = 3,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
code = 'R0124',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'R0124',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.are.same(expected_3, result[3])
|
||||
|
||||
local expected_4 = {
|
||||
source = 'pylint',
|
||||
message = "Unused variable 'test' (unused-variable)",
|
||||
lnum = 4,
|
||||
col = 4,
|
||||
end_lnum = 4,
|
||||
end_col = 8,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
code = 'W0612',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'W0612',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
assert.are.same(expected_4, result[4])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,33 @@
|
||||
describe('linter.rpmspec', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.rpmspec').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.spec')
|
||||
local output = [[
|
||||
warning: Macro expanded in comment on line 1: %{?fedora}
|
||||
error: line 2: Unknown tag: %if
|
||||
]]
|
||||
local result = parser(output, bufnr)
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_warning_1 = {
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
end_lnum = 0,
|
||||
lnum = 0,
|
||||
message = 'Macro expanded in comment',
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
source = 'rpmspec',
|
||||
}
|
||||
local expected_error_1 = {
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
end_lnum = 1,
|
||||
lnum = 1,
|
||||
message = 'Unknown tag: %if',
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
source = 'rpmspec',
|
||||
}
|
||||
assert.are.same(expected_error_1, result[1])
|
||||
assert.are.same(expected_warning_1, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,82 @@
|
||||
describe('linter.rubocop', function()
|
||||
it('can parse rubocop output', function()
|
||||
local parser = require('lint.linters.rubocop').parser
|
||||
local result = parser([[
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"path": "test.rb",
|
||||
"offenses": [
|
||||
{
|
||||
"severity": "convention",
|
||||
"message": "Use snake_case for method names.",
|
||||
"cop_name": "Naming/MethodName",
|
||||
"corrected": false,
|
||||
"correctable": false,
|
||||
"location": {
|
||||
"start_line": 3,
|
||||
"start_column": 5,
|
||||
"last_line": 3,
|
||||
"last_column": 11,
|
||||
"length": 7,
|
||||
"line": 3,
|
||||
"column": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"severity": "warning",
|
||||
"message": "Useless assignment to variable - `foo`.",
|
||||
"cop_name": "Lint/UselessAssignment",
|
||||
"corrected": false,
|
||||
"correctable": false,
|
||||
"location": {
|
||||
"start_line": 4,
|
||||
"start_column": 3,
|
||||
"last_line": 4,
|
||||
"last_column": 5,
|
||||
"length": 3,
|
||||
"line": 4,
|
||||
"column": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]])
|
||||
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_1 = {
|
||||
source = 'rubocop',
|
||||
lnum = 2,
|
||||
col = 4,
|
||||
end_lnum = 2,
|
||||
end_col = 11,
|
||||
severity = vim.diagnostic.severity.HINT,
|
||||
message = 'Use snake_case for method names.',
|
||||
code = 'Naming/MethodName',
|
||||
}
|
||||
|
||||
assert.are.same(expected_1, result[1])
|
||||
|
||||
local expected_2 = {
|
||||
source = 'rubocop',
|
||||
lnum = 3,
|
||||
col = 2,
|
||||
end_lnum = 3,
|
||||
end_col = 5,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
message = 'Useless assignment to variable - `foo`.',
|
||||
code = 'Lint/UselessAssignment',
|
||||
}
|
||||
|
||||
assert.are.same(expected_2, result[2])
|
||||
end)
|
||||
|
||||
it('can handle rubocop excluding the file', function()
|
||||
local parser = require('lint.linters.rubocop').parser
|
||||
local result = parser([[{ "files": [] }]])
|
||||
assert.are.same(0, #result)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,50 @@
|
||||
describe('linter.ruby', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.ruby').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.rb')
|
||||
local output = [[
|
||||
/foo.rb:2: warning: key :bar is duplicated and overwritten on line 2
|
||||
/foo.rb:2: warning: unused literal ignored
|
||||
/foo.rb:3: syntax error, unexpected end-of-input
|
||||
]]
|
||||
local result = parser(output, bufnr)
|
||||
|
||||
assert.are.same(3, #result)
|
||||
|
||||
local expected_warning_1 = {
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
end_lnum = 1,
|
||||
lnum = 1,
|
||||
message = 'key :bar is duplicated and overwritten on line 2',
|
||||
severity = 2,
|
||||
source = 'ruby',
|
||||
}
|
||||
|
||||
assert.are.same(expected_warning_1, result[1])
|
||||
|
||||
local expected_warning_2 = {
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
end_lnum = 1,
|
||||
lnum = 1,
|
||||
message = 'unused literal ignored',
|
||||
severity = 2,
|
||||
source = 'ruby',
|
||||
}
|
||||
|
||||
assert.are.same(expected_warning_2, result[2])
|
||||
|
||||
local expected_error_1 = {
|
||||
col = 0,
|
||||
end_col = 0,
|
||||
end_lnum = 2,
|
||||
lnum = 2,
|
||||
message = 'unexpected end-of-input',
|
||||
severity = 1,
|
||||
source = 'ruby',
|
||||
}
|
||||
|
||||
assert.are.same(expected_error_1, result[3])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,84 @@
|
||||
describe("linter.saltlint", function()
|
||||
it("can parse the output", function()
|
||||
local parser = require("lint.linters.saltlint").parser
|
||||
local result = parser([[
|
||||
[
|
||||
{
|
||||
"id": "903",
|
||||
"message": "State 'virt.reverted' is deprecated since SaltStack version '2016.3.0'",
|
||||
"filename": "/tmp/tmpybp_b5bk.sls",
|
||||
"linenumber": 3,
|
||||
"line": " virt.reverted:",
|
||||
"severity": "HIGH"
|
||||
},
|
||||
{
|
||||
"id": "217",
|
||||
"message": "\"requires\" looks like a typo. Did you mean \"require\"?",
|
||||
"filename": "/tmp/tmpybp_b5bk.sls",
|
||||
"linenumber": 9,
|
||||
"line": " - requires: foo",
|
||||
"severity": "LOW"
|
||||
},
|
||||
{
|
||||
"id": "201",
|
||||
"message": "Trailing whitespace",
|
||||
"filename": "/tmp/tmpybp_b5bk.sls",
|
||||
"linenumber": 12,
|
||||
"line": " file.create: ",
|
||||
"severity": "INFO"
|
||||
},
|
||||
{
|
||||
"id": "204",
|
||||
"message": "Lines should be no longer than 160 chars",
|
||||
"filename": "/tmp/tmpybp_b5bk.sls",
|
||||
"linenumber": 17,
|
||||
"line": " - name: test_long_line_aaa...",
|
||||
"severity": "VERY_LOW"
|
||||
}
|
||||
]
|
||||
]])
|
||||
|
||||
-- Count of results
|
||||
assert.are.same(4, #result)
|
||||
|
||||
-- JSON diagnostic with HIGH severity
|
||||
assert.are.same({
|
||||
lnum = 2,
|
||||
col = 1,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
message = "State 'virt.reverted' is deprecated since SaltStack version '2016.3.0'",
|
||||
source = "salt-lint",
|
||||
code = "903",
|
||||
}, result[1])
|
||||
|
||||
-- JSON diagnostic with LOW severity
|
||||
assert.are.same({
|
||||
lnum = 8,
|
||||
col = 1,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
message = '"requires" looks like a typo. Did you mean "require"?',
|
||||
source = "salt-lint",
|
||||
code = "217",
|
||||
}, result[2])
|
||||
|
||||
-- JSON diagnostic with INFO severity
|
||||
assert.are.same({
|
||||
lnum = 11,
|
||||
col = 1,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
message = "Trailing whitespace",
|
||||
source = "salt-lint",
|
||||
code = "201",
|
||||
}, result[3])
|
||||
|
||||
-- JSON diagnostic with VERY_LOW severity
|
||||
assert.are.same({
|
||||
lnum = 16,
|
||||
col = 1,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
message = "Lines should be no longer than 160 chars",
|
||||
source = "salt-lint",
|
||||
code = "204",
|
||||
}, result[4])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,81 @@
|
||||
describe("linter.snyk_iac", function()
|
||||
it("Parses output sample", function()
|
||||
local parser = require("lint.linters.snyk_iac").parser
|
||||
local bufnr = vim.uri_to_bufnr("file:///main.tf")
|
||||
local output = [[
|
||||
{
|
||||
"meta": {
|
||||
"isPrivate": true,
|
||||
"isLicensesEnabled": false,
|
||||
"ignoreSettings": {
|
||||
"adminOnly": true,
|
||||
"reasonRequired": true,
|
||||
"disregardFilesystemIgnores": false
|
||||
},
|
||||
"org": "",
|
||||
"orgPublicId": "",
|
||||
"policy": ""
|
||||
},
|
||||
"filesystemPolicy": false,
|
||||
"vulnerabilities": [],
|
||||
"dependencyCount": 0,
|
||||
"licensesPolicy": null,
|
||||
"ignoreSettings": null,
|
||||
"targetFile": "main.tf",
|
||||
"projectName": "example-tf",
|
||||
"org": "",
|
||||
"policy": "",
|
||||
"isPrivate": true,
|
||||
"targetFilePath": "/home/Projects/tmp/example-tf/main.tf",
|
||||
"packageManager": "terraformconfig",
|
||||
"path": "main.tf",
|
||||
"projectType": "terraformconfig",
|
||||
"ok": false,
|
||||
"infrastructureAsCodeIssues": [
|
||||
{
|
||||
"id": "SNYK-CC-TF-119",
|
||||
"title": "IAM Policy grants full administrative rights",
|
||||
"severity": "medium",
|
||||
"isIgnored": false,
|
||||
"subType": "IAM",
|
||||
"documentation": "https://security.snyk.io/rules/cloud/SNYK-CC-TF-119",
|
||||
"isGeneratedByCustomRule": false,
|
||||
"issue": "The IAM Policy grants all permissions to all resources",
|
||||
"impact": "Any identity with this policy will have full administrative rights in the account",
|
||||
"resolve": "Set `Actions` and `Resources` attributes to limited subset, e.g `Actions: ['s3:Create*']`",
|
||||
"remediation": {
|
||||
"cloudformation": "Set `Actions` and `Resources` attributes to limited subset, e.g `Actions: ['s3:Create*']`",
|
||||
"terraform": "Set `Actions` and `Resources` attributes to limited subset, e.g `Actions: ['s3:Create*']`"
|
||||
},
|
||||
"lineNumber": 20,
|
||||
"iacDescription": {
|
||||
"issue": "The IAM Policy grants all permissions to all resources",
|
||||
"impact": "Any identity with this policy will have full administrative rights in the account",
|
||||
"resolve": "Set `Actions` and `Resources` attributes to limited subset, e.g `Actions: ['s3:Create*']`"
|
||||
},
|
||||
"publicId": "SNYK-CC-TF-119",
|
||||
"msg": "data.aws_iam_policy_document[foo]",
|
||||
"references": [
|
||||
"https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html"
|
||||
],
|
||||
"path": ["data", "aws_iam_policy_document[foo]"],
|
||||
"compliance": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]]
|
||||
local result = parser(output, bufnr)
|
||||
local expected = {
|
||||
{
|
||||
source = "snyk",
|
||||
message = "IAM Policy grants full administrative rights - The IAM Policy grants all permissions to all resources - Any identity with this policy will have full administrative rights in the account",
|
||||
lnum = 19,
|
||||
end_lnum = 19,
|
||||
col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
code = "SNYK-CC-TF-119",
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,79 @@
|
||||
describe('linter.sqlfluff', function()
|
||||
it('multi-line output from sqlfluff', function()
|
||||
local parser = require('lint.linters.sqlfluff').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///non-existent.sql')
|
||||
-- actual output I got from running sqlfluff
|
||||
local result = parser([[
|
||||
[{"filepath": "stdin", "violations": [{"start_line_no": 68, "start_line_pos": 1, "code": "L003", "description": "Expected 1 indentation, found 0 [compared to line 52]"}, {"start_line_no": 68, "start_line_pos": 1, "code": "L013", "description": "Column expression without alias. Use explicit `AS` clause."}]}]
|
||||
|
||||
]], bufnr)
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected = {}
|
||||
expected[1] = {
|
||||
source = 'sqlfluff',
|
||||
message = 'Expected 1 indentation, found 0 [compared to line 52]',
|
||||
lnum = 67, -- mind the line indexing
|
||||
col = 0, -- mind the column indexing
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
user_data = {lsp = {code = 'L003'}},
|
||||
}
|
||||
assert.are.same(expected[1], result[1])
|
||||
|
||||
expected[2] = {
|
||||
source = 'sqlfluff',
|
||||
message = 'Column expression without alias. Use explicit `AS` clause.',
|
||||
lnum = 67,
|
||||
col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
user_data = {lsp = {code = 'L013'}},
|
||||
}
|
||||
assert.are.same(expected[2], result[2])
|
||||
|
||||
end)
|
||||
it('multi-line output from sqlfluff: old version', function()
|
||||
local parser = require('lint.linters.sqlfluff').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///non-existent.sql')
|
||||
-- actual output I got from running sqlfluff
|
||||
local result = parser([[
|
||||
[{"filepath": "stdin", "violations": [{"line_no": 68, "line_pos": 1, "code": "L003", "description": "Expected 1 indentation, found 0 [compared to line 52]"}, {"line_no": 68, "line_pos": 1, "code": "L013", "description": "Column expression without alias. Use explicit `AS` clause."}]}]
|
||||
|
||||
]], bufnr)
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected = {}
|
||||
expected[1] = {
|
||||
source = 'sqlfluff',
|
||||
message = 'Expected 1 indentation, found 0 [compared to line 52]',
|
||||
lnum = 67, -- mind the line indexing
|
||||
col = 0, -- mind the column indexing
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
user_data = {lsp = {code = 'L003'}},
|
||||
}
|
||||
assert.are.same(expected[1], result[1])
|
||||
|
||||
expected[2] = {
|
||||
source = 'sqlfluff',
|
||||
message = 'Column expression without alias. Use explicit `AS` clause.',
|
||||
lnum = 67,
|
||||
col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
user_data = {lsp = {code = 'L013'}},
|
||||
}
|
||||
assert.are.same(expected[2], result[2])
|
||||
|
||||
end)
|
||||
it("bad CLI args end in non-json output", function()
|
||||
local parser = require('lint.linters.sqlfluff').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///non-existent.sql')
|
||||
-- when problems are encountered, sqlfluff will report with plain text and
|
||||
-- not a formatted json
|
||||
local status, _ = pcall(parser, [[
|
||||
Error: Unknown dialect 'postgresql'
|
||||
]], bufnr)
|
||||
|
||||
-- not breaking should be enough, the parsing error is reported as "problem in first line-col"
|
||||
assert(status)
|
||||
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,47 @@
|
||||
describe('linter.staticcheck', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.staticcheck').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///main.go')
|
||||
local result = parser([[
|
||||
{"code":"S1001","severity":"error","location":{"file":"/main.go","line":8,"column":2},"end":{"file":"/main.go","line":8,"column":23},"message":"should use copy() instead of a loop"}
|
||||
{"code":"S1002","severity":"error","location":{"file":"/main.go","line":13,"column":5},"end":{"file":"/main.go","line":13,"column":14},"message":"should omit comparison to bool constant, can be simplified to x"}
|
||||
{"code":"S1002","severity":"error","location":{"file":"/sub.go","line":7,"column":5},"end":{"file":"/sub.go","line":7,"column":14},"message":"should omit comparison to bool constant, can be simplified to y"}
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_error_1 = {
|
||||
code = 'S1001',
|
||||
col = 1,
|
||||
end_col = 22,
|
||||
end_lnum = 7,
|
||||
lnum = 7,
|
||||
message = 'should use copy() instead of a loop',
|
||||
severity = 1,
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'S1001'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.are.same(expected_error_1, result[1])
|
||||
|
||||
local expected_error_2 = {
|
||||
code = 'S1002',
|
||||
col = 4,
|
||||
end_col = 13,
|
||||
end_lnum = 12,
|
||||
lnum = 12,
|
||||
message = 'should omit comparison to bool constant, can be simplified to x',
|
||||
severity = 1,
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'S1002'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.are.same(expected_error_2, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,47 @@
|
||||
describe("linter.swiftlint", function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require("lint.linters.swiftlint")().parser
|
||||
parser("", vim.api.nvim_get_current_buf())
|
||||
parser(" ", vim.api.nvim_get_current_buf())
|
||||
end)
|
||||
|
||||
it("can parse the output", function()
|
||||
local parser = require("lint.linters.swiftlint")().parser
|
||||
local result = parser(
|
||||
[[
|
||||
Linting 'File1.swift' (217/1344)
|
||||
Linting 'File2.swift' (218/1344)
|
||||
Linting 'MainViewModel.swift' (219/1344)
|
||||
/path/to/file/MainViewModel.swift:652:12: warning: File Length Violation: File should contain 500 lines or less: currently contains 652 (file_length)
|
||||
Linting 'DetailsViewModel.swift.swift' (217/1344)
|
||||
/path/to/file/DetailsViewModel.swift:12:14: error: Type Body Length Violation: Type body should span 700 lines or less excluding comments and whitespace: currently spans 738 lines (type_body_length)
|
||||
Linting 'File3.swift' (218/1344)
|
||||
Linting 'File4.swift' (219/1344)
|
||||
]],
|
||||
vim.api.nvim_get_current_buf()
|
||||
)
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected_warning = {
|
||||
source = "swiftlint",
|
||||
message = "File Length Violation: File should contain 500 lines or less: currently contains 652 (file_length)",
|
||||
lnum = 651,
|
||||
end_lnum = 651,
|
||||
col = 11,
|
||||
end_col = 11,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
assert.are.same(expected_warning, result[1])
|
||||
|
||||
local expected_error = {
|
||||
source = "swiftlint",
|
||||
message = "Type Body Length Violation: Type body should span 700 lines or less excluding comments and whitespace: currently spans 738 lines (type_body_length)",
|
||||
lnum = 11,
|
||||
end_lnum = 11,
|
||||
col = 13,
|
||||
end_col = 13,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
}
|
||||
assert.are.same(expected_error, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,53 @@
|
||||
describe('linter.systemdlint', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.systemdlint').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.service')
|
||||
local result = parser([[
|
||||
/foo.service:1:error:ExecNotFound:Command referenced not found
|
||||
/foo.service:2:info:NoFailureCheck:Return-code check is disabled. Errors are not reported
|
||||
/foo.service:3:warning:ReferencedUnitNotFound:The Unit 'bar.service' referenced was not found in filesystem
|
||||
]], bufnr)
|
||||
|
||||
assert.are.same(3, #result)
|
||||
|
||||
local expected_error = {
|
||||
code = 'ExecNotFound',
|
||||
source = 'systemdlint',
|
||||
message = 'Command referenced not found',
|
||||
lnum = 0,
|
||||
col = 0,
|
||||
end_lnum = 0,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
user_data = { lsp = { code = 'ExecNotFound' } },
|
||||
}
|
||||
assert.are.same(expected_error, result[1])
|
||||
|
||||
local expected_info = {
|
||||
code = 'NoFailureCheck',
|
||||
source = 'systemdlint',
|
||||
message = 'Return-code check is disabled. Errors are not reported',
|
||||
lnum = 1,
|
||||
col = 0,
|
||||
end_lnum = 1,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.INFO,
|
||||
user_data = { lsp = { code = 'NoFailureCheck' } },
|
||||
}
|
||||
assert.are.same(expected_info, result[2])
|
||||
|
||||
local expected_warning = {
|
||||
code = 'ReferencedUnitNotFound',
|
||||
source = 'systemdlint',
|
||||
message = 'The Unit \'bar.service\' referenced was not found in filesystem',
|
||||
lnum = 2,
|
||||
col = 0,
|
||||
end_lnum = 2,
|
||||
end_col = 0,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
user_data = { lsp = { code = 'ReferencedUnitNotFound' } },
|
||||
}
|
||||
assert.are.same(expected_warning, result[3])
|
||||
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,22 @@
|
||||
describe('linter.tflint', function()
|
||||
it('Parses output sample', function()
|
||||
local parser = require('lint.linters.tflint').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///main.tf')
|
||||
local result = parser(
|
||||
[[{"issues":[{"rule":{"name":"terraform_required_providers","severity":"warning","link":"https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/docs/rules/terraform_required_providers.md"},"message":"Missing version constraint for provider \"aws\" in \"required_providers\"","range":{"filename":"main.tf","start":{"line":19,"column":1},"end":{"line":19,"column":15}},"callers":[]}],"errors":[]}]],
|
||||
bufnr
|
||||
)
|
||||
assert.are.same(1, #result)
|
||||
local expected = {
|
||||
source = 'tflint',
|
||||
message = 'Missing version constraint for provider "aws" in "required_providers" (terraform_required_providers)\nReference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.2.2/docs/rules/terraform_required_providers.md',
|
||||
lnum = 19,
|
||||
col = 1,
|
||||
end_lnum = 19,
|
||||
end_col = 15,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
}
|
||||
|
||||
assert.are.same(expected, result[1])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,49 @@
|
||||
describe('linter.tfsec', function()
|
||||
it('Parses output sample', function()
|
||||
local parser = require('lint.linters.tfsec').parser
|
||||
local bufnr = vim.uri_to_bufnr('file:///main.tf')
|
||||
local output = [[
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"rule_id": "AVD-AWS-0065",
|
||||
"long_id": "aws-kms-auto-rotate-keys",
|
||||
"rule_description": "A KMS key is not configured to auto-rotate.",
|
||||
"rule_provider": "aws",
|
||||
"rule_service": "kms",
|
||||
"impact": "Long life KMS keys increase the attack surface when compromised",
|
||||
"resolution": "Configure KMS key to auto rotate",
|
||||
"links": [
|
||||
"https://aquasecurity.github.io/tfsec/v1.28.1/checks/aws/kms/auto-rotate-keys/",
|
||||
"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key#enable_key_rotation"
|
||||
],
|
||||
"description": "Key does not have rotation enabled.",
|
||||
"severity": "MEDIUM",
|
||||
"warning": false,
|
||||
"status": 0,
|
||||
"resource": "aws_kms_key.key",
|
||||
"location": {
|
||||
"filename": "/main.tf",
|
||||
"start_line": 1,
|
||||
"end_line": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]]
|
||||
local result = parser(output, bufnr)
|
||||
local expected = {
|
||||
{
|
||||
source = 'tfsec',
|
||||
message = "Key does not have rotation enabled. Long life KMS keys increase the attack surface when compromised",
|
||||
lnum = 0,
|
||||
end_lnum = 3,
|
||||
col = 1,
|
||||
end_col = 4,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
code = "AVD-AWS-0065",
|
||||
}
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
end)
|
||||
101
config/neovim/store/lazy-plugins/nvim-lint/tests/trivy_spec.lua
Normal file
101
config/neovim/store/lazy-plugins/nvim-lint/tests/trivy_spec.lua
Normal file
@ -0,0 +1,101 @@
|
||||
describe("linter.trivy", function()
|
||||
it("Parses output sample", function()
|
||||
local parser = require("lint.linters.trivy").parser
|
||||
local bufnr = vim.uri_to_bufnr("file:///main.tf")
|
||||
local output = [[
|
||||
{
|
||||
"SchemaVersion": 2,
|
||||
"ArtifactName": "main.tf",
|
||||
"ArtifactType": "filesystem",
|
||||
"Metadata": {
|
||||
"ImageConfig": {
|
||||
"architecture": "",
|
||||
"created": "0001-01-01T00:00:00Z",
|
||||
"os": "",
|
||||
"rootfs": {
|
||||
"type": "",
|
||||
"diff_ids": null
|
||||
},
|
||||
"config": {}
|
||||
}
|
||||
},
|
||||
"Results": [
|
||||
{
|
||||
"Target": ".",
|
||||
"Class": "config",
|
||||
"Type": "terraform",
|
||||
"MisconfSummary": {
|
||||
"Successes": 1,
|
||||
"Failures": 0,
|
||||
"Exceptions": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"Target": "main.tf",
|
||||
"Class": "config",
|
||||
"Type": "terraform",
|
||||
"MisconfSummary": {
|
||||
"Successes": 0,
|
||||
"Failures": 1,
|
||||
"Exceptions": 0
|
||||
},
|
||||
"Misconfigurations": [
|
||||
{
|
||||
"Type": "Terraform Security Check",
|
||||
"ID": "AVD-AWS-0065",
|
||||
"AVDID": "AVD-AWS-0065",
|
||||
"Title": "A KMS key is not configured to auto-rotate.",
|
||||
"Description": "You should configure your KMS keys to auto rotate to maintain security and defend against compromise.",
|
||||
"Message": "Key does not have rotation enabled.",
|
||||
"Query": "data..",
|
||||
"Resolution": "Configure KMS key to auto rotate",
|
||||
"Severity": "MEDIUM",
|
||||
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0065",
|
||||
"References": [
|
||||
"https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html",
|
||||
"https://avd.aquasec.com/misconfig/avd-aws-0065"
|
||||
],
|
||||
"Status": "FAIL",
|
||||
"Layer": {},
|
||||
"CauseMetadata": {
|
||||
"Resource": "aws_kms_key.foo",
|
||||
"Provider": "AWS",
|
||||
"Service": "kms",
|
||||
"StartLine": 15,
|
||||
"EndLine": 15,
|
||||
"Code": {
|
||||
"Lines": [
|
||||
{
|
||||
"Number": 15,
|
||||
"Content": "resource \"aws_kms_key\" \"foo\" {}",
|
||||
"IsCause": true,
|
||||
"Annotation": "",
|
||||
"Truncated": false,
|
||||
"FirstCause": true,
|
||||
"LastCause": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]]
|
||||
local result = parser(output, bufnr)
|
||||
local expected = {
|
||||
{
|
||||
source = "trivy",
|
||||
message = "A KMS key is not configured to auto-rotate. You should configure your KMS keys to auto rotate to maintain security and defend against compromise.",
|
||||
lnum = 14,
|
||||
end_lnum = 14,
|
||||
col = 15,
|
||||
end_col = 15,
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
code = "AVD-AWS-0065",
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,39 @@
|
||||
describe('linter.twigcs', function()
|
||||
it('ignores empty output', function()
|
||||
local parser = require('lint.linters.twigcs').parser
|
||||
|
||||
assert.are.same({}, parser('', vim.api.nvim_get_current_buf()))
|
||||
assert.are.same({}, parser(' ', vim.api.nvim_get_current_buf()))
|
||||
end)
|
||||
|
||||
it('parses emacs output correctly', function()
|
||||
local parser = require('lint.linters.twigcs').parser
|
||||
|
||||
local result = parser([[/Users/dblanken/code/testcode/test.twig:2:15: error - Should have 1 argument.
|
||||
/Users/dblanken/code/testcode/test.twig:4:2: error - Another problem.]])
|
||||
|
||||
assert.are.same(2, #result)
|
||||
|
||||
local expected = {
|
||||
col = 14,
|
||||
end_col = 14,
|
||||
lnum = 1,
|
||||
end_lnum = 1,
|
||||
message = 'Should have 1 argument.',
|
||||
severity = 1,
|
||||
source = 'twigcs',
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
col = 1,
|
||||
end_col = 1,
|
||||
lnum = 3,
|
||||
end_lnum = 3,
|
||||
message = 'Another problem.',
|
||||
severity = 1,
|
||||
source = 'twigcs',
|
||||
}
|
||||
assert.are.same(expected, result[2])
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,22 @@
|
||||
describe("lint.util", function()
|
||||
local util = require("lint.util")
|
||||
it("wrap can re-map diagnostics from lint result", function()
|
||||
local cspell = require("lint.linters.cspell")
|
||||
local custom_cspell = util.wrap(cspell, function(diagnostic)
|
||||
diagnostic.severity = vim.diagnostic.severity.HINT
|
||||
return diagnostic
|
||||
end)
|
||||
local output = [[
|
||||
/:259:8 - Unknown word (langserver)
|
||||
/:272:19 - Unknown word (noplugin)
|
||||
]]
|
||||
|
||||
local bufnr = vim.uri_to_bufnr('file:///foo.txt')
|
||||
local orig_result = cspell.parser(output, bufnr)
|
||||
local result = custom_cspell.parser(output, bufnr)
|
||||
assert.are.same(#result, 2)
|
||||
assert.are.same(#orig_result, 2)
|
||||
assert.are.same(result[1].severity, vim.diagnostic.severity.HINT)
|
||||
assert.are.same(orig_result[1].severity, vim.diagnostic.severity.INFO)
|
||||
end)
|
||||
end)
|
||||
@ -0,0 +1,8 @@
|
||||
describe('linter.vale', function()
|
||||
it("doesn't error on empty output", function()
|
||||
local parser = require('lint.linters.vale').parser
|
||||
parser('')
|
||||
parser(' ')
|
||||
end)
|
||||
end)
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
describe('linter.verilator', function()
|
||||
it('can parse the output', function()
|
||||
local parser = require('lint.linters.verilator').parser
|
||||
local result = parser([[
|
||||
%Warning-DECLFILENAME: t.v:24:8: Filename 't' does not match MODULE name: 'uart'
|
||||
24 | module uart
|
||||
| ^~~~
|
||||
... For warning description see https://verilator.org/warn/DECLFILENAME?v=5.006
|
||||
... Use "/* verilator lint_off DECLFILENAME */" and lint_on around source to disable this message.
|
||||
%Warning-PINCONNECTEMPTY: t.v:48:4: Cell pin connected by name with empty reference: 'wr_rst_busy'
|
||||
48 | .wr_rst_busy(),
|
||||
| ^~~~~~~~~~~
|
||||
%Warning-PINCONNECTEMPTY: t.v:49:4: Cell pin connected by name with empty reference: 'rd_rst_busy'
|
||||
49 | .rd_rst_busy(),
|
||||
| ^~~~~~~~~~~
|
||||
%Error: t.v:45:4: Cannot find file containing module: 'tx_fifo'
|
||||
45 | tx_fifo
|
||||
| ^~~~~~~
|
||||
%Error: t.v:45:4: This may be because there's no search path specified with -I<dir>.
|
||||
45 | tx_fifo
|
||||
| ^~~~~~~
|
||||
... Looked in:
|
||||
tx_fifo
|
||||
tx_fifo.v
|
||||
tx_fifo.sv
|
||||
obj_dir/tx_fifo
|
||||
obj_dir/tx_fifo.v
|
||||
obj_dir/tx_fifo.sv
|
||||
%Error: t.v:64:2: Cannot find file containing module: 'uart_tx'
|
||||
64 | uart_tx
|
||||
| ^~~~~~~
|
||||
%Error: Exiting due to 3 error(s), 3 warning(s)
|
||||
]], vim.api.nvim_get_current_buf())
|
||||
assert.are.same(6, #result)
|
||||
|
||||
local expected = {
|
||||
source = 'verilator',
|
||||
message = 'Filename \'t\' does not match MODULE name: \'uart\'',
|
||||
severity = vim.diagnostic.severity.WARN,
|
||||
lnum = 23,
|
||||
col = 7,
|
||||
end_lnum = 23,
|
||||
end_col = 7,
|
||||
code = 'DECLFILENAME',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = 'DECLFILENAME',
|
||||
}
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result[1])
|
||||
|
||||
expected = {
|
||||
source = 'verilator',
|
||||
message = 'This may be because there\'s no search path specified with -I<dir>.',
|
||||
severity = vim.diagnostic.severity.ERROR,
|
||||
lnum = 44,
|
||||
col = 3,
|
||||
end_lnum = 44,
|
||||
end_col = 3,
|
||||
code = '',
|
||||
user_data = {
|
||||
lsp = {
|
||||
code = '',
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.are.same(expected, result[5])
|
||||
end)
|
||||
end)
|
||||
Reference in New Issue
Block a user