Class: RubyLsp::MinitestReporter

Inherits:
Minitest::AbstractReporter
  • Object
show all
Defined in:
lib/ruby_lsp/test_reporters/minitest_reporter.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.minitest_plugin_init(_options) ⇒ Object

: (Hash[untyped, untyped]) -> void



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ruby_lsp/test_reporters/minitest_reporter.rb', line 60

def minitest_plugin_init(_options)
  # Remove the original progress reporter, so that we replace it with our own. We only do this if no other
  # reporters were included by the application itself to avoid double reporting
  reporters = Minitest.reporter.reporters

  if reporters.all? { |r| r.is_a?(Minitest::ProgressReporter) || r.is_a?(Minitest::SummaryReporter) }
    reporters.delete_if { |r| r.is_a?(Minitest::ProgressReporter) }
    reporters << ProgressReporterWithColor.new
  end

  # Add the JSON RPC reporter
  reporters << MinitestReporter.new
  PreventReporterOverridePatch.lsp_reporters = reporters
  Minitest.reporter.class.prepend(PreventReporterOverridePatch)
end

Instance Method Details

#handle_spec_test_id(method_name, line) ⇒ Object

: (String, Integer?) -> String



129
130
131
# File 'lib/ruby_lsp/test_reporters/minitest_reporter.rb', line 129

def handle_spec_test_id(method_name, line)
  method_name.gsub(/(?<=test_)\d{4}(?=_)/, format("%04d", line.to_s))
end

#prerecord(test_class_or_wrapper, method_name) ⇒ Object

: (untyped, String) -> void



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ruby_lsp/test_reporters/minitest_reporter.rb', line 78

def prerecord(test_class_or_wrapper, method_name)
  # In frameworks like Rails, they can control the Minitest execution by wrapping the test class
  # But they conform to responding to `name`, so we can use that as a guarantee
  # We are interested in the test class, not the wrapper
  name = test_class_or_wrapper.name

  klass = begin
    Object.const_get(name) # rubocop:disable Sorbet/ConstantsFromStrings
  rescue NameError
    # Handle Minitest specs that create classes with invalid constant names like "MySpec::when something is true"
    # If we can't resolve the constant, it means we were given the actual test class object, not the wrapper
    test_class_or_wrapper
  end

  uri, line = LspReporter.instance.uri_and_line_for(klass.instance_method(method_name))
  return unless uri

  id = "#{name}##{handle_spec_test_id(method_name, line)}"
  LspReporter.instance.start_test(id: id, uri: uri, line: line)
end

#record(result) ⇒ Object

: (Minitest::Result result) -> void



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ruby_lsp/test_reporters/minitest_reporter.rb', line 100

def record(result)
  file_path, line = result.source_location
  return unless file_path

  zero_based_line = line ? line - 1 : nil
  name = handle_spec_test_id(result.name, zero_based_line)
  id = "#{result.klass}##{name}"

  uri = URI::Generic.from_path(path: File.expand_path(file_path))

  if result.error?
    message = result.failures.first.message
    LspReporter.instance.record_error(id: id, uri: uri, message: message)
  elsif result.passed?
    LspReporter.instance.record_pass(id: id, uri: uri)
  elsif result.skipped?
    LspReporter.instance.record_skip(id: id, uri: uri)
  elsif result.failure
    message = result.failure.message
    LspReporter.instance.record_fail(id: id, uri: uri, message: message)
  end
end

#reportObject

: -> void



124
125
126
# File 'lib/ruby_lsp/test_reporters/minitest_reporter.rb', line 124

def report
  LspReporter.instance.shutdown
end