diff --git a/lua/neotest/client/init.lua b/lua/neotest/client/init.lua index f1c88515..9770084c 100644 --- a/lua/neotest/client/init.lua +++ b/lua/neotest/client/init.lua @@ -335,19 +335,35 @@ function neotest.Client:_get_adapter(position_id, adapter_id) end assert(position_id) - for a_id, adapter in pairs(self._adapters) do - if self._state:positions(a_id, position_id) then - return a_id, adapter - end - local root = self._state:positions(a_id) - if - (not root or vim.startswith(position_id, root:data().path)) - and (lib.files.is_dir(position_id) or adapter.is_test_file(position_id)) - then - return a_id, adapter + local function find_adapter() + for a_id, adapter in pairs(self._adapters) do + if self._state:positions(a_id, position_id) then + return a_id, adapter + end + + local root = self._state:positions(a_id) + if + (not root or vim.startswith(position_id, root:data().path)) + and (lib.files.is_dir(position_id) or adapter.is_test_file(position_id)) + then + return a_id, adapter + end end end + + -- First attempt to find adapter + local found_id, found_adapter = find_adapter() + if found_id then + return found_id, found_adapter + end + + -- If no adapter is found and client is started, update adapters for this path's directory and try again + if self._started then + local dir = lib.files.is_dir(position_id) and position_id or lib.files.parent(position_id) + self:_update_adapters(dir) + return find_adapter() + end end ---@async diff --git a/tests/unit/client/init_spec.lua b/tests/unit/client/init_spec.lua index c3019395..b25593b4 100644 --- a/tests/unit/client/init_spec.lua +++ b/tests/unit/client/init_spec.lua @@ -257,6 +257,39 @@ describe("neotest client", function() assert.Not.Nil(tree) end) end) + + describe("adapter discovery for paths outside cwd", function() + local parent_stub, update_adapters_stub + before_each(function() + -- Use a file path that would belong to a different project/root + local test_path = "/completely/different/path/test_file" + local parent_dir = "/completely/different/path" + + parent_stub = stub(lib.files, "parent") + parent_stub.on_call_with(test_path).returns(parent_dir) + + dirs[#dirs + 1] = parent_dir + + update_adapters_stub = stub(client, "_update_adapters") + end) + + after_each(function() + parent_stub:revert() + update_adapters_stub:revert() + end) + + a.it("calls _update_adapters when adapter not found for path", function() + local test_path = "/completely/different/path/test_file" + local parent_dir = "/completely/different/path" + + client:_ensure_started() + + client:_get_adapter(test_path) + + -- Verify _update_adapters was called with the parent directory + assert.stub(client._update_adapters).was_called_with(client, parent_dir) + end) + end) end) describe("running tests", function()