Skip to content

Commit f30f100

Browse files
authored
Escape file paths for test command resolution (#658)
1 parent 4b43b93 commit f30f100

File tree

2 files changed

+139
-7
lines changed

2 files changed

+139
-7
lines changed

lib/ruby_lsp/ruby_lsp_rails/rails_test_style.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,19 @@ def resolve_test_commands(items)
2626

2727
if tags.include?("test_dir")
2828
if children.empty?
29-
full_files.concat(Dir.glob(
30-
"#{path}/**/{*_test,test_*}.rb",
31-
File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
32-
))
29+
full_files.concat(
30+
Dir.glob(
31+
"#{path}/**/{*_test,test_*}.rb",
32+
File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
33+
).map! { |f| Shellwords.escape(f) },
34+
)
3335
end
3436
elsif tags.include?("test_file")
35-
full_files << path if children.empty?
37+
full_files << Shellwords.escape(path) if children.empty?
3638
elsif tags.include?("test_group")
37-
commands << "#{BASE_COMMAND} #{path} --name \"/#{Shellwords.escape(item[:id])}(#|::)/\""
39+
commands << "#{BASE_COMMAND} #{Shellwords.escape(path)} --name \"/#{Shellwords.escape(item[:id])}(#|::)/\""
3840
else
39-
full_files << "#{path}:#{item.dig(:range, :start, :line) + 1}"
41+
full_files << "#{Shellwords.escape(path)}:#{item.dig(:range, :start, :line) + 1}"
4042
end
4143

4244
queue.concat(children)

test/ruby_lsp_rails/rails_test_style_test.rb

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,136 @@ class SpecialCharsTest < ActiveSupport::TestCase
228228
end
229229
end
230230

231+
test "resolve test escapes file paths in groups" do
232+
with_server do |server|
233+
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
234+
235+
server.process_message({
236+
id: 1,
237+
method: "rubyLsp/resolveTestCommands",
238+
params: {
239+
items: [
240+
{
241+
id: "GroupTest",
242+
uri: "file:///test/group(v2)_test.rb",
243+
label: "GroupTest",
244+
range: {
245+
start: { line: 0, character: 0 },
246+
end: { line: 30, character: 3 },
247+
},
248+
tags: ["framework:rails", "test_group"],
249+
children: [],
250+
},
251+
],
252+
},
253+
})
254+
255+
result = pop_result(server)
256+
response = result.response
257+
258+
assert_equal(
259+
["#{RailsTestStyle::BASE_COMMAND} /test/group\\(v2\\)_test.rb --name \"/GroupTest(#|::)/\""],
260+
response[:commands],
261+
)
262+
end
263+
end
264+
265+
test "resolve test escapes single file paths" do
266+
with_server do |server|
267+
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
268+
269+
server.process_message({
270+
id: 1,
271+
method: "rubyLsp/resolveTestCommands",
272+
params: {
273+
items: [
274+
{
275+
id: "file:///test/example(v2)_test.rb",
276+
uri: "file:///test/example(v2)_test.rb",
277+
label: "/test/example(v2)_test.rb",
278+
tags: ["framework:rails", "test_file"],
279+
children: [],
280+
},
281+
],
282+
},
283+
})
284+
285+
result = pop_result(server)
286+
response = result.response
287+
288+
assert_equal(
289+
["#{RailsTestStyle::BASE_COMMAND} /test/example\\(v2\\)_test.rb"],
290+
response[:commands],
291+
)
292+
end
293+
end
294+
295+
test "resolve test escapes file paths inside directories" do
296+
Dir.stubs(:glob).returns(["/test/example(v2)_test.rb"])
297+
298+
with_server do |server|
299+
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
300+
301+
server.process_message({
302+
id: 1,
303+
method: "rubyLsp/resolveTestCommands",
304+
params: {
305+
items: [
306+
{
307+
id: "file:///test",
308+
uri: "file:///test",
309+
label: "/test",
310+
tags: ["test_dir", "framework:rails"],
311+
children: [],
312+
},
313+
],
314+
},
315+
})
316+
317+
result = pop_result(server)
318+
response = result.response
319+
320+
assert_equal(
321+
["#{RailsTestStyle::BASE_COMMAND} /test/example\\(v2\\)_test.rb"],
322+
response[:commands],
323+
)
324+
end
325+
end
326+
327+
test "resolve test escapes file paths for specific examples" do
328+
with_server do |server|
329+
sleep(0.1) while RubyLsp::Addon.addons.first.instance_variable_get(:@rails_runner_client).is_a?(NullClient)
330+
331+
server.process_message({
332+
id: 1,
333+
method: "rubyLsp/resolveTestCommands",
334+
params: {
335+
items: [
336+
{
337+
id: "ExampleTest#test_something",
338+
uri: "file:///test/example(v2)_test.rb",
339+
label: "test something",
340+
tags: ["framework:rails"],
341+
range: {
342+
start: { line: 10, character: 0 },
343+
end: { line: 15, character: 3 },
344+
},
345+
children: [],
346+
},
347+
],
348+
},
349+
})
350+
351+
result = pop_result(server)
352+
response = result.response
353+
354+
assert_equal(
355+
["#{RailsTestStyle::BASE_COMMAND} /test/example\\(v2\\)_test.rb:11"],
356+
response[:commands],
357+
)
358+
end
359+
end
360+
231361
test "tests with backslashes" do
232362
source = File.read(File.join(__dir__, "..", "fixtures", "test_with_escaped_quotes.rb"))
233363

0 commit comments

Comments
 (0)