olimorris / neotest-phpunit

πŸ§ͺ Neotest adapter for PHPUnit
MIT License
29 stars 22 forks source link

Issues with weird monorepo structures, can't get to work #26

Closed caliguIa closed 4 months ago

caliguIa commented 4 months ago

Hi, apologies as I don't think this is an issue with the adapter itself, but I for the life of me cannot get this to work and have spent about 3+days trying to now. If you wouldn't mind, I'd love a little help.

For work we have a monorepo with the following structure:

root root/platform root/platform/vendor/bin/phpunit root/platform/resources/client

the platform directory contains backend php code, and frontend code (inside resources client). When using neovim I open the platform directory, so for all intents and purposes this is my root dir.

platform contains the vendor dir in which phpunit is located.

platform contains a phpunit.xml & composer.json.

What I am seeing is if I open neovim from the platform directory, no tests are found. I have php parser installed via treesitter, treesitters checkhealth is all fine, and highlighting etc works as expected.

If I open the root/platform/resources/client directory directly then tests are found, but do not run (failing immediately, due to it trying to test the live DB (which it isn't)). However I need to have the root/platform directory as my "root" dir.

This is my neotest config:

{
        'nvim-neotest/neotest',
        dependencies = {
            'nvim-neotest/nvim-nio',
            'antoinemadec/FixCursorHold.nvim',
            'nvim-lua/plenary.nvim',
            'nvim-treesitter/nvim-treesitter',
            'nvim-neotest/neotest-jest',
            'olimorris/neotest-phpunit',
            'nvim-neotest/nvim-nio',
        },
        config = function()
            local neotest = require 'neotest'
            ---@diagnostic disable-next-line: missing-fields
            neotest.setup {
                adapters = {
                    require 'neotest-jest' {
                        -- TODO: make this dynamic based on the project, currently it's hardcoded for ous weird monorepo
                        cwd = '/Users/caligula/oneupsales/platform/resources/client',
                        jestCommand = 'npm test --',
                    },
                    require 'neotest-phpunit' {
                        phpunit_cmd = function()
                            return 'vendor/bin/phpunit'
                        end,
                        root_files = { 'phpunit.xml', 'pint.json', 'composer.json' },
                        -- filter_dirs = { '.git', 'node_modules' },
                        -- root_ignore_files = { 'vite.config.ts' },
                    },
                    -- require 'neotest-phpunit' {
                    --     phpunit_cmd = function()
                    --         return 'vendor/bin/phpunit'
                    --     end,
                    --     root_files = { 'phpunit.xml', 'pint.json', 'composer.json' },
                    --     filter_dirs = { '.git', 'node_modules', 'vendor' },
                    --     root_ignore_files = { 'vite.config.ts' },
                    -- },
                },
                ---@diagnostic disable-next-line: missing-fields
                diagnostic = {
                    enabled = true,
                },
                icons = {
                    failed = test_icons.failed,
                    passed = test_icons.passed,
                    running = test_icons.running,
                    skipped = test_icons.skipped,
                },
            }
        end,
        -- stylua: ignore
        keys = {
            { "<leader>tr", function() require("neotest").run.run() end, desc = "[T]est [r]un nearest" },

            { "<leader>tR", function() require("neotest").run.run(vim.fn.expand("%")) end, desc = "[T]est [R]un file" },

            { "<leader>tc", function() require("neotest").run.stop() end, desc = "[T]est [c]ancel nearest" },

            { "<leader>ta", function() require("neotest").run.attach() end, desc = "[T]est [a]ttach to nearest" },

            { "<leader>to", function() require("neotest").output.open({ enter = true, auto_close = true }) end, desc = "[T]est [o]utput open" },

            { "<leader>tO", function() require("neotest").output_panel.toggle() end, desc = "[T]est [O]utput panel" },

            { "<leader>ts", function() require("neotest").summary.toggle() end, desc = "[T]est [s]ummary" },

            { "<leader>tw", function() require("neotest").summary.toggle() end, desc = "[T]est [w]atch" },

            { "]t", function() require("neotest").jump.next({status = 'failed'}) end, desc = "Jump to next failed [t]est" },

            { "[t", function() require("neotest").jump.prev({status = 'failed'}) end, desc = "Jump to previous failed [t]est" },
        },
    },

As you can see from the various commented out lines, I have tried and continue to try may different options to get this to work.

my neotest.log is outputting the following error:

β”‚ WARN | 2024-04-27T10:45:42Z+0100 | ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:164 | CHILD | Error in remote call ...0.9.5/share/nvim/runtime/lua/vim/treesitter/language.lua:87: '' is not a valid lang
       β”‚ uage name
 104   β”‚ stack traceback:
 105   β”‚     [C]: in function 'error'
 106   β”‚     ...0.9.5/share/nvim/runtime/lua/vim/treesitter/language.lua:87: in function 'add'
 107   β”‚     ...5/share/nvim/runtime/lua/vim/treesitter/languagetree.lua:98: in function 'get_string_parser'
 108   β”‚     ...re/nvim/lazy/neotest/lua/neotest/lib/treesitter/init.lua:119: in function 'get_parse_root'
 109   β”‚     ...re/nvim/lazy/neotest/lua/neotest/lib/treesitter/init.lua:160: in function 'parse_positions_from_string'
 110   β”‚     ...re/nvim/lazy/neotest/lua/neotest/lib/treesitter/init.lua:207: in function 'func'
 111   β”‚     ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:156: in function <...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:155>
 112   β”‚     [C]: in function 'xpcall'
 113   β”‚     ...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:155: in function <...l/share/nvim/lazy/neotest/lua/neotest/lib/subprocess.lua:154>

which makes it seem like a treesitter issue, but as explained above I have checked and everything seems to be working as expected in regards to php and treesitter (execpt in regards to neotest).

I have uninstalled treesitter, and the php parser, reinstalled, stripped my treesitter config, down to it's most basic etc. nothing seems to help.

The tests run via the cli & in phpstorm fine.

I'm at a bit of a loss here, so if you have any thoughts I'd hugely appreciate it. Thank you!

olimorris commented 4 months ago

If you share an example folder structure I can clone I'll take a look

olimorris commented 4 months ago

What happens if you type :pwd in Neovim? Are you seeing root/platform?

Maybe try deleting all of your compiled treesitter languages. The error does seem to suggest it's a treesitter error. Have you posted this on the Neotest repo too?

caliguIa commented 4 months ago

Thank you for responding, I will make an example repo today, I really appreciate this.

Yes when I pwd, I see root/platform. Thanks for the suggestion, I will remove them all now. I haven't posted on neotest repo, no, as I'm able to use neotest with the jest adapter correctly

olimorris commented 4 months ago

Is Jest in the same monorepo?

I'd also advise setting the logging to trace in Neotest and seeing what's returned

caliguIa commented 4 months ago

https://github.com/caliguIa/neotest-phpunit-example-structure

here is an example folder structure, let me know if it is missing anything key, however I feel that is a very fair representation.

Yes jest is in the same monorepo, but is installed inside platform/resources/client. You can somewhat see this in the example repo linked. However my jest setup is not perfect, as you can see from my neotest config posted in the first comment above, as currently I'm having to hard code the value of the jest command. Whilst this works, obviously is not dynamic.

thanks again Oli, appreciate your time here.

caliguIa commented 4 months ago

By deleting all compiled TS parsers do you mean just TSUninstall all?

caliguIa commented 4 months ago

haha, okay this is a fun one. I enabled logging-level trace, and obviously am now bombarded by all of the jest tests, which made finding anything related to phpunit impossible. So, I disabled the neotest-jest adapter, and guess what, phpunit suddenly starts finding tests and running them works!

If I re-add the jest adapter, guess what phpunit adapter stops working... ha! I'm now wondering if I've just been really stupid and there is some glaringly obvious issue in my neotest config? OR if this an actual bug

caliguIa commented 4 months ago

I wonder if it's something to do with the cwd maybe being changed if one or the other is enabled? Does neotest itself have anything todo with cwd? I would've thought each adapter would've handled it themselves?

olimorris commented 4 months ago

I can't speak for how the Jest adapter works, but this adapter is relatively simple in terms of detecting the root, determining if a file is a test file, discovering tests in a file, forming a PHPUnit command etc. This adapter detects the cwd via the nio library.

olimorris commented 4 months ago

Right, I've added a bug report template to this repo. Apologies, I should have done this sooner.

Can you re-create this issue in that template, testing with the minimal config (please add the jest adapter config) in the monorepo structure, adding the logging etc.

This will just minimise the variables that could be at play within your config.

caliguIa commented 4 months ago

Great, thanks Oli, I will have a look at recreating with the template repo now. Again, appreciate your time on this (especially on a Sunday!)

caliguIa commented 4 months ago

Hey Oli, using your minimal config I cannot recreate the issue, must be something within my config causing the issue. Apologies for wasting your time here, but thanks for your help. Your minimal.lua in the bug report template will no doubt prove very helpful in debugging. Cheers and thank you for making the adapter, very excited to use it.

olimorris commented 4 months ago

No problem! And the minimal config is such a great way to troubleshoot problems.

Let me know how you get on.

caliguIa commented 4 months ago

Got it all working (mostly, haha), which is great. The only thing now is running an individual test will always run the entire file instead of the specific test, and the diagnostics/test summary always report the test as passing even when one of the tests (out of many fails). I think it's just picking up whatever the first test does and using that as the pass fail state. I haven't looked too much into this yet so am sure it's something my end to sort. Thanks

olimorris commented 4 months ago

Great to hear. Neovim config's...we've all lost days tweaking them πŸ˜† .

Is that after running :lua require("neotest").run.run()? The plugin should be able to detect singular tests with no problem.

caliguIa commented 4 months ago

Indeed, haha, but we love it.

Yes it's odd, in every file and for every test it's working as expected bar 2, I just so happened to choose the 2 tests that for some reason it seems to be playing up with (running all tests in file and then reporting a pass when some fail).

Incidentally the two tests it's playing up with are two tests that I know are currently failing, I wonder if there's something in that.

Anyway, it's just the two that I've seen so far, and everything else working perfectly, so inclined to go with that it's something in the codebase that's off. I will test this evening that if I make a test that is currently passing (and running fine) fail if I get the same result as the two that are playing up. If so I will report back here.

Anyway you've been far too generous with your time this weekend and I shall leave you in peace!

olimorris commented 4 months ago

Ahhh okay this is interesting! It may be that they are unique in how they're written and my Treesitter queries aren't picking them up. If you can obfuscate them and share them here I can take a look.

I have a bank of tests in this adapter that people have shared that originally the plugin couldn't pickup.

Hope you're enjoying the Neotest workflow! Totally changed my game.

caliguIa commented 4 months ago

Sorry, I will get back to you, just rather busy atm.