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