combi 0.2.1 → 0.3.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 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