Skip to content

Commit

Permalink
feat: jdtls with nio
Browse files Browse the repository at this point in the history
  • Loading branch information
atm1020 committed Aug 17, 2024
1 parent 1fb037c commit d4dbb4e
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 295 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ TEST_CONFIG=${TESTS_DIR}/minimal_init.lua

.PHONY: test lint format all

all: lint format
checks: format lint

test:
nvim --headless -c "PlenaryBustedDirectory {minimal_init = '${TEST_CONFIG}'}"
Expand All @@ -13,3 +13,4 @@ lint:

format:
~/.cargo/bin//stylua ${SRC_DIR} --config-path=.stylua.toml

12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
# neotest-jdtls (Under Development)
# neotest-jdtls
* This plugin provides a jdtls adapter for the [Neotest](https://github.com/rcarriga/neotest) framework.
* Depends on the nvim-java-core and nvim-java-test projects.

### Installation

```
{
'atm1020/neotest-jdtls',
dependencies = {
nvim-java/nvim-java-core,
nvim-java/nvim-java-test,
}
}
```

Expand All @@ -23,7 +18,12 @@ require("neotest").setup {
require('neotest-jdtls')
},
}


```
### Logging
- logs are written to `neotest-jdtls.log` within the `~/.local/share/nvim/` directory.
- log level can be set with `vim.g.neotest_jdtls_log_level`.

### Acknowledgements
- **[neotest-java](https://github.com/rcasia/neotest-java)**
6 changes: 4 additions & 2 deletions lua/neotest-jdtls/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ local project = require('neotest-jdtls.utils.project')

local group = vim.api.nvim_create_augroup('neotest-jdtls', { clear = true })

vim.api.nvim_create_autocmd({ 'BufWritePost' }, {
vim.api.nvim_create_autocmd({ 'BufWritePre' }, {
pattern = '*.java',
callback = project.autocmd_clear_cache,
callback = function()
project.clear_project_cache()
end,
group = group,
})

Expand Down
1 change: 0 additions & 1 deletion lua/neotest-jdtls/neotest/adapter.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
local nio = require('nio')

local adapter = {}

---@class neotest.Adapter
Expand Down
52 changes: 30 additions & 22 deletions lua/neotest-jdtls/neotest/impl/excute.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ end
local function get_java_test_item(test_file_uri)
---@type JavaTestItem
local java_test_items = jdtls.find_test_types_and_methods(test_file_uri)
log.debug('java_test_items', vim.inspect(java_test_items))
if #java_test_items ~= 1 then
log.info('Unexpected number of test items found: ', #java_test_items)
return {}
end
return java_test_items
end

Expand Down Expand Up @@ -83,7 +78,7 @@ local function handle_test(data, test_file_uri)
end

--- @param test_file_uri string
--- @return JunitLaunchRequestArguments
--- @return JunitLaunchRequestArguments|nil
local function handle_dir(tree, test_file_uri)
local file_nodes = {}
for _, node in tree:iter_nodes() do
Expand All @@ -92,7 +87,6 @@ local function handle_dir(tree, test_file_uri)
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
Expand All @@ -101,7 +95,7 @@ local function handle_dir(tree, test_file_uri)
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
if java_test_items and #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
Expand All @@ -111,14 +105,15 @@ local function handle_dir(tree, test_file_uri)
test_kind = java_test_item.testKind
end
else
log.info(
'Unexpected number of test items found: ',
#java_test_items,
' for ',
url
)
log.warn('Unexpected number of test items found for ', url)
end
end

if #items == 0 then
log.warn('No project name found')
return nil
end

return {
projectName = project_name,
testLevel = TestLevel.Class,
Expand All @@ -128,10 +123,13 @@ local function handle_dir(tree, test_file_uri)
end

--- @param test_file_uri string
--- @return JunitLaunchRequestArguments
--- @return JunitLaunchRequestArguments|nil
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')
if not java_test_items or #java_test_items == 0 then
log.info('No test items found')
return nil
end
local java_test_item = java_test_items[1]
return {
projectName = java_test_item.projectName,
Expand All @@ -151,7 +149,7 @@ end

local function run_test(dap_launcher_config, server)
local event = nio.control.event()
vim.schedule(function()
nio.run(function()
require('dap').run(dap_launcher_config, {
after = function(_)
shutdown_server(server)
Expand All @@ -163,10 +161,10 @@ local function run_test(dap_launcher_config, server)
end

---@param test_file_uri string
---@return JunitLaunchRequestArguments
---@return JunitLaunchRequestArguments|nil
local function resolve_junit_launch_arguments(tree, test_file_uri)
local data = tree:data()
---@type JunitLaunchRequestArguments
---@type JunitLaunchRequestArguments|nil
local arguments
if data.type == 'test' then
arguments = handle_test(data, test_file_uri)
Expand All @@ -177,6 +175,9 @@ local function resolve_junit_launch_arguments(tree, test_file_uri)
else
error('Unsupported type: ' .. data.type)
end
if not arguments then
return nil
end
return jdtls.get_junit_launch_arguments(arguments)
end

Expand All @@ -188,10 +189,17 @@ function M.build_spec(args)
local data = tree:data()
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)
if not junit_launch_arguments then
return {
context = {
file = data.path,
pos_id = data.id,
type = data.type,
},
}
end

local executable = jdtls.resolve_java_executable(
junit_launch_arguments.mainClass,
Expand All @@ -217,7 +225,7 @@ function M.build_spec(args)
run_test(dap_launcher_config, server)
else
dap_launcher_config.after = function()
vim.schedule(function()
nio.run(function()
shutdown_server(server)
end)
end
Expand Down
13 changes: 3 additions & 10 deletions lua/neotest-jdtls/neotest/impl/filter_dir.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,11 @@ local project = require('neotest-jdtls.utils.project')

local M = {}

M.filter_dir = function(name, rel_path, root)
local path = vim.uri_from_fname(root .. '/' .. rel_path)
log.debug('filter_dir check:', name, rel_path, path)
function M.filter_dir(name, rel_path, _)
local path_ok = false

local current_project = project.get_current_project(root)
if current_project.packages[path] then
local current_project = project.get_current_project()
if current_project.test_folders[rel_path] then
path_ok = true
else
if #current_project.longestTestFolder > #path then
path_ok = vim.startswith(current_project.longestTestFolder, path)
end
end
log.debug('filter_dir result:', name, rel_path, path_ok)
return path_ok
Expand Down
32 changes: 12 additions & 20 deletions lua/neotest-jdtls/neotest/impl/is_test_file.lua
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
local log = require('neotest-jdtls.utils.log')
local jdtls = require('neotest-jdtls.utils.jdtls_nio')
-- local project = require('neotest-jdtls.utils.project')
local project = require('neotest-jdtls.utils.project')
local M = {}

M.is_test_file = function(file_path)
-- check if file is a test file with project cache
-- local path = vim.uri_from_fname(file_path)
-- local is_test_file = false
--
-- local current_project = project.get_current_project(path)
-- if current_project.classes[path] then
-- is_test_file = true
-- end
-- log.debug('is_test_file result: ', file_path, path, is_test_file)

-- check if file is a test file with jdtls request
local err, is_test_file = jdtls.is_test_file(file_path)
if err then
log.error('is_test_file error: ', file_path, err)
return false
end
log.debug('is_test_file result: ', file_path, is_test_file)
function M.is_test_file(file_path)
local current_project = project.get_current_project()
local path = vim.uri_from_fname(file_path)
local is_test_file = current_project.methods[path] or false
log.debug(
'is_test_file result: ',
file_path,
path,
is_test_file,
vim.inspect(current_project.methods)
)
return is_test_file
end

Expand Down
31 changes: 29 additions & 2 deletions lua/neotest-jdtls/neotest/impl/results.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
local async = require('neotest.async')
local log = require('neotest-jdtls.utils.log')
local lib = require('neotest.lib')
local project = require('neotest-jdtls.utils.project')
local jdtls = require('neotest-jdtls.utils.jdtls')
local nio = require('nio')

local M = {}

Expand Down Expand Up @@ -78,8 +81,18 @@ end

local function merge_neotest_results(test_result_lookup, node_data)
if test_result_lookup[node_data.name] == nil then
log.debug('No test results found for', node_data.name)
return nil -- Maybe "status = Skipped" would be better with some message
local root = jdtls.root_dir()
nio.scheduler()
local current = project.get_current_project()
local path = node_data.path:sub(#root + 2)
--- If the node type is 'dir', and not in the project test folders (it's means there are no tests in it)
--- then mark it as skipped.
if not current.test_folders[path] and node_data.type == 'dir' then
return {
status = TestStatus.Skipped,
}
end
return nil
end

if #test_result_lookup[node_data.name] == 1 then
Expand All @@ -105,13 +118,27 @@ end
---@param result neotest.StrategyResult
---@param tree neotest.Tree
function M.results(spec, _, tree)
log.debug('Parsing test results', vim.inspect(spec.context.report))
--- Set the results to skipped if the report is not available
if not spec.context.report then
local results = {}
for _, node in tree:iter_nodes() do
local node_data = node:data()
results[node_data.id] = {
status = TestStatus.Skipped,
}
end
return results
end

local test_result_lookup = {}
local report = spec.context.report:get_results()
for _, item in ipairs(report) do
if item.children then
group_and_map_test_results(test_result_lookup, item)
end
end

local results = {}
for _, node in tree:iter_nodes() do
local node_data = node:data()
Expand Down
2 changes: 1 addition & 1 deletion lua/neotest-jdtls/neotest/impl/root.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ local log = require('neotest-jdtls.utils.log')
local M = {}

function M.root(_)
local root_dir = jdtls.get_client().config.root_dir
local root_dir = jdtls.root_dir()
log.debug('root_dir', root_dir)
return root_dir
end
Expand Down
Loading

0 comments on commit d4dbb4e

Please sign in to comment.