1
0
Fork 0
mirror of https://github.com/pnx/neotest-phpunit synced 2026-06-16 03:54:55 +02:00
neotest-phpunit/lua/neotest-pest/init.lua
2024-02-17 13:06:57 -05:00

185 lines
5 KiB
Lua

local lib = require('neotest.lib')
local logger = require('neotest.logging')
local utils = require('neotest-pest.utils')
local config = require('neotest-pest.config')
---@class neotest.Adapter
---@field name string
local NeotestAdapter = { name = "neotest-pest" }
---Find the project root directory given a current directory to work from.
---Should no root be found, the adapter can still be use dina non-project context
---if a test file matches.
---@async
---@param dir string @Directory to treat as cwd
---@return string | nil @Absolute root dir of test suite
function NeotestAdapter.root(dir)
local result = nil
logger.debug("Finding root...")
for _, root_ignore_file in ipairs(config("root_ignore_files")) do
logger.debug("Checking root ignore file", root_ignore_file)
result = lib.files.match_root_pattern(root_ignore_file)(dir)
if result then
logger.debug("Ignoring root because file", root_ignore_file)
return nil
end
end
for _, root_file in ipairs(config("root_files")) do
logger.debug("Checking root file", root_file)
result = lib.files.match_root_pattern(root_file)(dir)
if result then
logger.debug("Found root", result)
break
end
end
logger.debug("Root not found")
return result
end
---Filter directories when searching for test files
---@async
---@param name string Name of directory
---@param rel_path string Path to directory, relative to root
---@param root string Root directory of project
---@return boolean True when matching
function NeotestAdapter.filter_dir(name, rel_path, root)
for _, filter_dir in ipairs(config("filter_dirs")) do
if name == filter_dir then return false end
end
return true
end
---@async
---@param file_path string
---@return boolean
function NeotestAdapter.is_test_file(file_path)
for _, suffix in ipairs(config("test_file_suffix")) do
if vim.endswith(file_path, suffix) then return true end
end
return false
end
function NeotestAdapter.discover_positions(path)
local query = [[
((expression_statement
(member_call_expression
name: (name) @member_name (#eq? @member_name "group")
arguments: (arguments . (argument (string (string_value) @namespace.name)))
) @member
)) @namespace.definition
((function_call_expression
function: (name) @func_name (#match? @func_name "^(test|it)$")
arguments: (arguments . (argument (string (string_value) @test.name)))
)) @test.definition
]]
return lib.treesitter.parse_positions(path, query, {
position_id = "require('neotest-pest.utils').make_test_id",
})
end
---@param args neotest.RunArgs
---@return neotest.RunSpec | nil
function NeotestAdapter.build_spec(args)
local position = args.tree:data()
local results_path = config('results_path')
local binary = config('pest_cmd')
logger.info("Building spec for:", position)
logger.info("Results path:", results_path)
local command = {}
if config('sail_enabled') then
logger.info("Sail enabled")
command = vim.tbl_flatten({
"vendor/bin/sail", "bin", "pest",
position.name ~= "tests" and ("/var/www/html" .. string.sub(position.path, string.len(vim.loop.cwd() or "") + 1)),
})
else
logger.info("Sail not enabled")
command = vim.tbl_flatten({
binary,
position.name ~= "tests" and position.path,
})
end
command = vim.tbl_flatten({
command,
"--log-junit=" .. results_path,
})
if position.type == "test" then
local script_args = vim.tbl_flatten({
"--filter",
position.name,
})
command = vim.tbl_flatten({
command,
script_args,
})
end
logger.info("Command:", command)
return {
command = command,
context = {
results_path = results_path,
},
}
end
---@async
---@param spec neotest.RunSpec
---@param result neotest.StrategyResult
---@param tree neotest.Tree
---@return neotest.Result[]
function NeotestAdapter.results(test, result, tree)
local output_file = test.context.results_path
local ok, data = pcall(lib.files.read, output_file)
if not ok then
logger.error("No test output file found:", output_file)
return {}
end
local ok, parsed_data = pcall(lib.xml.parse, data)
if not ok then
logger.error("Failed to parse test output:", output_file)
return {}
end
local ok, results = pcall(utils.get_test_results, parsed_data, output_file)
if not ok then
logger.error("Could not get test results", output_file)
return {}
end
return results
end
setmetatable(NeotestAdapter, {
__call = function(_, opts)
logger.info("Initializing opts")
config.merge(opts or {})
return NeotestAdapter
end,
})
return NeotestAdapter