airbrake-ruby 3.2.2-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.
- checksums.yaml +7 -0
- data/lib/airbrake-ruby.rb +554 -0
- data/lib/airbrake-ruby/async_sender.rb +119 -0
- data/lib/airbrake-ruby/backtrace.rb +194 -0
- data/lib/airbrake-ruby/code_hunk.rb +53 -0
- data/lib/airbrake-ruby/config.rb +238 -0
- data/lib/airbrake-ruby/config/validator.rb +63 -0
- data/lib/airbrake-ruby/deploy_notifier.rb +47 -0
- data/lib/airbrake-ruby/file_cache.rb +48 -0
- data/lib/airbrake-ruby/filter_chain.rb +95 -0
- data/lib/airbrake-ruby/filters/context_filter.rb +29 -0
- data/lib/airbrake-ruby/filters/dependency_filter.rb +31 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +45 -0
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +33 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +90 -0
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +42 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +66 -0
- data/lib/airbrake-ruby/filters/keys_blacklist.rb +50 -0
- data/lib/airbrake-ruby/filters/keys_filter.rb +140 -0
- data/lib/airbrake-ruby/filters/keys_whitelist.rb +49 -0
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +28 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +104 -0
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +23 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +92 -0
- data/lib/airbrake-ruby/hash_keyable.rb +37 -0
- data/lib/airbrake-ruby/ignorable.rb +44 -0
- data/lib/airbrake-ruby/nested_exception.rb +39 -0
- data/lib/airbrake-ruby/notice.rb +165 -0
- data/lib/airbrake-ruby/notice_notifier.rb +228 -0
- data/lib/airbrake-ruby/performance_notifier.rb +161 -0
- data/lib/airbrake-ruby/promise.rb +99 -0
- data/lib/airbrake-ruby/response.rb +71 -0
- data/lib/airbrake-ruby/stat.rb +56 -0
- data/lib/airbrake-ruby/sync_sender.rb +111 -0
- data/lib/airbrake-ruby/tdigest.rb +393 -0
- data/lib/airbrake-ruby/time_truncate.rb +17 -0
- data/lib/airbrake-ruby/truncator.rb +115 -0
- data/lib/airbrake-ruby/version.rb +6 -0
- data/spec/airbrake_spec.rb +171 -0
- data/spec/async_sender_spec.rb +154 -0
- data/spec/backtrace_spec.rb +438 -0
- data/spec/code_hunk_spec.rb +118 -0
- data/spec/config/validator_spec.rb +189 -0
- data/spec/config_spec.rb +281 -0
- data/spec/deploy_notifier_spec.rb +41 -0
- data/spec/file_cache.rb +36 -0
- data/spec/filter_chain_spec.rb +83 -0
- data/spec/filters/context_filter_spec.rb +25 -0
- data/spec/filters/dependency_filter_spec.rb +14 -0
- data/spec/filters/exception_attributes_filter_spec.rb +63 -0
- data/spec/filters/gem_root_filter_spec.rb +44 -0
- data/spec/filters/git_last_checkout_filter_spec.rb +48 -0
- data/spec/filters/git_repository_filter.rb +53 -0
- data/spec/filters/git_revision_filter_spec.rb +126 -0
- data/spec/filters/keys_blacklist_spec.rb +236 -0
- data/spec/filters/keys_whitelist_spec.rb +205 -0
- data/spec/filters/root_directory_filter_spec.rb +42 -0
- data/spec/filters/sql_filter_spec.rb +219 -0
- data/spec/filters/system_exit_filter_spec.rb +14 -0
- data/spec/filters/thread_filter_spec.rb +279 -0
- data/spec/fixtures/notroot.txt +7 -0
- data/spec/fixtures/project_root/code.rb +221 -0
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +1 -0
- data/spec/fixtures/project_root/short_file.rb +3 -0
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +5 -0
- data/spec/helpers.rb +9 -0
- data/spec/ignorable_spec.rb +14 -0
- data/spec/nested_exception_spec.rb +75 -0
- data/spec/notice_notifier_spec.rb +436 -0
- data/spec/notice_notifier_spec/options_spec.rb +266 -0
- data/spec/notice_spec.rb +297 -0
- data/spec/performance_notifier_spec.rb +287 -0
- data/spec/promise_spec.rb +165 -0
- data/spec/response_spec.rb +82 -0
- data/spec/spec_helper.rb +102 -0
- data/spec/stat_spec.rb +35 -0
- data/spec/sync_sender_spec.rb +140 -0
- data/spec/tdigest_spec.rb +230 -0
- data/spec/time_truncate_spec.rb +13 -0
- data/spec/truncator_spec.rb +238 -0
- metadata +278 -0
@@ -0,0 +1,287 @@
|
|
1
|
+
RSpec.describe Airbrake::PerformanceNotifier do
|
2
|
+
let(:routes) { 'https://api.airbrake.io/api/v5/projects/1/routes-stats' }
|
3
|
+
let(:queries) { 'https://api.airbrake.io/api/v5/projects/1/queries-stats' }
|
4
|
+
|
5
|
+
let(:config) do
|
6
|
+
Airbrake::Config.new(
|
7
|
+
project_id: 1,
|
8
|
+
project_key: 'banana',
|
9
|
+
performance_stats: true,
|
10
|
+
performance_stats_flush_period: 0
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { described_class.new(config) }
|
15
|
+
|
16
|
+
before do
|
17
|
+
stub_request(:put, routes).to_return(status: 200, body: '')
|
18
|
+
stub_request(:put, queries).to_return(status: 200, body: '')
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#notify" do
|
22
|
+
it "rounds time to the floor minute" do
|
23
|
+
subject.notify(
|
24
|
+
Airbrake::Request.new(
|
25
|
+
method: 'GET',
|
26
|
+
route: '/foo',
|
27
|
+
status_code: 200,
|
28
|
+
start_time: Time.new(2018, 1, 1, 0, 0, 20, 0)
|
29
|
+
)
|
30
|
+
)
|
31
|
+
expect(
|
32
|
+
a_request(:put, routes).with(body: /"time":"2018-01-01T00:00:00\+00:00"/)
|
33
|
+
).to have_been_made
|
34
|
+
end
|
35
|
+
|
36
|
+
it "increments routes with the same key" do
|
37
|
+
subject.notify(
|
38
|
+
Airbrake::Request.new(
|
39
|
+
method: 'GET',
|
40
|
+
route: '/foo',
|
41
|
+
status_code: 200,
|
42
|
+
start_time: Time.new(2018, 1, 1, 0, 0, 20, 0)
|
43
|
+
)
|
44
|
+
)
|
45
|
+
subject.notify(
|
46
|
+
Airbrake::Request.new(
|
47
|
+
method: 'GET',
|
48
|
+
route: '/foo',
|
49
|
+
status_code: 200,
|
50
|
+
start_time: Time.new(2018, 1, 1, 0, 0, 50, 0)
|
51
|
+
)
|
52
|
+
)
|
53
|
+
expect(
|
54
|
+
a_request(:put, routes).with(body: /"count":2/)
|
55
|
+
).to have_been_made
|
56
|
+
end
|
57
|
+
|
58
|
+
it "groups routes by time" do
|
59
|
+
subject.notify(
|
60
|
+
Airbrake::Request.new(
|
61
|
+
method: 'GET',
|
62
|
+
route: '/foo',
|
63
|
+
status_code: 200,
|
64
|
+
start_time: Time.new(2018, 1, 1, 0, 0, 49, 0),
|
65
|
+
end_time: Time.new(2018, 1, 1, 0, 0, 50, 0)
|
66
|
+
)
|
67
|
+
)
|
68
|
+
subject.notify(
|
69
|
+
Airbrake::Request.new(
|
70
|
+
method: 'GET',
|
71
|
+
route: '/foo',
|
72
|
+
status_code: 200,
|
73
|
+
start_time: Time.new(2018, 1, 1, 0, 1, 49, 0),
|
74
|
+
end_time: Time.new(2018, 1, 1, 0, 1, 55, 0)
|
75
|
+
)
|
76
|
+
)
|
77
|
+
expect(
|
78
|
+
a_request(:put, routes).with(
|
79
|
+
body: %r|\A
|
80
|
+
{"routes":\[
|
81
|
+
{"method":"GET","route":"/foo","statusCode":200,
|
82
|
+
"time":"2018-01-01T00:00:00\+00:00","count":1,"sum":1000.0,
|
83
|
+
"sumsq":1000000.0,"tdigest":"AAAAAkA0AAAAAAAAAAAAAUR6AAAB"},
|
84
|
+
{"method":"GET","route":"/foo","statusCode":200,
|
85
|
+
"time":"2018-01-01T00:01:00\+00:00","count":1,"sum":6000.0,
|
86
|
+
"sumsq":36000000.0,"tdigest":"AAAAAkA0AAAAAAAAAAAAAUW7gAAB"}\]}
|
87
|
+
\z|x
|
88
|
+
)
|
89
|
+
).to have_been_made
|
90
|
+
end
|
91
|
+
|
92
|
+
it "groups routes by route key" do
|
93
|
+
subject.notify(
|
94
|
+
Airbrake::Request.new(
|
95
|
+
method: 'GET',
|
96
|
+
route: '/foo',
|
97
|
+
status_code: 200,
|
98
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
99
|
+
end_time: Time.new(2018, 1, 1, 0, 50, 0, 0)
|
100
|
+
)
|
101
|
+
)
|
102
|
+
subject.notify(
|
103
|
+
Airbrake::Request.new(
|
104
|
+
method: 'POST',
|
105
|
+
route: '/foo',
|
106
|
+
status_code: 200,
|
107
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
108
|
+
end_time: Time.new(2018, 1, 1, 0, 50, 0, 0)
|
109
|
+
)
|
110
|
+
)
|
111
|
+
expect(
|
112
|
+
a_request(:put, routes).with(
|
113
|
+
body: %r|\A
|
114
|
+
{"routes":\[
|
115
|
+
{"method":"GET","route":"/foo","statusCode":200,
|
116
|
+
"time":"2018-01-01T00:49:00\+00:00","count":1,"sum":60000.0,
|
117
|
+
"sumsq":3600000000.0,"tdigest":"AAAAAkA0AAAAAAAAAAAAAUdqYAAB"},
|
118
|
+
{"method":"POST","route":"/foo","statusCode":200,
|
119
|
+
"time":"2018-01-01T00:49:00\+00:00","count":1,"sum":60000.0,
|
120
|
+
"sumsq":3600000000.0,"tdigest":"AAAAAkA0AAAAAAAAAAAAAUdqYAAB"}\]}
|
121
|
+
\z|x
|
122
|
+
)
|
123
|
+
).to have_been_made
|
124
|
+
end
|
125
|
+
|
126
|
+
it "returns a promise" do
|
127
|
+
promise = subject.notify(
|
128
|
+
Airbrake::Request.new(
|
129
|
+
method: 'GET',
|
130
|
+
route: '/foo',
|
131
|
+
status_code: 200,
|
132
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
133
|
+
)
|
134
|
+
)
|
135
|
+
expect(promise).to be_an(Airbrake::Promise)
|
136
|
+
expect(promise.value).to eq('' => nil)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "doesn't send route stats when performance stats are disabled" do
|
140
|
+
notifier = described_class.new(
|
141
|
+
Airbrake::Config.new(
|
142
|
+
project_id: 1, project_key: '2', performance_stats: false
|
143
|
+
)
|
144
|
+
)
|
145
|
+
promise = notifier.notify(
|
146
|
+
Airbrake::Request.new(
|
147
|
+
method: 'GET', route: '/foo', status_code: 200, start_time: Time.new
|
148
|
+
)
|
149
|
+
)
|
150
|
+
expect(a_request(:put, routes)).not_to have_been_made
|
151
|
+
expect(promise.value).to eq(
|
152
|
+
'error' => "The Performance Stats feature is disabled"
|
153
|
+
)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "doesn't send route stats when current environment is ignored" do
|
157
|
+
notifier = described_class.new(
|
158
|
+
Airbrake::Config.new(
|
159
|
+
project_id: 1, project_key: '2', performance_stats: true,
|
160
|
+
environment: 'test', ignore_environments: %w[test]
|
161
|
+
)
|
162
|
+
)
|
163
|
+
promise = notifier.notify(
|
164
|
+
Airbrake::Request.new(
|
165
|
+
method: 'GET', route: '/foo', status_code: 200, start_time: Time.new
|
166
|
+
)
|
167
|
+
)
|
168
|
+
expect(a_request(:put, routes)).not_to have_been_made
|
169
|
+
expect(promise.value).to eq('error' => "The 'test' environment is ignored")
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "payload grouping" do
|
173
|
+
let(:flush_period) { 0.5 }
|
174
|
+
|
175
|
+
let(:config) do
|
176
|
+
Airbrake::Config.new(
|
177
|
+
project_id: 1,
|
178
|
+
project_key: 'banana',
|
179
|
+
performance_stats: true,
|
180
|
+
performance_stats_flush_period: flush_period
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "groups payload by performance name and sends it separately" do
|
185
|
+
subject.notify(
|
186
|
+
Airbrake::Request.new(
|
187
|
+
method: 'GET',
|
188
|
+
route: '/foo',
|
189
|
+
status_code: 200,
|
190
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
191
|
+
)
|
192
|
+
)
|
193
|
+
|
194
|
+
subject.notify(
|
195
|
+
Airbrake::Query.new(
|
196
|
+
method: 'POST',
|
197
|
+
route: '/foo',
|
198
|
+
query: 'SELECT * FROM things',
|
199
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
200
|
+
)
|
201
|
+
)
|
202
|
+
|
203
|
+
sleep(flush_period + 0.5)
|
204
|
+
|
205
|
+
expect(a_request(:put, routes)).to have_been_made
|
206
|
+
expect(a_request(:put, queries)).to have_been_made
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "when an ignore filter was defined" do
|
211
|
+
before { subject.add_filter(&:ignore!) }
|
212
|
+
|
213
|
+
it "doesn't notify airbrake of requests" do
|
214
|
+
subject.notify(
|
215
|
+
Airbrake::Request.new(
|
216
|
+
method: 'GET',
|
217
|
+
route: '/foo',
|
218
|
+
status_code: 200,
|
219
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
220
|
+
)
|
221
|
+
)
|
222
|
+
expect(a_request(:put, routes)).not_to have_been_made
|
223
|
+
end
|
224
|
+
|
225
|
+
it "doesn't notify airbrake of queries" do
|
226
|
+
subject.notify(
|
227
|
+
Airbrake::Query.new(
|
228
|
+
method: 'POST',
|
229
|
+
route: '/foo',
|
230
|
+
query: 'SELECT * FROM things',
|
231
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
232
|
+
)
|
233
|
+
)
|
234
|
+
expect(a_request(:put, queries)).not_to have_been_made
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context "when a filter that modifies payload was defined" do
|
239
|
+
before do
|
240
|
+
subject.add_filter do |resource|
|
241
|
+
resource.route = '[Filtered]'
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
it "notifies airbrake with modified payload" do
|
246
|
+
subject.notify(
|
247
|
+
Airbrake::Query.new(
|
248
|
+
method: 'POST',
|
249
|
+
route: '/foo',
|
250
|
+
query: 'SELECT * FROM things',
|
251
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
252
|
+
)
|
253
|
+
)
|
254
|
+
expect(
|
255
|
+
a_request(:put, queries).with(
|
256
|
+
body: /\A{"queries":\[{"method":"POST","route":"\[Filtered\]"/
|
257
|
+
)
|
258
|
+
).to have_been_made
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "#delete_filter" do
|
264
|
+
let(:filter) do
|
265
|
+
Class.new do
|
266
|
+
def call(resource)
|
267
|
+
resource.ignore!
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
before { subject.add_filter(filter.new) }
|
273
|
+
|
274
|
+
it "deletes a filter" do
|
275
|
+
subject.delete_filter(filter)
|
276
|
+
subject.notify(
|
277
|
+
Airbrake::Request.new(
|
278
|
+
method: 'POST',
|
279
|
+
route: '/foo',
|
280
|
+
status_code: 200,
|
281
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0)
|
282
|
+
)
|
283
|
+
)
|
284
|
+
expect(a_request(:put, routes)).to have_been_made
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
RSpec.describe Airbrake::Promise do
|
2
|
+
describe ".then" do
|
3
|
+
let(:resolved_with) { [] }
|
4
|
+
let(:rejected_with) { [] }
|
5
|
+
|
6
|
+
context "when it is not resolved" do
|
7
|
+
it "returns self" do
|
8
|
+
expect(subject.then {}).to eq(subject)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "doesn't call the resolve callbacks yet" do
|
12
|
+
subject.then { resolved_with << 1 }.then { resolved_with << 2 }
|
13
|
+
expect(resolved_with).to be_empty
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when it is resolved" do
|
18
|
+
shared_examples "then specs" do
|
19
|
+
it "returns self" do
|
20
|
+
expect(subject.then {}).to eq(subject)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "yields the resolved value" do
|
24
|
+
yielded = nil
|
25
|
+
subject.then { |value| yielded = value }
|
26
|
+
expect(yielded).to eq('id' => '123')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "calls the resolve callbacks" do
|
30
|
+
expect(resolved_with).to match_array([1, 2])
|
31
|
+
end
|
32
|
+
|
33
|
+
it "doesn't call the reject callbacks" do
|
34
|
+
expect(rejected_with).to be_empty
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "and there are some resolve and reject callbacks in place" do
|
39
|
+
before do
|
40
|
+
subject.then { resolved_with << 1 }.then { resolved_with << 2 }
|
41
|
+
subject.rescue { rejected_with << 1 }.rescue { rejected_with << 2 }
|
42
|
+
subject.resolve('id' => '123')
|
43
|
+
end
|
44
|
+
|
45
|
+
include_examples "then specs"
|
46
|
+
|
47
|
+
it "registers the resolve callbacks" do
|
48
|
+
subject.resolve('id' => '456')
|
49
|
+
expect(resolved_with).to match_array([1, 2, 1, 2])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "and additional then callbacks are added" do
|
54
|
+
before do
|
55
|
+
subject.resolve('id' => '123')
|
56
|
+
subject.then { resolved_with << 1 }.then { resolved_with << 2 }
|
57
|
+
end
|
58
|
+
|
59
|
+
include_examples "then specs"
|
60
|
+
|
61
|
+
it "doesn't register new resolve callbacks" do
|
62
|
+
subject.resolve('id' => '456')
|
63
|
+
expect(resolved_with).to match_array([1, 2])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe ".rescue" do
|
70
|
+
let(:resolved_with) { [] }
|
71
|
+
let(:rejected_with) { [] }
|
72
|
+
|
73
|
+
context "when it is not rejected" do
|
74
|
+
it "returns self" do
|
75
|
+
expect(subject.then {}).to eq(subject)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "doesn't call the reject callbacks yet" do
|
79
|
+
subject.rescue { rejected_with << 1 }.rescue { rejected_with << 2 }
|
80
|
+
expect(rejected_with).to be_empty
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when it is rejected" do
|
85
|
+
shared_examples "rescue specs" do
|
86
|
+
it "returns self" do
|
87
|
+
expect(subject.rescue {}).to eq(subject)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "yields the rejected value" do
|
91
|
+
yielded = nil
|
92
|
+
subject.rescue { |value| yielded = value }
|
93
|
+
expect(yielded).to eq('bingo')
|
94
|
+
end
|
95
|
+
|
96
|
+
it "doesn't call the resolve callbacks" do
|
97
|
+
expect(resolved_with).to be_empty
|
98
|
+
end
|
99
|
+
|
100
|
+
it "calls the reject callbacks" do
|
101
|
+
expect(rejected_with).to match_array([1, 2])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "and there are some resolve and reject callbacks in place" do
|
106
|
+
before do
|
107
|
+
subject.then { resolved_with << 1 }.then { resolved_with << 2 }
|
108
|
+
subject.rescue { rejected_with << 1 }.rescue { rejected_with << 2 }
|
109
|
+
subject.reject('bingo')
|
110
|
+
end
|
111
|
+
|
112
|
+
include_examples "rescue specs"
|
113
|
+
|
114
|
+
it "registers the reject callbacks" do
|
115
|
+
subject.reject('bingo again')
|
116
|
+
expect(rejected_with).to match_array([1, 2, 1, 2])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "and additional reject callbacks are added" do
|
121
|
+
before do
|
122
|
+
subject.reject('bingo')
|
123
|
+
subject.rescue { rejected_with << 1 }.rescue { rejected_with << 2 }
|
124
|
+
end
|
125
|
+
|
126
|
+
include_examples "rescue specs"
|
127
|
+
|
128
|
+
it "doesn't register new reject callbacks" do
|
129
|
+
subject.reject('bingo again')
|
130
|
+
expect(rejected_with).to match_array([1, 2])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe ".resolve" do
|
137
|
+
it "returns self" do
|
138
|
+
expect(subject.resolve(1)).to eq(subject)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "executes callbacks attached with .then" do
|
142
|
+
array = []
|
143
|
+
subject.then { |notice_id| array << notice_id }.rescue { array << 999 }
|
144
|
+
|
145
|
+
expect(array.size).to be_zero
|
146
|
+
subject.resolve(1)
|
147
|
+
expect(array).to match_array([1])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe ".reject" do
|
152
|
+
it "returns self" do
|
153
|
+
expect(subject.reject(1)).to eq(subject)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "executes callbacks attached with .rescue" do
|
157
|
+
array = []
|
158
|
+
subject.then { array << 1 }.rescue { |error| array << error }
|
159
|
+
|
160
|
+
expect(array.size).to be_zero
|
161
|
+
subject.reject(999)
|
162
|
+
expect(array).to match_array([999])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|