nvim-neotest / neotest-go

MIT License
125 stars 43 forks source link

[feature request] Table-driven tests written as map[string]struct{} #43

Closed bravoecho closed 1 year ago

bravoecho commented 1 year ago

Following the recent fixes, I now use the table-driven support extensively, and it's become essential to me.

Some of the table-driven tests I work on were written as map[string]struct{...}, following the advice by Dave Cheney (https://dave.cheney.net/2019/05/07/prefer-table-driven-tests), and these are not detected.

I tried to hack the Tree Sitter query myself into something like the snippet at the bottom, but I don't seem to be able to obtain a working solution.

I'll keep trying as this would be a killer feature for me, but in the meantime I would also like to ask for your help, if you had the time to look into this you would have my undying gratitude.

Thank you! ๐Ÿ™‚


PS: This is my attempt, it kind-of works in the online Tree Sitter Playground, as it catches the expected elements, but then it breaks if I try and use it in place of the original query

(block
    (short_var_declaration
        left: (expression_list
            (identifier) @test.cases
        )
        right: (expression_list
            (composite_literal
                type: (map_type
                    key: (type_identifier) @test.key.type 
                        (#eq? @test.key.type "string")
                    value: (struct_type)
                )
                body: (literal_value
                    .(keyed_element
                        (interpreted_string_literal) @test.name
                    )
                ) @test.definition
            )
        )
    )
    (for_statement
        (range_clause
            left: (expression_list
                (identifier) @test.name1
                    (#eq @test.name @test.name1)
                (identifier) @test.case
            )
            right: (identifier) @test.cases1
                (#eq? @test.cases @test.cases1)
        )
        body: (block
            (call_expression
                function: (selector_expression
                    field: (field_identifier) @test.method
                )
                    (#match? @test.method "^Run$")
                arguments: (argument_list
                    (identifier) @test.name2
                        (#eq? @test.name1 @test.name2)
                )
            )
        )
    )
)
sergii4 commented 1 year ago

Hi @bravoecho, support of map table test comes with #55 :)

bravoecho commented 1 year ago

That's such wonderful news, thank you, well done you folks!

sergii4 commented 1 year ago

I have tested it both manually and with unit test, but let me know if it doesn't work as expected

bravoecho commented 1 year ago

The map-based tests work perfectly, they are correctly marked as passing or failing when run in bulk, and they can also be run individually with :TestThis, which is super-brilliant!

Map-based table-driven tests ๐ŸŽ‰

On an unrelated note, I noticed something in the Go tests for the struct-based table tests, where individually failing tests are not reported correctly. For example, on a slightly modified version of the test:

Slightly confusing results in struct-based table-driven tests ๐Ÿง

By adding an assertion, and setting up of the tests to fail, the package-level test is correctly reported as failing, but one cannot see which subtest caused the failure.

It threw me off for a second, and I thought maybe it's a regression, but then I realised that it's just the infamous loop variable striking again, because the Run() function reuses the t from the closure (due to the underscore) ๐Ÿ˜น

Declaring a new t variable on each subtest

Anyway, I really think this feature that you just improved is one of the absolute coolest in all of Neovim, the wow factor, the "a-ha!" moment, the "I-didn't-know-Vim-could-do-this!" feature.

sergii4 commented 1 year ago

Thanks, @bravoecho for the feedback, I am really happy to hear that!