Skip to content

Commit f2e4170

Browse files
authored
Support document symbols for shared examples (#56)
* 👍 support shared_examples and shared_context I add document symbol support for shared_examples and shared_context. https://rspec.info/features/3-12/rspec-core/example-groups/shared-examples/ https://rspec.info/features/3-12/rspec-core/example-groups/shared-context/ * 👍 support shared_examples_for also shared_examples_for is alias for shared_examples. So I support shared_examples_for. https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/shared_example_group.rb#L101 * 🐛 fix forget leave context issue I forget to add on_call_node_leave for shared_... . * ✅ Add on_call_node_leave test for shared tests I add tests to implement on_call_node_leave for shared tests.
1 parent 2ae636e commit f2e4170

File tree

2 files changed

+352
-2
lines changed

2 files changed

+352
-2
lines changed

lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def on_call_node_enter(node)
3434
selection_range: range_from_node(node),
3535
range: range_from_node(node),
3636
)
37-
when "context", "describe"
37+
when "context", "describe", "shared_examples", "shared_context", "shared_examples_for"
3838
return if node.receiver && node.receiver&.slice != "RSpec"
3939

4040
name = generate_name(node)
@@ -57,7 +57,7 @@ def on_call_node_enter(node)
5757
sig { params(node: Prism::CallNode).void }
5858
def on_call_node_leave(node)
5959
case node.message
60-
when "context", "describe"
60+
when "context", "describe", "shared_examples", "shared_context", "shared_examples_for"
6161
return if node.receiver && node.receiver&.slice != "RSpec"
6262

6363
@response_builder.pop

spec/document_symbol_spec.rb

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,355 @@ def test_baz; end
8888
expect(foo.children[4].children[0].name).to eq("何かのテスト")
8989
end
9090
end
91+
92+
it "simple shared_examples" do
93+
source = <<~RUBY
94+
RSpec.shared_examples 'simple shared examples' do
95+
it 'does something' do
96+
end
97+
end
98+
RUBY
99+
100+
with_server(source, uri) do |server, uri|
101+
server.process_message(
102+
{
103+
id: 2,
104+
method: "textDocument/documentSymbol",
105+
params: {
106+
textDocument: { uri: uri },
107+
},
108+
},
109+
)
110+
111+
result = server.pop_response
112+
expect(result).to be_a(RubyLsp::Result)
113+
response = result.response
114+
115+
expect(response.count).to eq(1)
116+
shared = response[0]
117+
expect(shared.name).to eq("simple shared examples")
118+
expect(shared.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
119+
expect(shared.children.count).to eq(1)
120+
121+
example = shared.children[0]
122+
expect(example.name).to eq("does something")
123+
expect(example.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::METHOD)
124+
end
125+
end
126+
127+
it "symbol shared_examples" do
128+
source = <<~RUBY
129+
RSpec.shared_examples :symbol_shared_examples do
130+
it 'does something in symbol' do
131+
end
132+
end
133+
RUBY
134+
135+
with_server(source, uri) do |server, uri|
136+
server.process_message(
137+
{
138+
id: 2,
139+
method: "textDocument/documentSymbol",
140+
params: {
141+
textDocument: { uri: uri },
142+
},
143+
},
144+
)
145+
146+
result = server.pop_response
147+
expect(result).to be_a(RubyLsp::Result)
148+
response = result.response
149+
150+
expect(response.count).to eq(1)
151+
shared = response[0]
152+
expect(shared.name).to eq(":symbol_shared_examples")
153+
expect(shared.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
154+
expect(shared.children.count).to eq(1)
155+
156+
child = shared.children[0]
157+
expect(child.name).to eq("does something in symbol")
158+
expect(child.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::METHOD)
159+
end
160+
end
161+
162+
it "shared_examples with parameter" do
163+
source = <<~RUBY
164+
RSpec.shared_examples "shared example with parameter" do |parameter|
165+
let(:something) { parameter }
166+
it "uses the given parameter" do
167+
expect(something).to eq(parameter)
168+
end
169+
end
170+
RUBY
171+
172+
with_server(source, uri) do |server, uri|
173+
server.process_message(
174+
{
175+
id: 2,
176+
method: "textDocument/documentSymbol",
177+
params: {
178+
textDocument: { uri: uri },
179+
},
180+
},
181+
)
182+
183+
result = server.pop_response
184+
expect(result).to be_a(RubyLsp::Result)
185+
response = result.response
186+
187+
expect(response.count).to eq(1)
188+
shared = response[0]
189+
expect(shared.name).to eq("shared example with parameter")
190+
expect(shared.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
191+
expect(shared.children.count).to eq(1)
192+
193+
child1 = shared.children[0]
194+
expect(child1.name).to eq("uses the given parameter")
195+
expect(child1.kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::METHOD)
196+
end
197+
end
198+
199+
it "simple shared_context" do
200+
source = <<~RUBY
201+
RSpec.shared_context "simple shared_context" do
202+
before { @some_var = :some_value }
203+
def shared_method
204+
"it works"
205+
end
206+
let(:shared_let) { {'arbitrary' => 'object'} }
207+
subject do
208+
'this is the subject'
209+
end
210+
end
211+
RUBY
212+
213+
with_server(source, uri) do |server, uri|
214+
server.process_message(
215+
{
216+
id: 2,
217+
method: "textDocument/documentSymbol",
218+
params: {
219+
textDocument: { uri: uri },
220+
},
221+
},
222+
)
223+
224+
result = server.pop_response
225+
expect(result).to be_a(RubyLsp::Result)
226+
response = result.response
227+
228+
expect(response.count).to eq(1)
229+
expect(response[0].name).to eq("simple shared_context")
230+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
231+
expect(response[0].children.count).to eq(2)
232+
end
233+
end
234+
235+
it "symbol shared_context" do
236+
source = <<~RUBY
237+
RSpec.shared_context :symbol_shared_context do
238+
before { @some_var = :some_value }
239+
def shared_method
240+
"it works"
241+
end
242+
let(:shared_let) { {'arbitrary' => 'object'} }
243+
subject do
244+
'this is the subject'
245+
end
246+
end
247+
RUBY
248+
249+
with_server(source, uri) do |server, uri|
250+
server.process_message(
251+
{
252+
id: 2,
253+
method: "textDocument/documentSymbol",
254+
params: {
255+
textDocument: { uri: uri },
256+
},
257+
},
258+
)
259+
260+
result = server.pop_response
261+
expect(result).to be_a(RubyLsp::Result)
262+
response = result.response
263+
264+
expect(response.count).to eq(1)
265+
expect(response[0].name).to eq(":symbol_shared_context")
266+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
267+
expect(response[0].children.count).to eq(2)
268+
end
269+
end
270+
271+
it "simple shared_examples_for" do
272+
source = <<~RUBY
273+
RSpec.shared_examples_for "simple shared_examples_for" do
274+
before { @some_var = :some_value }
275+
def shared_method
276+
"it works"
277+
end
278+
let(:shared_let) { {'arbitrary' => 'object'} }
279+
subject do
280+
'this is the subject'
281+
end
282+
end
283+
RUBY
284+
285+
with_server(source, uri) do |server, uri|
286+
server.process_message(
287+
{
288+
id: 2,
289+
method: "textDocument/documentSymbol",
290+
params: {
291+
textDocument: { uri: uri },
292+
},
293+
},
294+
)
295+
296+
result = server.pop_response
297+
expect(result).to be_a(RubyLsp::Result)
298+
response = result.response
299+
300+
expect(response.count).to eq(1)
301+
expect(response[0].name).to eq("simple shared_examples_for")
302+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
303+
expect(response[0].children.count).to eq(2)
304+
end
305+
end
306+
307+
it "symbol shared_examples_for" do
308+
source = <<~RUBY
309+
RSpec.shared_examples_for :symbol_shared_examples_for do
310+
before { @some_var = :some_value }
311+
def shared_method
312+
"it works"
313+
end
314+
let(:shared_let) { {'arbitrary' => 'object'} }
315+
subject do
316+
'this is the subject'
317+
end
318+
end
319+
RUBY
320+
321+
with_server(source, uri) do |server, uri|
322+
server.process_message(
323+
{
324+
id: 2,
325+
method: "textDocument/documentSymbol",
326+
params: {
327+
textDocument: { uri: uri },
328+
},
329+
},
330+
)
331+
332+
result = server.pop_response
333+
expect(result).to be_a(RubyLsp::Result)
334+
response = result.response
335+
336+
expect(response.count).to eq(1)
337+
expect(response[0].name).to eq(":symbol_shared_examples_for")
338+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
339+
expect(response[0].children.count).to eq(2)
340+
end
341+
end
342+
343+
it "on_call_node_leave for shared examples" do
344+
source = <<~RUBY
345+
RSpec.shared_examples "shared examples" do
346+
end
347+
348+
describe "something" do
349+
end
350+
RUBY
351+
352+
with_server(source, uri) do |server, uri|
353+
server.process_message(
354+
{
355+
id: 2,
356+
method: "textDocument/documentSymbol",
357+
params: {
358+
textDocument: { uri: uri },
359+
},
360+
},
361+
)
362+
363+
result = server.pop_response
364+
expect(result).to be_a(RubyLsp::Result)
365+
response = result.response
366+
367+
expect(response.count).to eq(2)
368+
expect(response[0].name).to eq("shared examples")
369+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
370+
371+
expect(response[1].name).to eq("something")
372+
expect(response[1].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
373+
end
374+
end
375+
376+
it "on_call_node_leave for shared_context" do
377+
source = <<~RUBY
378+
RSpec.shared_context "shared context" do
379+
end
380+
381+
describe "something" do
382+
end
383+
RUBY
384+
385+
with_server(source, uri) do |server, uri|
386+
server.process_message(
387+
{
388+
id: 2,
389+
method: "textDocument/documentSymbol",
390+
params: {
391+
textDocument: { uri: uri },
392+
},
393+
},
394+
)
395+
396+
result = server.pop_response
397+
expect(result).to be_a(RubyLsp::Result)
398+
response = result.response
399+
400+
expect(response.count).to eq(2)
401+
expect(response[0].name).to eq("shared context")
402+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
403+
404+
expect(response[1].name).to eq("something")
405+
expect(response[1].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
406+
end
407+
end
408+
409+
it "on_call_node_leave for shared_examples_for" do
410+
source = <<~RUBY
411+
RSpec.shared_examples_for "shared examples for" do
412+
end
413+
414+
describe "something" do
415+
end
416+
RUBY
417+
418+
with_server(source, uri) do |server, uri|
419+
server.process_message(
420+
{
421+
id: 2,
422+
method: "textDocument/documentSymbol",
423+
params: {
424+
textDocument: { uri: uri },
425+
},
426+
},
427+
)
428+
429+
result = server.pop_response
430+
expect(result).to be_a(RubyLsp::Result)
431+
response = result.response
432+
433+
expect(response.count).to eq(2)
434+
expect(response[0].name).to eq("shared examples for")
435+
expect(response[0].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
436+
437+
expect(response[1].name).to eq("something")
438+
expect(response[1].kind).to eq(LanguageServer::Protocol::Constant::SymbolKind::MODULE)
439+
end
440+
end
91441
end
92442
end

0 commit comments

Comments
 (0)