airbrake-ruby 2.2.3 → 2.2.4

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.
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Airbrake::Filters::RootDirectoryFilter do
4
+ subject { described_class.new(root_directory) }
5
+
6
+ let(:root_directory) { '/var/www/project' }
7
+
8
+ let(:notice) do
9
+ Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
10
+ end
11
+
12
+ it "replaces root directory in the backtrace with a label" do
13
+ # rubocop:disable Metrics/LineLength
14
+ notice[:errors].first[:backtrace] = [
15
+ { file: "/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb" },
16
+ { file: "#{root_directory}/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb " },
17
+ { file: "/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb" },
18
+ { file: "#{root_directory}/gems/rspec-core-3.3.2/exe/rspec" }
19
+ ]
20
+ # rubocop:enable Metrics/LineLength
21
+
22
+ subject.call(notice)
23
+
24
+ # rubocop:disable Metrics/LineLength
25
+ expect(notice[:errors].first[:backtrace]).to(
26
+ eq(
27
+ [
28
+ { file: "/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb" },
29
+ { file: "[PROJECT_ROOT]/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb " },
30
+ { file: "/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb" },
31
+ { file: "[PROJECT_ROOT]/gems/rspec-core-3.3.2/exe/rspec" }
32
+ ]
33
+ )
34
+ )
35
+ # rubocop:enable Metrics/LineLength
36
+ end
37
+
38
+ it "does not filter file when it is nil" do
39
+ expect(notice[:errors].first[:file]).to be_nil
40
+ expect { subject.call(notice) }.not_to(
41
+ change { notice[:errors].first[:file] }
42
+ )
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Airbrake::Filters::SystemExitFilter do
4
+ it "marks SystemExit exceptions as ignored" do
5
+ notice = Airbrake::Notice.new(Airbrake::Config.new, SystemExit.new)
6
+ expect { subject.call(notice) }.to(
7
+ change { notice.ignored? }.from(false).to(true)
8
+ )
9
+ end
10
+
11
+ it "doesn't mark non SystemExit exceptions as ignored" do
12
+ notice = Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
13
+ expect(notice).not_to be_ignored
14
+ expect { subject.call(notice) }.not_to(change { notice.ignored? })
15
+ end
16
+ end
@@ -16,38 +16,214 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
16
16
  end.join
17
17
  end
18
18
 
19
- shared_examples "fiber variable ignore" do |key|
20
- it "ignores the :#{key} fiber variable" do
21
- new_thread do |th|
22
- th[key] = :bingo
23
- subject.call(notice)
19
+ describe "thread variables" do
20
+ shared_examples "expected thread variable" do |var|
21
+ it "attaches the thread variable" do
22
+ new_thread do |th|
23
+ th.thread_variable_set(:bingo, var)
24
+ subject.call(notice)
25
+ end
26
+
27
+ expect(notice[:params][:thread][:thread_variables][:bingo]).to eq(var)
24
28
  end
29
+ end
25
30
 
26
- fiber_variables = notice[:params][:thread][:fiber_variables]
27
- expect(fiber_variables[key]).to be_nil
31
+ context "given nil" do
32
+ include_examples "expected thread variable", nil
28
33
  end
29
- end
30
34
 
31
- %i[__recursive_key__ __rspec].each do |key|
32
- include_examples "fiber variable ignore", key
33
- end
35
+ context "given true" do
36
+ include_examples "expected thread variable", true
37
+ end
34
38
 
35
- it "appends thread variables" do
36
- new_thread do |th|
37
- th.thread_variable_set(:bingo, :bango)
38
- subject.call(notice)
39
+ context "given false" do
40
+ include_examples "expected thread variable", false
41
+ end
42
+
43
+ context "given a String" do
44
+ include_examples "expected thread variable", 'bango'
45
+ end
46
+
47
+ context "given a Symbol" do
48
+ include_examples "expected thread variable", :bango
49
+ end
50
+
51
+ context "given a Regexp" do
52
+ include_examples "expected thread variable", /bango/
53
+ end
54
+
55
+ context "given an Integer" do
56
+ include_examples "expected thread variable", 1
57
+ end
58
+
59
+ context "given a Float" do
60
+ include_examples "expected thread variable", 1.01
39
61
  end
40
62
 
41
- expect(notice[:params][:thread][:thread_variables][:bingo]).to eq(:bango)
63
+ context "given an Object" do
64
+ it "converts it to a String and attaches" do
65
+ new_thread do |th|
66
+ th.thread_variable_set(:bingo, Object.new)
67
+ subject.call(notice)
68
+ end
69
+
70
+ vars = notice[:params][:thread][:thread_variables]
71
+ expect(vars[:bingo]).to match(/\A#<Object:.+>\z/)
72
+ end
73
+ end
74
+
75
+ context "given an Array of nested Hashes with complex objects" do
76
+ let(:var) do
77
+ [
78
+ {
79
+ bango: {
80
+ bongo: [
81
+ {
82
+ bish: {
83
+ bash: 'foo',
84
+ bosh: Object.new
85
+ }
86
+ }
87
+ ]
88
+ }
89
+ },
90
+ 123
91
+ ]
92
+ end
93
+
94
+ it "converts objects to a safe objects" do
95
+ new_thread do |th|
96
+ th.thread_variable_set(:bingo, var)
97
+ subject.call(notice)
98
+ end
99
+
100
+ vars = notice[:params][:thread][:thread_variables]
101
+ expect(vars[:bingo]).to(
102
+ match(
103
+ [
104
+ {
105
+ bango: {
106
+ bongo: [
107
+ {
108
+ bish: {
109
+ bash: 'foo',
110
+ bosh: /\A#<Object:.+>\z/
111
+ }
112
+ }
113
+ ]
114
+ }
115
+ },
116
+ 123
117
+ ]
118
+ )
119
+ )
120
+ end
121
+ end
42
122
  end
43
123
 
44
- it "appends fiber variables" do
45
- new_thread do |th|
46
- th[:bingo] = :bango
47
- subject.call(notice)
124
+ describe "fiber variables" do
125
+ shared_examples "expected fiber variable" do |var|
126
+ it "attaches the fiber variable" do
127
+ new_thread do |th|
128
+ th[:bingo] = var
129
+ subject.call(notice)
130
+ end
131
+
132
+ expect(notice[:params][:thread][:fiber_variables][:bingo]).to eq(var)
133
+ end
134
+ end
135
+
136
+ context "given nil" do
137
+ include_examples "expected fiber variable", nil
138
+ end
139
+
140
+ context "given true" do
141
+ include_examples "expected fiber variable", true
48
142
  end
49
143
 
50
- expect(notice[:params][:thread][:fiber_variables][:bingo]).to eq(:bango)
144
+ context "given false" do
145
+ include_examples "expected fiber variable", false
146
+ end
147
+
148
+ context "given a String" do
149
+ include_examples "expected fiber variable", 'bango'
150
+ end
151
+
152
+ context "given a Symbol" do
153
+ include_examples "expected fiber variable", :bango
154
+ end
155
+
156
+ context "given a Regexp" do
157
+ include_examples "expected fiber variable", /bango/
158
+ end
159
+
160
+ context "given an Integer" do
161
+ include_examples "expected fiber variable", 1
162
+ end
163
+
164
+ context "given a Float" do
165
+ include_examples "expected fiber variable", 1.01
166
+ end
167
+
168
+ context "given an Object" do
169
+ it "converts it to a String and attaches" do
170
+ new_thread do |th|
171
+ th[:bingo] = Object.new
172
+ subject.call(notice)
173
+ end
174
+
175
+ vars = notice[:params][:thread][:fiber_variables]
176
+ expect(vars[:bingo]).to match(/\A#<Object:.+>\z/)
177
+ end
178
+ end
179
+
180
+ context "given an Array of nested Hashes with complex objects" do
181
+ let(:var) do
182
+ [
183
+ {
184
+ bango: {
185
+ bongo: [
186
+ {
187
+ bish: {
188
+ bash: 'foo',
189
+ bosh: Object.new
190
+ }
191
+ }
192
+ ]
193
+ }
194
+ },
195
+ 123
196
+ ]
197
+ end
198
+
199
+ it "converts objects to a safe objects" do
200
+ new_thread do |th|
201
+ th[:bingo] = var
202
+ subject.call(notice)
203
+ end
204
+
205
+ vars = notice[:params][:thread][:fiber_variables]
206
+ expect(vars[:bingo]).to(
207
+ match(
208
+ [
209
+ {
210
+ bango: {
211
+ bongo: [
212
+ {
213
+ bish: {
214
+ bash: 'foo',
215
+ bosh: /\A#<Object:.+>\z/
216
+ }
217
+ }
218
+ ]
219
+ }
220
+ },
221
+ 123
222
+ ]
223
+ )
224
+ )
225
+ end
226
+ end
51
227
  end
52
228
 
53
229
  it "appends name", skip: !Thread.current.respond_to?(:name) do
@@ -78,34 +254,4 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
78
254
  subject.call(notice)
79
255
  expect(notice[:params][:thread][:safe_level]).to eq(0)
80
256
  end
81
-
82
- context "when an IO-like object is stored" do
83
- let(:io_obj) do
84
- Class.new(IO) do
85
- def initialize; end
86
- end.new
87
- end
88
-
89
- before do
90
- expect(io_obj).to be_is_a(IO)
91
- end
92
-
93
- it "doesn't append the IO object to thread variables" do
94
- new_thread do |th|
95
- th.thread_variable_set(:io, io_obj)
96
- subject.call(notice)
97
- end
98
-
99
- expect(notice[:params][:thread][:thread_variables]).to be_nil
100
- end
101
-
102
- it "doesn't append the IO object to thread variables" do
103
- new_thread do |th|
104
- th[:io] = io_obj
105
- subject.call(notice)
106
- end
107
-
108
- expect(notice[:params][:thread][:fiber_variables][:io]).to be_nil
109
- end
110
- end
111
257
  end
data/spec/notice_spec.rb CHANGED
@@ -136,7 +136,7 @@ RSpec.describe Airbrake::Notice do
136
136
 
137
137
  context "when truncation failed" do
138
138
  it "returns nil" do
139
- expect_any_instance_of(Airbrake::PayloadTruncator).
139
+ expect_any_instance_of(Airbrake::Truncator).
140
140
  to receive(:reduce_max_size).and_return(0)
141
141
 
142
142
  encoded = Base64.encode64("\xD3\xE6\xBC\x9D\xBA").encode!('ASCII-8BIT')
@@ -29,7 +29,7 @@ RSpec.describe Airbrake::SyncSender do
29
29
 
30
30
  context "when request body is nil" do
31
31
  it "doesn't send a notice" do
32
- expect_any_instance_of(Airbrake::PayloadTruncator).
32
+ expect_any_instance_of(Airbrake::Truncator).
33
33
  to receive(:reduce_max_size).and_return(0)
34
34
 
35
35
  encoded = Base64.encode64("\xD3\xE6\xBC\x9D\xBA").encode!('ASCII-8BIT')
@@ -2,32 +2,28 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Airbrake::PayloadTruncator do
5
+ RSpec.describe Airbrake::Truncator do
6
6
  let(:max_size) { 1000 }
7
7
  let(:truncated_len) { '[Truncated]'.length }
8
8
  let(:max_len) { max_size + truncated_len }
9
9
 
10
10
  before do
11
- @truncator = described_class.new(max_size, Logger.new('/dev/null'))
11
+ @truncator = described_class.new(max_size)
12
12
  end
13
13
 
14
- describe "#truncate_error" do
15
- let(:error) do
16
- { type: 'AirbrakeTestError', message: 'App crashed!', backtrace: [] }
17
- end
18
-
19
- before do
20
- @stdout = StringIO.new
21
- end
22
-
14
+ describe "#truncate_object" do
23
15
  describe "error backtrace" do
16
+ let(:error) do
17
+ { type: 'AirbrakeTestError', message: 'App crashed!', backtrace: [] }
18
+ end
19
+
24
20
  before do
25
21
  backtrace = Array.new(size) do
26
22
  { file: 'foo.rb', line: 23, function: '<main>' }
27
23
  end
28
24
 
29
25
  @error = error.merge(backtrace: backtrace)
30
- described_class.new(max_size, Logger.new(@stdout)).truncate_error(@error)
26
+ described_class.new(max_size).truncate_object(@error)
31
27
  end
32
28
 
33
29
  context "when long" do
@@ -36,11 +32,6 @@ RSpec.describe Airbrake::PayloadTruncator do
36
32
  it "truncates the backtrace to the max size" do
37
33
  expect(@error[:backtrace].size).to eq(1000)
38
34
  end
39
-
40
- it "logs the about the number of truncated frames" do
41
- expect(@stdout.string).
42
- to match(/INFO -- .+ dropped 1003 frame\(s\) from AirbrakeTestError/)
43
- end
44
35
  end
45
36
 
46
37
  context "when short" do
@@ -49,17 +40,17 @@ RSpec.describe Airbrake::PayloadTruncator do
49
40
  it "does not truncate the backtrace" do
50
41
  expect(@error[:backtrace].size).to eq(size)
51
42
  end
52
-
53
- it "doesn't log anything" do
54
- expect(@stdout.string).to be_empty
55
- end
56
43
  end
57
44
  end
58
45
 
59
46
  describe "error message" do
47
+ let(:error) do
48
+ { type: 'AirbrakeTestError', message: 'App crashed!', backtrace: [] }
49
+ end
50
+
60
51
  before do
61
52
  @error = error.merge(message: message)
62
- described_class.new(max_size, Logger.new(@stdout)).truncate_error(@error)
53
+ described_class.new(max_size).truncate_object(@error)
63
54
  end
64
55
 
65
56
  context "when long" do
@@ -68,11 +59,6 @@ RSpec.describe Airbrake::PayloadTruncator do
68
59
  it "truncates the message" do
69
60
  expect(@error[:message].length).to eq(max_len)
70
61
  end
71
-
72
- it "logs about the truncated string" do
73
- expect(@stdout.string).
74
- to match(/INFO -- .+ truncated the message of AirbrakeTestError/)
75
- end
76
62
  end
77
63
 
78
64
  context "when short" do
@@ -82,15 +68,9 @@ RSpec.describe Airbrake::PayloadTruncator do
82
68
  it "doesn't truncate the message" do
83
69
  expect(@error[:message].length).to eq(msg_len)
84
70
  end
85
-
86
- it "doesn't log about the truncated string" do
87
- expect(@stdout.string).to be_empty
88
- end
89
71
  end
90
72
  end
91
- end
92
73
 
93
- describe "#truncate_object" do
94
74
  describe "given a hash with short values" do
95
75
  let(:params) do
96
76
  { bingo: 'bango', bongo: 'bish', bash: 'bosh' }
@@ -270,7 +250,7 @@ RSpec.describe Airbrake::PayloadTruncator do
270
250
 
271
251
  context "with strings that equal to max_size" do
272
252
  before do
273
- @truncator = described_class.new(max_size, Logger.new('/dev/null'))
253
+ @truncator = described_class.new(max_size)
274
254
  end
275
255
 
276
256
  let(:params) { { unicode: '1111' } }
@@ -399,7 +379,7 @@ RSpec.describe Airbrake::PayloadTruncator do
399
379
 
400
380
  describe "unicode payload" do
401
381
  before do
402
- @truncator = described_class.new(max_size - 1, Logger.new('/dev/null'))
382
+ @truncator = described_class.new(max_size - 1)
403
383
  end
404
384
 
405
385
  describe "truncation" do