ruby-lsp 0.23.20 → 0.23.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp-test-exec +18 -0
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +2 -2
- data/lib/ruby_lsp/listeners/spec_style.rb +77 -61
- data/lib/ruby_lsp/listeners/test_style.rb +45 -13
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +9 -3
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +38 -4
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +0 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48c7e1cdc0e7f0a31cbc69002bf6a6c3dea0779272757ee40ae90e4199199446
|
4
|
+
data.tar.gz: 1cd0d4a426ed4b1c44540e9e3344f73623f0ea0193374cab8faa727528474bf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac87c3a6dcc52b2696076d9793b42f03f56a4e0fbe258cc20f09502bbb289f91acccb3593ebfd36d61b5eeb0ec0bc3ab697acc332b61889fd256db2600029eca
|
7
|
+
data.tar.gz: be146b667f656ddb1103756a4cf79bd294981fa5f3d0cebc38e44498168799b14941c1768e9f030e80d4f4f7e8c4e4b0107e9cbaf694184ddc037824a05a2f1f
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.23.
|
1
|
+
0.23.22
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Append to RUBYOPT the necessary requires to hook our custom test reporters so that results are automatically
|
5
|
+
# reflected in the test explorer
|
6
|
+
rubyopt = [
|
7
|
+
*ENV["RUBYOPT"],
|
8
|
+
"-rbundler/setup",
|
9
|
+
"-r#{File.expand_path("../lib/ruby_lsp/test_reporters/minitest_reporter", __dir__)}",
|
10
|
+
"-r#{File.expand_path("../lib/ruby_lsp/test_reporters/test_unit_reporter", __dir__)}",
|
11
|
+
].join(" ")
|
12
|
+
|
13
|
+
# Replace this process with whatever command was passed. We only want to set RUBYOPT.
|
14
|
+
# The way you use this executable is by prefixing your test command with `ruby-lsp-test-exec`, like so:
|
15
|
+
# ruby-lsp-test-exec bundle exec ruby -Itest test/example_test.rb
|
16
|
+
# ruby-lsp-test-exec bundle exec ruby -Ispec spec/example_spec.rb
|
17
|
+
# ruby-lsp-test-exec bundle exec rspec spec/example_spec.rb
|
18
|
+
exec({ "RUBYOPT" => rubyopt }, *ARGV)
|
@@ -103,7 +103,7 @@ module RubyIndexer
|
|
103
103
|
#: (RBS::AST::Members::MethodDefinition member, Entry::Namespace owner) -> void
|
104
104
|
def handle_method(member, owner)
|
105
105
|
name = member.name.name
|
106
|
-
uri = URI::Generic.from_path(path: member.location.buffer.name)
|
106
|
+
uri = URI::Generic.from_path(path: member.location.buffer.name.to_s)
|
107
107
|
location = to_ruby_indexer_location(member.location)
|
108
108
|
comments = comments_to_string(member)
|
109
109
|
|
@@ -267,7 +267,7 @@ module RubyIndexer
|
|
267
267
|
|
268
268
|
#: (RBS::AST::Members::Alias member, Entry::Namespace owner_entry) -> void
|
269
269
|
def handle_signature_alias(member, owner_entry)
|
270
|
-
uri = URI::Generic.from_path(path: member.location.buffer.name)
|
270
|
+
uri = URI::Generic.from_path(path: member.location.buffer.name.to_s)
|
271
271
|
comments = comments_to_string(member)
|
272
272
|
|
273
273
|
entry = Entry::UnresolvedMethodAlias.new(
|
@@ -4,12 +4,24 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Listeners
|
6
6
|
class SpecStyle < TestDiscovery
|
7
|
+
class Group
|
8
|
+
#: String
|
9
|
+
attr_reader :id
|
10
|
+
|
11
|
+
#: (String) -> void
|
12
|
+
def initialize(id)
|
13
|
+
@id = id
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class ClassGroup < Group; end
|
18
|
+
class DescribeGroup < Group; end
|
19
|
+
|
7
20
|
#: (ResponseBuilders::TestCollection, GlobalState, Prism::Dispatcher, URI::Generic) -> void
|
8
21
|
def initialize(response_builder, global_state, dispatcher, uri)
|
9
22
|
super
|
10
23
|
|
11
|
-
@
|
12
|
-
@spec_class_stack = [] #: Array[bool]
|
24
|
+
@spec_group_id_stack = [] #: Array[Group?]
|
13
25
|
|
14
26
|
dispatcher.register(
|
15
27
|
self,
|
@@ -22,21 +34,21 @@ module RubyLsp
|
|
22
34
|
|
23
35
|
#: (Prism::ClassNode) -> void
|
24
36
|
def on_class_node_enter(node)
|
25
|
-
with_test_ancestor_tracking(node) do |
|
26
|
-
|
27
|
-
@spec_class_stack.push(is_spec)
|
37
|
+
with_test_ancestor_tracking(node) do |name, ancestors|
|
38
|
+
@spec_group_id_stack << (ancestors.include?("Minitest::Spec") ? ClassGroup.new(name) : nil)
|
28
39
|
end
|
29
40
|
end
|
30
41
|
|
31
42
|
#: (Prism::ClassNode) -> void
|
32
43
|
def on_class_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
33
44
|
super
|
34
|
-
|
35
|
-
@spec_class_stack.pop
|
45
|
+
@spec_group_id_stack.pop
|
36
46
|
end
|
37
47
|
|
38
48
|
#: (Prism::CallNode) -> void
|
39
49
|
def on_call_node_enter(node)
|
50
|
+
return unless in_spec_context?
|
51
|
+
|
40
52
|
case node.name
|
41
53
|
when :describe
|
42
54
|
handle_describe(node)
|
@@ -49,84 +61,63 @@ module RubyLsp
|
|
49
61
|
def on_call_node_leave(node)
|
50
62
|
return unless node.name == :describe && !node.receiver
|
51
63
|
|
52
|
-
@
|
64
|
+
@spec_group_id_stack.pop
|
53
65
|
end
|
54
66
|
|
55
67
|
private
|
56
68
|
|
57
69
|
#: (Prism::CallNode) -> void
|
58
70
|
def handle_describe(node)
|
71
|
+
# Describes will include the nesting of all classes and all outer describes as part of its ID, unlike classes
|
72
|
+
# that ignore describes
|
59
73
|
return if node.block.nil?
|
60
74
|
|
61
75
|
description = extract_description(node)
|
62
76
|
return unless description
|
63
77
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
description,
|
69
|
-
description,
|
70
|
-
@uri,
|
71
|
-
range_from_node(node),
|
72
|
-
framework: :minitest,
|
73
|
-
)
|
74
|
-
@response_builder.add(test_item)
|
75
|
-
@response_builder.add_code_lens(test_item)
|
78
|
+
parent = latest_group
|
79
|
+
id = case parent
|
80
|
+
when Requests::Support::TestItem
|
81
|
+
"#{parent.id}::#{description}"
|
76
82
|
else
|
77
|
-
|
83
|
+
description
|
78
84
|
end
|
79
85
|
|
80
|
-
|
86
|
+
test_item = Requests::Support::TestItem.new(
|
87
|
+
id,
|
88
|
+
description,
|
89
|
+
@uri,
|
90
|
+
range_from_node(node),
|
91
|
+
framework: :minitest,
|
92
|
+
)
|
93
|
+
|
94
|
+
parent.add(test_item)
|
95
|
+
@response_builder.add_code_lens(test_item)
|
96
|
+
@spec_group_id_stack << DescribeGroup.new(id)
|
81
97
|
end
|
82
98
|
|
83
99
|
#: (Prism::CallNode) -> void
|
84
100
|
def handle_example(node)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
101
|
+
# Minitest formats the descriptions into test method names by using the count of examples with the description
|
102
|
+
# We are not guaranteed to discover examples in the exact order using static analysis, so we use the line number
|
103
|
+
# instead. Note that anonymous examples mixed with meta-programming will not be handled correctly
|
104
|
+
description = extract_description(node) || "anonymous"
|
105
|
+
line = node.location.start_line - 1
|
106
|
+
parent = latest_group
|
107
|
+
return unless parent.is_a?(Requests::Support::TestItem)
|
91
108
|
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
#: (String, Prism::CallNode) -> void
|
96
|
-
def add_to_parent_test_group(description, node)
|
97
|
-
parent_test_group = find_parent_test_group
|
98
|
-
return unless parent_test_group
|
109
|
+
id = "#{parent.id}##{format("test_%04d_%s", line, description)}"
|
99
110
|
|
100
111
|
test_item = Requests::Support::TestItem.new(
|
101
|
-
|
112
|
+
id,
|
102
113
|
description,
|
103
114
|
@uri,
|
104
115
|
range_from_node(node),
|
105
116
|
framework: :minitest,
|
106
117
|
)
|
107
|
-
parent_test_group.add(test_item)
|
108
|
-
@response_builder.add_code_lens(test_item)
|
109
|
-
end
|
110
|
-
|
111
|
-
#: -> Requests::Support::TestItem?
|
112
|
-
def find_parent_test_group
|
113
|
-
root_group_name, nested_describe_groups = if @nesting.empty?
|
114
|
-
[@describe_block_nesting.first, @describe_block_nesting[1..]]
|
115
|
-
else
|
116
|
-
[RubyIndexer::Index.actual_nesting(@nesting, nil).join("::"), @describe_block_nesting]
|
117
|
-
end
|
118
|
-
return unless root_group_name
|
119
|
-
|
120
|
-
test_group = @response_builder[root_group_name] #: Requests::Support::TestItem?
|
121
|
-
return unless test_group
|
122
|
-
|
123
|
-
return test_group unless nested_describe_groups
|
124
118
|
|
125
|
-
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
test_group
|
119
|
+
parent.add(test_item)
|
120
|
+
@response_builder.add_code_lens(test_item)
|
130
121
|
end
|
131
122
|
|
132
123
|
#: (Prism::CallNode) -> String?
|
@@ -144,11 +135,36 @@ module RubyLsp
|
|
144
135
|
end
|
145
136
|
end
|
146
137
|
|
138
|
+
#: -> (Requests::Support::TestItem | ResponseBuilders::TestCollection)
|
139
|
+
def latest_group
|
140
|
+
return @response_builder if @spec_group_id_stack.compact.empty?
|
141
|
+
|
142
|
+
first_class_index = @spec_group_id_stack.rindex { |i| i.is_a?(ClassGroup) } || 0
|
143
|
+
first_class = @spec_group_id_stack[0] #: as !nil
|
144
|
+
item = @response_builder[first_class.id] #: as !nil
|
145
|
+
|
146
|
+
# Descend into child items from the beginning all the way to the latest class group, ignoring describes
|
147
|
+
@spec_group_id_stack[1..first_class_index] #: as !nil
|
148
|
+
.each do |group|
|
149
|
+
next unless group.is_a?(ClassGroup)
|
150
|
+
|
151
|
+
item = item[group.id] #: as !nil
|
152
|
+
end
|
153
|
+
|
154
|
+
# From the class forward, we must take describes into account
|
155
|
+
@spec_group_id_stack[first_class_index + 1..] #: as !nil
|
156
|
+
.each do |group|
|
157
|
+
next unless group
|
158
|
+
|
159
|
+
item = item[group.id] #: as !nil
|
160
|
+
end
|
161
|
+
|
162
|
+
item
|
163
|
+
end
|
164
|
+
|
147
165
|
#: -> bool
|
148
166
|
def in_spec_context?
|
149
|
-
|
150
|
-
|
151
|
-
@spec_class_stack.last #: as !nil
|
167
|
+
@nesting.empty? || @spec_group_id_stack.any? { |id| id }
|
152
168
|
end
|
153
169
|
end
|
154
170
|
end
|
@@ -34,7 +34,7 @@ module RubyLsp
|
|
34
34
|
if tags.include?("test_dir")
|
35
35
|
if children.empty?
|
36
36
|
full_files.concat(Dir.glob(
|
37
|
-
"#{path}/**/{*_test,test_
|
37
|
+
"#{path}/**/{*_test,test_*,*_spec}.rb",
|
38
38
|
File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
|
39
39
|
))
|
40
40
|
end
|
@@ -44,7 +44,7 @@ module RubyLsp
|
|
44
44
|
# If all of the children of the current test group are other groups, then there's no need to add it to the
|
45
45
|
# aggregated examples
|
46
46
|
unless children.any? && children.all? { |child| child[:tags].include?("test_group") }
|
47
|
-
aggregated_tests[path][item[:
|
47
|
+
aggregated_tests[path][item[:id]] = { tags: tags, examples: [] }
|
48
48
|
end
|
49
49
|
else
|
50
50
|
class_name, method_name = item[:id].split("#")
|
@@ -74,7 +74,9 @@ module RubyLsp
|
|
74
74
|
end
|
75
75
|
|
76
76
|
unless full_files.empty?
|
77
|
-
|
77
|
+
specs, tests = full_files.partition { |path| spec?(path) }
|
78
|
+
commands << "#{BASE_COMMAND} -Itest -e \"ARGV.each { |f| require f }\" #{tests.join(" ")}" if tests.any?
|
79
|
+
commands << "#{BASE_COMMAND} -Ispec -e \"ARGV.each { |f| require f }\" #{specs.join(" ")}" if specs.any?
|
78
80
|
end
|
79
81
|
|
80
82
|
commands
|
@@ -82,10 +84,15 @@ module RubyLsp
|
|
82
84
|
|
83
85
|
private
|
84
86
|
|
87
|
+
#: (String) -> bool
|
88
|
+
def spec?(path)
|
89
|
+
File.fnmatch?("**/spec/**/*_spec.rb", path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
90
|
+
end
|
91
|
+
|
85
92
|
#: (String, Hash[String, Hash[Symbol, untyped]]) -> String
|
86
93
|
def handle_minitest_groups(file_path, groups_and_examples)
|
87
94
|
regexes = groups_and_examples.flat_map do |group, info|
|
88
|
-
examples = info[:examples]
|
95
|
+
examples = info[:examples].map { |e| e.gsub(/test_\d{4}/, "test_\\d{4}") }
|
89
96
|
group_regex = Shellwords.escape(group).gsub(
|
90
97
|
Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
|
91
98
|
".*",
|
@@ -105,7 +112,8 @@ module RubyLsp
|
|
105
112
|
"(#{regexes.join("|")})"
|
106
113
|
end
|
107
114
|
|
108
|
-
|
115
|
+
load_path = spec?(file_path) ? "-Ispec" : "-Itest"
|
116
|
+
"#{BASE_COMMAND} #{load_path} #{file_path} --name \"/#{regex}/\""
|
109
117
|
end
|
110
118
|
|
111
119
|
#: (String, Hash[String, Hash[Symbol, untyped]]) -> Array[String]
|
@@ -148,6 +156,7 @@ module RubyLsp
|
|
148
156
|
super
|
149
157
|
|
150
158
|
@framework = :minitest #: Symbol
|
159
|
+
@parent_stack = [@response_builder] #: Array[(Requests::Support::TestItem | ResponseBuilders::TestCollection)?]
|
151
160
|
|
152
161
|
dispatcher.register(
|
153
162
|
self,
|
@@ -173,12 +182,33 @@ module RubyLsp
|
|
173
182
|
framework: @framework,
|
174
183
|
)
|
175
184
|
|
176
|
-
|
185
|
+
last_test_group.add(test_item)
|
177
186
|
@response_builder.add_code_lens(test_item)
|
187
|
+
@parent_stack << test_item
|
188
|
+
else
|
189
|
+
@parent_stack << nil
|
178
190
|
end
|
179
191
|
end
|
180
192
|
end
|
181
193
|
|
194
|
+
#: (Prism::ClassNode node) -> void
|
195
|
+
def on_class_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
196
|
+
@parent_stack.pop
|
197
|
+
super
|
198
|
+
end
|
199
|
+
|
200
|
+
#: (Prism::ModuleNode node) -> void
|
201
|
+
def on_module_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
202
|
+
@parent_stack << nil
|
203
|
+
super
|
204
|
+
end
|
205
|
+
|
206
|
+
#: (Prism::ModuleNode node) -> void
|
207
|
+
def on_module_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
208
|
+
@parent_stack.pop
|
209
|
+
super
|
210
|
+
end
|
211
|
+
|
182
212
|
#: (Prism::DefNode node) -> void
|
183
213
|
def on_def_node_enter(node)
|
184
214
|
return if @visibility_stack.last != :public
|
@@ -187,12 +217,8 @@ module RubyLsp
|
|
187
217
|
return unless name.start_with?("test_")
|
188
218
|
|
189
219
|
current_group_name = RubyIndexer::Index.actual_nesting(@nesting, nil).join("::")
|
190
|
-
|
191
|
-
|
192
|
-
# previously pushed and thus we return early and avoid adding items for a framework this listener is not
|
193
|
-
# interested in
|
194
|
-
test_item = @response_builder[current_group_name]
|
195
|
-
return unless test_item
|
220
|
+
parent = @parent_stack.last
|
221
|
+
return unless parent.is_a?(Requests::Support::TestItem)
|
196
222
|
|
197
223
|
example_item = Requests::Support::TestItem.new(
|
198
224
|
"#{current_group_name}##{name}",
|
@@ -201,7 +227,7 @@ module RubyLsp
|
|
201
227
|
range_from_node(node),
|
202
228
|
framework: @framework,
|
203
229
|
)
|
204
|
-
|
230
|
+
parent.add(example_item)
|
205
231
|
@response_builder.add_code_lens(example_item)
|
206
232
|
end
|
207
233
|
|
@@ -224,6 +250,12 @@ module RubyLsp
|
|
224
250
|
|
225
251
|
private
|
226
252
|
|
253
|
+
#: -> (Requests::Support::TestItem | ResponseBuilders::TestCollection)
|
254
|
+
def last_test_group
|
255
|
+
index = @parent_stack.rindex { |i| i } #: as !nil
|
256
|
+
@parent_stack[index] #: as Requests::Support::TestItem | ResponseBuilders::TestCollection
|
257
|
+
end
|
258
|
+
|
227
259
|
#: (Array[String] attached_ancestors, String fully_qualified_name) -> bool
|
228
260
|
def non_declarative_minitest?(attached_ancestors, fully_qualified_name)
|
229
261
|
return false unless attached_ancestors.include?("Minitest::Test")
|
@@ -6,6 +6,7 @@ require "json"
|
|
6
6
|
require "socket"
|
7
7
|
require "singleton"
|
8
8
|
require "tmpdir"
|
9
|
+
require_relative "../../ruby_indexer/lib/ruby_indexer/uri"
|
9
10
|
|
10
11
|
module RubyLsp
|
11
12
|
class LspReporter
|
@@ -19,15 +20,20 @@ module RubyLsp
|
|
19
20
|
dir_path = File.join(Dir.tmpdir, "ruby-lsp")
|
20
21
|
FileUtils.mkdir_p(dir_path)
|
21
22
|
|
22
|
-
|
23
|
+
# Remove in 1 month once updates have rolled out
|
24
|
+
legacy_port_path = File.join(dir_path, "test_reporter_port")
|
25
|
+
port_db_path = File.join(dir_path, "test_reporter_port_db.json")
|
23
26
|
port = ENV["RUBY_LSP_REPORTER_PORT"]
|
24
27
|
|
25
28
|
@io = begin
|
26
29
|
# The environment variable is only used for tests. The extension always writes to the temporary file
|
27
30
|
if port
|
28
31
|
TCPSocket.new("localhost", port)
|
29
|
-
elsif File.exist?(
|
30
|
-
|
32
|
+
elsif File.exist?(port_db_path)
|
33
|
+
db = JSON.load_file(port_db_path)
|
34
|
+
TCPSocket.new("localhost", db[Dir.pwd])
|
35
|
+
elsif File.exist?(legacy_port_path)
|
36
|
+
TCPSocket.new("localhost", File.read(legacy_port_path))
|
31
37
|
else
|
32
38
|
# For tests that don't spawn the TCP server
|
33
39
|
require "stringio"
|
@@ -8,7 +8,6 @@ rescue LoadError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
require_relative "lsp_reporter"
|
11
|
-
require "ruby_indexer/lib/ruby_indexer/uri"
|
12
11
|
|
13
12
|
module RubyLsp
|
14
13
|
# An override of the default progress reporter in Minitest to add color to the output
|
@@ -31,6 +30,30 @@ module RubyLsp
|
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
33
|
+
# This patch is here to prevent other gems from overriding or adding more Minitest reporters. Otherwise, they may
|
34
|
+
# break the integration between the server and extension
|
35
|
+
module PreventReporterOverridePatch
|
36
|
+
@lsp_reporters = [] #: Array[Minitest::AbstractReporter]
|
37
|
+
|
38
|
+
class << self
|
39
|
+
#: Array[Minitest::AbstractReporter]
|
40
|
+
attr_accessor :lsp_reporters
|
41
|
+
end
|
42
|
+
|
43
|
+
# Patch the writer to prevent replacing the entire array
|
44
|
+
#: (untyped) -> void
|
45
|
+
def reporters=(reporters)
|
46
|
+
# Do nothing. We don't want other gems to override our reporter
|
47
|
+
end
|
48
|
+
|
49
|
+
# Patch the reader to prevent appending more reporters. This method always returns a temporary copy of the real
|
50
|
+
# reporters so that if any gem mutates it, it continues to return the original reporters
|
51
|
+
#: -> Array[untyped]
|
52
|
+
def reporters
|
53
|
+
PreventReporterOverridePatch.lsp_reporters.dup
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
34
57
|
class MinitestReporter < Minitest::AbstractReporter
|
35
58
|
class << self
|
36
59
|
#: (Hash[untyped, untyped]) -> void
|
@@ -46,6 +69,8 @@ module RubyLsp
|
|
46
69
|
|
47
70
|
# Add the JSON RPC reporter
|
48
71
|
reporters << MinitestReporter.new
|
72
|
+
PreventReporterOverridePatch.lsp_reporters = reporters
|
73
|
+
Minitest.reporter.class.prepend(PreventReporterOverridePatch)
|
49
74
|
end
|
50
75
|
end
|
51
76
|
|
@@ -54,15 +79,19 @@ module RubyLsp
|
|
54
79
|
uri, line = LspReporter.instance.uri_and_line_for(test_class.instance_method(method_name))
|
55
80
|
return unless uri
|
56
81
|
|
57
|
-
|
82
|
+
id = "#{test_class.name}##{handle_spec_test_id(method_name, line)}"
|
83
|
+
LspReporter.instance.start_test(id: id, uri: uri, line: line)
|
58
84
|
end
|
59
85
|
|
60
86
|
#: (Minitest::Result result) -> void
|
61
87
|
def record(result)
|
62
|
-
|
63
|
-
file_path, _line = result.source_location
|
88
|
+
file_path, line = result.source_location
|
64
89
|
return unless file_path
|
65
90
|
|
91
|
+
zero_based_line = line ? line - 1 : nil
|
92
|
+
name = handle_spec_test_id(result.name, zero_based_line)
|
93
|
+
id = "#{result.klass}##{name}"
|
94
|
+
|
66
95
|
uri = URI::Generic.from_path(path: File.expand_path(file_path))
|
67
96
|
|
68
97
|
if result.error?
|
@@ -82,6 +111,11 @@ module RubyLsp
|
|
82
111
|
def report
|
83
112
|
LspReporter.instance.shutdown
|
84
113
|
end
|
114
|
+
|
115
|
+
#: (String, Integer?) -> String
|
116
|
+
def handle_spec_test_id(method_name, line)
|
117
|
+
method_name.gsub(/(?<=test_)\d{4}(?=_)/, format("%04d", line.to_s))
|
118
|
+
end
|
85
119
|
end
|
86
120
|
end
|
87
121
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
version: '3'
|
53
53
|
- - "<"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
55
|
+
version: '5'
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
58
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -62,7 +62,7 @@ dependencies:
|
|
62
62
|
version: '3'
|
63
63
|
- - "<"
|
64
64
|
- !ruby/object:Gem::Version
|
65
|
-
version: '
|
65
|
+
version: '5'
|
66
66
|
- !ruby/object:Gem::Dependency
|
67
67
|
name: sorbet-runtime
|
68
68
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +84,7 @@ executables:
|
|
84
84
|
- ruby-lsp
|
85
85
|
- ruby-lsp-check
|
86
86
|
- ruby-lsp-launcher
|
87
|
+
- ruby-lsp-test-exec
|
87
88
|
extensions: []
|
88
89
|
extra_rdoc_files: []
|
89
90
|
files:
|
@@ -93,6 +94,7 @@ files:
|
|
93
94
|
- exe/ruby-lsp
|
94
95
|
- exe/ruby-lsp-check
|
95
96
|
- exe/ruby-lsp-launcher
|
97
|
+
- exe/ruby-lsp-test-exec
|
96
98
|
- lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb
|
97
99
|
- lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb
|
98
100
|
- lib/ruby-lsp.rb
|
@@ -228,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
230
|
- !ruby/object:Gem::Version
|
229
231
|
version: '0'
|
230
232
|
requirements: []
|
231
|
-
rubygems_version: 3.6.
|
233
|
+
rubygems_version: 3.6.9
|
232
234
|
specification_version: 4
|
233
235
|
summary: An opinionated language server for Ruby
|
234
236
|
test_files: []
|