Skip to content

Commit

Permalink
feat #33, fix #48
Browse files Browse the repository at this point in the history
  • Loading branch information
joshmedeski authored and AbaoFromCUG committed Jun 27, 2024
1 parent 353364a commit 8d0df46
Show file tree
Hide file tree
Showing 10 changed files with 531 additions and 176 deletions.
118 changes: 30 additions & 88 deletions lua/neotest-vitest/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function adapter.discover_positions(path)
arguments: (arguments (string (string_fragment) @test.name) (arrow_function))
)) @test.definition
]]

query = query .. string.gsub(query, "arrow_function", "function_expression")
return lib.treesitter.parse_positions(path, query, { nested_tests = true })
end

Expand Down Expand Up @@ -200,17 +200,19 @@ end

local function escapeTestPattern(s)
return (
s:gsub("%(", "%\\(")
:gsub("%)", "%\\)")
:gsub("%]", "%\\]")
:gsub("%[", "%\\[")
:gsub("%*", "%\\*")
:gsub("%+", "%\\+")
:gsub("%-", "%\\-")
:gsub("%?", "%\\?")
:gsub("%$", "%\\$")
:gsub("%^", "%\\^")
:gsub("%/", "%\\/")
s:gsub("%(", "\\(")
:gsub("%)", "\\)")
:gsub("%]", "\\]")
:gsub("%[", "\\[")
:gsub("%.", "\\.")
:gsub("%*", "\\*")
:gsub("%+", "\\+")
:gsub("%-", "\\-")
:gsub("%?", "\\?")
:gsub(" ", "\\s")
:gsub("%$", "\\$")
:gsub("%^", "\\^")
:gsub("%/", "\\/")
)
end

Expand Down Expand Up @@ -244,72 +246,6 @@ local function getCwd(path)
return nil
end

local function cleanAnsi(s)
return s:gsub("\x1b%[%d+;%d+;%d+;%d+;%d+m", "")
:gsub("\x1b%[%d+;%d+;%d+;%d+m", "")
:gsub("\x1b%[%d+;%d+;%d+m", "")
:gsub("\x1b%[%d+;%d+m", "")
:gsub("\x1b%[%d+m", "")
end

local function parsed_json_to_results(data, output_file, consoleOut)
local tests = {}

for _, testResult in pairs(data.testResults) do
local testFn = testResult.name

for _, assertionResult in pairs(testResult.assertionResults) do
local status, name = assertionResult.status, assertionResult.title

if name == nil then
logger.error("Failed to find parsed test result ", assertionResult)
return {}
end

local keyid = testFn

for _, value in ipairs(assertionResult.ancestorTitles) do
if value ~= "" then
keyid = keyid .. "::" .. value
end
end

keyid = keyid .. "::" .. name

if status == "pending" or status == "todo" then
status = "skipped"
end

tests[keyid] = {
status = status,
short = name .. ": " .. status,
output = consoleOut,
location = assertionResult.location,
}

if not vim.tbl_isempty(assertionResult.failureMessages) then
local errors = {}

for i, failMessage in ipairs(assertionResult.failureMessages) do
local msg = cleanAnsi(failMessage)

errors[i] = {
line = (assertionResult.location and assertionResult.location.line - 1 or nil),
column = (assertionResult.location and assertionResult.location.column or nil),
message = msg,
}

tests[keyid].short = tests[keyid].short .. "\n" .. msg
end

tests[keyid].errors = errors
end
end
end

return tests
end

---@param args neotest.RunArgs
---@return neotest.RunSpec | nil
function adapter.build_spec(args)
Expand All @@ -319,16 +255,22 @@ function adapter.build_spec(args)
if not tree then
return
end
local names = {}
while tree and tree:data().type ~= "file" do
table.insert(names, 1, tree:data().name)
tree = tree:parent() --[[@as neotest.Tree]]
end
local testNamePattern = table.concat(names, " ")

local pos = args.tree:data()
local testNamePattern = ".*"

if pos.type == "test" then
testNamePattern = escapeTestPattern(pos.name) .. "$"
if #testNamePattern == 0 then
testNamePattern = ".*"
else
testNamePattern = "^\\s?" .. escapeTestPattern(testNamePattern)
end

if pos.type == "namespace" then
testNamePattern = "^ " .. escapeTestPattern(pos.name)
local pos = args.tree:data()
if pos.type == "test" then
testNamePattern = testNamePattern .. "$"
end

local binary = args.vitestCommand or getVitestCommand(pos.path)
Expand All @@ -345,7 +287,7 @@ function adapter.build_spec(args)
"--reporter=verbose",
"--reporter=json",
"--outputFile=" .. results_path,
"--testNamePattern=" .. testNamePattern,
"'--testNamePattern=" .. testNamePattern .. "'",
vim.fs.normalize(pos.path),
})

Expand Down Expand Up @@ -377,7 +319,7 @@ function adapter.build_spec(args)
return {}
end

return parsed_json_to_results(parsed, results_path, nil)
return util.parsed_json_to_results(parsed, results_path, nil)
end
end,
strategy = get_strategy_config(args.strategy, command, cwd),
Expand Down Expand Up @@ -407,7 +349,7 @@ function adapter.results(spec, b, tree)
return {}
end

local results = parsed_json_to_results(parsed, output_file, b.output)
local results = util.parsed_json_to_results(parsed, output_file, b.output)

return results
end
Expand Down
67 changes: 66 additions & 1 deletion lua/neotest-vitest/util.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local vim = vim
local logger = require("neotest.logging")
local validate = vim.validate
local uv = vim.loop

Expand Down Expand Up @@ -229,4 +229,69 @@ function M.stream(file_path)
return queue.get, exit_future.set
end

function M.cleanAnsi(s)
return s:gsub("\x1b%[%d+;%d+;%d+;%d+;%d+m", "")
:gsub("\x1b%[%d+;%d+;%d+;%d+m", "")
:gsub("\x1b%[%d+;%d+;%d+m", "")
:gsub("\x1b%[%d+;%d+m", "")
:gsub("\x1b%[%d+m", "")
end
function M.parsed_json_to_results(data, output_file, consoleOut)
local tests = {}

for _, testResult in pairs(data.testResults) do
local testFn = testResult.name

for _, assertionResult in pairs(testResult.assertionResults) do
local status, name = assertionResult.status, assertionResult.title

if name == nil then
logger.error("Failed to find parsed test result ", assertionResult)
return {}
end

local keyid = testFn

for _, value in ipairs(assertionResult.ancestorTitles) do
if value ~= "" then
keyid = keyid .. "::" .. value
end
end

keyid = keyid .. "::" .. name

if status == "pending" or status == "todo" then
status = "skipped"
end

tests[keyid] = {
status = status,
short = name .. ": " .. status,
output = consoleOut,
location = assertionResult.location,
}

if not vim.tbl_isempty(assertionResult.failureMessages) then
local errors = {}

for i, failMessage in ipairs(assertionResult.failureMessages) do
local msg = M.cleanAnsi(failMessage)

errors[i] = {
line = (assertionResult.location and assertionResult.location.line - 1 or nil),
column = (assertionResult.location and assertionResult.location.column or nil),
message = msg,
}

tests[keyid].short = tests[keyid].short .. "\n" .. msg
end

tests[keyid].errors = errors
end
end
end

return tests
end

return M
5 changes: 3 additions & 2 deletions scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ if [ ! -d .testdeps ]; then
git clone --depth 1 https://github.com/nvim-lua/plenary.nvim.git .testdeps/plenary.nvim
git clone --depth 1 https://github.com/nvim-treesitter/nvim-treesitter.git .testdeps/nvim-treesitter
git clone --depth 1 https://github.com/nvim-neotest/neotest.git .testdeps/neotest
git clone --depth 1 https://github.com/nvim-neotest/nvim-nio.git .testdeps/nvim-nio
fi

if [[ -n $1 ]]; then
nvim --headless --noplugin -u tests/init.vim -c "PlenaryBustedFile $1" | tee "${tempfile}"
nvim --headless --noplugin -u tests/minimal_init.vim -c "PlenaryBustedFile $1" | tee "${tempfile}"
else
nvim --headless --noplugin -u tests/init.vim -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/init.vim'}" | tee "${tempfile}"
nvim --headless --noplugin -u tests/minimal_init.vim -c "PlenaryBustedDirectory tests/ {minimal_init = 'tests/minimal_init.vim'}" | tee "${tempfile}"
fi

# Plenary doesn't emit exit code 1 when tests have errors during setup
Expand Down
31 changes: 16 additions & 15 deletions spec/basic.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { describe ,it ,test } from 'vitest'
import { describe, it, test, expect } from 'vitest'

describe("describe text", () => {
it("1", () => {
console.log("do test");
});
describe("describe arrow function", () => {
test("foo", () => {
expect(true).to.equal(true);
});

it("2", async () => {
console.log("do test");
});

test("3", () => {
console.log("do test");
});
it("bar(error)", () => {
expect(true).to.equal(false);
});
});

test("4", async () => {
console.log("do test");
});
describe("describe vanilla function", function() {
test("foo", () => {
console.log("do test");
});
it("bar", () => {
console.log("do test");
});
});
Binary file added spec/bun.lockb
Binary file not shown.
22 changes: 22 additions & 0 deletions spec/nested.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, it, test, expect } from 'vitest'

describe("first level", () => {
describe("second level", () => {
it("foo", () => {
expect(true).to.equal(true);
});
it("bar(error)", () => {
expect(true).to.equal(false);
});
});
});

describe("A", () => {
it("foo", () => {
expect(true).to.equal(true);
});
it("bar(error)", () => {
expect(true).to.equal(false);
});
});

15 changes: 13 additions & 2 deletions tests/init_options_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ local config_override = function()
end

describe("build_spec with override", function()
local raw_tempname
before_each(function()
raw_tempname = require("neotest.async").fn.tempname
require("neotest.async").fn.tempname = function()
return "/tmp/foo"
end
end)
after_each(function()
require("neotest.async").fn.tempname = raw_tempname
end)
async.it("builds command", function()
local plugin = require("neotest-vitest")({
vitestCommand = binary_override,
Expand All @@ -34,10 +44,11 @@ describe("build_spec with override", function()
assert.contains(command, "--watch=false")
assert.contains(command, "--reporter=verbose")
--[[ assert.contains(command, "--config=" .. config_override()) ]]
assert.contains(command, "--testNamePattern=.*")
assert.contains(command, "./spec/basic.test.ts")
assert.contains(command, "'--testNamePattern=.*'")
assert.contains(command, "spec/basic.test.ts")
assert.is.truthy(spec.context.file)
assert.is.truthy(spec.context.results_path)

assert.is.same(
spec.env,
{ override = "override", adapter_override = true, spec_override = true }
Expand Down
Loading

0 comments on commit 8d0df46

Please sign in to comment.