nvim-neotest / neotest

An extensible framework for interacting with tests within NeoVim.
MIT License
2.13k stars 105 forks source link

[BUG] adapter for directory takes precedence over adapter for file, incorrectly resulting in "No tests found" #353

Open trevorwhitney opened 5 months ago

trevorwhitney commented 5 months ago

NeoVim Version Output of nvim --version

NVIM v0.9.5
Build type: Release
LuaJIT 2.1.1693350652

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "
/nix/store/62nlxbqim2rgahbid2g7q5aryvzayycm-neovim-unwrapped-0.9.5/share/nvim
"

Run :checkhealth for more info

Describe the bug In a multi-language repo, the wrong adapter can be used if only one of the adapters matches the root directory, but other adapters would match the file you want to test. For example, I have both neotest-go and neotest-vim-test enabled, and a repository with both go and typescript files. The root of the repository has a go.mod, thus making neotest-go match as an adapter for the directory, When I try to run the typescript test (which I want to be handled by the neotest-vim-test adapater), it tries to use the neotest-go adapter because I'm guessing neotest-vim-test doesn't match any directory pattern as it can be used for so many different langauges? As a result, I get the "No tests found" error because neotest-go doesn't know how to handle the typescript file, but since it's named file.test.ts instead of file_test.go, I would expect the neotest-vim-test adapter to be used.

To Reproduce Please provide a minimal init.lua to reproduce which can be run as the following:

nvim --clean -u minimal.lua

You can edit the following example file to include your adapters and other required setup.

vim.opt.runtimepath:remove(vim.fn.expand("~/.config/nvim"))
vim.opt.packpath:remove(vim.fn.expand("~/.local/share/nvim/site"))

local lazypath = "/tmp/lazy/lazy.nvim"

if not vim.loop.fs_stat(lazypath) then
    vim.fn.system({
        "git",
        "clone",
        "--filter=blob:none",
        "https://github.com/folke/lazy.nvim.git",
        "--branch=stable", -- latest stable release
        lazypath,
    })
end

vim.opt.rtp:prepend(lazypath)

require("lazy").setup({
    "nvim-neotest/neotest",
    dependencies = {
        "nvim-lua/plenary.nvim",
        "nvim-treesitter/nvim-treesitter",
        -- Install adapters here
        "nvim-neotest/neotest-vim-test",
        "nvim-neotest/neotest-go",
                "vim-test/vim-test"
    },
    config = function()
        -- Install any required parsers
        require("nvim-treesitter.configs").setup({
            ensure_installed = {},
        })

        require("neotest").setup({
            -- Add adapters to the list
            adapters = {
                require("neotest-vim-test")({
                    ignore_file_types = { "go" },
                }),

                require("neotest-go")({
                    experimental = {
                        test_table = true,
                    },
                }),
            },
        })
    end,
})

Steps to reproduce the behavior:

  1. Start with a multi-language repo, like a repo that has both a go.mod and a package.json in the root. For example, I ran into this on a public repo I'm working on: https://github.com/grafana/loki-release
  2. If using the above repo, run npm install and go mod tidy, then open the file actions/should-release/__tests__/github.test.ts
  3. Put cursor on the first test, and run :lua require('neotest').run.run(), and see No tests found. If you turn on debug logs, you'll see it reporting that it's using the neotest-go adapter as that one matches the root directory
  4. Change minimal.lua to remove neotest-go, and go through the same steps. The test will run fine

Expected behavior I would expect the neotest-vim-test adapter to be used, since it should match the file github.test.ts, while neotest-go should not match github.test.ts

Logs

INFO | 2024-01-26T14:42:42Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/config/init.lua:389 | Configuration complete
DEBUG | 2024-01-26T14:42:42Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/config/init.lua:390 | User config {
  adapters = { {
      _build_spec = <function 1>,
      _discover_positions = <function 2>,
      _is_test_file = <function 3>,
      _remote_build_spec = <function 4>,
      build_spec = <function 5>,
      discover_positions = <function 6>,
      filter_dir = <function 7>,
      is_test_file = <function 8>,
      name = "neotest-vim-test",
      results = <function 9>,
      root = <function 10>,
      <metatable> = {
        __call = <function 11>
      }
    }, {
      _generate_position_id = <function 12>,
      build_spec = <function 13>,
      discover_positions = <function 14>,
      is_test_file = <function 15>,
      name = "neotest-go",
      prepare_results = <function 16>,
      results = <function 17>,
      root = <function 18>,
      <metatable> = {
        __call = <function 19>
      }
    } },
  benchmark = {
    enabled = true
  },
  consumers = {},
  default_strategy = "integrated",
  diagnostic = {
    enabled = true,
    severity = 1
  },
  discovery = {
    concurrent = 16,
    enabled = true
  },
  floating = {
    border = "rounded",
    max_height = 0.6,
    max_width = 0.6,
    options = {}
  },
  highlights = {
    adapter_name = "NeotestAdapterName",
    border = "NeotestBorder",
    dir = "NeotestDir",
    expand_marker = "NeotestExpandMarker",
    failed = "NeotestFailed",
    file = "NeotestFile",
    focused = "NeotestFocused",
    indent = "NeotestIndent",
    marked = "NeotestMarked",
    namespace = "NeotestNamespace",
    passed = "NeotestPassed",
    running = "NeotestRunning",
    select_win = "NeotestWinSelect",
    skipped = "NeotestSkipped",
    target = "NeotestTarget",
    test = "NeotestTest",
    unknown = "NeotestUnknown",
    watching = "NeotestWatching"
  },
  icons = {
    child_indent = "│",
    child_prefix = "├",
    collapsed = "─",
    expanded = "╮",
    failed = "",
    final_child_indent = " ",
    final_child_prefix = "╰",
    non_collapsible = "─",
    passed = "",
    running = "",
    running_animated = { "/", "|", "\\", "-", "/", "|", "\\", "-" },
    skipped = "",
    unknown = "",
    watching = ""
  },
  jump = {
    enabled = true
  },
  log_level = 1,
  output = {
    enabled = true,
    open_on_run = "short"
  },
  output_panel = {
    enabled = true,
    open = "botright split | resize 15"
  },
  projects = {
    <metatable> = {
      __index = <function 20>
    }
  },
  quickfix = {
    enabled = true,
    open = false
  },
  run = {
    enabled = true
  },
  running = {
    concurrent = true
  },
  state = {
    enabled = true
  },
  status = {
    enabled = true,
    signs = true,
    virtual_text = false
  },
  strategies = {
    integrated = {
      height = 40,
      width = 120
    }
  },
  summary = {
    animated = true,
    enabled = true,
    expand_errors = true,
    follow = true,
    mappings = {
      attach = "a",
      clear_marked = "M",
      clear_target = "T",
      debug = "d",
      debug_marked = "D",
      expand = { "<CR>", "<2-LeftMouse>" },
      expand_all = "e",
      jumpto = "i",
      mark = "m",
      next_failed = "J",
      output = "o",
      prev_failed = "K",
      run = "r",
      run_marked = "R",
      short = "O",
      stop = "u",
      target = "t",
      watch = "w"
    },
    open = "botright vsplit | vertical resize 50"
  },
  watch = {
    enabled = true,
    symbol_queries = {
      elixir = <function 21>,
      go = "        ;query\n        ;Captures imported types\n        (qualified_type name: (type_identifier) @symbol)\n        ;Captures package-local and built-in types\n        (type_identifier)@symbol\n        ;Captures imported function calls and variables/constants\n        (selector_expression field: (field_identifier) @symbol)\n        ;Captures package-local functions calls\n        (call_expression function: (identifier) @symbol)\n      ",
      lua = '        ;query\n        ;Captures module names in require calls\n        (function_call\n          name: ((identifier) @function (#eq? @function "require"))\n          arguments: (arguments (string) @symbol))\n      ',
      python = "        ;query\n        ;Captures imports and modules they're imported from\n        (import_from_statement (_ (identifier) @symbol))\n        (import_statement (_ (identifier) @symbol))\n      ",
      ruby = '        ;query\n        ;rspec - class name\n        (call\n          method: (identifier) @_ (#match? @_ "^(describe|context)")\n          arguments: (argument_list (constant) @symbol )\n        )\n\n        ;rspec - namespaced class name\n        (call\n          method: (identifier)\n          arguments: (argument_list\n            (scope_resolution\n              name: (constant) @symbol))\n        )\n      '
    }
  }
}
INFO | 2024-01-26T14:43:06Z-0700 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:33 | Starting child process
INFO | 2024-01-26T14:43:06Z-0700 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:36 | Parent address: localhost:43083
INFO | 2024-01-26T14:43:06Z-0700 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:42 | Starting child process with command: /nix/store/62nlxbqim2rgahbid2g7q5aryvzayycm-neovim-unwrapped-0.9.5/bin/nvim --embed --headless -n
INFO | 2024-01-26T14:43:06Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:380 | Initialising client
INFO | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting starting event
DEBUG | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event starting
INFO | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/adapters/init.lua:18 | Found 1 adapters for directory /home/twhitney/workspace/loki-release
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/adapters/init.lua:19 | Adapters: { {
    adapter = {
      _generate_position_id = <function 1>,
      build_spec = <function 2>,
      discover_positions = <function 3>,
      is_test_file = <function 4>,
      name = "neotest-go",
      prepare_results = <function 5>,
      results = <function 6>,
      root = <function 7>,
      <metatable> = {
        __call = <function 8>
      }
    },
    root = "/home/twhitney/workspace/loki-release"
  } }
INFO | 2024-01-26T14:43:06Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:281 | Searching /home/twhitney/workspace/loki-release for test files
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: docs
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: node_modules
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: badges
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: cmd
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: coverage
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: actions
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: vendor
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: workflows
DEBUG | 2024-01-26T14:43:06Z-0700 | ...al/share/nvim/lazy/neotest/lua/neotest/lib/file/find.lua:26 | Scanning directory: node_modules/node-fetch

... tons of Scanning Directory logs omitted as it scanned everything in node_modules, and went over the GitHub comment character max...

DEBUG | 2024-01-26T14:43:06Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:297 | Found { {
    id = "/home/twhitney/workspace/loki-release",
    name = "loki-release",
    path = "/home/twhitney/workspace/loki-release",
    type = "dir"
  } }
DEBUG | 2024-01-26T14:43:06Z-0700 | ...hare/nvim/lazy/neotest/lua/neotest/client/state/init.lua:54 | New positions at ID /home/twhitney/workspace/loki-release
INFO | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting discover_positions event
DEBUG | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener diagnostic for event discover_positions
DEBUG | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event discover_positions
DEBUG | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener state for event discover_positions
DEBUG | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener status for event discover_positions
INFO | 2024-01-26T14:43:06Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:327 | Discovering files with 16 workers
INFO | 2024-01-26T14:43:06Z-0700 | ...ocal/share/nvim/lazy/neotest/lua/neotest/client/init.lua:496 | Initialisation finished in 0.182 seconds
INFO | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:48 | Emitting started event
DEBUG | 2024-01-26T14:43:06Z-0700 | ...are/nvim/lazy/neotest/lua/neotest/client/events/init.lua:50 | Calling listener summary for event started