diff --git a/lib/ruby_lsp/listeners/code_lens.rb b/lib/ruby_lsp/listeners/code_lens.rb index 2eb91487e..13153b550 100644 --- a/lib/ruby_lsp/listeners/code_lens.rb +++ b/lib/ruby_lsp/listeners/code_lens.rb @@ -39,7 +39,7 @@ def initialize(response_builder, global_state, uri, dispatcher) @path = T.let(uri.to_standardized_path, T.nilable(String)) # visibility_stack is a stack of [current_visibility, previous_visibility] @visibility_stack = T.let([[:public, :public]], T::Array[T::Array[T.nilable(Symbol)]]) - @group_stack = T.let([], T::Array[String]) + @group_stack = T.let([], T::Array[[Symbol, String]]) @group_id = T.let(1, Integer) @group_id_stack = T.let([], T::Array[Integer]) # We want to avoid adding code lenses for nested definitions @@ -63,15 +63,15 @@ def initialize(response_builder, global_state, uri, dispatcher) def on_class_node_enter(node) @visibility_stack.push([:public, :public]) class_name = node.constant_path.slice - @group_stack.push(class_name) + @group_stack.push([:class, class_name]) if @path && class_name.end_with?("Test") add_test_code_lens( node, name: class_name, - command: generate_test_command(group_stack: @group_stack), + command: generate_test_command(group_stack: @group_stack.map(&:last)), kind: :group, - id: generate_fully_qualified_id(group_stack: @group_stack), + id: generate_fully_qualified_id(group_stack: @group_stack.map(&:last)), ) @group_id_stack.push(@group_id) @@ -96,7 +96,7 @@ def on_def_node_enter(node) @def_depth += 1 return if @def_depth > 1 - class_name = @group_stack.last + class_name = @group_stack.last&.last return unless class_name&.end_with?("Test") visibility, _ = @visibility_stack.last @@ -106,9 +106,9 @@ def on_def_node_enter(node) add_test_code_lens( node, name: method_name, - command: generate_test_command(method_name: method_name, group_stack: @group_stack), + command: generate_test_command(method_name: method_name, group_stack: @group_stack.map(&:last)), kind: :example, - id: generate_fully_qualified_id(group_stack: @group_stack, method_name: method_name), + id: generate_fully_qualified_id(group_stack: @group_stack.map(&:last), method_name: method_name), ) end end @@ -122,9 +122,9 @@ def on_def_node_leave(node) sig { params(node: Prism::ModuleNode).void } def on_module_node_enter(node) if (path = namespace_constant_name(node)) - @group_stack.push(path) + @group_stack.push([:module, path]) else - @group_stack.push(DYNAMIC_REFERENCE_MARKER) + @group_stack.push([:module, DYNAMIC_REFERENCE_MARKER]) end end @@ -293,17 +293,21 @@ def add_spec_code_lens(node, kind:) else # Reset spec_id when entering a new group @spec_id = 0 - @group_stack.push(name) + @group_stack.push([:describe, name]) end if @path + # Remove any class or module names from the group stack. + # Specs don't include the class name in the test selector. + group_stack = @group_stack.filter_map { |type, value| value if type == :describe } + method_name = format("test_%04d_%s", @spec_id, name) if kind == :example add_test_code_lens( node, name: name, - command: generate_test_command(group_stack: @group_stack, spec_name: method_name), + command: generate_test_command(group_stack: group_stack, spec_name: method_name), kind: kind, - id: generate_fully_qualified_id(group_stack: @group_stack, method_name: method_name), + id: generate_fully_qualified_id(group_stack: group_stack, method_name: method_name), ) end end diff --git a/test/requests/code_lens_expectations_test.rb b/test/requests/code_lens_expectations_test.rb index e4541474f..a878a2fb4 100644 --- a/test/requests/code_lens_expectations_test.rb +++ b/test/requests/code_lens_expectations_test.rb @@ -79,12 +79,12 @@ class FooTest < MiniTest::Test ) assert_equal("Run In Terminal", T.must(response[4]).command.title) assert_equal( - "bundle exec ruby -Itest /fake.rb --name \"/^FooTest::a(#|::)/\"", + "bundle exec ruby -Itest /fake.rb --name \"/^a(#|::)/\"", T.must(response[4]).command.arguments[2], ) assert_equal("Run In Terminal", T.must(response[7]).command.title) assert_equal( - "bundle exec ruby -Itest /fake.rb --name \"/^FooTest::a#test_0001_b$/\"", + "bundle exec ruby -Itest /fake.rb --name \"/^a#test_0001_b$/\"", T.must(response[7]).command.arguments[2], ) end