Skip to content

Commit

Permalink
feat: add 'dir' support
Browse files Browse the repository at this point in the history
  • Loading branch information
atm1020 committed Jun 24, 2024
1 parent 5ad66ca commit 01ee80c
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 86 deletions.
15 changes: 0 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,5 @@ require("neotest").setup {
}
```

### Setup with watch feature
```lua
require("neotest").setup {
adapters = {
require('neotest-jdtls')
},
watch = {
enabled = true,
symbol_queries = {
java = require('neotest-jdtls.utils').symbol_query
}
}
}
```

### Acknowledgements
- **[neotest-java](https://github.com/rcasia/neotest-java)**
180 changes: 123 additions & 57 deletions lua/neotest-jdtls/impl/excute.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,40 @@ local TestLevel = {
Method = 6,
}

---Returns a stream reader function
---@param conn uv_tcp_t
---@return fun(err: string, buffer: string) # callback function
-- local function get_stream_reader(conn)
-- -- self.conn = conn
-- -- self.result_parser = self.result_parser_fac:get_parser()
--
-- return vim.schedule_wrap(function(err, buffer)
-- if err then
-- -- self:on_error(err)
-- -- self:on_close()
-- -- self.conn:close()
-- return
-- end
--
-- if buffer then
-- log.debug('buffer >> ', buffer)
-- -- self:on_update(buffer)
-- else
-- log.debug('buffer is nil close')
-- -- self:on_close(conn)
-- conn:close()
-- -- self.conn:close()
-- end
-- end)
-- end

local function setup(server, dap_launcher_config, report)
server:bind('127.0.0.1', 0)
server:listen(128, function(err)
assert(not err, err)
local sock = assert(vim.loop.new_tcp(), 'uv.new_tcp must return handle')
server:accept(sock)
-- report:get_stream_reader(sock))
local success = sock:read_start(report:get_stream_reader(sock))
assert(success == 0, 'failed to listen to reader')
end)
Expand All @@ -33,9 +61,34 @@ local function setup(server, dap_launcher_config, report)
return dap_launcher_config
end

--- @param java_test_item JavaTestItem
---@return JavaTestItem
---@param test_file_uri string
local function get_java_test_item(test_file_uri)
---@type JavaTestItem
local java_test_items = execute_command({
command = 'vscode.java.test.findTestTypesAndMethods',
arguments = { test_file_uri },
}).result
log.debug('java_test_items', vim.inspect(java_test_items))
if java_test_items == nil then
return {}
end
assert(
#java_test_items == 1,
'Too many test items found: '
.. #java_test_items
.. ' for '
.. test_file_uri
)
return java_test_items
end

--- @param test_file_uri string
--- @return JunitLaunchRequestArguments
local function handle_test(data, java_test_item)
local function handle_test(data, test_file_uri)
local java_test_items = get_java_test_item(test_file_uri)
assert(#java_test_items ~= 0, 'No test items found')
local java_test_item = java_test_items[1]
---@type JavaTestItem
local closest_item = nil
local start_line = data.range[1] + 1
Expand All @@ -46,6 +99,7 @@ local function handle_test(data, java_test_item)
end
closest_item = children
end

return {
projectName = closest_item.projectName,
testLevel = TestLevel.Method,
Expand All @@ -54,22 +108,62 @@ local function handle_test(data, java_test_item)
}
end

--- @param java_test_item JavaTestItem
--- @param test_file_uri string
--- @return JunitLaunchRequestArguments
local function handle_file(java_test_item)
local m = nil
local testNames = {}
for _, children in ipairs(java_test_item.children) do
table.insert(testNames, children.jdtHandler)
if m == nil then
m = children
local function handle_dir(tree, test_file_uri)
local file_nodes = {}
for _, node in tree:iter_nodes() do
local node_data = node:data()
if
node_data.type == 'file'
and vim.startswith(vim.uri_from_fname(node_data.path), test_file_uri)
then
log.debug('node_data', vim.inspect(node_data))
file_nodes[node_data.id] = vim.uri_from_fname(node_data.path)
end
end
local items = {}
local project_name = nil
local test_kind = nil
for _, url in pairs(file_nodes) do
local java_test_items = get_java_test_item(url)
if #java_test_items == 1 then
local java_test_item = java_test_items[1]
table.insert(items, java_test_item.fullName)
if project_name == nil then
project_name = java_test_item.projectName
end
if test_kind == nil then
test_kind = java_test_item.testKind
end
else
log.info(
'Unexpected number of test items found: ',
#java_test_items,
' for ',
url
)
end
end
return {
projectName = project_name,
testLevel = TestLevel.Class,
testKind = test_kind,
testNames = items,
}
end

--- @param test_file_uri string
--- @return JunitLaunchRequestArguments
local function handle_file(test_file_uri)
local java_test_items = get_java_test_item(test_file_uri)
assert(#java_test_items == 1, 'No test items found')
local java_test_item = java_test_items[1]
return {
projectName = m.projectName,
projectName = java_test_item.projectName,
testLevel = TestLevel.Class,
testKind = m.testKind,
testNames = { vim.split(m.fullName, '#')[1] },
testKind = java_test_item.testKind,
testNames = { vim.split(java_test_item.fullName, '#')[1] },
}
end

Expand All @@ -94,47 +188,20 @@ local function run_test(dap_launcher_config, server)
event.wait()
end

--- @return ResolvedMainClass
local function resolve_main_class()
local class_list = execute_command({
command = 'vscode.java.resolveMainClass',
arguments = nil,
}).result
assert(#class_list > 0, 'No main class found')
return class_list[1]
end

---@return JavaTestItem
---@param test_file_uri string
local function get_java_test_item(test_file_uri)
---@type JavaTestItem
local java_test_items = execute_command({
command = 'vscode.java.test.findTestTypesAndMethods',
arguments = { test_file_uri },
}).result
assert(#java_test_items == 1, 'Too many test items found')
return java_test_items[1]
end

---@param test_file_uri string
---@return JunitLaunchRequestArguments
local function resolve_junit_launch_arguments(data, test_file_uri)
if
data.type ~= 'test'
and data.type ~= 'file'
and data.type ~= 'namespace'
then
error('Unsupported test type: ' .. data.type)
end

local java_test_item = get_java_test_item(test_file_uri)
local function resolve_junit_launch_arguments(tree, test_file_uri)
local data = tree:data()
---@type JunitLaunchRequestArguments
local arguments
if data.type == 'test' then
arguments = handle_test(data, java_test_item)
arguments = handle_test(data, test_file_uri)
elseif data.type == 'dir' then
arguments = handle_dir(tree, test_file_uri)
elseif data.type == 'file' or data.type == 'namespace' then
arguments = handle_file(test_file_uri)
else
-- file and namespace
arguments = handle_file(java_test_item)
error('Unsupported type: ' .. data.type)
end
local launch_arguments = execute_command({
command = 'vscode.java.test.junit.argument',
Expand All @@ -150,30 +217,28 @@ function M.build_spec(args)
local strategy = args.strategy
local tree = args and args.tree
local data = tree:data()
log.debug('data', vim.inspect(data))

local resolved_main_class = resolve_main_class()
local test_file_uri = vim.uri_from_fname(data.path)

log.debug('file_uri', test_file_uri)

local junit_launch_arguments =
resolve_junit_launch_arguments(tree, test_file_uri)

local executable = execute_command({
command = 'vscode.java.resolveJavaExecutable',
arguments = {
resolved_main_class.mainClass,
resolved_main_class.projectName,
junit_launch_arguments.mainClass,
junit_launch_arguments.projectName,
},
}).result

local junit_launch_arguments =
resolve_junit_launch_arguments(data, test_file_uri)

local is_debug = strategy == 'dap'
local dap_launcher_config =
data_adapters.get_dap_launcher_config(junit_launch_arguments, executable, {
debug = is_debug,
label = 'Launch All Java Tests',
})

log.debug('dap_launcher_config', vim.inspect(dap_launcher_config))
local report = JUnitReport(ResultParserFactory(), ReportViewer())
local server = assert(vim.loop.new_tcp(), 'uv.new_tcp() must return handle')
dap_launcher_config = setup(server, dap_launcher_config, report)
Expand Down Expand Up @@ -208,6 +273,7 @@ return M

--- @class JunitLaunchRequestArguments
--- @field projectName string
--- @field mainClass string
--- @field testLevel number
--- @field testKind string
--- @field testNames string[]
Expand Down
18 changes: 12 additions & 6 deletions lua/neotest-jdtls/impl/filter_dir.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local log = require('neotest-jdtls.log')

local M = {}

local excluded_directories = {
Expand All @@ -8,8 +10,7 @@ local excluded_directories = {
'resources',
'main',
}

M.filter_dir = function(name, rel_path, _)
local function filter(name, rel_path, _)
if vim.tbl_contains(excluded_directories, name) then
return false
end
Expand All @@ -18,15 +19,20 @@ M.filter_dir = function(name, rel_path, _)
return true
end

-- if vim.endswith(rel_path, name) then
--
-- return true
-- end
if vim.endswith(rel_path, name) then
return true
end

if string.find(rel_path, 'test') then
return true
end
return false
end

M.filter_dir = function(name, rel_path, _)
local res = filter(name, rel_path, _)
log.debug('filter_dir: ', name, rel_path, res)
return res
end

return M
2 changes: 2 additions & 0 deletions lua/neotest-jdtls/impl/is_test_file.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
local log = require('neotest-jdtls.log')
local M = {}

M.is_test_file = function(file_path)
local is_test_file = string.find(file_path, 'test') ~= nil
and string.find(file_path, '.java') ~= nil
and string.find(file_path, '.class') == nil
log.debug('is_test_file: ', is_test_file)
return is_test_file
end

Expand Down
13 changes: 13 additions & 0 deletions lua/neotest-jdtls/impl/root.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
local utils = require('neotest-jdtls.utils')
local log = require('neotest-jdtls.log')

local M = {}

function M.root(dir)
local root_dir = utils.jdtls().config.root_dir
log.debug('input', dir, 'root_dir', root_dir)
-- return root_dir
return dir
end

return M
15 changes: 7 additions & 8 deletions lua/neotest-jdtls/init.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
local utils = require('neotest-jdtls.utils')

local adapter = {}
---@class neotest.Adapter
---@field name string
Expand All @@ -10,9 +8,8 @@ adapter.Adapter = { name = 'neotest-jdtls' }
---@async
---@param dir string @Directory to treat as cwd
---@return string | nil @Absolute root dir of test suite
function adapter.Adapter.root(_)
local root_dir = utils.jdtls().config.root_dir
return root_dir
function adapter.Adapter.root(dir)
return require('neotest-jdtls.impl.root').root(dir)
end

---Filter directories when searching for test files
Expand All @@ -22,9 +19,11 @@ end
---@param root string Root directory of project
---@return boolean
function adapter.Adapter.filter_dir(name, rel_path, root)
local res =
require('neotest-jdtls.impl.filter_dir').filter_dir(name, rel_path, root)
return res
return require('neotest-jdtls.impl.filter_dir').filter_dir(
name,
rel_path,
root
)
end

---@async
Expand Down
1 change: 1 addition & 0 deletions lua/neotest-jdtls/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ local M = {}

M.symbol_query = [[
;query
;Capture variable declaration
(type_identifier) @symbol
]]

Expand Down
1 change: 1 addition & 0 deletions tests/filter_dir_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe('filter_dir', function()
local dirs = {
{ 'test', 'test', root },
{ 'src', 'src/test/java/com/example', root },
{ 'src', 'module2/src', root },
}

for _, dir in ipairs(dirs) do
Expand Down

0 comments on commit 01ee80c

Please sign in to comment.