combi 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57984131b9c91dbbc19bcf4452f74c3396149a70
4
- data.tar.gz: 922c99d9c61e3fd1b6441be10834ff915bc34de3
3
+ metadata.gz: e8d52d86d25a8990c1034e0acfaadb4417164c07
4
+ data.tar.gz: 90ae51a9bf47ce6a2ff6fcfe13ea95fb076a8ba6
5
5
  SHA512:
6
- metadata.gz: f76796d8fc85770a6033a05221fca650bcf4f5246940af218866940fd2d6a445838ec44a7a59557cfe4270192a4c29d929775201849e83994a60d27c9e660a79
7
- data.tar.gz: 452d3fbca7a3d29d14852533adcd48b1bfe6ae740fabb920abbea76885ac63720c79bcb52d91e0b627ec2c5a4f2af72f87d86d471fce724ed860a570760a4922
6
+ metadata.gz: 67235e10e87a924be9c053eead194bf0f6f30f47682a3c13a204d0f77d01354810841664116b2791ae2ade902103d0f9a1c2fe31ca8e6bf6771aa6c7b68b829e
7
+ data.tar.gz: 0d5f694d3db7fc22d18a01cc40d64474a296e4811bf40ac9084347e7c89ae17cc824165c3a7729cc0430a034d6a1e2bcf84aa7d91666bae54917d4f16caeb5ac
@@ -21,9 +21,6 @@ module Combi
21
21
  service_instance.actions.each do |service_name|
22
22
  self.add_routes_for(service_name, service_instance)
23
23
  end
24
- service_instance.fast_actions.each do |service_name|
25
- self.add_routes_for(service_name, service_instance, fast: true)
26
- end
27
24
  service_instance.setup(self, options[:context])
28
25
  end
29
26
 
@@ -93,16 +90,16 @@ module Combi
93
90
  service_class.new
94
91
  end
95
92
 
96
- def add_routes_for(service_name, service_instance, options = {})
93
+ def add_routes_for(service_name, service_instance)
97
94
  service_instance.remote_methods.each do |method|
98
- add_route_for(service_name, method, service_instance, options)
95
+ add_route_for(service_name, method, service_instance)
99
96
  end
100
97
  end
101
98
 
102
- def add_route_for(service_name, action_name, service_instance, options = {})
99
+ def add_route_for(service_name, action_name, service_instance)
103
100
  path = [service_name, action_name].join('/')
104
101
  puts "New route: #{path} :: #{service_instance}"
105
- @routes[path] = {service_instance: service_instance, options: options}
102
+ @routes[path] = service_instance
106
103
  end
107
104
 
108
105
  # Funny name of a exception used to signal that the requested
@@ -114,14 +111,10 @@ module Combi
114
111
 
115
112
  def resolve_route(service_name, kind)
116
113
  path = [service_name, kind].join('/')
117
- handler = @routes[path]
118
- if handler
119
- return service_instance = handler[:service_instance]
120
- else
121
- log "[WARNING] Service Path #{path} not found"
122
- log "[WARNING] routes: #{@routes.keys.inspect}"
123
- raise UnknownStop.new(path)
124
- end
114
+ return @routes[path] if @routes[path]
115
+ log "[WARNING] Service Path #{path} not found"
116
+ log "[WARNING] routes: #{@routes.keys.inspect}"
117
+ raise UnknownStop.new(path)
125
118
  end
126
119
 
127
120
  def invoke_service(service_name, action, params)
@@ -53,17 +53,21 @@ module Combi
53
53
  def request(name, kind, message, options = {})
54
54
  options[:timeout] ||= RPC_DEFAULT_TIMEOUT
55
55
 
56
- correlation_id = Combi::Correlation.generate
57
- waiter = @response_store.wait_for(correlation_id, options[:timeout])
58
56
  url = "#{@options[:remote_api]}#{name}/#{kind}"
59
57
  message_json = Yajl::Encoder.encode(message)
60
58
  request_async = EventMachine::HttpRequest.new(url, connection_timeout: options[:timeout]).post(body: message_json)
61
- request_async.callback do |r|
62
- parsed = Yajl::Parser.parse(r.response, symbolize_keys: true)
63
- waiter.succeed(parsed)
64
- end
65
- request_async.errback do |x|
66
- waiter.fail(Timeout::Error.new)
59
+ if options[:fast]
60
+ waiter = nil
61
+ else
62
+ correlation_id = Combi::Correlation.generate
63
+ waiter = @response_store.wait_for(correlation_id, options[:timeout])
64
+ request_async.callback do |r|
65
+ parsed = Yajl::Parser.parse(r.response, symbolize_keys: true)
66
+ waiter.succeed(parsed)
67
+ end
68
+ request_async.errback do |x|
69
+ waiter.fail(Timeout::Error.new)
70
+ end
67
71
  end
68
72
  waiter
69
73
  end
@@ -5,22 +5,32 @@ module Combi
5
5
 
6
6
  def request(service_name, kind, message, options = {})
7
7
  options[:timeout] ||= RPC_DEFAULT_TIMEOUT
8
- waiter = EventMachine::DefaultDeferrable.new
9
- begin
10
- Timeout.timeout(options[:timeout]) do
11
- message = Yajl::Parser.parse(Yajl::Encoder.encode(message), symbolize_keys: true)
12
- response = invoke_service(service_name, kind, message)
13
- response.callback do |service_response|
14
- waiter.succeed service_response
8
+ message = Yajl::Parser.parse(Yajl::Encoder.encode(message), symbolize_keys: true)
9
+ if options[:fast]
10
+ operation = Proc.new do
11
+ Timeout.timeout(options[:timeout]) do
12
+ invoke_service(service_name, kind, message)
15
13
  end
16
- response.errback do |service_response|
17
- waiter.fail error: service_response
14
+ end
15
+ EM::defer operation
16
+ return nil
17
+ else
18
+ waiter = EventMachine::DefaultDeferrable.new
19
+ begin
20
+ Timeout.timeout(options[:timeout]) do
21
+ response = invoke_service(service_name, kind, message)
22
+ response.callback do |service_response|
23
+ waiter.succeed service_response
24
+ end
25
+ response.errback do |service_response|
26
+ waiter.fail error: service_response
27
+ end
18
28
  end
29
+ rescue Timeout::Error => e
30
+ waiter.fail error: 'Timeout::Error'
19
31
  end
20
- rescue Timeout::Error => e
21
- waiter.fail error: 'Timeout::Error'
32
+ waiter
22
33
  end
23
- waiter
24
34
  end
25
35
  end
26
36
  end
@@ -25,57 +25,61 @@ module Combi
25
25
  end
26
26
  end
27
27
 
28
- def add_routes_for(service_name, service_instance, options = {})
29
- create_queue_for_service(service_name, options)
28
+ def add_routes_for(service_name, service_instance)
29
+ create_queue_for_service(service_name)
30
30
  super
31
31
  end
32
32
 
33
- def create_queue_for_service(service_name, options = {})
33
+ def create_queue_for_service(service_name)
34
34
  log "creating queue #{service_name}"
35
35
  queue_options = {}
36
36
  subscription_options = {}
37
- if options[:fast] == true
38
- queue_options[:auto_delete] = false
39
- else
40
- subscription_options[:ack] = true
41
- end
37
+ subscription_options[:ack] = true
42
38
  queue_service.ready do
43
39
  queue_service.queue(service_name.to_s, queue_options) do |queue|
44
- log "subscribing to queue #{service_name.to_s} with options #{queue_options}"
40
+ log "subscribing to queue #{service_name.to_s}"
45
41
  queue.subscribe(subscription_options) do |delivery_info, payload|
46
- respond service_name, payload, delivery_info
47
- queue_service.acknowledge delivery_info unless options[:fast] == true
42
+ process_queue_message service_name, payload, delivery_info
43
+ queue_service.acknowledge delivery_info
48
44
  end
49
45
  end
50
46
  end
51
47
  end
52
48
 
53
- def request(name, kind, message, options = {})
54
- log "Preparing request: #{name}.#{kind} #{message.inspect[0..500]}\t|| #{options.inspect}"
55
- options[:timeout] ||= RPC_DEFAULT_TIMEOUT
56
- options[:routing_key] = name.to_s
57
- correlation_id = Combi::Correlation.generate
58
- options[:correlation_id] = correlation_id
59
- waiter = @response_store.wait_for(correlation_id, options[:timeout])
49
+ def request(name, kind, message, timeout: RPC_DEFAULT_TIMEOUT, fast: false)
50
+ log "Preparing request: #{name}.#{kind} #{message.inspect[0..500]}\t|| timeout: #{timeout} fast: #{fast}"
51
+ options = {
52
+ timeout: timeout,
53
+ routing_key: name.to_s
54
+ }
55
+ if fast
56
+ waiter = nil
57
+ else
58
+ correlation_id = Combi::Correlation.generate
59
+ options[:correlation_id] = correlation_id
60
+ waiter = @response_store.wait_for correlation_id, timeout
61
+ end
60
62
  queue_service.next_ready_only do
61
63
  log "Making request: #{name}.#{kind} #{message.inspect[0..500]}\t|| #{options.inspect[0..500]}"
62
- queue_service.call(kind, message, options)
64
+ queue_service.publish_request(kind, message, options)
63
65
  end
64
66
  waiter
65
67
  end
66
68
 
67
- def respond(service_name, request, delivery_info)
69
+ def process_queue_message(service_name, request, delivery_info)
68
70
  message = Yajl::Parser.parse request, symbolize_keys: true
69
71
  kind = message[:kind]
70
72
  payload = message[:payload]
71
73
  options = message[:options]
72
74
  response = invoke_service(service_name, kind, payload)
73
- response.callback do |service_response|
74
- queue_service.respond service_response, delivery_info
75
- end
76
- response.errback do |service_response|
77
- failure_response = { error: service_response }
78
- queue_service.respond failure_response, delivery_info
75
+ if delivery_info.reply_to
76
+ response.callback do |service_response|
77
+ queue_service.respond service_response, delivery_info
78
+ end
79
+ response.errback do |service_response|
80
+ failure_response = { error: service_response }
81
+ queue_service.respond failure_response, delivery_info
82
+ end
79
83
  end
80
84
  end
81
85
 
@@ -32,10 +32,6 @@ module Combi
32
32
  session && session.close
33
33
  end
34
34
 
35
- def ws
36
- @ws
37
- end
38
-
39
35
  end
40
36
 
41
37
  class Client
@@ -52,7 +48,7 @@ module Combi
52
48
  end
53
49
 
54
50
  def stop!
55
- @ws && @ws.close
51
+ ws && ws.close
56
52
  @bus.log "stop requested"
57
53
  end
58
54
 
@@ -90,7 +86,6 @@ module Combi
90
86
  end
91
87
 
92
88
  def ws
93
- @bus.log "ws present: #{@ws != nil}"
94
89
  @ws
95
90
  end
96
91
 
@@ -175,32 +170,41 @@ module Combi
175
170
  response = {error: {klass: e.class.name, message: e.message, backtrace: e.backtrace } }
176
171
  end
177
172
 
178
- msg = {result: 'ok', correlation_id: message[:correlation_id]}
173
+ if message[:correlation_id]
174
+ # The client is insterested in a response
175
+ msg = {result: 'ok', correlation_id: message[:correlation_id]}
179
176
 
180
- response.callback do |service_response|
181
- msg[:response] = service_response
182
- serialized = Yajl::Encoder.encode msg
183
- ws.send serialized
184
- end
185
- response.errback do |service_response|
186
- msg[:response] = {error: service_response}
187
- serialized = Yajl::Encoder.encode msg
188
- ws.send serialized
177
+ response.callback do |service_response|
178
+ msg[:response] = service_response
179
+ send_response ws, msg
180
+ end
181
+ response.errback do |service_response|
182
+ msg[:response] = {error: service_response}
183
+ send_response ws, msg
184
+ end
189
185
  end
190
186
  end
191
187
 
192
- def request(name, kind, message, options = {})
193
- options[:timeout] ||= RPC_DEFAULT_TIMEOUT
194
- correlation_id = Combi::Correlation.generate
188
+ def send_response(ws, message)
189
+ serialized = Yajl::Encoder.encode message
190
+ ws.send serialized
191
+ end
192
+
193
+ def request(name, kind, message, timeout: RPC_DEFAULT_TIMEOUT, fast: false, ws: nil)
195
194
  msg = {
196
195
  service: name,
197
196
  kind: kind,
198
- payload: message,
199
- correlation_id: correlation_id
197
+ payload: message
200
198
  }
201
- waiter = @response_store.wait_for(correlation_id, options[:timeout])
199
+ if fast
200
+ waiter = nil
201
+ else
202
+ correlation_id = Combi::Correlation.generate
203
+ msg[:correlation_id] = correlation_id
204
+ waiter = @response_store.wait_for(correlation_id, timeout)
205
+ end
202
206
  @ready.callback do |r|
203
- web_socket = @machine.ws || options[:ws]
207
+ web_socket = @machine.respond_to?(:ws) ? @machine.ws : ws
204
208
  unless web_socket.nil?
205
209
  serialized = Yajl::Encoder.encode msg
206
210
  log "sending request #{serialized}"
@@ -114,12 +114,13 @@ module Combi
114
114
  end
115
115
  end
116
116
 
117
- def call(kind, message, options = {})
118
- log "sending request #{kind} #{message.inspect[0..500]} with options #{options.inspect}"
119
- raise "RPC is not enabled or reply_to is not included" if (@rpc_queue.nil? || @rpc_queue.name.nil?) && options[:reply_to].nil?
117
+ def publish_request(kind, message, options = {})
118
+ if options.has_key? :correlation_id
119
+ # wants a response
120
+ options[:reply_to] = @rpc_queue.name
121
+ end
120
122
  options[:expiration] = ((options[:timeout] || RPC_DEFAULT_TIMEOUT) * 1000).to_i
121
- options[:routing_key] ||= 'rcalls_queue'
122
- options[:reply_to] ||= @rpc_queue.name
123
+ log "sending request #{kind} #{message.inspect[0..500]} with options #{options.inspect}"
123
124
  request = Yajl::Encoder.encode kind: kind, payload: message, options: {}
124
125
  publish request, options
125
126
  end
@@ -6,6 +6,7 @@ module Combi
6
6
  context[:service_bus] = service_bus
7
7
  setup_context(context)
8
8
  setup_services
9
+ self
9
10
  end
10
11
 
11
12
  def setup_context(context)
@@ -32,10 +33,6 @@ module Combi
32
33
  []
33
34
  end
34
35
 
35
- def fast_actions
36
- []
37
- end
38
-
39
36
  def remote_methods
40
37
  @_REMOTE_METHODS ||= public_methods(false) - Combi::Service.public_instance_methods
41
38
  end
@@ -1,3 +1,3 @@
1
1
  module Combi
2
- VERSION = '0.2.1'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -17,7 +17,7 @@ describe 'Combi::Bus' do
17
17
  Given(:path) { 'class/remote' }
18
18
  When { bus.add_service service_definition }
19
19
  Then { bus.routes.keys.length == 1 }
20
- And { bus.routes[path][:service_instance] == service_definition }
20
+ And { bus.routes[path] == service_definition }
21
21
  end
22
22
 
23
23
  context 'via modules' do
@@ -34,7 +34,7 @@ describe 'Combi::Bus' do
34
34
  puts bus.routes.keys.inspect
35
35
  }
36
36
  Then { bus.routes.keys.length == 1 }
37
- And { bus.routes[path][:service_instance].is_a? service_definition }
37
+ And { bus.routes[path].is_a? service_definition }
38
38
  end
39
39
  end
40
40
  end
@@ -49,6 +49,24 @@ describe 'Combi::Queue' do
49
49
  end
50
50
  end
51
51
 
52
+ context 'fire and forget' do
53
+ describe 'does not send a response' do
54
+ When(:service) { provider.add_service null_service }
55
+ Then do
56
+ em do
57
+ expect(provider.queue_service).not_to receive(:respond)
58
+ expect(service).to receive(:do_it) do
59
+ done
60
+ provider.stop!
61
+ consumer.stop!
62
+ end
63
+ prepare
64
+ consumer.request :null, :do_it, {}, fast: true
65
+ end
66
+ end
67
+ end
68
+ end
69
+
52
70
  context "it resist a reconnection" do
53
71
  puts "VERY UNSTABLE TEST"
54
72
  When(:service) { provider.add_service null_service }
@@ -46,6 +46,23 @@ describe 'Combi::WebSocket' do
46
46
  end
47
47
  end
48
48
 
49
+ context 'fire and forget' do
50
+ describe 'does not send a response' do
51
+ When(:service) { provider.add_service null_service }
52
+ Then do
53
+ em do
54
+ expect(provider).not_to receive(:send_response)
55
+ expect(service).to receive(:do_it) do
56
+ done
57
+ provider.stop!
58
+ consumer.stop!
59
+ end
60
+ prepare
61
+ consumer.request :null, :do_it, {}, fast: true
62
+ end
63
+ end
64
+ end
65
+ end
49
66
 
50
67
  context 'it notify when the connection is opened' do
51
68
  Then do
@@ -38,165 +38,254 @@ shared_examples_for "standard_bus" do
38
38
  end
39
39
  end
40
40
 
41
+ Given(:calculator_service) do
42
+ Module.new do
43
+ def actions; [:calculator]; end
44
+ def incr(params)
45
+ @counter += 1
46
+ end
47
+ def initialize
48
+ @counter = 0
49
+ end
50
+ def counter
51
+ @counter
52
+ end
53
+ end
54
+ end
55
+
41
56
  Given(:finalize) do
42
57
  provider.stop!
43
58
  consumer.stop!
44
59
  end
45
60
 
46
- context 'can invoke services' do
47
- When(:service) { provider.add_service boring_salutation_service }
48
- When(:params) { { who: 'world' } }
49
- Then do
50
- em do
51
- prepare
52
- EM.synchrony do
53
- service_result = EM::Synchrony.sync consumer.request(:say_hello, :do_it, params, { timeout: 2 })
54
- service_result.should eq "Hello world"
55
- done
56
- finalize
61
+ context 'fire and forget' do
62
+ context 'can invoke services' do
63
+ When(:service) { provider.add_service calculator_service }
64
+ When(:params) { { who: 'world' } }
65
+ When(:service_response) do
66
+ srv_resp = "UNSET"
67
+ em do
68
+ prepare
69
+ EM.synchrony do
70
+ srv_resp = consumer.request(:calculator, :incr, {}, {fast: true})
71
+ spec_waiter = EM::DefaultDeferrable.new
72
+ EM.add_periodic_timer 0.1 do
73
+ spec_waiter.succeed service.counter if service.counter == 1
74
+ end
75
+ EM::Synchrony.sync spec_waiter
76
+ done
77
+ finalize
78
+ end
57
79
  end
80
+ srv_resp
58
81
  end
82
+ Then { service_response.should_not be_a EM::Deferrable }
83
+ And { service_response.should be_nil }
84
+ And { service.counter.should eq 1 }
59
85
  end
60
- end
61
86
 
62
- context 'fails with error => Timeout::Error when the response is slow' do
63
- Given(:time_base) { 0.01 }
64
- When(:params) { { time: time_base*4 } }
65
- When(:service) { provider.add_service slow_service }
66
- Then do
67
- em do
68
- prepare
69
- EM.synchrony do
70
- service_result = EM::Synchrony.sync consumer.request(:sleep, :do_it, params, { timeout: time_base/2.0 })
71
- service_result.should be_a Hash
72
- service_result.should have_key :error
73
- service_result[:error].should eq 'Timeout::Error'
74
- done(time_base) #timeout response must came before this timeout
87
+ context 'ignores service errors' do
88
+ Given(:error_message) { 'service is broken' }
89
+ When(:service) { provider.add_service broken_service }
90
+ Then do
91
+ em do
92
+ prepare
93
+ EM.synchrony do
94
+ service_result = consumer.request(:shout_error, :do_it, {message: error_message}, { fast: true })
95
+ service_result.should be_nil
96
+ done
97
+ finalize
98
+ end
75
99
  end
76
- finalize
77
100
  end
78
101
  end
79
- end
80
102
 
81
- context 'return the same data type returned by service' do
82
- Given(:result_container) { {} }
83
- Given(:params) { { data: data } }
84
- When(:service) { provider.add_service echo_service }
85
- When('service is called') do
86
- em do
87
- prepare
88
- EM.synchrony do
89
- result_container[:result] = EM::Synchrony.sync consumer.request(:echo_this, :do_it, params)
90
- done
91
- finalize
103
+ context 'ignores unknown services' do
104
+ Then do
105
+ em do
106
+ prepare
107
+ EM.synchrony do
108
+ service_result = consumer.request(:mssing_service, :do_it, {}, { fast: true })
109
+ service_result.should be_nil
110
+ done
111
+ finalize
112
+ end
92
113
  end
93
114
  end
94
115
  end
116
+ end
95
117
 
96
- context 'for string' do
97
- Given(:data) { "a simple string" }
98
- Then { result_container[:result].should eq data}
118
+ context 'ignores service errors' do
119
+ When(:service) { provider.add_service boring_salutation_service }
120
+ Then do
121
+ em do
122
+ prepare
123
+ EM.synchrony do
124
+ service_result = consumer.request(:say_hello, :to_no_one, {}, { fast: true })
125
+ service_result.should be_nil
126
+ done
127
+ finalize
128
+ end
129
+ end
130
+ end
99
131
  end
100
132
 
101
- context 'for numbers' do
102
- Given(:data) { 237.324 }
103
- Then { result_container[:result].should eq data}
133
+ context 'expecting response' do
134
+ context 'can invoke services' do
135
+ When(:service) { provider.add_service boring_salutation_service }
136
+ When(:params) { { who: 'world' } }
137
+ Then do
138
+ em do
139
+ prepare
140
+ EM.synchrony do
141
+ service_result = EM::Synchrony.sync consumer.request(:say_hello, :do_it, params, { timeout: 2 })
142
+ service_result.should eq "Hello world"
143
+ done
144
+ finalize
145
+ end
146
+ end
147
+ end
104
148
  end
105
149
 
106
- context 'for arrays' do
107
- Given(:data) { [1, 2, 3.0, "4", "cinco"]}
108
- Then { result_container[:result].should eq data}
150
+ context 'fails with error => Timeout::Error when the response is slow' do
151
+ Given(:time_base) { 0.01 }
152
+ When(:params) { { time: time_base*4 } }
153
+ When(:service) { provider.add_service slow_service }
154
+ Then do
155
+ em do
156
+ prepare
157
+ EM.synchrony do
158
+ service_result = EM::Synchrony.sync consumer.request(:sleep, :do_it, params, { timeout: time_base/2.0 })
159
+ service_result.should be_a Hash
160
+ service_result.should have_key :error
161
+ service_result[:error].should eq 'Timeout::Error'
162
+ done(time_base) #timeout response must came before this timeout
163
+ end
164
+ finalize
165
+ end
166
+ end
109
167
  end
110
168
 
111
- context 'for symbols always return a string' do
112
- Given(:data) { :some_symbol }
113
- Then { result_container[:result].should eq data.to_s}
114
- end
169
+ context 'return the same data type returned by service' do
170
+ Given(:result_container) { {} }
171
+ Given(:params) { { data: data } }
172
+ When(:service) { provider.add_service echo_service }
173
+ When('service is called') do
174
+ em do
175
+ prepare
176
+ EM.synchrony do
177
+ result_container[:result] = EM::Synchrony.sync consumer.request(:echo_this, :do_it, params)
178
+ done
179
+ finalize
180
+ end
181
+ end
182
+ end
115
183
 
116
- context 'for maps' do
117
- context 'with string keys' do
118
- Given(:data) { {'a' => 1, 'b' => 'dos'} }
119
- Then { result_container[:result].keys.should eq data.keys.map(&:to_sym)}
120
- And { result_container[:result].values.should eq data.values }
184
+ context 'for string' do
185
+ Given(:data) { "a simple string" }
186
+ Then { result_container[:result].should eq data}
121
187
  end
122
- context 'with symbol keys' do
123
- Given(:data) { {a: 1, b: 'dos'} }
188
+
189
+ context 'for numbers' do
190
+ Given(:data) { 237.324 }
124
191
  Then { result_container[:result].should eq data}
125
192
  end
126
- end
127
193
 
128
- context 'for objects returns their json version' do
129
- Given(:custom_json) { {val: 'value'} }
130
- Given(:custom_class) do
131
- Class.new do
132
- def initialize(custom_json)
133
- @custom_json = custom_json
134
- end
135
- def to_json
136
- @custom_json
194
+ context 'for arrays' do
195
+ Given(:data) { [1, 2, 3.0, "4", "cinco"]}
196
+ Then { result_container[:result].should eq data}
197
+ end
198
+
199
+ context 'for symbols always return a string' do
200
+ Given(:data) { :some_symbol }
201
+ Then { result_container[:result].should eq data.to_s}
202
+ end
203
+
204
+ context 'for maps' do
205
+ context 'with string keys' do
206
+ Given(:data) { {'a' => 1, 'b' => 'dos'} }
207
+ Then { result_container[:result].keys.should eq data.keys.map(&:to_sym)}
208
+ And { result_container[:result].values.should eq data.values }
209
+ end
210
+ context 'with symbol keys' do
211
+ Given(:data) { {a: 1, b: 'dos'} }
212
+ Then { result_container[:result].should eq data}
213
+ end
214
+ end
215
+
216
+ context 'for objects returns their json version' do
217
+ Given(:custom_json) { {val: 'value'} }
218
+ Given(:custom_class) do
219
+ Class.new do
220
+ def initialize(custom_json)
221
+ @custom_json = custom_json
222
+ end
223
+ def to_json
224
+ @custom_json
225
+ end
137
226
  end
138
227
  end
228
+ Given(:data) { custom_class.new(custom_json).to_json}
229
+ Then { result_container[:result].should eq custom_json}
139
230
  end
140
- Given(:data) { custom_class.new(custom_json).to_json}
141
- Then { result_container[:result].should eq custom_json}
142
231
  end
143
- end
144
232
 
145
- context 'return something when service raise an error' do
146
- Given(:error_message) { 'service is broken' }
147
- When(:service) { provider.add_service broken_service }
148
- Then do
149
- em do
150
- prepare
151
- EM.synchrony do
152
- service_result = EM::Synchrony.sync consumer.request(:shout_error, :do_it, {message: error_message}, { timeout: 0.1 })
153
- service_result[:error].should be_a Hash
154
- service_result[:error][:message].should eq error_message
155
- service_result[:error][:backtrace].should_not be_nil
156
- service_result[:error][:backtrace].should be_an Array
157
- done
158
- finalize
233
+ context 'return something when service raise an error' do
234
+ Given(:error_message) { 'service is broken' }
235
+ When(:service) { provider.add_service broken_service }
236
+ Then do
237
+ em do
238
+ prepare
239
+ EM.synchrony do
240
+ service_result = EM::Synchrony.sync consumer.request(:shout_error, :do_it, {message: error_message}, { timeout: 0.1 })
241
+ service_result[:error].should be_a Hash
242
+ service_result[:error][:message].should eq error_message
243
+ service_result[:error][:backtrace].should_not be_nil
244
+ service_result[:error][:backtrace].should be_an Array
245
+ done
246
+ finalize
247
+ end
159
248
  end
160
249
  end
161
250
  end
162
- end
163
251
 
164
- context 'return an error when requesting an unknown service' do
165
- Given(:error_message) { Combi::Bus::UnknownStop.name }
166
- When(:service) { provider.add_service broken_service }
167
- Then do
168
- em do
169
- prepare
170
- EM.synchrony do
171
- begin
172
- service_result = EM::Synchrony.sync consumer.request(:some_not_service, :do_it, {}, { timeout: 0.1 })
173
- if defined?(Combi::Queue) and consumer.class == Combi::Queue
174
- service_result[:error].should eq "Timeout::Error"
175
- else
176
- service_result[:error][:klass].should eq error_message
177
- service_result[:error][:message].should eq 'some_not_service/do_it'
252
+ context 'return an error when requesting an unknown service' do
253
+ Given(:error_message) { Combi::Bus::UnknownStop.name }
254
+ When(:service) { provider.add_service broken_service }
255
+ Then do
256
+ em do
257
+ prepare
258
+ EM.synchrony do
259
+ begin
260
+ service_result = EM::Synchrony.sync consumer.request(:some_not_service, :do_it, {}, { timeout: 0.1 })
261
+ if defined?(Combi::Queue) and consumer.class == Combi::Queue
262
+ service_result[:error].should eq "Timeout::Error"
263
+ else
264
+ service_result[:error][:klass].should eq error_message
265
+ service_result[:error][:message].should eq 'some_not_service/do_it'
266
+ end
267
+ done
268
+ finalize
178
269
  end
179
- done
180
- finalize
181
270
  end
182
271
  end
183
272
  end
184
273
  end
185
- end
186
274
 
187
- context 'return an error when requesting an unknown action for the service' do
188
- Given(:error_message) { Combi::Bus::UnknownStop.name }
189
- When(:service) { provider.add_service echo_service }
190
- Then do
191
- em do
192
- prepare
193
- EM.synchrony do
194
- begin
195
- service_result = EM::Synchrony.sync consumer.request(:echo_this, :do_other, {}, { timeout: 0.1 })
196
- service_result[:error][:klass].should eq error_message
197
- service_result[:error][:message].should eq 'echo_this/do_other'
198
- done
199
- finalize
275
+ context 'return an error when requesting an unknown action for the service' do
276
+ Given(:error_message) { Combi::Bus::UnknownStop.name }
277
+ When(:service) { provider.add_service echo_service }
278
+ Then do
279
+ em do
280
+ prepare
281
+ EM.synchrony do
282
+ begin
283
+ service_result = EM::Synchrony.sync consumer.request(:echo_this, :do_other, {}, { timeout: 0.1 })
284
+ service_result[:error][:klass].should eq error_message
285
+ service_result[:error][:message].should eq 'echo_this/do_other'
286
+ done
287
+ finalize
288
+ end
200
289
  end
201
290
  end
202
291
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: combi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - German Del Zotto