protobuf-cucumber 3.10.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.
Files changed (204) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rubocop.yml +70 -0
  4. data/.rubocop_todo.yml +145 -0
  5. data/.travis.yml +40 -0
  6. data/.yardopts +5 -0
  7. data/CHANGES.md +344 -0
  8. data/CONTRIBUTING.md +16 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +33 -0
  12. data/Rakefile +64 -0
  13. data/bin/protoc-gen-ruby +22 -0
  14. data/bin/rpc_server +5 -0
  15. data/install-protobuf.sh +28 -0
  16. data/lib/protobuf.rb +129 -0
  17. data/lib/protobuf/cli.rb +257 -0
  18. data/lib/protobuf/code_generator.rb +120 -0
  19. data/lib/protobuf/decoder.rb +28 -0
  20. data/lib/protobuf/deprecation.rb +117 -0
  21. data/lib/protobuf/descriptors.rb +3 -0
  22. data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
  23. data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -0
  24. data/lib/protobuf/encoder.rb +11 -0
  25. data/lib/protobuf/enum.rb +365 -0
  26. data/lib/protobuf/exceptions.rb +9 -0
  27. data/lib/protobuf/field.rb +74 -0
  28. data/lib/protobuf/field/base_field.rb +380 -0
  29. data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
  30. data/lib/protobuf/field/bool_field.rb +64 -0
  31. data/lib/protobuf/field/bytes_field.rb +78 -0
  32. data/lib/protobuf/field/double_field.rb +25 -0
  33. data/lib/protobuf/field/enum_field.rb +61 -0
  34. data/lib/protobuf/field/field_array.rb +104 -0
  35. data/lib/protobuf/field/field_hash.rb +122 -0
  36. data/lib/protobuf/field/fixed32_field.rb +25 -0
  37. data/lib/protobuf/field/fixed64_field.rb +28 -0
  38. data/lib/protobuf/field/float_field.rb +43 -0
  39. data/lib/protobuf/field/int32_field.rb +21 -0
  40. data/lib/protobuf/field/int64_field.rb +34 -0
  41. data/lib/protobuf/field/integer_field.rb +23 -0
  42. data/lib/protobuf/field/message_field.rb +51 -0
  43. data/lib/protobuf/field/sfixed32_field.rb +27 -0
  44. data/lib/protobuf/field/sfixed64_field.rb +28 -0
  45. data/lib/protobuf/field/signed_integer_field.rb +29 -0
  46. data/lib/protobuf/field/sint32_field.rb +21 -0
  47. data/lib/protobuf/field/sint64_field.rb +21 -0
  48. data/lib/protobuf/field/string_field.rb +51 -0
  49. data/lib/protobuf/field/uint32_field.rb +21 -0
  50. data/lib/protobuf/field/uint64_field.rb +21 -0
  51. data/lib/protobuf/field/varint_field.rb +77 -0
  52. data/lib/protobuf/generators/base.rb +85 -0
  53. data/lib/protobuf/generators/enum_generator.rb +39 -0
  54. data/lib/protobuf/generators/extension_generator.rb +27 -0
  55. data/lib/protobuf/generators/field_generator.rb +193 -0
  56. data/lib/protobuf/generators/file_generator.rb +262 -0
  57. data/lib/protobuf/generators/group_generator.rb +122 -0
  58. data/lib/protobuf/generators/message_generator.rb +104 -0
  59. data/lib/protobuf/generators/option_generator.rb +17 -0
  60. data/lib/protobuf/generators/printable.rb +160 -0
  61. data/lib/protobuf/generators/service_generator.rb +50 -0
  62. data/lib/protobuf/lifecycle.rb +33 -0
  63. data/lib/protobuf/logging.rb +39 -0
  64. data/lib/protobuf/message.rb +260 -0
  65. data/lib/protobuf/message/fields.rb +233 -0
  66. data/lib/protobuf/message/serialization.rb +85 -0
  67. data/lib/protobuf/optionable.rb +70 -0
  68. data/lib/protobuf/rpc/buffer.rb +78 -0
  69. data/lib/protobuf/rpc/client.rb +140 -0
  70. data/lib/protobuf/rpc/connectors/base.rb +221 -0
  71. data/lib/protobuf/rpc/connectors/ping.rb +89 -0
  72. data/lib/protobuf/rpc/connectors/socket.rb +78 -0
  73. data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
  74. data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
  75. data/lib/protobuf/rpc/env.rb +60 -0
  76. data/lib/protobuf/rpc/error.rb +28 -0
  77. data/lib/protobuf/rpc/error/client_error.rb +31 -0
  78. data/lib/protobuf/rpc/error/server_error.rb +43 -0
  79. data/lib/protobuf/rpc/middleware.rb +25 -0
  80. data/lib/protobuf/rpc/middleware/exception_handler.rb +40 -0
  81. data/lib/protobuf/rpc/middleware/logger.rb +95 -0
  82. data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
  83. data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
  84. data/lib/protobuf/rpc/middleware/runner.rb +18 -0
  85. data/lib/protobuf/rpc/rpc.pb.rb +64 -0
  86. data/lib/protobuf/rpc/rpc_method.rb +16 -0
  87. data/lib/protobuf/rpc/server.rb +39 -0
  88. data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
  89. data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
  90. data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
  91. data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
  92. data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
  93. data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
  94. data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
  95. data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
  96. data/lib/protobuf/rpc/service.rb +172 -0
  97. data/lib/protobuf/rpc/service_directory.rb +261 -0
  98. data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
  99. data/lib/protobuf/rpc/service_filters.rb +250 -0
  100. data/lib/protobuf/rpc/stat.rb +119 -0
  101. data/lib/protobuf/socket.rb +21 -0
  102. data/lib/protobuf/tasks.rb +1 -0
  103. data/lib/protobuf/tasks/compile.rake +80 -0
  104. data/lib/protobuf/varint.rb +20 -0
  105. data/lib/protobuf/varint_pure.rb +31 -0
  106. data/lib/protobuf/version.rb +3 -0
  107. data/lib/protobuf/wire_type.rb +10 -0
  108. data/lib/protobuf/zmq.rb +21 -0
  109. data/profile.html +5103 -0
  110. data/proto/dynamic_discovery.proto +44 -0
  111. data/proto/google/protobuf/compiler/plugin.proto +147 -0
  112. data/proto/google/protobuf/descriptor.proto +779 -0
  113. data/proto/rpc.proto +69 -0
  114. data/protobuf-cucumber.gemspec +57 -0
  115. data/spec/benchmark/tasks.rb +143 -0
  116. data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
  117. data/spec/encoding/all_types_spec.rb +103 -0
  118. data/spec/encoding/extreme_values_spec.rb +0 -0
  119. data/spec/functional/class_inheritance_spec.rb +52 -0
  120. data/spec/functional/code_generator_spec.rb +58 -0
  121. data/spec/functional/socket_server_spec.rb +59 -0
  122. data/spec/functional/zmq_server_spec.rb +105 -0
  123. data/spec/lib/protobuf/cli_spec.rb +317 -0
  124. data/spec/lib/protobuf/code_generator_spec.rb +87 -0
  125. data/spec/lib/protobuf/enum_spec.rb +307 -0
  126. data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
  127. data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
  128. data/spec/lib/protobuf/field/enum_field_spec.rb +44 -0
  129. data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
  130. data/spec/lib/protobuf/field/field_hash_spec.rb +168 -0
  131. data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
  132. data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
  133. data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
  134. data/spec/lib/protobuf/field/int32_field_spec.rb +120 -0
  135. data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
  136. data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
  137. data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
  138. data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
  139. data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
  140. data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
  141. data/spec/lib/protobuf/field/string_field_spec.rb +79 -0
  142. data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
  143. data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
  144. data/spec/lib/protobuf/field_spec.rb +192 -0
  145. data/spec/lib/protobuf/generators/base_spec.rb +154 -0
  146. data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
  147. data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
  148. data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
  149. data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
  150. data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
  151. data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
  152. data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
  153. data/spec/lib/protobuf/message_spec.rb +944 -0
  154. data/spec/lib/protobuf/optionable_spec.rb +265 -0
  155. data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
  156. data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
  157. data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
  158. data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
  159. data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -0
  160. data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
  161. data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
  162. data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
  163. data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +91 -0
  164. data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
  165. data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
  166. data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
  167. data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
  168. data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
  169. data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +35 -0
  170. data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
  171. data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
  172. data/spec/lib/protobuf/rpc/stat_spec.rb +101 -0
  173. data/spec/lib/protobuf/varint_spec.rb +29 -0
  174. data/spec/lib/protobuf_spec.rb +105 -0
  175. data/spec/spec_helper.rb +42 -0
  176. data/spec/support/all.rb +6 -0
  177. data/spec/support/packed_field.rb +23 -0
  178. data/spec/support/protos/all_types.data.bin +0 -0
  179. data/spec/support/protos/all_types.data.txt +119 -0
  180. data/spec/support/protos/enum.pb.rb +63 -0
  181. data/spec/support/protos/enum.proto +37 -0
  182. data/spec/support/protos/extreme_values.data.bin +0 -0
  183. data/spec/support/protos/google_unittest.bin +0 -0
  184. data/spec/support/protos/google_unittest.pb.rb +798 -0
  185. data/spec/support/protos/google_unittest.proto +884 -0
  186. data/spec/support/protos/google_unittest_custom_options.bin +0 -0
  187. data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
  188. data/spec/support/protos/google_unittest_custom_options.proto +424 -0
  189. data/spec/support/protos/google_unittest_import.pb.rb +55 -0
  190. data/spec/support/protos/google_unittest_import.proto +73 -0
  191. data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
  192. data/spec/support/protos/google_unittest_import_public.proto +41 -0
  193. data/spec/support/protos/map-test.bin +157 -0
  194. data/spec/support/protos/map-test.pb.rb +85 -0
  195. data/spec/support/protos/map-test.proto +68 -0
  196. data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
  197. data/spec/support/protos/multi_field_extensions.proto +35 -0
  198. data/spec/support/protos/resource.pb.rb +172 -0
  199. data/spec/support/protos/resource.proto +137 -0
  200. data/spec/support/resource_service.rb +23 -0
  201. data/spec/support/server.rb +65 -0
  202. data/spec/support/test_app_file.rb +2 -0
  203. data/varint_prof.rb +82 -0
  204. metadata +579 -0
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'protobuf/rpc/service_dispatcher'
3
+
4
+ RSpec.describe Protobuf::Rpc::ServiceDispatcher do
5
+ let(:app) { proc { |env| env } }
6
+ let(:env) do
7
+ Protobuf::Rpc::Env.new(
8
+ 'method_name' => method_name,
9
+ 'request' => request,
10
+ 'rpc_service' => service_class,
11
+ 'service_name' => service_name,
12
+ )
13
+ end
14
+ let(:method_name) { :find }
15
+ let(:request) { request_type.new(:name => 'required') }
16
+ let(:request_type) { service_class.rpcs[method_name].request_type }
17
+ let(:response) { response_type.new(:name => 'required') }
18
+ let(:response_type) { service_class.rpcs[method_name].response_type }
19
+ let(:rpc_service) { service_class.new(env) }
20
+ let(:service_class) { Test::ResourceService }
21
+ let(:service_name) { service_class.to_s }
22
+
23
+ subject { described_class.new(app) }
24
+
25
+ before { allow(subject).to receive(:rpc_service).and_return(rpc_service) }
26
+
27
+ describe '#call' do
28
+ before { allow(rpc_service).to receive(:response).and_return(response) }
29
+
30
+ it "dispatches the request" do
31
+ stack_env = subject._call(env)
32
+ expect(stack_env.response).to eq response
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,517 @@
1
+ require 'spec_helper'
2
+
3
+ class FilterTest
4
+ include Protobuf::Rpc::ServiceFilters
5
+
6
+ attr_accessor :called
7
+
8
+ # Initialize the hash keys as instance vars
9
+ def initialize(ivar_hash)
10
+ @called = []
11
+ ivar_hash.each_pair do |key, value|
12
+ self.class.class_eval do
13
+ attr_accessor key
14
+ end
15
+ __send__("#{key}=", value)
16
+ end
17
+ end
18
+
19
+ def endpoint
20
+ @called << :endpoint
21
+ end
22
+
23
+ def self.clear_filters!
24
+ @defined_filters = nil
25
+ @filters = nil
26
+ @rescue_filters = nil
27
+ end
28
+ end
29
+
30
+ RSpec.describe Protobuf::Rpc::ServiceFilters do
31
+ let(:params) { {} }
32
+ subject { FilterTest.new(params) }
33
+ after(:each) { FilterTest.clear_filters! }
34
+
35
+ describe '#before_filter' do
36
+ let(:params) { { :before_filter_calls => 0 } }
37
+
38
+ before(:all) do
39
+ class FilterTest
40
+ private
41
+
42
+ def verify_before
43
+ @called << :verify_before
44
+ @before_filter_calls += 1
45
+ end
46
+
47
+ def foo
48
+ @called << :foo
49
+ end
50
+ end
51
+ end
52
+
53
+ before do
54
+ FilterTest.before_filter(:verify_before)
55
+ FilterTest.before_filter(:verify_before)
56
+ FilterTest.before_filter(:foo)
57
+ end
58
+
59
+ specify { expect(subject.class).to respond_to(:before_filter) }
60
+ specify { expect(subject.class).to respond_to(:before_action) }
61
+
62
+ it 'calls filters in the order they were defined' do
63
+ subject.__send__(:run_filters, :endpoint)
64
+ expect(subject.called).to eq [:verify_before, :foo, :endpoint]
65
+ expect(subject.before_filter_calls).to eq 1
66
+ end
67
+
68
+ context 'when filter is configured with "only"' do
69
+ before(:all) do
70
+ class FilterTest
71
+ private
72
+
73
+ def endpoint_with_verify
74
+ @called << :endpoint_with_verify
75
+ end
76
+ end
77
+ end
78
+
79
+ before do
80
+ FilterTest.clear_filters!
81
+ FilterTest.before_filter(:verify_before, :only => :endpoint_with_verify)
82
+ end
83
+
84
+ context 'when invoking a method defined in "only" option' do
85
+ it 'invokes the filter' do
86
+ subject.__send__(:run_filters, :endpoint_with_verify)
87
+ expect(subject.called).to eq [:verify_before, :endpoint_with_verify]
88
+ end
89
+ end
90
+
91
+ context 'when invoking a method not defined by "only" option' do
92
+ it 'does not invoke the filter' do
93
+ subject.__send__(:run_filters, :endpoint)
94
+ expect(subject.called).to eq [:endpoint]
95
+ end
96
+ end
97
+ end
98
+
99
+ context 'when filter is configured with "except"' do
100
+ before(:all) do
101
+ class FilterTest
102
+ private
103
+
104
+ def endpoint_without_verify
105
+ @called << :endpoint_without_verify
106
+ end
107
+ end
108
+ end
109
+
110
+ before do
111
+ FilterTest.clear_filters!
112
+ FilterTest.before_filter(:verify_before, :except => :endpoint_without_verify)
113
+ end
114
+
115
+ context 'when invoking a method not defined in "except" option' do
116
+ it 'invokes the filter' do
117
+ subject.__send__(:run_filters, :endpoint)
118
+ expect(subject.called).to eq [:verify_before, :endpoint]
119
+ end
120
+ end
121
+
122
+ context 'when invoking a method defined by "except" option' do
123
+ it 'does not invoke the filter' do
124
+ subject.__send__(:run_filters, :endpoint_without_verify)
125
+ expect(subject.called).to eq [:endpoint_without_verify]
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'when filter is configured with "if"' do
131
+ before(:all) do
132
+ class FilterTest
133
+ private
134
+
135
+ def check_true
136
+ true
137
+ end
138
+
139
+ def check_false
140
+ false
141
+ end
142
+
143
+ def verify_before
144
+ @called << :verify_before
145
+ end
146
+ end
147
+ end
148
+
149
+ context 'when "if" option is a method that returns true' do
150
+ before do
151
+ FilterTest.clear_filters!
152
+ FilterTest.before_filter(:verify_before, :if => :check_true)
153
+ end
154
+
155
+ it 'invokes the filter' do
156
+ subject.__send__(:run_filters, :endpoint)
157
+ expect(subject.called).to eq [:verify_before, :endpoint]
158
+ end
159
+ end
160
+
161
+ context 'when "if" option is a callable that returns true' do
162
+ before do
163
+ FilterTest.clear_filters!
164
+ FilterTest.before_filter(:verify_before, :if => ->(_service) { true })
165
+ end
166
+
167
+ it 'invokes the filter' do
168
+ subject.__send__(:run_filters, :endpoint)
169
+ expect(subject.called).to eq [:verify_before, :endpoint]
170
+ end
171
+ end
172
+
173
+ context 'when "if" option is a method that returns false' do
174
+ before do
175
+ FilterTest.clear_filters!
176
+ FilterTest.before_filter(:verify_before, :if => :check_false)
177
+ end
178
+
179
+ it 'skips the filter' do
180
+ subject.__send__(:run_filters, :endpoint)
181
+ expect(subject.called).to eq [:endpoint]
182
+ end
183
+ end
184
+
185
+ context 'when "if" option is a callable that returns false' do
186
+ before do
187
+ FilterTest.clear_filters!
188
+ FilterTest.before_filter(:verify_before, :if => ->(_service) { false })
189
+ end
190
+
191
+ it 'skips the filter' do
192
+ subject.__send__(:run_filters, :endpoint)
193
+ expect(subject.called).to eq [:endpoint]
194
+ end
195
+ end
196
+ end
197
+
198
+ context 'when filter is configured with "unless"' do
199
+ before(:all) do
200
+ class FilterTest
201
+ private
202
+
203
+ def check_true
204
+ true
205
+ end
206
+
207
+ def check_false
208
+ false
209
+ end
210
+
211
+ def verify_before
212
+ @called << :verify_before
213
+ end
214
+ end
215
+ end
216
+
217
+ context 'when "unless" option is a method that returns false' do
218
+ before do
219
+ FilterTest.clear_filters!
220
+ FilterTest.before_filter(:verify_before, :unless => :check_false)
221
+ end
222
+
223
+ it 'invokes the filter' do
224
+ subject.__send__(:run_filters, :endpoint)
225
+ expect(subject.called).to eq [:verify_before, :endpoint]
226
+ end
227
+ end
228
+
229
+ context 'when "unless" option is a callable that returns true' do
230
+ before do
231
+ FilterTest.clear_filters!
232
+ FilterTest.before_filter(:verify_before, :unless => ->(_service) { false })
233
+ end
234
+
235
+ it 'invokes the filter' do
236
+ subject.__send__(:run_filters, :endpoint)
237
+ expect(subject.called).to eq [:verify_before, :endpoint]
238
+ end
239
+ end
240
+
241
+ context 'when "unless" option is a method that returns false' do
242
+ before do
243
+ FilterTest.clear_filters!
244
+ FilterTest.before_filter(:verify_before, :unless => :check_true)
245
+ end
246
+
247
+ it 'skips the filter' do
248
+ subject.__send__(:run_filters, :endpoint)
249
+ expect(subject.called).to eq [:endpoint]
250
+ end
251
+ end
252
+
253
+ context 'when "unless" option is a callable that returns false' do
254
+ before do
255
+ FilterTest.clear_filters!
256
+ FilterTest.before_filter(:verify_before, :unless => ->(_service) { true })
257
+ end
258
+
259
+ it 'skips the filter' do
260
+ subject.__send__(:run_filters, :endpoint)
261
+ expect(subject.called).to eq [:endpoint]
262
+ end
263
+ end
264
+ end
265
+
266
+ context 'when filter returns false' do
267
+ before(:all) do
268
+ class FilterTest
269
+ private
270
+
271
+ def short_circuit_filter
272
+ @called << :short_circuit_filter
273
+ false
274
+ end
275
+ end
276
+ end
277
+
278
+ before do
279
+ FilterTest.clear_filters!
280
+ FilterTest.before_filter(:short_circuit_filter)
281
+ end
282
+
283
+ it 'does not invoke the rpc method' do
284
+ expect(subject).not_to receive(:endpoint)
285
+ subject.__send__(:run_filters, :endpoint)
286
+ expect(subject.called).to eq [:short_circuit_filter]
287
+ end
288
+ end
289
+ end
290
+
291
+ describe '#after_filter' do
292
+ let(:params) { { :after_filter_calls => 0 } }
293
+
294
+ before(:all) do
295
+ class FilterTest
296
+ private
297
+
298
+ def verify_after
299
+ @called << :verify_after
300
+ @after_filter_calls += 1
301
+ end
302
+
303
+ def foo
304
+ @called << :foo
305
+ end
306
+ end
307
+ end
308
+
309
+ before do
310
+ FilterTest.after_filter(:verify_after)
311
+ FilterTest.after_filter(:verify_after)
312
+ FilterTest.after_filter(:foo)
313
+ end
314
+
315
+ specify { expect(subject.class).to respond_to(:after_filter) }
316
+ specify { expect(subject.class).to respond_to(:after_action) }
317
+
318
+ it 'calls filters in the order they were defined' do
319
+ subject.__send__(:run_filters, :endpoint)
320
+ expect(subject.called).to eq [:endpoint, :verify_after, :foo]
321
+ expect(subject.after_filter_calls).to eq 1
322
+ end
323
+ end
324
+
325
+ describe '#around_filter' do
326
+ let(:params) { {} }
327
+
328
+ before(:all) do
329
+ class FilterTest
330
+ private
331
+
332
+ def outer_around
333
+ @called << :outer_around_top
334
+ yield
335
+ @called << :outer_around_bottom
336
+ end
337
+
338
+ def inner_around
339
+ @called << :inner_around_top
340
+ yield
341
+ @called << :inner_around_bottom
342
+ end
343
+ end
344
+ end
345
+
346
+ before do
347
+ FilterTest.around_filter(:outer_around)
348
+ FilterTest.around_filter(:inner_around)
349
+ FilterTest.around_filter(:outer_around)
350
+ FilterTest.around_filter(:inner_around)
351
+ end
352
+
353
+ specify { expect(subject.class).to respond_to(:around_filter) }
354
+ specify { expect(subject.class).to respond_to(:around_action) }
355
+
356
+ it 'calls filters in the order they were defined' do
357
+ subject.__send__(:run_filters, :endpoint)
358
+ expect(subject.called).to eq(
359
+ [
360
+ :outer_around_top,
361
+ :inner_around_top,
362
+ :endpoint,
363
+ :inner_around_bottom,
364
+ :outer_around_bottom,
365
+ ],
366
+ )
367
+ end
368
+
369
+ context 'when around_filter does not yield' do
370
+ before do
371
+ class FilterTest
372
+ private
373
+
374
+ def inner_around
375
+ @called << :inner_around
376
+ end
377
+ end
378
+ end
379
+
380
+ before do
381
+ FilterTest.around_filter(:outer_around)
382
+ FilterTest.around_filter(:inner_around)
383
+ end
384
+
385
+ it 'cancels calling the rest of the filters and the endpoint' do
386
+ expect(subject).not_to receive(:endpoint)
387
+ subject.__send__(:run_filters, :endpoint)
388
+ expect(subject.called).to eq(
389
+ [
390
+ :outer_around_top,
391
+ :inner_around,
392
+ :outer_around_bottom,
393
+ ],
394
+ )
395
+ end
396
+
397
+ end
398
+ end
399
+
400
+ describe '#rescue_from' do
401
+ before do
402
+ class CustomError1 < StandardError; end
403
+ class CustomError2 < StandardError; end
404
+ class CustomError3 < StandardError; end
405
+ end
406
+
407
+ before do
408
+ class FilterTest
409
+ private
410
+
411
+ def filter_with_error1
412
+ @called << :filter_with_error1
413
+ fail CustomError1, 'Filter 1 failed'
414
+ end
415
+
416
+ def filter_with_error2
417
+ @called << :filter_with_error2
418
+ fail CustomError1, 'Filter 2 failed'
419
+ end
420
+
421
+ def filter_with_error3
422
+ @called << :filter_with_error3
423
+ fail CustomError3, 'Filter 3 failed'
424
+ end
425
+
426
+ def filter_with_runtime_error
427
+ @called << :filter_with_runtime_error
428
+ fail 'Filter with runtime error failed'
429
+ end
430
+
431
+ def custom_error_occurred(ex)
432
+ @ex_class = ex.class
433
+ @called << :custom_error_occurred
434
+ end
435
+ end
436
+ end
437
+
438
+ let(:params) { { :ex_class => nil } }
439
+
440
+ context 'when defining multiple errors with a given callback' do
441
+ before do
442
+ FilterTest.rescue_from(CustomError1, CustomError2, CustomError3, :with => :custom_error_occurred)
443
+ end
444
+ before { FilterTest.before_filter(:filter_with_error3) }
445
+
446
+ it 'short-circuits the call stack' do
447
+ expect do
448
+ expect(subject).not_to receive(:endpoint)
449
+ subject.__send__(:run_filters, :endpoint)
450
+ expect(subject.called).to eq([:filter_with_error3, :custom_error_occurred])
451
+ expect(subject.ex_class).to eq CustomError3
452
+ end.not_to raise_error
453
+ end
454
+ end
455
+
456
+ context 'when defined with options' do
457
+ context 'when :with option is not given' do
458
+ specify do
459
+ expect { FilterTest.rescue_from(CustomError1) }.to raise_error(ArgumentError, /with/)
460
+ end
461
+ end
462
+
463
+ context 'when error occurs inside filter' do
464
+ before { FilterTest.rescue_from(CustomError1, :with => :custom_error_occurred) }
465
+ before { FilterTest.before_filter(:filter_with_error1) }
466
+
467
+ it 'short-circuits the call stack' do
468
+ expect do
469
+ expect(subject).not_to receive(:endpoint)
470
+ subject.__send__(:run_filters, :endpoint)
471
+ expect(subject.called).to eq([:filter_with_error1, :custom_error_occurred])
472
+ expect(subject.ex_class).to eq CustomError1
473
+ end.not_to raise_error
474
+ end
475
+ end
476
+ end
477
+
478
+ context 'when defined with block' do
479
+ before do
480
+ FilterTest.rescue_from(CustomError1) do |service, ex|
481
+ service.ex_class = ex.class
482
+ service.called << :block_rescue_handler
483
+ end
484
+ end
485
+ before { FilterTest.before_filter(:filter_with_error1) }
486
+
487
+ it 'short-circuits the call stack' do
488
+ expect do
489
+ expect(subject).not_to receive(:endpoint)
490
+ subject.__send__(:run_filters, :endpoint)
491
+ expect(subject.called).to eq([:filter_with_error1, :block_rescue_handler])
492
+ expect(subject.ex_class).to eq CustomError1
493
+ end.not_to raise_error
494
+ end
495
+ end
496
+
497
+ context 'when thrown exception inherits from a mapped exception' do
498
+ before do
499
+ FilterTest.rescue_from(StandardError) do |service, ex|
500
+ service.ex_class = ex.class
501
+ service.called << :standard_error_rescue_handler
502
+ end
503
+ end
504
+ before { FilterTest.before_filter(:filter_with_runtime_error) }
505
+
506
+ it 'rescues with the given callable' do
507
+ expect do
508
+ expect(subject).not_to receive(:endpoint)
509
+ subject.__send__(:run_filters, :endpoint)
510
+ expect(subject.called).to eq([:filter_with_runtime_error, :standard_error_rescue_handler])
511
+ expect(subject.ex_class).to eq RuntimeError
512
+ end.not_to raise_error
513
+ end
514
+ end
515
+ end
516
+
517
+ end