diff --git a/lua/neotest-golang/ast.lua b/lua/neotest-golang/ast.lua index 19ddc8d6..2e752438 100644 --- a/lua/neotest-golang/ast.lua +++ b/lua/neotest-golang/ast.lua @@ -135,7 +135,7 @@ function M.detect_tests(file_path) if options.get().testify == true then -- only detect receiver methods if testify is enabled, to avoid confusion - query = query .. testify.receiver_method_query + query = query .. testify.namespace_query end ---@type neotest.Tree diff --git a/lua/neotest-golang/testify.lua b/lua/neotest-golang/testify.lua index b426a560..34c3b540 100644 --- a/lua/neotest-golang/testify.lua +++ b/lua/neotest-golang/testify.lua @@ -7,51 +7,62 @@ local M = {} local lookup_map = {} M.lookup_query = [[ - ; query for detecting package, struct and test suite, for use in lookup. + ; query for the lookup between receiver and test suite. + + ; package main // @package (package_clause (package_identifier) @package) - (type_declaration - (type_spec - name: (type_identifier) @struct_name - type: (struct_type))) - (method_declaration - receiver: (parameter_list - (parameter_declaration - type: (pointer_type - (type_identifier) @receiver_type))) - name: (field_identifier) @method_name) + + ; func TestSuite(t *testing.T) { // @test_function + ; suite.Run(t, new(testSuiteStruct)) // @suite_receiver + ; } (function_declaration - name: (identifier) @function_name) + name: (identifier) @test_function (#match? @test_function "^Test") ) (call_expression function: (selector_expression - operand: (identifier) @module - field: (field_identifier) @run (#eq? @run "Run")) + operand: (identifier) + field: (field_identifier)) arguments: (argument_list (identifier) (call_expression arguments: (argument_list - (type_identifier) @suite_receiver)))) - -; capture variable declarations -(short_var_declaration - left: (expression_list - (identifier) @var_name) - right: (expression_list - (unary_expression - operand: (composite_literal - type: (type_identifier) @struct_type)))) - -(assignment_statement - left: (expression_list - (identifier) @var_name) - right: (expression_list - (unary_expression - operand: (composite_literal - type: (type_identifier) @struct_type)))) + (type_identifier) @suite_struct)))) + + ; func TestSuite(t *testing.T) { // + ; s := &testSuiteStruct{} // @suite_struct + ; suite.Run(t, s) + ; } + (function_declaration + name: (identifier) @test_function (#match? @test_function "^Test") + parameters: (parameter_list + (parameter_declaration + name: (identifier) + type: (pointer_type + (qualified_type + package: (package_identifier) + name: (type_identifier))))) + body: (block + (short_var_declaration + left: (expression_list + (identifier)) + right: (expression_list + (unary_expression + operand: (composite_literal + type: (type_identifier) @suite_struct + body: (literal_value))))) + (expression_statement + (call_expression + function: (selector_expression + operand: (identifier) + field: (field_identifier)) + arguments: (argument_list + (identifier) + (identifier)))))) + ]] -M.receiver_method_query = [[ - ; query for receiver method, to be used as test suite namespace. +M.namespace_query = [[ + ; query for receiver method, to be used as test suite namespace initially (will be replaced later). (method_declaration receiver: (parameter_list (parameter_declaration @@ -147,40 +158,20 @@ function M.generate_lookup_map() suites = {}, } - -- Collect all receivers - for _, struct in ipairs(matches.struct_name or {}) do + -- Collect all receivers (same name as suite structs) + for _, struct in ipairs(matches.suite_struct or {}) do lookup[filepath].receivers[struct.text] = true end -- Collect all test suite functions and their receivers - for _, func in ipairs(matches.function_name or {}) do + for _, func in ipairs(matches.test_function or {}) do if func.text:match("^Test") then - for _, node in ipairs(matches.suite_receiver or {}) do + for _, node in ipairs(matches.suite_struct or {}) do lookup[filepath].suites[node.text] = func.text global_suites[node.text] = func.text end end end - - -- Handle var_name and struct_type matches - if matches.var_name and matches.struct_type then - for i, var in ipairs(matches.var_name) do - local struct_type = matches.struct_type[i] - if struct_type then - -- Add the struct_type as a receiver - lookup[filepath].receivers[struct_type.text] = true - - -- Find the corresponding function_name (test suite) - for _, func in ipairs(matches.function_name or {}) do - if func.text:match("^Test") then - lookup[filepath].suites[struct_type.text] = func.text - global_suites[struct_type.text] = func.text - break - end - end - end - end - end end -- Second pass: ensure all files have all receivers and suites @@ -246,8 +237,6 @@ function M.run_query_on_file(filepath, query_string) vim.api.nvim_buf_delete(bufnr, { force = true }) - vim.notify(vim.inspect(matches)) - return matches end