diff --git a/lua/test-samurai-go-runner/init.lua b/lua/test-samurai-go-runner/init.lua index abdf025..fc8c1fd 100644 --- a/lua/test-samurai-go-runner/init.lua +++ b/lua/test-samurai-go-runner/init.lua @@ -187,6 +187,32 @@ local function order_with_display(names, display_map) return ordered, display end +local function filter_parents_for_subtest(passes, failures, skips) + local all_tests = {} + for _, n in ipairs(passes) do table.insert(all_tests, n) end + for _, n in ipairs(failures) do table.insert(all_tests, n) end + for _, n in ipairs(skips) do table.insert(all_tests, n) end + + local has_children = {} + for _, n in ipairs(all_tests) do + local root = n:match("^([^/]+)/") + if root then + has_children[root] = true + end + end + + local function filter_parents(names) + local out = {} + for _, n in ipairs(names) do + if not has_children[n] then + table.insert(out, n) + end + end + return out + end + return filter_parents(passes), filter_parents(failures), filter_parents(skips) +end + local function display_name(name) if not name or name == "" then return name @@ -467,7 +493,7 @@ function runner.build_failed_command(last_command, failures, _scope_kind) } end -function runner.parse_results(output) +function runner.parse_results(output, parser_state) if not output or output == "" then return { passes = {}, failures = {}, skips = {}, display = { passes = {}, failures = {}, skips = {} } } end @@ -511,6 +537,22 @@ function runner.parse_results(output) failures = collect_unique(failures) skips = collect_unique(skips) + if parser_state and parser_state.spec_scope == "subtest" then + passes, failures, skips = filter_parents_for_subtest(passes, failures, skips) + pass_display = {} + fail_display = {} + skip_display = {} + for _, n in ipairs(passes) do + pass_display[n] = display_name(n) + end + for _, n in ipairs(failures) do + fail_display[n] = display_name(n) + end + for _, n in ipairs(skips) do + skip_display[n] = display_name(n) + end + end + passes, display.passes = order_with_display(passes, pass_display) failures, display.failures = order_with_display(failures, fail_display) skips, display.skips = order_with_display(skips, skip_display) diff --git a/tests/test_go_runner_spec.lua b/tests/test_go_runner_spec.lua index ea11c55..38a9c00 100644 --- a/tests/test_go_runner_spec.lua +++ b/tests/test_go_runner_spec.lua @@ -223,4 +223,59 @@ describe("test-samurai-go-runner", function() assert.equals(file, items[1].filename) assert.equals(5, items[1].lnum) end) + + it("filters parent tests for subtest scope", function() + -- This is a simpler test of the filtering logic + -- In real usage, parser_state.spec_scope = "subtest" is passed through core.lua + local passes = { "TestFoo", "TestFoo/first" } + local failures = {} + local skips = {} + + -- Manually call what parse_results should do + local all_tests = {} + for _, n in ipairs(passes) do table.insert(all_tests, n) end + for _, n in ipairs(failures) do table.insert(all_tests, n) end + for _, n in ipairs(skips) do table.insert(all_tests, n) end + + local has_children = {} + for _, n in ipairs(all_tests) do + local root = n:match("^([^/]+)/") + if root then has_children[root] = true end + end + + -- TestFoo should have been marked as having children + assert.is_true(has_children["TestFoo"], "TestFoo should be marked as having children") + + local filtered_passes = {} + for _, n in ipairs(passes) do + if not has_children[n] then + table.insert(filtered_passes, n) + end + end + + assert.are.same({ "TestFoo/first" }, filtered_passes, "TestFoo should be filtered out") + end) + + it("parse_results keeps parent test when spec_scope is function", function() + local output = table.concat({ + vim.json.encode({ Action = "run", Test = "TestFoo" }), + vim.json.encode({ Action = "pass", Test = "TestFoo" }), + vim.json.encode({ Action = "pass", Test = "TestFoo/first" }), + }, "\n") + + local parser_state = { spec_scope = "function" } + local results = runner.parse_results(output, parser_state) + assert.are.same({ "TestFoo", "TestFoo/first" }, results.passes) + end) + + it("parse_results keeps parent test when setup fails even in subtest scope", function() + local output = table.concat({ + vim.json.encode({ Action = "run", Test = "TestFoo" }), + vim.json.encode({ Action = "fail", Test = "TestFoo" }), + }, "\n") + + local parser_state = { spec_scope = "subtest" } + local results = runner.parse_results(output, parser_state) + assert.are.same({ "TestFoo" }, results.failures) + end) end)