better_errors 2.1.1 → 2.2.0

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.

Potentially problematic release.


This version of better_errors might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ae01bfc76b45f6af1df26c7268229088f8de251
4
- data.tar.gz: f95f617f84e01f1641bf193d735d45d85360b768
3
+ metadata.gz: d53ee50b3a870061cf9298e5225635771043d6d7
4
+ data.tar.gz: b4280966bd31d24f4f4cb12ea54c1eea11bccdaa
5
5
  SHA512:
6
- metadata.gz: 4881b5a147d85c9c7ed116a8838e45745bd95958df71dea8934e0b5601fd32cde2a016bbc419a855f9e29dd8e6bab322fcae8d676a78ede120d134809dac29b7
7
- data.tar.gz: 6fb75468216fc264250e8f6726d47689025352441701cb83b2c125b541ac389c491da6ba8b3eeded2759b99be47f5c0cd103b54315122d7a33905261d02d4cca
6
+ metadata.gz: e068142eaef86037e0cc6088672158a0a9d021e49e7fe9a823c888d1f319181e07b18a03852b46da4a6d9a0db49f6d420ac7359ceb6ec4a35549bb56b403bec5
7
+ data.tar.gz: 9c184752196c2cf65b7dba20f94cf3b47428c6fd067c880ffa452bca8ed2fa6d3e84e5cd64ae6e295199622fe4e1ff2d6d09979d2a35e0b9bf36d38c6ebfdd33
@@ -2,5 +2,8 @@ sudo: false
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
- - 2.1.0
6
- - 2.0.0
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3
9
+ - 2.4
data/Gemfile CHANGED
@@ -3,8 +3,9 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem "rake"
6
- gem "rack"
7
- gem "rspec", "2.14.1"
6
+ gem "rack", "1.6.4"
7
+ gem "rspec", "3.5.0"
8
+ gem "rspec-its"
8
9
  gem "binding_of_caller", platforms: :ruby
9
10
  gem "pry", "0.9.12"
10
11
  gem "yard"
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2015 Charlie Somerville
1
+ Copyright (c) 2012-2016 Charlie Somerville
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -6,10 +6,14 @@ Better Errors replaces the standard Rails error page with a much better and more
6
6
 
7
7
  ## Features
8
8
 
9
+ For screenshots of these features, [see the wiki](https://github.com/charliesome/better_errors/wiki).
10
+
9
11
  * Full stack trace
10
12
  * Source code inspection for all stack frames (with highlighting)
11
13
  * Local and instance variable inspection
12
- * Live REPL on every stack frame
14
+ * Live shell (REPL) on every stack frame
15
+ * Links directly to the source line in your editor
16
+ * Useful information in non-HTML requests
13
17
 
14
18
  ## Installation
15
19
 
@@ -95,6 +99,14 @@ in `development`. Another option would be to use Webrick, Mongrel, Thin,
95
99
  or another single-process server as your `rails server`, when you are trying
96
100
  to troubleshoot an issue in development.
97
101
 
102
+ ##Specify editor to open files in
103
+
104
+ ```ruby
105
+ # e.g. in config/initializers/better_errors.rb
106
+ # Other preset values are [:mvim, :macvim, :textmate, :txmt, :tm, :sublime, :subl, :st]
107
+ BetterErrors.editor = :mvim
108
+ ```
109
+
98
110
  ## Get in touch!
99
111
 
100
112
  If you're using better_errors, I'd love to hear from you. Drop me a line and tell me what you think!
@@ -58,6 +58,14 @@ module BetterErrors
58
58
  exception.backtrace
59
59
  end
60
60
 
61
+ def exception_type
62
+ exception.type
63
+ end
64
+
65
+ def exception_message
66
+ exception.message.lstrip
67
+ end
68
+
61
69
  def application_frames
62
70
  backtrace_frames.select(&:application?)
63
71
  end
@@ -100,7 +100,7 @@ module BetterErrors
100
100
  end
101
101
 
102
102
  status_code = 500
103
- if defined? ActionDispatch::ExceptionWrapper
103
+ if defined?(ActionDispatch::ExceptionWrapper) && exception
104
104
  status_code = ActionDispatch::ExceptionWrapper.new(env, exception).status_code
105
105
  end
106
106
 
@@ -115,7 +115,7 @@ module BetterErrors
115
115
  def log_exception
116
116
  return unless BetterErrors.logger
117
117
 
118
- message = "\n#{@error_page.exception.type} - #{@error_page.exception.message}:\n"
118
+ message = "\n#{@error_page.exception_type} - #{@error_page.exception_message}:\n"
119
119
  @error_page.backtrace_frames.each do |frame|
120
120
  message << " #{frame}\n"
121
121
  end
@@ -4,7 +4,9 @@ module BetterErrors
4
4
  attr_reader :exception, :message, :backtrace
5
5
 
6
6
  def initialize(exception)
7
- if exception.respond_to?(:original_exception) && exception.original_exception
7
+ if exception.respond_to?(:cause)
8
+ exception = exception.cause if exception.cause
9
+ elsif exception.respond_to?(:original_exception) && exception.original_exception
8
10
  exception = exception.original_exception
9
11
  end
10
12
 
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
3
  <head>
4
- <title><%= exception.type %> at <%= request_path %></title>
4
+ <title><%= exception_type %> at <%= request_path %></title>
5
5
  </head>
6
6
  <body>
7
7
  <%# Stylesheets are placed in the <body> for Turbolinks compatibility. %>
@@ -731,8 +731,8 @@
731
731
 
732
732
  <div class='top'>
733
733
  <header class="exception">
734
- <h2><strong><%= exception.type %></strong> <span>at <%= request_path %></span></h2>
735
- <p><%= exception.message %></p>
734
+ <h2><strong><%= exception_type %></strong> <span>at <%= request_path %></span></h2>
735
+ <p><%= exception_message %></p>
736
736
  </header>
737
737
  </div>
738
738
 
@@ -1,6 +1,6 @@
1
- <%== text_heading("=", "%s at %s" % [exception.type, request_path]) %>
1
+ <%== text_heading("=", "%s at %s" % [exception_type, request_path]) %>
2
2
 
3
- > <%== exception.message %>
3
+ > <%== exception_message %>
4
4
  <% if backtrace_frames.any? %>
5
5
 
6
6
  <%== text_heading("-", "%s, line %i" % [first_frame.pretty_path, first_frame.line]) %>
@@ -45,26 +45,28 @@
45
45
  </div>
46
46
  </div>
47
47
 
48
- <div class="sub">
49
- <h3>Local Variables</h3>
50
- <div class='inset variables'>
51
- <table class="var_table">
52
- <% @frame.local_variables.each do |name, value| %>
53
- <tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
54
- <% end %>
55
- </table>
48
+ <% if BetterErrors.binding_of_caller_available? && @frame.frame_binding %>
49
+ <div class="sub">
50
+ <h3>Local Variables</h3>
51
+ <div class='inset variables'>
52
+ <table class="var_table">
53
+ <% @frame.local_variables.each do |name, value| %>
54
+ <tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
55
+ <% end %>
56
+ </table>
57
+ </div>
56
58
  </div>
57
- </div>
58
59
 
59
- <div class="sub">
60
- <h3>Instance Variables</h3>
61
- <div class="inset variables">
62
- <table class="var_table">
63
- <% @frame.instance_variables.each do |name, value| %>
64
- <tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
65
- <% end %>
66
- </table>
60
+ <div class="sub">
61
+ <h3>Instance Variables</h3>
62
+ <div class="inset variables">
63
+ <table class="var_table">
64
+ <% @frame.instance_variables.each do |name, value| %>
65
+ <tr><td class="name"><%= name %></td><td><pre><%== inspect_value value %></pre></td></tr>
66
+ <% end %>
67
+ </table>
68
+ </div>
67
69
  </div>
68
- </div>
69
70
 
70
- <!-- <%= Time.now.to_f - @var_start_time %> seconds -->
71
+ <!-- <%= Time.now.to_f - @var_start_time %> seconds -->
72
+ <% end %>
@@ -1,3 +1,3 @@
1
1
  module BetterErrors
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.0"
3
3
  end
@@ -7,13 +7,13 @@ module BetterErrors
7
7
  let(:formatter) { CodeFormatter.new(filename, 8) }
8
8
 
9
9
  it "picks an appropriate scanner" do
10
- formatter.coderay_scanner.should == :ruby
10
+ expect(formatter.coderay_scanner).to eq(:ruby)
11
11
  end
12
12
 
13
13
  it "shows 5 lines of context" do
14
- formatter.line_range.should == (3..13)
14
+ expect(formatter.line_range).to eq(3..13)
15
15
 
16
- formatter.context_lines.should == [
16
+ expect(formatter.context_lines).to eq([
17
17
  "three\n",
18
18
  "four\n",
19
19
  "five\n",
@@ -25,40 +25,40 @@ module BetterErrors
25
25
  "eleven\n",
26
26
  "twelve\n",
27
27
  "thirteen\n"
28
- ]
28
+ ])
29
29
  end
30
30
 
31
31
  it "works when the line is right on the edge" do
32
32
  formatter = CodeFormatter.new(filename, 20)
33
- formatter.line_range.should == (15..20)
33
+ expect(formatter.line_range).to eq(15..20)
34
34
  end
35
35
 
36
36
  describe CodeFormatter::HTML do
37
37
  it "highlights the erroring line" do
38
38
  formatter = CodeFormatter::HTML.new(filename, 8)
39
- formatter.output.should =~ /highlight.*eight/
39
+ expect(formatter.output).to match(/highlight.*eight/)
40
40
  end
41
41
 
42
42
  it "works when the line is right on the edge" do
43
43
  formatter = CodeFormatter::HTML.new(filename, 20)
44
- formatter.output.should_not == formatter.source_unavailable
44
+ expect(formatter.output).not_to eq(formatter.source_unavailable)
45
45
  end
46
46
 
47
47
  it "doesn't barf when the lines don't make any sense" do
48
48
  formatter = CodeFormatter::HTML.new(filename, 999)
49
- formatter.output.should == formatter.source_unavailable
49
+ expect(formatter.output).to eq(formatter.source_unavailable)
50
50
  end
51
51
 
52
52
  it "doesn't barf when the file doesn't exist" do
53
53
  formatter = CodeFormatter::HTML.new("fkdguhskd7e l", 1)
54
- formatter.output.should == formatter.source_unavailable
54
+ expect(formatter.output).to eq(formatter.source_unavailable)
55
55
  end
56
56
  end
57
57
 
58
58
  describe CodeFormatter::Text do
59
59
  it "highlights the erroring line" do
60
60
  formatter = CodeFormatter::Text.new(filename, 8)
61
- formatter.output.should == <<-TEXT.gsub(/^ /, "")
61
+ expect(formatter.output).to eq <<-TEXT.gsub(/^ /, "")
62
62
  3 three
63
63
  4 four
64
64
  5 five
@@ -75,17 +75,17 @@ module BetterErrors
75
75
 
76
76
  it "works when the line is right on the edge" do
77
77
  formatter = CodeFormatter::Text.new(filename, 20)
78
- formatter.output.should_not == formatter.source_unavailable
78
+ expect(formatter.output).not_to eq(formatter.source_unavailable)
79
79
  end
80
80
 
81
81
  it "doesn't barf when the lines don't make any sense" do
82
82
  formatter = CodeFormatter::Text.new(filename, 999)
83
- formatter.output.should == formatter.source_unavailable
83
+ expect(formatter.output).to eq(formatter.source_unavailable)
84
84
  end
85
85
 
86
86
  it "doesn't barf when the file doesn't exist" do
87
87
  formatter = CodeFormatter::Text.new("fkdguhskd7e l", 1)
88
- formatter.output.should == formatter.source_unavailable
88
+ expect(formatter.output).to eq(formatter.source_unavailable)
89
89
  end
90
90
  end
91
91
  end
@@ -19,15 +19,15 @@ module BetterErrors
19
19
  }
20
20
 
21
21
  it "includes the error message" do
22
- response.should include("you divided by zero you silly goose!")
22
+ expect(response).to include("you divided by zero you silly goose!")
23
23
  end
24
24
 
25
25
  it "includes the request path" do
26
- response.should include("/some/path")
26
+ expect(response).to include("/some/path")
27
27
  end
28
28
 
29
29
  it "includes the exception class" do
30
- response.should include("ZeroDivisionError")
30
+ expect(response).to include("ZeroDivisionError")
31
31
  end
32
32
 
33
33
  context "variable inspection" do
@@ -36,41 +36,57 @@ module BetterErrors
36
36
  if BetterErrors.binding_of_caller_available?
37
37
  it "shows local variables" do
38
38
  html = error_page.do_variables("index" => 0)[:html]
39
- html.should include("local_a")
40
- html.should include(":value_for_local_a")
41
- html.should include("local_b")
42
- html.should include(":value_for_local_b")
39
+ expect(html).to include("local_a")
40
+ expect(html).to include(":value_for_local_a")
41
+ expect(html).to include("local_b")
42
+ expect(html).to include(":value_for_local_b")
43
43
  end
44
44
  else
45
45
  it "tells the user to add binding_of_caller to their gemfile to get fancy features" do
46
46
  html = error_page.do_variables("index" => 0)[:html]
47
- html.should include(%{gem "binding_of_caller"})
47
+ expect(html).to include(%{gem "binding_of_caller"})
48
48
  end
49
49
  end
50
50
 
51
51
  it "shows instance variables" do
52
52
  html = error_page.do_variables("index" => 0)[:html]
53
- html.should include("inst_c")
54
- html.should include(":value_for_inst_c")
55
- html.should include("inst_d")
56
- html.should include(":value_for_inst_d")
53
+ expect(html).to include("inst_c")
54
+ expect(html).to include(":value_for_inst_c")
55
+ expect(html).to include("inst_d")
56
+ expect(html).to include(":value_for_inst_d")
57
57
  end
58
58
 
59
59
  it "shows filter instance variables" do
60
- BetterErrors.stub(:ignored_instance_variables).and_return([ :@inst_d ])
60
+ allow(BetterErrors).to receive(:ignored_instance_variables).and_return([ :@inst_d ])
61
61
  html = error_page.do_variables("index" => 0)[:html]
62
- html.should include("inst_c")
63
- html.should include(":value_for_inst_c")
64
- html.should_not include('<td class="name">@inst_d</td>')
65
- html.should_not include("<pre>:value_for_inst_d</pre>")
62
+ expect(html).to include("inst_c")
63
+ expect(html).to include(":value_for_inst_c")
64
+ expect(html).not_to include('<td class="name">@inst_d</td>')
65
+ expect(html).not_to include("<pre>:value_for_inst_d</pre>")
66
66
  end
67
67
  end
68
68
 
69
69
  it "doesn't die if the source file is not a real filename" do
70
- exception.stub(:backtrace).and_return([
70
+ allow(exception).to receive(:backtrace).and_return([
71
71
  "<internal:prelude>:10:in `spawn_rack_application'"
72
72
  ])
73
- response.should include("Source unavailable")
73
+ expect(response).to include("Source unavailable")
74
+ end
75
+
76
+ context 'with an exception with blank lines' do
77
+ class SpacedError < StandardError
78
+ def initialize(message = nil)
79
+ message = "\n\n#{message}" if message
80
+ super
81
+ end
82
+ end
83
+
84
+ let!(:exception) { raise SpacedError, "Danger Warning!" rescue $! }
85
+
86
+ it 'should not include leading blank lines from exception_message' do
87
+ expect(exception.message).to match(/\A\n\n/)
88
+ expect(error_page.exception_message).not_to match(/\A\n\n/)
89
+ end
74
90
  end
75
91
  end
76
92
  end
@@ -6,42 +6,42 @@ module BetterErrors
6
6
  let(:exception) { RuntimeError.new("oh no :(") }
7
7
 
8
8
  it "passes non-error responses through" do
9
- app.call({}).should == ":)"
9
+ expect(app.call({})).to eq(":)")
10
10
  end
11
11
 
12
12
  it "calls the internal methods" do
13
- app.should_receive :internal_call
13
+ expect(app).to receive :internal_call
14
14
  app.call("PATH_INFO" => "/__better_errors/1/preform_awesomness")
15
15
  end
16
16
 
17
17
  it "calls the internal methods on any subfolder path" do
18
- app.should_receive :internal_call
18
+ expect(app).to receive :internal_call
19
19
  app.call("PATH_INFO" => "/any_sub/folder/path/__better_errors/1/preform_awesomness")
20
20
  end
21
21
 
22
22
  it "shows the error page" do
23
- app.should_receive :show_error_page
23
+ expect(app).to receive :show_error_page
24
24
  app.call("PATH_INFO" => "/__better_errors/")
25
25
  end
26
26
 
27
27
  it "shows the error page on any subfolder path" do
28
- app.should_receive :show_error_page
28
+ expect(app).to receive :show_error_page
29
29
  app.call("PATH_INFO" => "/any_sub/folder/path/__better_errors/")
30
30
  end
31
31
 
32
32
  it "doesn't show the error page to a non-local address" do
33
- app.should_not_receive :better_errors_call
33
+ expect(app).not_to receive :better_errors_call
34
34
  app.call("REMOTE_ADDR" => "1.2.3.4")
35
35
  end
36
36
 
37
37
  it "shows to a whitelisted IP" do
38
38
  BetterErrors::Middleware.allow_ip! '77.55.33.11'
39
- app.should_receive :better_errors_call
39
+ expect(app).to receive :better_errors_call
40
40
  app.call("REMOTE_ADDR" => "77.55.33.11")
41
41
  end
42
42
 
43
43
  it "respects the X-Forwarded-For header" do
44
- app.should_not_receive :better_errors_call
44
+ expect(app).not_to receive :better_errors_call
45
45
  app.call(
46
46
  "REMOTE_ADDR" => "127.0.0.1",
47
47
  "HTTP_X_FORWARDED_FOR" => "1.2.3.4",
@@ -61,12 +61,20 @@ module BetterErrors
61
61
 
62
62
  it "shows that no errors have been recorded" do
63
63
  status, headers, body = app.call("PATH_INFO" => "/__better_errors")
64
- body.join.should match /No errors have been recorded yet./
64
+ expect(body.join).to match /No errors have been recorded yet./
65
+ end
66
+
67
+ it 'does not attempt to use ActionDispatch::ExceptionWrapper with a nil exception' do
68
+ ad_ew = double("ActionDispatch::ExceptionWrapper")
69
+ stub_const('ActionDispatch::ExceptionWrapper', ad_ew)
70
+ ad_ew.should_not_receive :new
71
+
72
+ status, headers, body = app.call("PATH_INFO" => "/__better_errors")
65
73
  end
66
74
 
67
75
  it "shows that no errors have been recorded on any subfolder path" do
68
76
  status, headers, body = app.call("PATH_INFO" => "/any_sub/folder/path/__better_errors")
69
- body.join.should match /No errors have been recorded yet./
77
+ expect(body.join).to match /No errors have been recorded yet./
70
78
  end
71
79
  end
72
80
 
@@ -76,76 +84,102 @@ module BetterErrors
76
84
  it "returns status 500" do
77
85
  status, headers, body = app.call({})
78
86
 
79
- status.should == 500
87
+ expect(status).to eq(500)
80
88
  end
81
89
 
82
- context "original_exception" do
83
- class OriginalExceptionException < Exception
84
- attr_reader :original_exception
90
+ if Exception.new.respond_to?(:cause)
91
+ context "cause" do
92
+ class OtherException < Exception
93
+ def initialize(message)
94
+ super(message)
95
+ end
96
+ end
85
97
 
86
- def initialize(message, original_exception = nil)
87
- super(message)
88
- @original_exception = original_exception
98
+ it "shows Original Exception if it responds_to and has an cause" do
99
+ app = Middleware.new(->env {
100
+ begin
101
+ raise "Original Exception"
102
+ rescue
103
+ raise OtherException.new("Other Exception")
104
+ end
105
+ })
106
+
107
+ status, _, body = app.call({})
108
+
109
+ expect(status).to eq(500)
110
+ expect(body.join).not_to match(/\n> Other Exception\n/)
111
+ expect(body.join).to match(/\n> Original Exception\n/)
89
112
  end
90
113
  end
114
+ else
115
+ context "original_exception" do
116
+ class OriginalExceptionException < Exception
117
+ attr_reader :original_exception
118
+
119
+ def initialize(message, original_exception = nil)
120
+ super(message)
121
+ @original_exception = original_exception
122
+ end
123
+ end
91
124
 
92
- it "shows Original Exception if it responds_to and has an original_exception" do
93
- app = Middleware.new(->env {
94
- raise OriginalExceptionException.new("Other Exception", Exception.new("Original Exception"))
95
- })
125
+ it "shows Original Exception if it responds_to and has an original_exception" do
126
+ app = Middleware.new(->env {
127
+ raise OriginalExceptionException.new("Other Exception", Exception.new("Original Exception"))
128
+ })
96
129
 
97
- status, _, body = app.call({})
130
+ status, _, body = app.call({})
98
131
 
99
- status.should == 500
100
- body.join.should_not match(/Other Exception/)
101
- body.join.should match(/Original Exception/)
102
- end
132
+ expect(status).to eq(500)
133
+ expect(body.join).not_to match(/Other Exception/)
134
+ expect(body.join).to match(/Original Exception/)
135
+ end
103
136
 
104
- it "won't crash if the exception responds_to but doesn't have an original_exception" do
105
- app = Middleware.new(->env {
106
- raise OriginalExceptionException.new("Other Exception")
107
- })
137
+ it "won't crash if the exception responds_to but doesn't have an original_exception" do
138
+ app = Middleware.new(->env {
139
+ raise OriginalExceptionException.new("Other Exception")
140
+ })
108
141
 
109
- status, _, body = app.call({})
142
+ status, _, body = app.call({})
110
143
 
111
- status.should == 500
112
- body.join.should match(/Other Exception/)
144
+ expect(status).to eq(500)
145
+ expect(body.join).to match(/Other Exception/)
146
+ end
113
147
  end
114
148
  end
115
149
 
116
150
  it "returns ExceptionWrapper's status_code" do
117
151
  ad_ew = double("ActionDispatch::ExceptionWrapper")
118
- ad_ew.stub('new').with({}, exception ){ double("ExceptionWrapper", status_code: 404) }
152
+ allow(ad_ew).to receive('new').with({}, exception) { double("ExceptionWrapper", status_code: 404) }
119
153
  stub_const('ActionDispatch::ExceptionWrapper', ad_ew)
120
154
 
121
155
  status, headers, body = app.call({})
122
156
 
123
- status.should == 404
157
+ expect(status).to eq(404)
124
158
  end
125
159
 
126
160
  it "returns UTF-8 error pages" do
127
161
  status, headers, body = app.call({})
128
162
 
129
- headers["Content-Type"].should match /charset=utf-8/
163
+ expect(headers["Content-Type"]).to match /charset=utf-8/
130
164
  end
131
165
 
132
166
  it "returns text pages by default" do
133
167
  status, headers, body = app.call({})
134
168
 
135
- headers["Content-Type"].should match /text\/plain/
169
+ expect(headers["Content-Type"]).to match /text\/plain/
136
170
  end
137
171
 
138
172
  it "returns HTML pages by default" do
139
173
  # Chrome's 'Accept' header looks similar this.
140
174
  status, headers, body = app.call("HTTP_ACCEPT" => "text/html,application/xhtml+xml;q=0.9,*/*")
141
175
 
142
- headers["Content-Type"].should match /text\/html/
176
+ expect(headers["Content-Type"]).to match /text\/html/
143
177
  end
144
178
 
145
179
  it "logs the exception" do
146
180
  logger = Object.new
147
- logger.should_receive :fatal
148
- BetterErrors.stub(:logger).and_return(logger)
181
+ expect(logger).to receive :fatal
182
+ allow(BetterErrors).to receive(:logger).and_return(logger)
149
183
 
150
184
  app.call({})
151
185
  end
@@ -1,4 +1,5 @@
1
1
  require "spec_helper"
2
+ require "rspec/its"
2
3
 
3
4
  module BetterErrors
4
5
  describe RaisedException do
@@ -24,8 +25,8 @@ module BetterErrors
24
25
  its(:type) { should == SyntaxError }
25
26
 
26
27
  it "has the right filename and line number in the backtrace" do
27
- subject.backtrace.first.filename.should == "foo.rb"
28
- subject.backtrace.first.line.should == 123
28
+ expect(subject.backtrace.first.filename).to eq("foo.rb")
29
+ expect(subject.backtrace.first.line).to eq(123)
29
30
  end
30
31
  end
31
32
 
@@ -44,8 +45,8 @@ module BetterErrors
44
45
  its(:type) { should == Haml::SyntaxError }
45
46
 
46
47
  it "has the right filename and line number in the backtrace" do
47
- subject.backtrace.first.filename.should == "foo.rb"
48
- subject.backtrace.first.line.should == 123
48
+ expect(subject.backtrace.first.filename).to eq("foo.rb")
49
+ expect(subject.backtrace.first.line).to eq(123)
49
50
  end
50
51
  end
51
52
 
@@ -64,8 +65,8 @@ module BetterErrors
64
65
  its(:type) { should == Sprockets::Coffeelint::Error }
65
66
 
66
67
  it "has the right filename and line number in the backtrace" do
67
- subject.backtrace.first.filename.should == "app/assets/javascripts/files/index.coffee"
68
- subject.backtrace.first.line.should == 11
68
+ expect(subject.backtrace.first.filename).to eq("app/assets/javascripts/files/index.coffee")
69
+ expect(subject.backtrace.first.line).to eq(11)
69
70
  end
70
71
  end
71
72
  end
@@ -15,23 +15,23 @@ module BetterErrors
15
15
 
16
16
  it "does line continuation" do
17
17
  output, prompt, filled = repl.send_input ""
18
- output.should == "=> nil\n"
19
- prompt.should == ">>"
20
- filled.should == ""
18
+ expect(output).to eq("=> nil\n")
19
+ expect(prompt).to eq(">>")
20
+ expect(filled).to eq("")
21
21
 
22
22
  output, prompt, filled = repl.send_input "def f(x)"
23
- output.should == ""
24
- prompt.should == ".."
25
- filled.should == " "
23
+ expect(output).to eq("")
24
+ expect(prompt).to eq("..")
25
+ expect(filled).to eq(" ")
26
26
 
27
27
  output, prompt, filled = repl.send_input "end"
28
28
  if RUBY_VERSION >= "2.1.0"
29
- output.should == "=> :f\n"
29
+ expect(output).to eq("=> :f\n")
30
30
  else
31
- output.should == "=> nil\n"
31
+ expect(output).to eq("=> nil\n")
32
32
  end
33
- prompt.should == ">>"
34
- filled.should == ""
33
+ expect(prompt).to eq(">>")
34
+ expect(filled).to eq("")
35
35
  end
36
36
 
37
37
  it_behaves_like "a REPL provider"
@@ -1,18 +1,18 @@
1
1
  shared_examples_for "a REPL provider" do
2
2
  it "evaluates ruby code in a given context" do
3
3
  repl.send_input("local_a = 456")
4
- fresh_binding.eval("local_a").should == 456
4
+ expect(fresh_binding.eval("local_a")).to eq(456)
5
5
  end
6
6
 
7
7
  it "returns a tuple of output and the new prompt" do
8
8
  output, prompt = repl.send_input("1 + 2")
9
- output.should == "=> 3\n"
10
- prompt.should == ">>"
9
+ expect(output).to eq("=> 3\n")
10
+ expect(prompt).to eq(">>")
11
11
  end
12
12
 
13
13
  it "doesn't barf if the code throws an exception" do
14
14
  output, prompt = repl.send_input("raise Exception")
15
- output.should include "Exception: Exception"
16
- prompt.should == ">>"
15
+ expect(output).to include "Exception: Exception"
16
+ expect(prompt).to eq(">>")
17
17
  end
18
18
  end
@@ -4,80 +4,80 @@ module BetterErrors
4
4
  describe StackFrame do
5
5
  context "#application?" do
6
6
  it "is true for application filenames" do
7
- BetterErrors.stub(:application_root).and_return("/abc/xyz")
7
+ allow(BetterErrors).to receive(:application_root).and_return("/abc/xyz")
8
8
  frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index")
9
9
 
10
- frame.should be_application
10
+ expect(frame).to be_application
11
11
  end
12
12
 
13
13
  it "is false for everything else" do
14
- BetterErrors.stub(:application_root).and_return("/abc/xyz")
14
+ allow(BetterErrors).to receive(:application_root).and_return("/abc/xyz")
15
15
  frame = StackFrame.new("/abc/nope", 123, "foo")
16
16
 
17
- frame.should_not be_application
17
+ expect(frame).not_to be_application
18
18
  end
19
19
 
20
20
  it "doesn't care if no application_root is set" do
21
21
  frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index")
22
22
 
23
- frame.should_not be_application
23
+ expect(frame).not_to be_application
24
24
  end
25
25
  end
26
26
 
27
27
  context "#gem?" do
28
28
  it "is true for gem filenames" do
29
- Gem.stub(:path).and_return(["/abc/xyz"])
29
+ allow(Gem).to receive(:path).and_return(["/abc/xyz"])
30
30
  frame = StackFrame.new("/abc/xyz/gems/whatever-1.2.3/lib/whatever.rb", 123, "foo")
31
31
 
32
- frame.should be_gem
32
+ expect(frame).to be_gem
33
33
  end
34
34
 
35
35
  it "is false for everything else" do
36
- Gem.stub(:path).and_return(["/abc/xyz"])
36
+ allow(Gem).to receive(:path).and_return(["/abc/xyz"])
37
37
  frame = StackFrame.new("/abc/nope", 123, "foo")
38
38
 
39
- frame.should_not be_gem
39
+ expect(frame).not_to be_gem
40
40
  end
41
41
  end
42
42
 
43
43
  context "#application_path" do
44
44
  it "chops off the application root" do
45
- BetterErrors.stub(:application_root).and_return("/abc/xyz")
45
+ allow(BetterErrors).to receive(:application_root).and_return("/abc/xyz")
46
46
  frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index")
47
47
 
48
- frame.application_path.should == "app/controllers/crap_controller.rb"
48
+ expect(frame.application_path).to eq("app/controllers/crap_controller.rb")
49
49
  end
50
50
  end
51
51
 
52
52
  context "#gem_path" do
53
53
  it "chops of the gem path and stick (gem) there" do
54
- Gem.stub(:path).and_return(["/abc/xyz"])
54
+ allow(Gem).to receive(:path).and_return(["/abc/xyz"])
55
55
  frame = StackFrame.new("/abc/xyz/gems/whatever-1.2.3/lib/whatever.rb", 123, "foo")
56
56
 
57
- frame.gem_path.should == "whatever (1.2.3) lib/whatever.rb"
57
+ expect(frame.gem_path).to eq("whatever (1.2.3) lib/whatever.rb")
58
58
  end
59
59
 
60
60
  it "prioritizes gem path over application path" do
61
- BetterErrors.stub(:application_root).and_return("/abc/xyz")
62
- Gem.stub(:path).and_return(["/abc/xyz/vendor"])
61
+ allow(BetterErrors).to receive(:application_root).and_return("/abc/xyz")
62
+ allow(Gem).to receive(:path).and_return(["/abc/xyz/vendor"])
63
63
  frame = StackFrame.new("/abc/xyz/vendor/gems/whatever-1.2.3/lib/whatever.rb", 123, "foo")
64
64
 
65
- frame.gem_path.should == "whatever (1.2.3) lib/whatever.rb"
65
+ expect(frame.gem_path).to eq("whatever (1.2.3) lib/whatever.rb")
66
66
  end
67
67
  end
68
68
 
69
69
  context "#pretty_path" do
70
70
  it "returns #application_path for application paths" do
71
- BetterErrors.stub(:application_root).and_return("/abc/xyz")
71
+ allow(BetterErrors).to receive(:application_root).and_return("/abc/xyz")
72
72
  frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index")
73
- frame.pretty_path.should == frame.application_path
73
+ expect(frame.pretty_path).to eq(frame.application_path)
74
74
  end
75
75
 
76
76
  it "returns #gem_path for gem paths" do
77
- Gem.stub(:path).and_return(["/abc/xyz"])
77
+ allow(Gem).to receive(:path).and_return(["/abc/xyz"])
78
78
  frame = StackFrame.new("/abc/xyz/gems/whatever-1.2.3/lib/whatever.rb", 123, "foo")
79
79
 
80
- frame.pretty_path.should == frame.gem_path
80
+ expect(frame.pretty_path).to eq(frame.gem_path)
81
81
  end
82
82
  end
83
83
 
@@ -87,36 +87,36 @@ module BetterErrors
87
87
  rescue SyntaxError => syntax_error
88
88
  end
89
89
  frames = StackFrame.from_exception(syntax_error)
90
- frames.first.filename.should == "my_file.rb"
91
- frames.first.line.should == 123
90
+ expect(frames.first.filename).to eq("my_file.rb")
91
+ expect(frames.first.line).to eq(123)
92
92
  end
93
93
 
94
94
  it "doesn't blow up if no method name is given" do
95
95
  error = StandardError.allocate
96
96
 
97
- error.stub(:backtrace).and_return(["foo.rb:123"])
97
+ allow(error).to receive(:backtrace).and_return(["foo.rb:123"])
98
98
  frames = StackFrame.from_exception(error)
99
- frames.first.filename.should == "foo.rb"
100
- frames.first.line.should == 123
99
+ expect(frames.first.filename).to eq("foo.rb")
100
+ expect(frames.first.line).to eq(123)
101
101
 
102
- error.stub(:backtrace).and_return(["foo.rb:123: this is an error message"])
102
+ allow(error).to receive(:backtrace).and_return(["foo.rb:123: this is an error message"])
103
103
  frames = StackFrame.from_exception(error)
104
- frames.first.filename.should == "foo.rb"
105
- frames.first.line.should == 123
104
+ expect(frames.first.filename).to eq("foo.rb")
105
+ expect(frames.first.line).to eq(123)
106
106
  end
107
107
 
108
108
  it "ignores a backtrace line if its format doesn't make any sense at all" do
109
109
  error = StandardError.allocate
110
- error.stub(:backtrace).and_return(["foo.rb:123:in `foo'", "C:in `find'", "bar.rb:123:in `bar'"])
110
+ allow(error).to receive(:backtrace).and_return(["foo.rb:123:in `foo'", "C:in `find'", "bar.rb:123:in `bar'"])
111
111
  frames = StackFrame.from_exception(error)
112
- frames.count.should == 2
112
+ expect(frames.count).to eq(2)
113
113
  end
114
114
 
115
115
  it "doesn't blow up if a filename contains a colon" do
116
116
  error = StandardError.allocate
117
- error.stub(:backtrace).and_return(["crap:filename.rb:123"])
117
+ allow(error).to receive(:backtrace).and_return(["crap:filename.rb:123"])
118
118
  frames = StackFrame.from_exception(error)
119
- frames.first.filename.should == "crap:filename.rb"
119
+ expect(frames.first.filename).to eq("crap:filename.rb")
120
120
  end
121
121
 
122
122
  it "doesn't blow up with a BasicObject as frame binding" do
@@ -125,7 +125,7 @@ module BetterErrors
125
125
  ::Kernel.binding
126
126
  end
127
127
  frame = StackFrame.new("/abc/xyz/app/controllers/crap_controller.rb", 123, "index", obj.my_binding)
128
- frame.class_name.should == 'BasicObject'
128
+ expect(frame.class_name).to eq('BasicObject')
129
129
  end
130
130
 
131
131
  it "sets method names properly" do
@@ -140,11 +140,11 @@ module BetterErrors
140
140
 
141
141
  frame = StackFrame.from_exception(obj.my_method).first
142
142
  if BetterErrors.binding_of_caller_available?
143
- frame.method_name.should == "#my_method"
144
- frame.class_name.should == "String"
143
+ expect(frame.method_name).to eq("#my_method")
144
+ expect(frame.class_name).to eq("String")
145
145
  else
146
- frame.method_name.should == "my_method"
147
- frame.class_name.should == nil
146
+ expect(frame.method_name).to eq("my_method")
147
+ expect(frame.class_name).to eq(nil)
148
148
  end
149
149
  end
150
150
 
@@ -3,38 +3,38 @@ require "spec_helper"
3
3
  describe BetterErrors do
4
4
  context ".editor" do
5
5
  it "defaults to textmate" do
6
- subject.editor["foo.rb", 123].should == "txmt://open?url=file://foo.rb&line=123"
6
+ expect(subject.editor["foo.rb", 123]).to eq("txmt://open?url=file://foo.rb&line=123")
7
7
  end
8
8
 
9
9
  it "url escapes the filename" do
10
- subject.editor["&.rb", 0].should == "txmt://open?url=file://%26.rb&line=0"
10
+ expect(subject.editor["&.rb", 0]).to eq("txmt://open?url=file://%26.rb&line=0")
11
11
  end
12
12
 
13
13
  [:emacs, :emacsclient].each do |editor|
14
14
  it "uses emacs:// scheme when set to #{editor.inspect}" do
15
15
  subject.editor = editor
16
- subject.editor[].should start_with "emacs://"
16
+ expect(subject.editor[]).to start_with "emacs://"
17
17
  end
18
18
  end
19
19
 
20
20
  [:macvim, :mvim].each do |editor|
21
21
  it "uses mvim:// scheme when set to #{editor.inspect}" do
22
22
  subject.editor = editor
23
- subject.editor[].should start_with "mvim://"
23
+ expect(subject.editor[]).to start_with "mvim://"
24
24
  end
25
25
  end
26
26
 
27
27
  [:sublime, :subl, :st].each do |editor|
28
28
  it "uses subl:// scheme when set to #{editor.inspect}" do
29
29
  subject.editor = editor
30
- subject.editor[].should start_with "subl://"
30
+ expect(subject.editor[]).to start_with "subl://"
31
31
  end
32
32
  end
33
33
 
34
34
  [:textmate, :txmt, :tm].each do |editor|
35
35
  it "uses txmt:// scheme when set to #{editor.inspect}" do
36
36
  subject.editor = editor
37
- subject.editor[].should start_with "txmt://"
37
+ expect(subject.editor[]).to start_with "txmt://"
38
38
  end
39
39
  end
40
40
 
@@ -42,7 +42,7 @@ describe BetterErrors do
42
42
  it "uses emacs:// scheme when EDITOR=#{editor}" do
43
43
  ENV["EDITOR"] = editor
44
44
  subject.editor = subject.default_editor
45
- subject.editor[].should start_with "emacs://"
45
+ expect(subject.editor[]).to start_with "emacs://"
46
46
  end
47
47
  end
48
48
 
@@ -50,15 +50,15 @@ describe BetterErrors do
50
50
  it "uses mvim:// scheme when EDITOR=#{editor}" do
51
51
  ENV["EDITOR"] = editor
52
52
  subject.editor = subject.default_editor
53
- subject.editor[].should start_with "mvim://"
53
+ expect(subject.editor[]).to start_with "mvim://"
54
54
  end
55
55
  end
56
56
 
57
57
  ["subl -w", "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl"].each do |editor|
58
- it "uses mvim:// scheme when EDITOR=#{editor}" do
58
+ it "uses subl:// scheme when EDITOR=#{editor}" do
59
59
  ENV["EDITOR"] = editor
60
60
  subject.editor = subject.default_editor
61
- subject.editor[].should start_with "subl://"
61
+ expect(subject.editor[]).to start_with "subl://"
62
62
  end
63
63
  end
64
64
 
@@ -66,7 +66,7 @@ describe BetterErrors do
66
66
  it "uses txmt:// scheme when EDITOR=#{editor}" do
67
67
  ENV["EDITOR"] = editor
68
68
  subject.editor = subject.default_editor
69
- subject.editor[].should start_with "txmt://"
69
+ expect(subject.editor[]).to start_with "txmt://"
70
70
  end
71
71
  end
72
72
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_errors
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charlie Somerville
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-09 00:00:00.000000000 Z
11
+ date: 2017-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: erubis
@@ -70,6 +70,15 @@ files:
70
70
  - README.md
71
71
  - Rakefile
72
72
  - better_errors.gemspec
73
+ - feature-screenshots/1-application-error.jpg
74
+ - feature-screenshots/2-other-application-frame.jpg
75
+ - feature-screenshots/3-live-shell.jpg
76
+ - feature-screenshots/4-other-frames.jpg
77
+ - feature-screenshots/5-open-editor.jpg
78
+ - feature-screenshots/6-local-variables.jpg
79
+ - feature-screenshots/7-non-html-requests.jpg
80
+ - feature-screenshots/8-xhr-shows-text-error.jpg
81
+ - feature-screenshots/9-xhr-error-in-manual-console.jpg
73
82
  - lib/better_errors.rb
74
83
  - lib/better_errors/code_formatter.rb
75
84
  - lib/better_errors/code_formatter/html.rb
@@ -119,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
128
  version: '0'
120
129
  requirements: []
121
130
  rubyforge_project:
122
- rubygems_version: 2.2.2
131
+ rubygems_version: 2.6.8
123
132
  signing_key:
124
133
  specification_version: 4
125
134
  summary: Better error page for Rails and other Rack apps