diff --git a/lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb b/lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb index 8818611..062ad90 100644 --- a/lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb +++ b/lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb @@ -34,7 +34,7 @@ def on_call_node_enter(node) selection_range: range_from_node(node), range: range_from_node(node), ) - when "context", "describe" + when "context", "describe", "shared_examples", "shared_context", "shared_examples_for" return if node.receiver && node.receiver&.slice != "RSpec" name = generate_name(node) @@ -57,7 +57,7 @@ def on_call_node_enter(node) sig { params(node: Prism::CallNode).void } def on_call_node_leave(node) case node.message - when "context", "describe" + when "context", "describe", "shared_examples", "shared_context", "shared_examples_for" return if node.receiver && node.receiver&.slice != "RSpec" @response_builder.pop diff --git a/spec/document_symbol_spec.rb b/spec/document_symbol_spec.rb index 0346365..6561e52 100644 --- a/spec/document_symbol_spec.rb +++ b/spec/document_symbol_spec.rb @@ -88,5 +88,355 @@ def test_baz; end expect(foo.children[4].children[0].name).to eq("何かのテスト") end end + + it "simple shared_examples" do + source = <<~RUBY + RSpec.shared_examples 'simple shared examples' do + it 'does something' do + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + shared = response[0] + expect(shared.name).to eq("simple shared examples") + expect(shared.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(shared.children.count).to eq(1) + + example = shared.children[0] + expect(example.name).to eq("does something") + expect(example.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::METHOD) + end + end + + it "symbol shared_examples" do + source = <<~RUBY + RSpec.shared_examples :symbol_shared_examples do + it 'does something in symbol' do + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + shared = response[0] + expect(shared.name).to eq(":symbol_shared_examples") + expect(shared.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(shared.children.count).to eq(1) + + child = shared.children[0] + expect(child.name).to eq("does something in symbol") + expect(child.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::METHOD) + end + end + + it "shared_examples with parameter" do + source = <<~RUBY + RSpec.shared_examples "shared example with parameter" do |parameter| + let(:something) { parameter } + it "uses the given parameter" do + expect(something).to eq(parameter) + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + shared = response[0] + expect(shared.name).to eq("shared example with parameter") + expect(shared.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(shared.children.count).to eq(1) + + child1 = shared.children[0] + expect(child1.name).to eq("uses the given parameter") + expect(child1.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::METHOD) + end + end + + it "simple shared_context" do + source = <<~RUBY + RSpec.shared_context "simple shared_context" do + before { @some_var = :some_value } + def shared_method + "it works" + end + let(:shared_let) { {'arbitrary' => 'object'} } + subject do + 'this is the subject' + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + expect(response[0].name).to eq("simple shared_context") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(response[0].children.count).to eq(2) + end + end + + it "symbol shared_context" do + source = <<~RUBY + RSpec.shared_context :symbol_shared_context do + before { @some_var = :some_value } + def shared_method + "it works" + end + let(:shared_let) { {'arbitrary' => 'object'} } + subject do + 'this is the subject' + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + expect(response[0].name).to eq(":symbol_shared_context") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(response[0].children.count).to eq(2) + end + end + + it "simple shared_examples_for" do + source = <<~RUBY + RSpec.shared_examples_for "simple shared_examples_for" do + before { @some_var = :some_value } + def shared_method + "it works" + end + let(:shared_let) { {'arbitrary' => 'object'} } + subject do + 'this is the subject' + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + expect(response[0].name).to eq("simple shared_examples_for") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(response[0].children.count).to eq(2) + end + end + + it "symbol shared_examples_for" do + source = <<~RUBY + RSpec.shared_examples_for :symbol_shared_examples_for do + before { @some_var = :some_value } + def shared_method + "it works" + end + let(:shared_let) { {'arbitrary' => 'object'} } + subject do + 'this is the subject' + end + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(1) + expect(response[0].name).to eq(":symbol_shared_examples_for") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + expect(response[0].children.count).to eq(2) + end + end + + it "on_call_node_leave for shared examples" do + source = <<~RUBY + RSpec.shared_examples "shared examples" do + end + + describe "something" do + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(2) + expect(response[0].name).to eq("shared examples") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + + expect(response[1].name).to eq("something") + expect(response[1].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + end + end + + it "on_call_node_leave for shared_context" do + source = <<~RUBY + RSpec.shared_context "shared context" do + end + + describe "something" do + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(2) + expect(response[0].name).to eq("shared context") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + + expect(response[1].name).to eq("something") + expect(response[1].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + end + end + + it "on_call_node_leave for shared_examples_for" do + source = <<~RUBY + RSpec.shared_examples_for "shared examples for" do + end + + describe "something" do + end + RUBY + + with_server(source, uri) do |server, uri| + server.process_message( + { + id: 2, + method: "textDocument/documentSymbol", + params: { + textDocument: { uri: uri }, + }, + }, + ) + + result = server.pop_response + expect(result).to be_a(RubyLsp::Result) + response = result.response + + expect(response.count).to eq(2) + expect(response[0].name).to eq("shared examples for") + expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + + expect(response[1].name).to eq("something") + expect(response[1].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE) + end + end end end