airbrake-ruby 5.1.1-java → 6.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/async_sender.rb +3 -1
  3. data/lib/airbrake-ruby/config/processor.rb +2 -1
  4. data/lib/airbrake-ruby/config.rb +14 -7
  5. data/lib/airbrake-ruby/context.rb +51 -0
  6. data/lib/airbrake-ruby/file_cache.rb +1 -1
  7. data/lib/airbrake-ruby/filter_chain.rb +2 -0
  8. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  9. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  10. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +2 -2
  11. data/lib/airbrake-ruby/filters/git_repository_filter.rb +1 -1
  12. data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
  13. data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
  14. data/lib/airbrake-ruby/filters/sql_filter.rb +2 -2
  15. data/lib/airbrake-ruby/filters/thread_filter.rb +2 -3
  16. data/lib/airbrake-ruby/grouppable.rb +1 -1
  17. data/lib/airbrake-ruby/ignorable.rb +0 -2
  18. data/lib/airbrake-ruby/mergeable.rb +1 -1
  19. data/lib/airbrake-ruby/monotonic_time.rb +1 -1
  20. data/lib/airbrake-ruby/notice_notifier.rb +3 -4
  21. data/lib/airbrake-ruby/performance_notifier.rb +1 -2
  22. data/lib/airbrake-ruby/remote_settings/callback.rb +1 -1
  23. data/lib/airbrake-ruby/remote_settings/settings_data.rb +2 -2
  24. data/lib/airbrake-ruby/remote_settings.rb +27 -4
  25. data/lib/airbrake-ruby/tdigest.rb +10 -9
  26. data/lib/airbrake-ruby/thread_pool.rb +8 -6
  27. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  28. data/lib/airbrake-ruby/version.rb +2 -2
  29. data/lib/airbrake-ruby.rb +3 -2
  30. data/spec/airbrake_spec.rb +139 -76
  31. data/spec/async_sender_spec.rb +10 -8
  32. data/spec/backtrace_spec.rb +13 -10
  33. data/spec/benchmark_spec.rb +5 -3
  34. data/spec/code_hunk_spec.rb +24 -15
  35. data/spec/config/processor_spec.rb +20 -3
  36. data/spec/config/validator_spec.rb +5 -2
  37. data/spec/config_spec.rb +25 -16
  38. data/spec/context_spec.rb +54 -0
  39. data/spec/deploy_notifier_spec.rb +6 -4
  40. data/spec/file_cache_spec.rb +1 -0
  41. data/spec/filter_chain_spec.rb +29 -24
  42. data/spec/filters/context_filter_spec.rb +14 -5
  43. data/spec/filters/dependency_filter_spec.rb +3 -1
  44. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  45. data/spec/filters/gem_root_filter_spec.rb +5 -2
  46. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  47. data/spec/filters/git_repository_filter.rb +9 -9
  48. data/spec/filters/git_revision_filter_spec.rb +20 -20
  49. data/spec/filters/keys_allowlist_spec.rb +25 -16
  50. data/spec/filters/keys_blocklist_spec.rb +25 -18
  51. data/spec/filters/root_directory_filter_spec.rb +3 -3
  52. data/spec/filters/sql_filter_spec.rb +26 -26
  53. data/spec/filters/system_exit_filter_spec.rb +4 -2
  54. data/spec/filters/thread_filter_spec.rb +16 -14
  55. data/spec/loggable_spec.rb +2 -2
  56. data/spec/monotonic_time_spec.rb +8 -6
  57. data/spec/nested_exception_spec.rb +46 -46
  58. data/spec/notice_notifier/options_spec.rb +23 -13
  59. data/spec/notice_notifier_spec.rb +52 -47
  60. data/spec/notice_spec.rb +6 -2
  61. data/spec/performance_notifier_spec.rb +67 -60
  62. data/spec/promise_spec.rb +38 -32
  63. data/spec/remote_settings/callback_spec.rb +27 -8
  64. data/spec/remote_settings/settings_data_spec.rb +4 -4
  65. data/spec/remote_settings_spec.rb +23 -9
  66. data/spec/response_spec.rb +34 -12
  67. data/spec/stashable_spec.rb +5 -5
  68. data/spec/stat_spec.rb +7 -5
  69. data/spec/sync_sender_spec.rb +49 -16
  70. data/spec/tdigest_spec.rb +61 -56
  71. data/spec/thread_pool_spec.rb +65 -56
  72. data/spec/time_truncate_spec.rb +4 -2
  73. data/spec/timed_trace_spec.rb +32 -30
  74. data/spec/truncator_spec.rb +72 -43
  75. metadata +52 -49
data/lib/airbrake-ruby.rb CHANGED
@@ -58,6 +58,7 @@ require 'airbrake-ruby/benchmark'
58
58
  require 'airbrake-ruby/monotonic_time'
59
59
  require 'airbrake-ruby/timed_trace'
60
60
  require 'airbrake-ruby/queue'
61
+ require 'airbrake-ruby/context'
61
62
 
62
63
  # Airbrake is a thin wrapper around instances of the notifier classes (such as
63
64
  # notice, performance & deploy notifiers). It creates a way to access them via a
@@ -273,7 +274,7 @@ module Airbrake
273
274
  # Airbrake.notify('App crashed!') #=> raises Airbrake::Error
274
275
  #
275
276
  # @return [nil]
276
- # rubocop:disable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
277
+ # rubocop:disable Style/IfUnlessModifier
277
278
  def close
278
279
  if defined?(@notice_notifier) && @notice_notifier
279
280
  @notice_notifier.close
@@ -289,7 +290,7 @@ module Airbrake
289
290
 
290
291
  nil
291
292
  end
292
- # rubocop:enable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
293
+ # rubocop:enable Style/IfUnlessModifier
293
294
 
294
295
  # Pings the Airbrake Deploy API endpoint about the occurred deploy.
295
296
  #
@@ -30,11 +30,9 @@ RSpec.describe Airbrake do
30
30
 
31
31
  it "yields the config" do
32
32
  expect do |b|
33
- begin
34
- described_class.configure(&b)
35
- rescue Airbrake::Error
36
- nil
37
- end
33
+ described_class.configure(&b)
34
+ rescue Airbrake::Error
35
+ nil
38
36
  end.to yield_with_args(Airbrake::Config)
39
37
  end
40
38
 
@@ -62,26 +60,26 @@ RSpec.describe Airbrake do
62
60
 
63
61
  context "when called multiple times" do
64
62
  it "doesn't overwrite performance notifier" do
65
- described_class.configure {}
63
+ described_class.configure { anything }
66
64
  performance_notifier = described_class.performance_notifier
67
65
 
68
- described_class.configure {}
66
+ described_class.configure { anything }
69
67
  expect(described_class.performance_notifier).to eql(performance_notifier)
70
68
  end
71
69
 
72
70
  it "doesn't overwrite notice notifier" do
73
- described_class.configure {}
71
+ described_class.configure { anything }
74
72
  notice_notifier = described_class.notice_notifier
75
73
 
76
- described_class.configure {}
74
+ described_class.configure { anything }
77
75
  expect(described_class.notice_notifier).to eql(notice_notifier)
78
76
  end
79
77
 
80
78
  it "doesn't overwrite deploy notifier" do
81
- described_class.configure {}
79
+ described_class.configure { anything }
82
80
  deploy_notifier = described_class.deploy_notifier
83
81
 
84
- described_class.configure {}
82
+ described_class.configure { anything }
85
83
  expect(described_class.deploy_notifier).to eql(deploy_notifier)
86
84
  end
87
85
 
@@ -91,20 +89,24 @@ RSpec.describe Airbrake do
91
89
  c.project_key = '2'
92
90
  end
93
91
 
94
- expect(described_class.notice_notifier).not_to receive(:add_filter)
95
- 10.times { described_class.configure {} }
92
+ allow(described_class.notice_notifier).to receive(:add_filter)
93
+
94
+ 10.times { described_class.configure { anything } }
95
+
96
+ expect(described_class.notice_notifier).not_to have_received(:add_filter)
96
97
  end
97
98
 
98
99
  it "appends some default filters" do
99
100
  allow(described_class.notice_notifier).to receive(:add_filter)
100
- expect(described_class.notice_notifier).to receive(:add_filter).with(
101
- an_instance_of(Airbrake::Filters::RootDirectoryFilter),
102
- )
103
101
 
104
102
  described_class.configure do |c|
105
103
  c.project_id = 1
106
104
  c.project_key = '2'
107
105
  end
106
+
107
+ expect(described_class.notice_notifier).to have_received(:add_filter).with(
108
+ an_instance_of(Airbrake::Filters::RootDirectoryFilter),
109
+ )
108
110
  end
109
111
  end
110
112
 
@@ -112,14 +114,21 @@ RSpec.describe Airbrake do
112
114
  before { allow(described_class.notice_notifier).to receive(:add_filter) }
113
115
 
114
116
  it "adds blocklist filter" do
115
- expect(described_class.notice_notifier).to receive(:add_filter)
116
- .with(an_instance_of(Airbrake::Filters::KeysBlocklist))
117
+ allow(described_class.notice_notifier).to receive(:add_filter)
118
+
117
119
  described_class.configure { |c| c.blocklist_keys = %w[password] }
120
+
121
+ expect(described_class.notice_notifier).to have_received(:add_filter)
122
+ .with(an_instance_of(Airbrake::Filters::KeysBlocklist))
118
123
  end
119
124
 
120
125
  it "initializes blocklist with specified parameters" do
121
- expect(Airbrake::Filters::KeysBlocklist).to receive(:new).with(%w[password])
126
+ allow(Airbrake::Filters::KeysBlocklist).to receive(:new)
127
+
122
128
  described_class.configure { |c| c.blocklist_keys = %w[password] }
129
+
130
+ expect(Airbrake::Filters::KeysBlocklist)
131
+ .to have_received(:new).with(%w[password])
123
132
  end
124
133
  end
125
134
 
@@ -127,14 +136,17 @@ RSpec.describe Airbrake do
127
136
  before { allow(described_class.notice_notifier).to receive(:add_filter) }
128
137
 
129
138
  it "adds allowlist filter" do
130
- expect(described_class.notice_notifier).to receive(:add_filter)
131
- .with(an_instance_of(Airbrake::Filters::KeysAllowlist))
132
139
  described_class.configure { |c| c.allowlist_keys = %w[banana] }
140
+ expect(described_class.notice_notifier).to have_received(:add_filter)
141
+ .with(an_instance_of(Airbrake::Filters::KeysAllowlist))
133
142
  end
134
143
 
135
144
  it "initializes allowlist with specified parameters" do
136
- expect(Airbrake::Filters::KeysAllowlist).to receive(:new).with(%w[banana])
145
+ allow(Airbrake::Filters::KeysAllowlist).to receive(:new)
146
+
137
147
  described_class.configure { |c| c.allowlist_keys = %w[banana] }
148
+ expect(Airbrake::Filters::KeysAllowlist)
149
+ .to have_received(:new).with(%w[banana])
138
150
  end
139
151
  end
140
152
 
@@ -142,77 +154,90 @@ RSpec.describe Airbrake do
142
154
  before { allow(described_class.notice_notifier).to receive(:add_filter) }
143
155
 
144
156
  it "adds root directory filter" do
145
- expect(described_class.notice_notifier).to receive(:add_filter)
146
- .with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
147
157
  described_class.configure { |c| c.root_directory = '/my/path' }
158
+
159
+ expect(described_class.notice_notifier).to have_received(:add_filter)
160
+ .with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
148
161
  end
149
162
 
150
163
  it "initializes root directory filter with specified path" do
151
- expect(Airbrake::Filters::RootDirectoryFilter)
152
- .to receive(:new).with('/my/path')
164
+ allow(Airbrake::Filters::RootDirectoryFilter).to receive(:new)
153
165
  described_class.configure { |c| c.root_directory = '/my/path' }
166
+
167
+ expect(Airbrake::Filters::RootDirectoryFilter)
168
+ .to have_received(:new).with('/my/path')
154
169
  end
155
170
 
156
171
  it "adds git revision filter" do
157
- expect(described_class.notice_notifier).to receive(:add_filter)
158
- .with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
159
172
  described_class.configure { |c| c.root_directory = '/my/path' }
173
+ expect(described_class.notice_notifier).to have_received(:add_filter)
174
+ .with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
160
175
  end
161
176
 
162
177
  it "initializes git revision filter with correct root directory" do
163
- expect(Airbrake::Filters::GitRevisionFilter)
164
- .to receive(:new).with('/my/path')
178
+ allow(Airbrake::Filters::GitRevisionFilter).to receive(:new)
165
179
  described_class.configure { |c| c.root_directory = '/my/path' }
180
+
181
+ expect(Airbrake::Filters::GitRevisionFilter)
182
+ .to have_received(:new).with('/my/path')
166
183
  end
167
184
 
168
185
  it "adds git repository filter" do
169
- expect(described_class.notice_notifier).to receive(:add_filter)
170
- .with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
171
186
  described_class.configure { |c| c.root_directory = '/my/path' }
187
+
188
+ expect(described_class.notice_notifier).to have_received(:add_filter)
189
+ .with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
172
190
  end
173
191
 
174
192
  it "initializes git repository filter with correct root directory" do
175
- expect(Airbrake::Filters::GitRepositoryFilter)
176
- .to receive(:new).with('/my/path')
193
+ allow(Airbrake::Filters::GitRepositoryFilter).to receive(:new)
194
+
177
195
  described_class.configure { |c| c.root_directory = '/my/path' }
196
+
197
+ expect(Airbrake::Filters::GitRepositoryFilter)
198
+ .to have_received(:new).with('/my/path')
178
199
  end
179
200
 
180
201
  it "adds git last checkout filter" do
181
- expect(described_class.notice_notifier).to receive(:add_filter)
182
- .with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
183
202
  described_class.configure { |c| c.root_directory = '/my/path' }
203
+ expect(described_class.notice_notifier).to have_received(:add_filter)
204
+ .with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
184
205
  end
185
206
 
186
207
  it "initializes git last checkout filter with correct root directory" do
187
- expect(Airbrake::Filters::GitLastCheckoutFilter)
188
- .to receive(:new).with('/my/path')
208
+ allow(Airbrake::Filters::GitLastCheckoutFilter).to receive(:new)
189
209
  described_class.configure { |c| c.root_directory = '/my/path' }
210
+
211
+ expect(Airbrake::Filters::GitLastCheckoutFilter)
212
+ .to have_received(:new).with('/my/path')
190
213
  end
191
214
  end
192
215
  end
193
216
 
194
217
  describe ".notify_request" do
218
+ before do
219
+ allow(described_class.performance_notifier).to receive(:notify)
220
+ end
221
+
195
222
  context "when :stash key is not provided" do
196
223
  it "doesn't add anything to the stash of the request" do
197
- expect(described_class.performance_notifier).to receive(:notify) do |request|
198
- expect(request.stash).to be_empty
199
- end
200
-
201
224
  described_class.notify_request(
202
225
  method: 'GET',
203
226
  route: '/',
204
227
  status_code: 200,
205
228
  timing: 1,
206
229
  )
230
+
231
+ expect(
232
+ described_class.performance_notifier,
233
+ ).to have_received(:notify) do |request|
234
+ expect(request.stash).to be_empty
235
+ end
207
236
  end
208
237
  end
209
238
 
210
239
  context "when :stash key is provided" do
211
240
  it "adds the value as the stash of the request" do
212
- expect(described_class.performance_notifier).to receive(:notify) do |request|
213
- expect(request.stash).to eq(request_id: 1)
214
- end
215
-
216
241
  described_class.notify_request(
217
242
  {
218
243
  method: 'GET',
@@ -222,13 +247,19 @@ RSpec.describe Airbrake do
222
247
  },
223
248
  request_id: 1,
224
249
  )
250
+
251
+ expect(
252
+ described_class.performance_notifier,
253
+ ).to have_received(:notify) do |request|
254
+ expect(request.stash).to eq(request_id: 1)
255
+ end
225
256
  end
226
257
  end
227
258
  end
228
259
 
229
260
  describe ".notify_request_sync" do
230
261
  it "notifies request synchronously" do
231
- expect(described_class.performance_notifier).to receive(:notify_sync)
262
+ allow(described_class.performance_notifier).to receive(:notify_sync)
232
263
 
233
264
  described_class.notify_request_sync(
234
265
  {
@@ -239,31 +270,35 @@ RSpec.describe Airbrake do
239
270
  },
240
271
  request_id: 1,
241
272
  )
273
+
274
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
242
275
  end
243
276
  end
244
277
 
245
278
  describe ".notify_query" do
279
+ before do
280
+ allow(described_class.performance_notifier).to receive(:notify)
281
+ end
282
+
246
283
  context "when :stash key is not provided" do
247
284
  it "doesn't add anything to the stash of the query" do
248
- expect(described_class.performance_notifier).to receive(:notify) do |query|
249
- expect(query.stash).to be_empty
250
- end
251
-
252
285
  described_class.notify_query(
253
286
  method: 'GET',
254
287
  route: '/',
255
288
  query: '',
256
289
  timing: 1,
257
290
  )
291
+
292
+ expect(
293
+ described_class.performance_notifier,
294
+ ).to have_received(:notify) do |query|
295
+ expect(query.stash).to be_empty
296
+ end
258
297
  end
259
298
  end
260
299
 
261
300
  context "when :stash key is provided" do
262
301
  it "adds the value as the stash of the query" do
263
- expect(described_class.performance_notifier).to receive(:notify) do |query|
264
- expect(query.stash).to eq(request_id: 1)
265
- end
266
-
267
302
  described_class.notify_query(
268
303
  {
269
304
  method: 'GET',
@@ -273,13 +308,19 @@ RSpec.describe Airbrake do
273
308
  },
274
309
  request_id: 1,
275
310
  )
311
+
312
+ expect(
313
+ described_class.performance_notifier,
314
+ ).to have_received(:notify) do |query|
315
+ expect(query.stash).to eq(request_id: 1)
316
+ end
276
317
  end
277
318
  end
278
319
  end
279
320
 
280
321
  describe ".notify_query_sync" do
281
322
  it "notifies query synchronously" do
282
- expect(described_class.performance_notifier).to receive(:notify_sync)
323
+ allow(described_class.performance_notifier).to receive(:notify_sync)
283
324
 
284
325
  described_class.notify_query_sync(
285
326
  {
@@ -290,33 +331,35 @@ RSpec.describe Airbrake do
290
331
  },
291
332
  request_id: 1,
292
333
  )
334
+
335
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
293
336
  end
294
337
  end
295
338
 
296
339
  describe ".notify_performance_breakdown" do
340
+ before do
341
+ allow(described_class.performance_notifier).to receive(:notify)
342
+ end
343
+
297
344
  context "when :stash key is not provided" do
298
345
  it "doesn't add anything to the stash of the performance breakdown" do
299
- expect(described_class.performance_notifier).to receive(:notify) do |query|
300
- expect(query.stash).to be_empty
301
- end
302
-
303
346
  described_class.notify_query(
304
347
  method: 'GET',
305
348
  route: '/',
306
349
  query: '',
307
350
  timing: 1,
308
351
  )
309
- end
310
- end
311
352
 
312
- context "when :stash key is provided" do
313
- it "adds the value as the stash of the performance breakdown" do
314
353
  expect(
315
354
  described_class.performance_notifier,
316
- ).to receive(:notify) do |performance_breakdown|
317
- expect(performance_breakdown.stash).to eq(request_id: 1)
355
+ ).to have_received(:notify) do |query|
356
+ expect(query.stash).to be_empty
318
357
  end
358
+ end
359
+ end
319
360
 
361
+ context "when :stash key is provided" do
362
+ it "adds the value as the stash of the performance breakdown" do
320
363
  described_class.notify_performance_breakdown(
321
364
  {
322
365
  method: 'GET',
@@ -327,13 +370,19 @@ RSpec.describe Airbrake do
327
370
  },
328
371
  request_id: 1,
329
372
  )
373
+
374
+ expect(
375
+ described_class.performance_notifier,
376
+ ).to have_received(:notify) do |performance_breakdown|
377
+ expect(performance_breakdown.stash).to eq(request_id: 1)
378
+ end
330
379
  end
331
380
  end
332
381
  end
333
382
 
334
383
  describe ".notify_performance_breakdown_sync" do
335
384
  it "notifies performance breakdown synchronously" do
336
- expect(described_class.performance_notifier).to receive(:notify_sync)
385
+ allow(described_class.performance_notifier).to receive(:notify_sync)
337
386
 
338
387
  described_class.notify_performance_breakdown_sync(
339
388
  {
@@ -345,29 +394,33 @@ RSpec.describe Airbrake do
345
394
  },
346
395
  request_id: 1,
347
396
  )
397
+
398
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
348
399
  end
349
400
  end
350
401
 
351
402
  describe ".notify_queue" do
403
+ before do
404
+ allow(described_class.performance_notifier).to receive(:notify)
405
+ end
406
+
352
407
  context "when :stash key is not provided" do
353
408
  it "doesn't add anything to the stash of the queue" do
354
- expect(described_class.performance_notifier).to receive(:notify) do |queue|
355
- expect(queue.stash).to be_empty
356
- end
357
-
358
409
  described_class.notify_queue(
359
410
  queue: 'bananas',
360
411
  error_count: 10,
361
412
  )
413
+
414
+ expect(
415
+ described_class.performance_notifier,
416
+ ).to have_received(:notify) do |queue|
417
+ expect(queue.stash).to be_empty
418
+ end
362
419
  end
363
420
  end
364
421
 
365
422
  context "when :stash key is provided" do
366
423
  it "adds the value as the stash of the queue" do
367
- expect(described_class.performance_notifier).to receive(:notify) do |queue|
368
- expect(queue.stash).to eq(request_id: 1)
369
- end
370
-
371
424
  described_class.notify_queue(
372
425
  {
373
426
  queue: 'bananas',
@@ -375,13 +428,19 @@ RSpec.describe Airbrake do
375
428
  },
376
429
  request_id: 1,
377
430
  )
431
+
432
+ expect(
433
+ described_class.performance_notifier,
434
+ ).to have_received(:notify) do |queue|
435
+ expect(queue.stash).to eq(request_id: 1)
436
+ end
378
437
  end
379
438
  end
380
439
  end
381
440
 
382
441
  describe ".notify_queue_sync" do
383
442
  it "notifies queue synchronously" do
384
- expect(described_class.performance_notifier).to receive(:notify_sync)
443
+ allow(described_class.performance_notifier).to receive(:notify_sync)
385
444
 
386
445
  described_class.notify_queue_sync(
387
446
  {
@@ -390,6 +449,8 @@ RSpec.describe Airbrake do
390
449
  },
391
450
  request_id: 1,
392
451
  )
452
+
453
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
393
454
  end
394
455
  end
395
456
 
@@ -412,6 +473,7 @@ RSpec.describe Airbrake do
412
473
  end
413
474
  end
414
475
 
476
+ # rubocop:disable RSpec/MessageSpies
415
477
  describe ".close" do
416
478
  after { described_class.reset }
417
479
 
@@ -456,4 +518,5 @@ RSpec.describe Airbrake do
456
518
  end
457
519
  end
458
520
  end
521
+ # rubocop:enable RSpec/MessageSpies
459
522
  end
@@ -13,18 +13,20 @@ RSpec.describe Airbrake::AsyncSender do
13
13
  end
14
14
 
15
15
  describe "#send" do
16
+ subject(:async_sender) { described_class.new }
17
+
16
18
  context "when sender has the capacity to send" do
17
19
  it "sends notices to Airbrake" do
18
- 2.times { subject.send(notice, Airbrake::Promise.new) }
19
- subject.close
20
+ 2.times { async_sender.send(notice, Airbrake::Promise.new) }
21
+ async_sender.close
20
22
 
21
23
  expect(a_request(:post, endpoint)).to have_been_made.twice
22
24
  end
23
25
 
24
26
  it "returns a resolved promise" do
25
27
  promise = Airbrake::Promise.new
26
- subject.send(notice, promise)
27
- subject.close
28
+ async_sender.send(notice, promise)
29
+ async_sender.close
28
30
 
29
31
  expect(promise).to be_resolved
30
32
  end
@@ -40,8 +42,8 @@ RSpec.describe Airbrake::AsyncSender do
40
42
  end
41
43
 
42
44
  it "doesn't send the exceeded notices to Airbrake" do
43
- 15.times { subject.send(notice, Airbrake::Promise.new) }
44
- subject.close
45
+ 15.times { async_sender.send(notice, Airbrake::Promise.new) }
46
+ async_sender.close
45
47
 
46
48
  expect(a_request(:post, endpoint)).not_to have_been_made
47
49
  end
@@ -49,9 +51,9 @@ RSpec.describe Airbrake::AsyncSender do
49
51
  it "returns a rejected promise" do
50
52
  promise = nil
51
53
  15.times do
52
- promise = subject.send(notice, Airbrake::Promise.new)
54
+ promise = async_sender.send(notice, Airbrake::Promise.new)
53
55
  end
54
- subject.close
56
+ async_sender.close
55
57
 
56
58
  expect(promise).to be_rejected
57
59
  expect(promise.value).to eq(
@@ -177,10 +177,13 @@ RSpec.describe Airbrake::Backtrace do
177
177
  end
178
178
 
179
179
  it "logs frames that cannot be parsed" do
180
- expect(Airbrake::Loggable.instance).to receive(:error).with(
180
+ allow(Airbrake::Loggable.instance).to receive(:error)
181
+
182
+ described_class.parse(ex)
183
+
184
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
181
185
  /can't parse 'a b c 1 23 321 .rb'/,
182
186
  )
183
- described_class.parse(ex)
184
187
  end
185
188
  end
186
189
 
@@ -298,9 +301,9 @@ RSpec.describe Airbrake::Backtrace do
298
301
  it "attaches code to those frames files of which match root_directory" do
299
302
  ex = RuntimeError.new
300
303
  backtrace = [
301
- project_root_path('code.rb') + ":94:in `to_json'",
302
- fixture_path('notroot.txt' + ":3:in `pineapple'"),
303
- project_root_path('vendor/bundle/ignored_file.rb') + ":2:in `ignore_me'",
304
+ "#{project_root_path('code.rb')}:94:in `to_json'",
305
+ fixture_path("notroot.txt:3:in `pineapple'"),
306
+ "#{project_root_path('vendor/bundle/ignored_file.rb')}:2:in `ignore_me'",
304
307
  ]
305
308
  ex.set_backtrace(backtrace)
306
309
  expect(described_class.parse(ex)).to eq(parsed_backtrace)
@@ -335,7 +338,7 @@ RSpec.describe Airbrake::Backtrace do
335
338
 
336
339
  it "attaches code to those frames files of which match root_directory" do
337
340
  ex = RuntimeError.new
338
- ex.set_backtrace([project_root_path('code.rb') + ":94:in `to_json'"])
341
+ ex.set_backtrace(["#{project_root_path('code.rb')}:94:in `to_json'"])
339
342
  expect(described_class.parse(ex)).to eq(parsed_backtrace)
340
343
  end
341
344
  end
@@ -387,9 +390,9 @@ RSpec.describe Airbrake::Backtrace do
387
390
  it "attaches code to first N frames" do
388
391
  ex = RuntimeError.new
389
392
  backtrace = [
390
- project_root_path('code.rb') + ":94:in `to_json'",
391
- project_root_path('code.rb') + ":95:in `to_json'",
392
- project_root_path('code.rb') + ":96:in `to_json'",
393
+ "#{project_root_path('code.rb')}:94:in `to_json'",
394
+ "#{project_root_path('code.rb')}:95:in `to_json'",
395
+ "#{project_root_path('code.rb')}:96:in `to_json'",
393
396
  ]
394
397
  ex.set_backtrace(backtrace)
395
398
  expect(described_class.parse(ex)).to eq(parsed_backtrace)
@@ -417,7 +420,7 @@ RSpec.describe Airbrake::Backtrace do
417
420
 
418
421
  it "doesn't attach code to frames" do
419
422
  ex = RuntimeError.new
420
- backtrace = [project_root_path('code.rb') + ":94:in `to_json'"]
423
+ backtrace = ["#{project_root_path('code.rb')}:94:in `to_json'"]
421
424
  ex.set_backtrace(backtrace)
422
425
  expect(described_class.parse(ex)).to eq(parsed_backtrace)
423
426
  end
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::Benchmark do
2
+ subject(:benchmark) { described_class.new }
3
+
2
4
  describe ".measure" do
3
5
  it "returns measured performance time" do
4
6
  expect(described_class.measure { '10' * 10 }).to be_kind_of(Numeric)
@@ -6,14 +8,14 @@ RSpec.describe Airbrake::Benchmark do
6
8
  end
7
9
 
8
10
  describe "#stop" do
9
- before { subject }
11
+ before { benchmark }
10
12
 
11
13
  context "when called one time" do
12
14
  its(:stop) { is_expected.to eq(true) }
13
15
  end
14
16
 
15
17
  context "when called twice or more" do
16
- before { subject.stop }
18
+ before { benchmark.stop }
17
19
 
18
20
  its(:stop) { is_expected.to eq(false) }
19
21
  end
@@ -25,7 +27,7 @@ RSpec.describe Airbrake::Benchmark do
25
27
  end
26
28
 
27
29
  context "when #stop was called" do
28
- before { subject.stop }
30
+ before { benchmark.stop }
29
31
 
30
32
  its(:duration) { is_expected.to be > 0 }
31
33
  end