diff --git a/lib/ruby_lsp/ruby_lsp_rspec/rspec_formatter.rb b/lib/ruby_lsp/ruby_lsp_rspec/rspec_formatter.rb index 75ecee8..6e6ff0d 100644 --- a/lib/ruby_lsp/ruby_lsp_rspec/rspec_formatter.rb +++ b/lib/ruby_lsp/ruby_lsp_rspec/rspec_formatter.rb @@ -45,7 +45,10 @@ def example_failed(notification) example = notification.example uri = uri_for(example) id = generate_id(example) - RubyLsp::LspReporter.instance.record_fail(id: id, message: notification.exception.message, uri: uri) + message = notification.message_lines.join("\n") + message << "\n\n" + message << notification.formatted_backtrace.map(&method(:adjust_backtrace)).map { |s| "# " + s }.join("\n") + RubyLsp::LspReporter.instance.record_fail(id: id, message: message, uri: uri) end def example_pending(notification) @@ -69,6 +72,12 @@ def uri_for(example) def generate_id(example) [example, *example.example_group.parent_groups].reverse.map(&:location).join("::") end + + def adjust_backtrace(backtrace) + # Correct the backtrace entry so that vscode recognized it as a link to open + parts = backtrace.split(":", 3) + parts[0].sub(/^\./, "file://" + File.expand_path(".")) + ":" + parts[1] + " : " + parts[2] + end end end end diff --git a/spec/rspec_formatter_spec.rb b/spec/rspec_formatter_spec.rb index b489031..ee08065 100644 --- a/spec/rspec_formatter_spec.rb +++ b/spec/rspec_formatter_spec.rb @@ -82,7 +82,7 @@ "method" => "fail", "params" => { "id" => "./spec/fixtures/rspec_example_spec.rb:11::./spec/fixtures/rspec_example_spec.rb:12::./spec/fixtures/rspec_example_spec.rb:17", - "message" => "\nexpected: 1\n got: 2\n\n(compared using ==)\n", + "message" => %r{Failure/Error: expect\(2\).to eq\(1\)\n\n expected: 1\n got: 2\n\n \(compared using ==\)\n\n# file://#{fixture_path}:18 : in [`']block \(3 levels\) in '}, "uri" => "file://#{fixture_path}", }, }, @@ -128,14 +128,14 @@ "method" => "fail", "params" => { "id" => "./spec/fixtures/rspec_example_spec.rb:11::./spec/fixtures/rspec_example_spec.rb:12::./spec/fixtures/rspec_example_spec.rb:30", - "message" => "oops", + "message" => %r{Failure/Error: raise "oops"\n\nRuntimeError:\n oops\n\n# file://#{fixture_path}:31 : in [`']block \(3 levels\) in '}, "uri" => "file://#{fixture_path}", }, }, { "method" => "finish", "params" => {} }, ] - expect(events).to eq(expected) + expect(events).to match(expected) end describe "RubyLsp::RSpec::RSpecFormatter notifications" do @@ -175,8 +175,8 @@ end it "invokes ProgressFormatter's example_failed" do - exception = double("Exception", message: "error message") - allow(notification).to receive(:exception).and_return(exception) + allow(notification).to receive(:message_lines).and_return(["message lines"]) + allow(notification).to receive(:formatted_backtrace).and_return(["spec/example_spec.rb:13:in `something'"]) expect_any_instance_of(RSpec::Core::Formatters::ProgressFormatter).to receive(:example_failed)