airbrake-ruby 5.2.0-java → 5.2.1-java

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +3 -2
  3. data/lib/airbrake-ruby/async_sender.rb +3 -1
  4. data/lib/airbrake-ruby/context.rb +51 -0
  5. data/lib/airbrake-ruby/filter_chain.rb +2 -0
  6. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  7. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  8. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
  9. data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
  10. data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
  11. data/lib/airbrake-ruby/filters/sql_filter.rb +2 -2
  12. data/lib/airbrake-ruby/filters/thread_filter.rb +1 -1
  13. data/lib/airbrake-ruby/ignorable.rb +0 -2
  14. data/lib/airbrake-ruby/notice_notifier.rb +3 -4
  15. data/lib/airbrake-ruby/performance_notifier.rb +1 -2
  16. data/lib/airbrake-ruby/remote_settings/settings_data.rb +1 -1
  17. data/lib/airbrake-ruby/tdigest.rb +7 -6
  18. data/lib/airbrake-ruby/thread_pool.rb +5 -3
  19. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  20. data/lib/airbrake-ruby/version.rb +1 -1
  21. data/spec/airbrake_spec.rb +139 -76
  22. data/spec/async_sender_spec.rb +10 -8
  23. data/spec/backtrace_spec.rb +13 -10
  24. data/spec/benchmark_spec.rb +5 -3
  25. data/spec/code_hunk_spec.rb +24 -15
  26. data/spec/config/processor_spec.rb +12 -4
  27. data/spec/config/validator_spec.rb +5 -2
  28. data/spec/config_spec.rb +24 -16
  29. data/spec/context_spec.rb +54 -0
  30. data/spec/deploy_notifier_spec.rb +6 -4
  31. data/spec/file_cache_spec.rb +1 -0
  32. data/spec/filter_chain_spec.rb +29 -24
  33. data/spec/filters/context_filter_spec.rb +14 -5
  34. data/spec/filters/dependency_filter_spec.rb +3 -1
  35. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  36. data/spec/filters/gem_root_filter_spec.rb +5 -2
  37. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  38. data/spec/filters/git_repository_filter.rb +9 -9
  39. data/spec/filters/git_revision_filter_spec.rb +19 -19
  40. data/spec/filters/keys_allowlist_spec.rb +25 -16
  41. data/spec/filters/keys_blocklist_spec.rb +25 -18
  42. data/spec/filters/root_directory_filter_spec.rb +3 -3
  43. data/spec/filters/sql_filter_spec.rb +26 -26
  44. data/spec/filters/system_exit_filter_spec.rb +4 -2
  45. data/spec/filters/thread_filter_spec.rb +15 -13
  46. data/spec/loggable_spec.rb +2 -2
  47. data/spec/monotonic_time_spec.rb +8 -6
  48. data/spec/nested_exception_spec.rb +46 -46
  49. data/spec/notice_notifier/options_spec.rb +23 -13
  50. data/spec/notice_notifier_spec.rb +52 -47
  51. data/spec/notice_spec.rb +6 -2
  52. data/spec/performance_notifier_spec.rb +67 -60
  53. data/spec/promise_spec.rb +38 -32
  54. data/spec/remote_settings/callback_spec.rb +27 -8
  55. data/spec/remote_settings/settings_data_spec.rb +4 -4
  56. data/spec/remote_settings_spec.rb +18 -8
  57. data/spec/response_spec.rb +34 -12
  58. data/spec/stashable_spec.rb +5 -5
  59. data/spec/stat_spec.rb +7 -5
  60. data/spec/sync_sender_spec.rb +49 -16
  61. data/spec/tdigest_spec.rb +60 -55
  62. data/spec/thread_pool_spec.rb +65 -55
  63. data/spec/time_truncate_spec.rb +4 -2
  64. data/spec/timed_trace_spec.rb +32 -30
  65. data/spec/truncator_spec.rb +72 -43
  66. metadata +51 -48
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::Filters::ThreadFilter do
2
+ subject(:thread_filter) { described_class.new }
3
+
2
4
  let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
3
5
 
4
6
  def new_thread
@@ -17,7 +19,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
17
19
  it "attaches the thread variable" do
18
20
  new_thread do |th|
19
21
  th.thread_variable_set(:bingo, var)
20
- subject.call(notice)
22
+ thread_filter.call(notice)
21
23
  end
22
24
 
23
25
  expect(notice[:params][:thread][:thread_variables][:bingo]).to eq(var)
@@ -60,7 +62,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
60
62
  it "converts it to a String and attaches" do
61
63
  new_thread do |th|
62
64
  th.thread_variable_set(:bingo, Object.new)
63
- subject.call(notice)
65
+ thread_filter.call(notice)
64
66
  end
65
67
 
66
68
  vars = notice[:params][:thread][:thread_variables]
@@ -90,7 +92,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
90
92
  it "converts objects to a safe objects" do
91
93
  new_thread do |th|
92
94
  th.thread_variable_set(:bingo, var)
93
- subject.call(notice)
95
+ thread_filter.call(notice)
94
96
  end
95
97
 
96
98
  vars = notice[:params][:thread][:thread_variables]
@@ -121,7 +123,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
121
123
 
122
124
  new_thread do |th|
123
125
  th.thread_variable_set(var, :bingo)
124
- subject.call(notice)
126
+ thread_filter.call(notice)
125
127
  end
126
128
 
127
129
  thread_variables = notice[:params][:thread][:thread_variables]
@@ -134,7 +136,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
134
136
  it "attaches the fiber variable" do
135
137
  new_thread do |th|
136
138
  th[:bingo] = var
137
- subject.call(notice)
139
+ thread_filter.call(notice)
138
140
  end
139
141
 
140
142
  expect(notice[:params][:thread][:fiber_variables][:bingo]).to eq(var)
@@ -177,7 +179,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
177
179
  it "converts it to a String and attaches" do
178
180
  new_thread do |th|
179
181
  th[:bingo] = Object.new
180
- subject.call(notice)
182
+ thread_filter.call(notice)
181
183
  end
182
184
 
183
185
  vars = notice[:params][:thread][:fiber_variables]
@@ -207,7 +209,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
207
209
  it "converts objects to a safe objects" do
208
210
  new_thread do |th|
209
211
  th[:bingo] = var
210
- subject.call(notice)
212
+ thread_filter.call(notice)
211
213
  end
212
214
 
213
215
  vars = notice[:params][:thread][:fiber_variables]
@@ -237,31 +239,31 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
237
239
  it "appends name" do
238
240
  new_thread do |th|
239
241
  th.name = 'bingo'
240
- subject.call(notice)
242
+ thread_filter.call(notice)
241
243
  end
242
244
 
243
245
  expect(notice[:params][:thread][:name]).to eq('bingo')
244
246
  end
245
247
 
246
248
  it "appends thread inspect (self)" do
247
- subject.call(notice)
249
+ thread_filter.call(notice)
248
250
  expect(notice[:params][:thread][:self]).to match(/\A#<Thread:.+>\z/)
249
251
  end
250
252
 
251
253
  it "appends thread group" do
252
- subject.call(notice)
254
+ thread_filter.call(notice)
253
255
  expect(notice[:params][:thread][:group][0]).to match(/\A#<Thread:.+>\z/)
254
256
  end
255
257
 
256
258
  it "appends priority" do
257
- subject.call(notice)
259
+ thread_filter.call(notice)
258
260
  expect(notice[:params][:thread][:priority]).to eq(0)
259
261
  end
260
262
 
261
263
  it "appends safe_level", skip: (
262
264
  "Not supported on this version of Ruby." unless Airbrake::HAS_SAFE_LEVEL
263
265
  ) do
264
- subject.call(notice)
266
+ thread_filter.call(notice)
265
267
  expect(notice[:params][:thread][:safe_level]).to eq(0)
266
268
  end
267
269
 
@@ -270,7 +272,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
270
272
 
271
273
  new_thread do |th|
272
274
  th[key] = :bingo
273
- subject.call(notice)
275
+ thread_filter.call(notice)
274
276
  end
275
277
 
276
278
  fiber_variables = notice[:params][:thread][:fiber_variables]
@@ -6,12 +6,12 @@ RSpec.describe Airbrake::Loggable do
6
6
  end
7
7
 
8
8
  describe "#logger" do
9
- let(:subject) do
9
+ subject(:class_with_logger) do
10
10
  Class.new { include Airbrake::Loggable }.new
11
11
  end
12
12
 
13
13
  it "returns a logger that has Logger::WARN severity" do
14
- expect(subject.logger.level).to eq(Logger::WARN)
14
+ expect(class_with_logger.logger.level).to eq(Logger::WARN)
15
15
  end
16
16
  end
17
17
  end
@@ -1,23 +1,25 @@
1
1
  RSpec.describe Airbrake::MonotonicTime do
2
+ subject(:monotonic_time) { described_class }
3
+
2
4
  describe ".time_in_ms" do
3
5
  it "returns monotonic time in milliseconds" do
4
- expect(subject.time_in_ms).to be_a(Float)
6
+ expect(monotonic_time.time_in_ms).to be_a(Float)
5
7
  end
6
8
 
7
9
  it "always returns time in the future" do
8
- old_time = subject.time_in_ms
9
- expect(subject.time_in_ms).to be > old_time
10
+ old_time = monotonic_time.time_in_ms
11
+ expect(monotonic_time.time_in_ms).to be > old_time
10
12
  end
11
13
  end
12
14
 
13
15
  describe ".time_in_s" do
14
16
  it "returns monotonic time in seconds" do
15
- expect(subject.time_in_s).to be_a(Float)
17
+ expect(monotonic_time.time_in_s).to be_a(Float)
16
18
  end
17
19
 
18
20
  it "always returns time in the future" do
19
- old_time = subject.time_in_s
20
- expect(subject.time_in_s).to be > old_time
21
+ old_time = monotonic_time.time_in_s
22
+ expect(monotonic_time.time_in_s).to be > old_time
21
23
  end
22
24
  end
23
25
  end
@@ -1,73 +1,73 @@
1
1
  RSpec.describe Airbrake::NestedException do
2
2
  describe "#as_json" do
3
3
  context "given exceptions with backtraces" do
4
+ # rubocop:disable RSpec/MultipleExpectations
4
5
  it "unwinds nested exceptions" do
5
6
  begin
6
- begin
7
- raise AirbrakeTestError
8
- rescue AirbrakeTestError
9
- Ruby21Error.raise_error('bingo')
10
- end
11
- rescue Ruby21Error => ex
12
- nested_exception = described_class.new(ex)
13
- exceptions = nested_exception.as_json
14
-
15
- expect(exceptions.size).to eq(2)
16
- expect(exceptions[0][:message]).to eq('bingo')
17
- expect(exceptions[1][:message]).to eq('App crashed!')
18
- expect(exceptions[0][:backtrace]).not_to be_empty
19
- expect(exceptions[1][:backtrace]).not_to be_empty
7
+ raise AirbrakeTestError
8
+ rescue AirbrakeTestError
9
+ Ruby21Error.raise_error('bingo')
20
10
  end
11
+ rescue Ruby21Error => ex
12
+ nested_exception = described_class.new(ex)
13
+ exceptions = nested_exception.as_json
14
+
15
+ expect(exceptions.size).to eq(2)
16
+ expect(exceptions[0][:message]).to eq('bingo')
17
+ expect(exceptions[1][:message]).to eq('App crashed!')
18
+ expect(exceptions[0][:backtrace]).not_to be_empty
19
+ expect(exceptions[1][:backtrace]).not_to be_empty
21
20
  end
21
+ # rubocop:enable RSpec/MultipleExpectations
22
22
 
23
+ # rubocop:disable RSpec/MultipleExpectations
23
24
  it "unwinds no more than 3 nested exceptions" do
24
25
  begin
26
+ raise AirbrakeTestError
27
+ rescue AirbrakeTestError
25
28
  begin
26
- raise AirbrakeTestError
27
- rescue AirbrakeTestError
29
+ Ruby21Error.raise_error('bongo')
30
+ rescue Ruby21Error
28
31
  begin
29
- Ruby21Error.raise_error('bongo')
32
+ Ruby21Error.raise_error('bango')
30
33
  rescue Ruby21Error
31
- begin
32
- Ruby21Error.raise_error('bango')
33
- rescue Ruby21Error
34
- Ruby21Error.raise_error('bingo')
35
- end
34
+ Ruby21Error.raise_error('bingo')
36
35
  end
37
36
  end
38
- rescue Ruby21Error => ex
39
- nested_exception = described_class.new(ex)
40
- exceptions = nested_exception.as_json
41
-
42
- expect(exceptions.size).to eq(3)
43
- expect(exceptions[0][:message]).to eq('bingo')
44
- expect(exceptions[1][:message]).to eq('bango')
45
- expect(exceptions[2][:message]).to eq('bongo')
46
- expect(exceptions[0][:backtrace]).not_to be_empty
47
- expect(exceptions[1][:backtrace]).not_to be_empty
48
37
  end
38
+ rescue Ruby21Error => ex
39
+ nested_exception = described_class.new(ex)
40
+ exceptions = nested_exception.as_json
41
+
42
+ expect(exceptions.size).to eq(3)
43
+ expect(exceptions[0][:message]).to eq('bingo')
44
+ expect(exceptions[1][:message]).to eq('bango')
45
+ expect(exceptions[2][:message]).to eq('bongo')
46
+ expect(exceptions[0][:backtrace]).not_to be_empty
47
+ expect(exceptions[1][:backtrace]).not_to be_empty
49
48
  end
49
+ # rubocop:enable RSpec/MultipleExpectations
50
50
  end
51
51
 
52
52
  context "given exceptions without backtraces" do
53
+ # rubocop:disable RSpec/MultipleExpectations
53
54
  it "sets backtrace to nil" do
54
55
  begin
55
- begin
56
- raise AirbrakeTestError
57
- rescue AirbrakeTestError => ex2
58
- ex2.set_backtrace([])
59
- Ruby21Error.raise_error('bingo')
60
- end
61
- rescue Ruby21Error => ex1
62
- ex1.set_backtrace([])
63
- nested_exception = described_class.new(ex1)
64
- exceptions = nested_exception.as_json
65
-
66
- expect(exceptions.size).to eq(2)
67
- expect(exceptions[0][:backtrace]).to be_empty
68
- expect(exceptions[1][:backtrace]).to be_empty
56
+ raise AirbrakeTestError
57
+ rescue AirbrakeTestError => ex2
58
+ ex2.set_backtrace([])
59
+ Ruby21Error.raise_error('bingo')
69
60
  end
61
+ rescue Ruby21Error => ex1
62
+ ex1.set_backtrace([])
63
+ nested_exception = described_class.new(ex1)
64
+ exceptions = nested_exception.as_json
65
+
66
+ expect(exceptions.size).to eq(2)
67
+ expect(exceptions[0][:backtrace]).to be_empty
68
+ expect(exceptions[1][:backtrace]).to be_empty
70
69
  end
70
+ # rubocop:enable RSpec/MultipleExpectations
71
71
  end
72
72
  end
73
73
  end
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::NoticeNotifier do
2
+ subject(:notice_notifier) { described_class.new }
3
+
2
4
  let(:project_id) { 105138 }
3
5
  let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
4
6
  let(:localhost) { 'http://localhost:8080' }
@@ -27,7 +29,7 @@ RSpec.describe Airbrake::NoticeNotifier do
27
29
 
28
30
  example(title) do
29
31
  stub_request(:post, endpoint).to_return(status: 201, body: '{}')
30
- subject.notify_sync(ex)
32
+ notice_notifier.notify_sync(ex)
31
33
 
32
34
  expect(a_request(:post, endpoint)).to have_been_made.once
33
35
  end
@@ -35,7 +37,7 @@ RSpec.describe Airbrake::NoticeNotifier do
35
37
 
36
38
  path = '/api/v3/projects/105138/notices'
37
39
 
38
- context "given a full host" do
40
+ context "given a full host with port" do
39
41
  include_examples('endpoint', localhost = 'http://localhost:8080',
40
42
  URI.join(localhost, path),
41
43
  "sends notices to the specified host's endpoint")
@@ -63,13 +65,13 @@ RSpec.describe Airbrake::NoticeNotifier do
63
65
 
64
66
  describe ":root_directory" do
65
67
  before do
66
- subject.add_filter(
68
+ notice_notifier.add_filter(
67
69
  Airbrake::Filters::RootDirectoryFilter.new('/home/kyrylo/code'),
68
70
  )
69
71
  end
70
72
 
71
73
  it "filters out frames" do
72
- subject.notify_sync(ex)
74
+ notice_notifier.notify_sync(ex)
73
75
 
74
76
  expect(
75
77
  a_request(:post, endpoint)
@@ -82,7 +84,7 @@ RSpec.describe Airbrake::NoticeNotifier do
82
84
  before { Airbrake::Config.instance.merge(root_directory: dir) }
83
85
 
84
86
  it "being included into the notice's payload" do
85
- subject.notify_sync(ex)
87
+ notice_notifier.notify_sync(ex)
86
88
  expect(
87
89
  a_request(:post, endpoint)
88
90
  .with(body: %r{"rootDirectory":"/bingo/bango"}),
@@ -100,6 +102,7 @@ RSpec.describe Airbrake::NoticeNotifier do
100
102
  end
101
103
  end
102
104
 
105
+ # rubocop:disable RSpec/MultipleMemoizedHelpers
103
106
  describe ":proxy" do
104
107
  let(:proxy) do
105
108
  WEBrick::HTTPServer.new(
@@ -142,7 +145,7 @@ RSpec.describe Airbrake::NoticeNotifier do
142
145
  "safe to run this test on 2.6+ once we upgrade to Webmock 3.5+",
143
146
  )
144
147
  end
145
- subject.notify_sync(ex)
148
+ notice_notifier.notify_sync(ex)
146
149
 
147
150
  proxied_request = requests.pop(true)
148
151
 
@@ -155,13 +158,14 @@ RSpec.describe Airbrake::NoticeNotifier do
155
158
  # rubocop:enable Layout/LineLength
156
159
  end
157
160
  end
161
+ # rubocop:enable RSpec/MultipleMemoizedHelpers
158
162
 
159
163
  describe ":environment" do
160
164
  context "when present" do
161
165
  before { Airbrake::Config.instance.merge(environment: :production) }
162
166
 
163
167
  it "being included into the notice's payload" do
164
- subject.notify_sync(ex)
168
+ notice_notifier.notify_sync(ex)
165
169
  expect(
166
170
  a_request(:post, endpoint)
167
171
  .with(body: /"context":{.*"environment":"production".*}/),
@@ -175,7 +179,7 @@ RSpec.describe Airbrake::NoticeNotifier do
175
179
  before { Airbrake::Config.instance.merge(params) }
176
180
 
177
181
  it "sends a notice" do
178
- subject.notify_sync(ex)
182
+ notice_notifier.notify_sync(ex)
179
183
  expect(a_request(:post, endpoint)).to have_been_made
180
184
  end
181
185
  end
@@ -184,7 +188,7 @@ RSpec.describe Airbrake::NoticeNotifier do
184
188
  before { Airbrake::Config.instance.merge(params) }
185
189
 
186
190
  it "ignores exceptions occurring in envs that were not configured" do
187
- subject.notify_sync(ex)
191
+ notice_notifier.notify_sync(ex)
188
192
  expect(a_request(:post, endpoint)).not_to have_been_made
189
193
  end
190
194
  end
@@ -207,9 +211,15 @@ RSpec.describe Airbrake::NoticeNotifier do
207
211
  include_examples 'ignored notice', params
208
212
 
209
213
  it "returns early and doesn't try to parse the given exception" do
210
- expect(Airbrake::Notice).not_to receive(:new)
211
- expect(subject.notify_sync(ex))
214
+ allow(Airbrake::Notice).to receive(:new)
215
+
216
+ expect(notice_notifier.notify_sync(ex))
212
217
  .to eq('error' => "current environment 'development' is ignored")
218
+
219
+ expect(Airbrake::Notice).not_to have_received(:new)
220
+ end
221
+
222
+ it "doesn't make an HTTP request" do
213
223
  expect(a_request(:post, endpoint)).not_to have_been_made
214
224
  end
215
225
  end
@@ -246,9 +256,9 @@ RSpec.describe Airbrake::NoticeNotifier do
246
256
  end
247
257
 
248
258
  it "sends a notice" do
249
- notice = subject.build_notice(ex)
259
+ notice = notice_notifier.build_notice(ex)
250
260
  notice[:context][:headers] = 'banana'
251
- subject.notify_sync(notice)
261
+ notice_notifier.notify_sync(notice)
252
262
 
253
263
  expect(a_request(:post, endpoint)).to have_been_made
254
264
  end
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::NoticeNotifier do
2
+ subject(:notice_notifier) { described_class.new }
3
+
2
4
  before do
3
5
  Airbrake::Config.instance = Airbrake::Config.new(
4
6
  project_id: 1,
@@ -15,13 +17,13 @@ RSpec.describe Airbrake::NoticeNotifier do
15
17
  it "appends the context filter" do
16
18
  expect_any_instance_of(Airbrake::FilterChain).to receive(:add_filter)
17
19
  .with(instance_of(Airbrake::Filters::ContextFilter))
18
- subject
20
+ notice_notifier
19
21
  end
20
22
 
21
23
  it "appends the exception attributes filter" do
22
24
  expect_any_instance_of(Airbrake::FilterChain).to receive(:add_filter)
23
25
  .with(instance_of(Airbrake::Filters::ExceptionAttributesFilter))
24
- subject
26
+ notice_notifier
25
27
  end
26
28
  end
27
29
  end
@@ -39,14 +41,14 @@ RSpec.describe Airbrake::NoticeNotifier do
39
41
  before { stub_request(:post, endpoint).to_return(status: 201, body: body) }
40
42
 
41
43
  it "returns a promise" do
42
- expect(subject.notify('ex')).to be_an(Airbrake::Promise)
44
+ expect(notice_notifier.notify('ex')).to be_an(Airbrake::Promise)
43
45
  sleep 1
44
46
  end
45
47
 
46
48
  it "refines the notice object" do
47
- subject.add_filter { |n| n[:params] = { foo: 'bar' } }
48
- notice = subject.build_notice('ex')
49
- subject.notify(notice)
49
+ notice_notifier.add_filter { |n| n[:params] = { foo: 'bar' } }
50
+ notice = notice_notifier.build_notice('ex')
51
+ notice_notifier.notify(notice)
50
52
  expect(notice[:params]).to eq(foo: 'bar')
51
53
  sleep 1
52
54
  end
@@ -55,54 +57,55 @@ RSpec.describe Airbrake::NoticeNotifier do
55
57
  before { Airbrake::Config.instance.merge(project_id: nil) }
56
58
 
57
59
  it "returns a rejected promise" do
58
- promise = subject.notify({})
60
+ promise = notice_notifier.notify({})
59
61
  expect(promise).to be_rejected
60
62
  end
61
63
  end
62
64
 
63
65
  context "when a notice is not ignored" do
64
66
  it "yields the notice" do
65
- expect { |b| subject.notify('ex', &b) }
67
+ expect { |b| notice_notifier.notify('ex', &b) }
66
68
  .to yield_with_args(Airbrake::Notice)
67
69
  sleep 1
68
70
  end
69
71
  end
70
72
 
71
73
  context "when a notice is ignored via a filter" do
72
- before { subject.add_filter(&:ignore!) }
74
+ before { notice_notifier.add_filter(&:ignore!) }
73
75
 
74
76
  it "yields the notice" do
75
- expect { |b| subject.notify('ex', &b) }
77
+ expect { |b| notice_notifier.notify('ex', &b) }
76
78
  .to yield_with_args(Airbrake::Notice)
77
79
  end
78
80
 
79
81
  it "returns a rejected promise" do
80
- value = subject.notify('ex').value
82
+ value = notice_notifier.notify('ex').value
81
83
  expect(value['error']).to match(/was marked as ignored/)
82
84
  end
83
85
  end
84
86
 
85
87
  context "when a notice is ignored via an inline filter" do
86
- before { subject.add_filter { raise AirbrakeTestError } }
88
+ before { notice_notifier.add_filter { raise AirbrakeTestError } }
87
89
 
88
90
  it "doesn't invoke regular filters" do
89
- expect { subject.notify('ex', &:ignore!) }.not_to raise_error
91
+ expect { notice_notifier.notify('ex', &:ignore!) }.not_to raise_error
90
92
  end
91
93
  end
92
94
 
93
95
  context "when async sender has workers" do
94
96
  it "sends an exception asynchronously" do
95
97
  expect_any_instance_of(Airbrake::AsyncSender).to receive(:send)
96
- subject.notify('foo', bingo: 'bango')
98
+ notice_notifier.notify('foo', bingo: 'bango')
97
99
  end
98
100
  end
99
101
 
100
102
  context "when async sender doesn't have workers" do
101
103
  it "sends an exception synchronously" do
102
- expect_any_instance_of(Airbrake::AsyncSender)
104
+ allow_any_instance_of(Airbrake::AsyncSender)
103
105
  .to receive(:has_workers?).and_return(false)
104
106
  expect_any_instance_of(Airbrake::SyncSender).to receive(:send)
105
- subject.notify('foo', bingo: 'bango')
107
+
108
+ notice_notifier.notify('foo', bingo: 'bango')
106
109
  end
107
110
  end
108
111
 
@@ -116,11 +119,11 @@ RSpec.describe Airbrake::NoticeNotifier do
116
119
 
117
120
  it "doesn't send an notice" do
118
121
  expect_any_instance_of(Airbrake::AsyncSender).not_to receive(:send)
119
- subject.notify('foo', bingo: 'bango')
122
+ notice_notifier.notify('foo', bingo: 'bango')
120
123
  end
121
124
 
122
125
  it "returns a rejected promise" do
123
- promise = subject.notify('foo', bingo: 'bango')
126
+ promise = notice_notifier.notify('foo', bingo: 'bango')
124
127
  expect(promise.value).to eq('error' => "current environment 'test' is ignored")
125
128
  end
126
129
  end
@@ -139,18 +142,18 @@ RSpec.describe Airbrake::NoticeNotifier do
139
142
  before { stub_request(:post, endpoint).to_return(status: 201, body: body.to_json) }
140
143
 
141
144
  it "returns a reponse hash" do
142
- expect(subject.notify_sync('ex')).to eq(body)
145
+ expect(notice_notifier.notify_sync('ex')).to eq(body)
143
146
  end
144
147
 
145
148
  it "refines the notice object" do
146
- subject.add_filter { |n| n[:params] = { foo: 'bar' } }
147
- notice = subject.build_notice('ex')
148
- subject.notify_sync(notice)
149
+ notice_notifier.add_filter { |n| n[:params] = { foo: 'bar' } }
150
+ notice = notice_notifier.build_notice('ex')
151
+ notice_notifier.notify_sync(notice)
149
152
  expect(notice[:params]).to eq(foo: 'bar')
150
153
  end
151
154
 
152
155
  it "sends an exception synchronously" do
153
- subject.notify_sync('foo', bingo: 'bango')
156
+ notice_notifier.notify_sync('foo', bingo: 'bango')
154
157
  expect(
155
158
  a_request(:post, endpoint).with(
156
159
  body: /"params":{.*"bingo":"bango".*}/,
@@ -160,30 +163,30 @@ RSpec.describe Airbrake::NoticeNotifier do
160
163
 
161
164
  context "when a notice is not ignored" do
162
165
  it "yields the notice" do
163
- expect { |b| subject.notify_sync('ex', &b) }
166
+ expect { |b| notice_notifier.notify_sync('ex', &b) }
164
167
  .to yield_with_args(Airbrake::Notice)
165
168
  end
166
169
  end
167
170
 
168
171
  context "when a notice is ignored via a filter" do
169
- before { subject.add_filter(&:ignore!) }
172
+ before { notice_notifier.add_filter(&:ignore!) }
170
173
 
171
174
  it "yields the notice" do
172
- expect { |b| subject.notify_sync('ex', &b) }
175
+ expect { |b| notice_notifier.notify_sync('ex', &b) }
173
176
  .to yield_with_args(Airbrake::Notice)
174
177
  end
175
178
 
176
179
  it "returns an error hash" do
177
- response = subject.notify_sync('ex')
180
+ response = notice_notifier.notify_sync('ex')
178
181
  expect(response['error']).to match(/was marked as ignored/)
179
182
  end
180
183
  end
181
184
 
182
185
  context "when a notice is ignored via an inline filter" do
183
- before { subject.add_filter { raise AirbrakeTestError } }
186
+ before { notice_notifier.add_filter { raise AirbrakeTestError } }
184
187
 
185
188
  it "doesn't invoke regular filters" do
186
- expect { subject.notify('ex', &:ignore!) }.not_to raise_error
189
+ expect { notice_notifier.notify('ex', &:ignore!) }.not_to raise_error
187
190
  end
188
191
  end
189
192
 
@@ -196,11 +199,11 @@ RSpec.describe Airbrake::NoticeNotifier do
196
199
 
197
200
  it "doesn't send an notice" do
198
201
  expect_any_instance_of(Airbrake::SyncSender).not_to receive(:send)
199
- subject.notify_sync('foo', bingo: 'bango')
202
+ notice_notifier.notify_sync('foo', bingo: 'bango')
200
203
  end
201
204
 
202
205
  it "returns an error hash" do
203
- expect(subject.notify_sync('foo'))
206
+ expect(notice_notifier.notify_sync('foo'))
204
207
  .to eq('error' => "current environment 'test' is ignored")
205
208
  end
206
209
  end
@@ -209,17 +212,19 @@ RSpec.describe Airbrake::NoticeNotifier do
209
212
  describe "#add_filter" do
210
213
  context "given a block" do
211
214
  it "appends a new filter to the filter chain" do
212
- notifier = subject
215
+ notifier = notice_notifier
213
216
  b = proc {}
217
+ # rubocop:disable RSpec/StubbedMock
214
218
  expect_any_instance_of(Airbrake::FilterChain)
215
219
  .to receive(:add_filter) { |*args| expect(args.last).to be(b) }
220
+ # rubocop:enable RSpec/StubbedMock
216
221
  notifier.add_filter(&b)
217
222
  end
218
223
  end
219
224
 
220
225
  context "given a class" do
221
226
  it "appends a new filter to the filter chain" do
222
- notifier = subject
227
+ notifier = notice_notifier
223
228
  klass = Class.new
224
229
  expect_any_instance_of(Airbrake::FilterChain)
225
230
  .to receive(:add_filter).with(klass)
@@ -231,14 +236,14 @@ RSpec.describe Airbrake::NoticeNotifier do
231
236
  describe "#build_notice" do
232
237
  context "when given exception is another notice" do
233
238
  it "merges params with the notice" do
234
- notice = subject.build_notice('ex')
235
- other = subject.build_notice(notice, foo: 'bar')
239
+ notice = notice_notifier.build_notice('ex')
240
+ other = notice_notifier.build_notice(notice, foo: 'bar')
236
241
  expect(other[:params]).to eq(foo: 'bar')
237
242
  end
238
243
 
239
- it "it returns the provided notice" do
240
- notice = subject.build_notice('ex')
241
- other = subject.build_notice(notice, foo: 'bar')
244
+ it "returns the provided notice" do
245
+ notice = notice_notifier.build_notice('ex')
246
+ other = notice_notifier.build_notice(notice, foo: 'bar')
242
247
  expect(other).to eq(notice)
243
248
  end
244
249
  end
@@ -246,7 +251,7 @@ RSpec.describe Airbrake::NoticeNotifier do
246
251
  context "when given exception is an Exception" do
247
252
  it "prevents mutation of passed-in params hash" do
248
253
  params = { immutable: true }
249
- notice = subject.build_notice('ex', params)
254
+ notice = notice_notifier.build_notice('ex', params)
250
255
  notice[:params][:mutable] = true
251
256
  expect(params).to eq(immutable: true)
252
257
  end
@@ -260,7 +265,7 @@ RSpec.describe Airbrake::NoticeNotifier do
260
265
  ]
261
266
  allow(Kernel).to receive(:caller).and_return(backtrace)
262
267
 
263
- notice = subject.build_notice(Exception.new)
268
+ notice = notice_notifier.build_notice(Exception.new)
264
269
 
265
270
  expect(notice[:errors].first[:backtrace]).to eq(
266
271
  [
@@ -280,7 +285,7 @@ RSpec.describe Airbrake::NoticeNotifier do
280
285
  ]
281
286
  allow(Kernel).to receive(:caller).and_return(backtrace)
282
287
 
283
- notice = subject.build_notice(Exception.new)
288
+ notice = notice_notifier.build_notice(Exception.new)
284
289
 
285
290
  expect(notice[:errors].first[:backtrace]).to eq(
286
291
  [
@@ -296,7 +301,7 @@ RSpec.describe Airbrake::NoticeNotifier do
296
301
  # TODO: this seems to be bugged. Fix later.
297
302
  context "when given exception is a Java exception", skip: true do
298
303
  before do
299
- expect(Airbrake::Backtrace).to receive(:java_exception?).and_return(true)
304
+ allow(Airbrake::Backtrace).to receive(:java_exception?).and_return(true)
300
305
  end
301
306
 
302
307
  it "automatically generates the backtrace" do
@@ -307,7 +312,7 @@ RSpec.describe Airbrake::NoticeNotifier do
307
312
  ]
308
313
  allow(Kernel).to receive(:caller).and_return(backtrace)
309
314
 
310
- notice = subject.build_notice(Exception.new)
315
+ notice = notice_notifier.build_notice(Exception.new)
311
316
 
312
317
  # rubocop:disable Layout/LineLength
313
318
  expect(notice[:errors].first[:backtrace]).to eq(
@@ -323,12 +328,12 @@ RSpec.describe Airbrake::NoticeNotifier do
323
328
 
324
329
  context "when async sender is closed" do
325
330
  before do
326
- expect_any_instance_of(Airbrake::AsyncSender)
331
+ allow_any_instance_of(Airbrake::AsyncSender)
327
332
  .to receive(:closed?).and_return(true)
328
333
  end
329
334
 
330
335
  it "raises error" do
331
- expect { subject.build_notice(Exception.new('oops')) }.to raise_error(
336
+ expect { notice_notifier.build_notice(Exception.new('oops')) }.to raise_error(
332
337
  Airbrake::Error,
333
338
  "Airbrake is closed; can't build exception: Exception: oops",
334
339
  )
@@ -339,7 +344,7 @@ RSpec.describe Airbrake::NoticeNotifier do
339
344
  describe "#close" do
340
345
  it "sends the close message to async sender" do
341
346
  expect_any_instance_of(Airbrake::AsyncSender).to receive(:close)
342
- subject.close
347
+ notice_notifier.close
343
348
  end
344
349
  end
345
350
 
@@ -350,7 +355,7 @@ RSpec.describe Airbrake::NoticeNotifier do
350
355
  describe "#merge_context" do
351
356
  it "merges the provided context with the notice object" do
352
357
  expect_any_instance_of(Hash).to receive(:merge!).with(apples: 'oranges')
353
- subject.merge_context(apples: 'oranges')
358
+ notice_notifier.merge_context(apples: 'oranges')
354
359
  end
355
360
  end
356
361
  end