ruby-lsp 0.23.13 → 0.23.15

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/exe/ruby-lsp-launcher +9 -1
  4. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +1 -1
  5. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +6 -3
  6. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +4 -2
  7. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +59 -29
  8. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +5 -4
  9. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +5 -1
  10. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +8 -3
  11. data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
  12. data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
  13. data/lib/ruby_indexer/test/configuration_test.rb +6 -4
  14. data/lib/ruby_indexer/test/constant_test.rb +34 -34
  15. data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
  16. data/lib/ruby_indexer/test/index_test.rb +139 -135
  17. data/lib/ruby_indexer/test/instance_variables_test.rb +37 -37
  18. data/lib/ruby_indexer/test/method_test.rb +118 -118
  19. data/lib/ruby_indexer/test/prefix_tree_test.rb +13 -13
  20. data/lib/ruby_indexer/test/rbs_indexer_test.rb +64 -70
  21. data/lib/ruby_indexer/test/test_case.rb +2 -2
  22. data/lib/ruby_indexer/test/uri_test.rb +15 -2
  23. data/lib/ruby_lsp/erb_document.rb +12 -4
  24. data/lib/ruby_lsp/global_state.rb +1 -1
  25. data/lib/ruby_lsp/listeners/code_lens.rb +3 -3
  26. data/lib/ruby_lsp/listeners/completion.rb +24 -11
  27. data/lib/ruby_lsp/listeners/definition.rb +1 -1
  28. data/lib/ruby_lsp/listeners/document_link.rb +3 -1
  29. data/lib/ruby_lsp/listeners/document_symbol.rb +3 -3
  30. data/lib/ruby_lsp/listeners/folding_ranges.rb +8 -4
  31. data/lib/ruby_lsp/listeners/hover.rb +2 -2
  32. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +12 -5
  33. data/lib/ruby_lsp/listeners/signature_help.rb +5 -1
  34. data/lib/ruby_lsp/listeners/spec_style.rb +1 -1
  35. data/lib/ruby_lsp/listeners/test_style.rb +3 -3
  36. data/lib/ruby_lsp/requests/code_action_resolve.rb +4 -3
  37. data/lib/ruby_lsp/requests/completion_resolve.rb +1 -1
  38. data/lib/ruby_lsp/requests/hover.rb +2 -2
  39. data/lib/ruby_lsp/requests/on_type_formatting.rb +4 -2
  40. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +1 -2
  41. data/lib/ruby_lsp/requests/references.rb +2 -1
  42. data/lib/ruby_lsp/requests/rename.rb +8 -5
  43. data/lib/ruby_lsp/requests/semantic_highlighting.rb +4 -4
  44. data/lib/ruby_lsp/requests/show_syntax_tree.rb +1 -1
  45. data/lib/ruby_lsp/requests/support/common.rb +3 -1
  46. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +2 -2
  47. data/lib/ruby_lsp/requests/support/source_uri.rb +1 -1
  48. data/lib/ruby_lsp/response_builders/document_symbol.rb +3 -2
  49. data/lib/ruby_lsp/response_builders/hover.rb +1 -1
  50. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +1 -1
  51. data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
  52. data/lib/ruby_lsp/server.rb +12 -4
  53. data/lib/ruby_lsp/setup_bundler.rb +5 -2
  54. data/lib/ruby_lsp/static_docs.rb +8 -1
  55. data/lib/ruby_lsp/store.rb +3 -2
  56. data/lib/ruby_lsp/test_helper.rb +0 -1
  57. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +152 -0
  58. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +105 -0
  59. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +94 -0
  60. data/lib/ruby_lsp/type_inferrer.rb +4 -1
  61. metadata +6 -6
  62. data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +0 -109
  63. data/lib/ruby_lsp/test_reporter.rb +0 -207
  64. data/lib/ruby_lsp/test_unit_test_runner.rb +0 -98
@@ -1,207 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "json"
5
- require "delegate"
6
-
7
- $stdout.binmode
8
- $stdout.sync = true
9
- $stderr.binmode
10
- $stderr.sync = true
11
-
12
- module RubyLsp
13
- module TestReporter
14
- class << self
15
- #: (id: String, uri: URI::Generic) -> void
16
- def start_test(id:, uri:)
17
- params = {
18
- id: id,
19
- uri: uri.to_s,
20
- }
21
- send_message("start", params)
22
- end
23
-
24
- #: (id: String, uri: URI::Generic) -> void
25
- def record_pass(id:, uri:)
26
- params = {
27
- id: id,
28
- uri: uri.to_s,
29
- }
30
- send_message("pass", params)
31
- end
32
-
33
- #: (id: String, message: String, uri: URI::Generic) -> void
34
- def record_fail(id:, message:, uri:)
35
- params = {
36
- id: id,
37
- message: message,
38
- uri: uri.to_s,
39
- }
40
- send_message("fail", params)
41
- end
42
-
43
- #: (id: String, uri: URI::Generic) -> void
44
- def record_skip(id:, uri:)
45
- params = {
46
- id: id,
47
- uri: uri.to_s,
48
- }
49
- send_message("skip", params)
50
- end
51
-
52
- #: (id: String, message: String?, uri: URI::Generic) -> void
53
- def record_error(id:, message:, uri:)
54
- params = {
55
- id: id,
56
- message: message,
57
- uri: uri.to_s,
58
- }
59
- send_message("error", params)
60
- end
61
-
62
- #: (message: String) -> void
63
- def append_output(message:)
64
- params = {
65
- message: message,
66
- }
67
- send_message("append_output", params)
68
- end
69
-
70
- # Gather the results returned by Coverage.result and format like the VS Code test explorer expects
71
- #
72
- # Coverage result format:
73
- #
74
- # Lines are reported in order as an array where each number is the number of times it was executed. For example,
75
- # the following says that line 0 was executed 1 time and line 1 executed 3 times: [1, 3].
76
- # Nil values represent lines for which coverage is not available, like empty lines, comments or keywords like
77
- # `else`
78
- #
79
- # Branches are a hash containing the name of the branch and the location where it is found in tuples with the
80
- # following elements: [NAME, ID, START_LINE, START_COLUMN, END_LINE, END_COLUMN] as the keys and the value is the
81
- # number of times it was executed
82
- #
83
- # Methods are a similar hash [ClassName, :method_name, START_LINE, START_COLUMN, END_LINE, END_COLUMN] => NUMBER
84
- # OF EXECUTIONS
85
- #
86
- # Example:
87
- # {
88
- # "file_path" => {
89
- # "lines" => [1, 2, 3, nil],
90
- # "branches" => {
91
- # ["&.", 0, 6, 21, 6, 65] => { [:then, 1, 6, 21, 6, 65] => 0, [:else, 5, 7, 0, 7, 87] => 1 }
92
- # },
93
- # "methods" => {
94
- # ["Foo", :bar, 6, 21, 6, 65] => 0
95
- # }
96
- # }
97
- #: () -> Hash[String, StatementCoverage]
98
- def gather_coverage_results
99
- # Ignore coverage results inside dependencies
100
- bundle_path = Bundler.bundle_path.to_s
101
- default_gems_path = File.dirname(RbConfig::CONFIG["rubylibdir"])
102
-
103
- result = Coverage.result.reject do |file_path, _coverage_info|
104
- file_path.start_with?(bundle_path) ||
105
- file_path.start_with?(default_gems_path) ||
106
- file_path.start_with?("eval")
107
- end
108
-
109
- result.to_h do |file_path, coverage_info|
110
- # Format the branch coverage information as VS Code expects it and then group it based on the start line of
111
- # the conditional that causes the branching. We need to match each line coverage data with the branches that
112
- # spawn from that line
113
- branch_by_line = coverage_info[:branches]
114
- .flat_map do |branch, data|
115
- branch_name, _branch_id, branch_start_line, _branch_start_col, _branch_end_line, _branch_end_col = branch
116
-
117
- data.map do |then_or_else, execution_count|
118
- name, _id, start_line, start_column, end_line, end_column = then_or_else
119
-
120
- {
121
- groupingLine: branch_start_line,
122
- executed: execution_count,
123
- location: {
124
- start: { line: start_line, character: start_column },
125
- end: { line: end_line, character: end_column },
126
- },
127
- label: "#{branch_name} #{name}",
128
- }
129
- end
130
- end
131
- .group_by { |branch| branch[:groupingLine] }
132
-
133
- # Format the line coverage information, gathering any branch coverage data associated with that line
134
- data = coverage_info[:lines].filter_map.with_index do |execution_count, line_index|
135
- next if execution_count.nil?
136
-
137
- {
138
- executed: execution_count,
139
- location: { line: line_index, character: 0 },
140
- branches: branch_by_line[line_index] || [],
141
- }
142
- end
143
-
144
- # The expected format is URI => { executed: number_of_times_executed, location: { ... }, branches: [ ... ] }
145
- [URI::Generic.from_path(path: File.expand_path(file_path)).to_s, data]
146
- end
147
- end
148
-
149
- private
150
-
151
- #: (method_name: String?, params: Hash[String, untyped]) -> void
152
- def send_message(method_name, params)
153
- json_message = { method: method_name, params: params }.to_json
154
- ORIGINAL_STDOUT.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
155
- end
156
- end
157
-
158
- ORIGINAL_STDOUT = $stdout #: IO
159
-
160
- class IOWrapper < SimpleDelegator
161
- #: (Object) -> void
162
- def puts(*args)
163
- args.each { |arg| log(convert_line_breaks(arg) + "\r\n") }
164
- end
165
-
166
- #: (Object) -> void
167
- def print(*args)
168
- args.each { |arg| log(convert_line_breaks(arg)) }
169
- end
170
-
171
- #: (Object) -> void
172
- def write(*args)
173
- args.each { |arg| log(convert_line_breaks(arg)) }
174
- end
175
-
176
- private
177
-
178
- #: (Object) -> String
179
- def convert_line_breaks(message)
180
- message.to_s.gsub("\n", "\r\n")
181
- end
182
-
183
- #: (String) -> void
184
- def log(message)
185
- TestReporter.append_output(message: message)
186
- end
187
- end
188
- end
189
- end
190
-
191
- if ENV["RUBY_LSP_TEST_RUNNER"]
192
- # We wrap the default output stream so that we can capture anything written to stdout and emit it as part of the JSON
193
- # event stream.
194
- $> = RubyLsp::TestReporter::IOWrapper.new($stdout)
195
-
196
- if ENV["RUBY_LSP_TEST_RUNNER"] == "coverage"
197
- # Auto start coverage when running tests under that profile. This avoids the user from having to configure coverage
198
- # manually for their project or adding extra dependencies
199
- require "coverage"
200
- Coverage.start(:all)
201
-
202
- at_exit do
203
- coverage_results = RubyLsp::TestReporter.gather_coverage_results
204
- File.write(File.join(".ruby-lsp", "coverage_result.json"), coverage_results.to_json)
205
- end
206
- end
207
- end
@@ -1,98 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- begin
5
- require "test/unit"
6
- require "test/unit/ui/testrunner"
7
- rescue LoadError
8
- return
9
- end
10
-
11
- require_relative "test_reporter"
12
- require "ruby_indexer/lib/ruby_indexer/uri"
13
-
14
- module RubyLsp
15
- class TestRunner < ::Test::Unit::UI::TestRunner
16
- private
17
-
18
- #: (::Test::Unit::TestCase test) -> void
19
- def test_started(test)
20
- current_test = test
21
- @current_uri = uri_for_test(current_test)
22
- return unless @current_uri
23
-
24
- @current_test_id = "#{current_test.class.name}##{current_test.method_name}"
25
- TestReporter.start_test(
26
- id: @current_test_id,
27
- uri: @current_uri,
28
- )
29
- end
30
-
31
- #: (::Test::Unit::TestCase test) -> void
32
- def test_finished(test)
33
- if test.passed?
34
- TestReporter.record_pass(
35
- id: @current_test_id,
36
- uri: @current_uri,
37
- )
38
- end
39
- end
40
-
41
- #: (::Test::Unit::Failure | ::Test::Unit::Error | ::Test::Unit::Pending result) -> void
42
- def result_fault(result)
43
- case result
44
- when ::Test::Unit::Failure
45
- record_failure(result)
46
- when ::Test::Unit::Error
47
- record_error(result)
48
- when ::Test::Unit::Pending
49
- record_skip(result)
50
- end
51
- end
52
-
53
- #: (::Test::Unit::Failure failure) -> void
54
- def record_failure(failure)
55
- TestReporter.record_fail(
56
- id: @current_test_id,
57
- message: failure.message,
58
- uri: @current_uri,
59
- )
60
- end
61
-
62
- #: (::Test::Unit::Error error) -> void
63
- def record_error(error)
64
- TestReporter.record_error(
65
- id: @current_test_id,
66
- message: error.message,
67
- uri: @current_uri,
68
- )
69
- end
70
-
71
- #: (::Test::Unit::Pending pending) -> void
72
- def record_skip(pending)
73
- TestReporter.record_skip(id: @current_test_id, uri: @current_uri)
74
- end
75
-
76
- #: (::Test::Unit::TestCase test) -> URI::Generic?
77
- def uri_for_test(test)
78
- location = test.method(test.method_name).source_location
79
- return unless location # TODO: when might this be nil?
80
-
81
- file, _line = location
82
- return if file.start_with?("(eval at ") # test is dynamically defined (TODO: better way to check?)
83
-
84
- absolute_path = File.expand_path(file, Dir.pwd)
85
- URI::Generic.from_path(path: absolute_path)
86
- end
87
-
88
- #: -> void
89
- def attach_to_mediator
90
- @mediator.add_listener(Test::Unit::TestResult::FAULT, &method(:result_fault))
91
- @mediator.add_listener(Test::Unit::TestCase::STARTED_OBJECT, &method(:test_started))
92
- @mediator.add_listener(Test::Unit::TestCase::FINISHED_OBJECT, &method(:test_finished))
93
- end
94
- end
95
- end
96
-
97
- Test::Unit::AutoRunner.register_runner(:ruby_lsp) { |_auto_runner| RubyLsp::TestRunner }
98
- Test::Unit::AutoRunner.default_runner = :ruby_lsp