ably-rest 0.9.2 → 0.9.3

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: 006c13b2408ff07c78159727a7e0bbd1a2eea9ab
4
- data.tar.gz: 691848a554d61eb6c785cc7515f169e36bed8241
3
+ metadata.gz: 610101b34de5bd5283cda560a5aff2d115842529
4
+ data.tar.gz: 499b0a8ec74ab12356b7e8e94330f13283670458
5
5
  SHA512:
6
- metadata.gz: 5ef3a684409bf54433d1c81b76da2555e6aa885dc547e4c11c8e4e94f24adf25c56cc84a2613f5d8b11c03294126a5b03b826a6a744820e1765b7eb4433eebf5
7
- data.tar.gz: 562e4212388a59f3b53e699ff1933a1d02563b3c62af75370919c8dba10b984013e43a38bc73a33b364fe65952537d02d96eb77b30953e2c1df9d81382caf7fa
6
+ metadata.gz: 650f6502ebfd7dd5f3183cb1bb42f98be067145859a4e3d39a692e1abb38c3dbf18cd0b363a6d21a586321c04288900c63b914625e5a082436e9f8c8220c1bdd
7
+ data.tar.gz: f5926a4f1d213782974e1c5cd79ac4cb12c6dac941eafb7d8de2a6f49cc6c9e25b4e028de177d6da4ee40ba230d1d0062b8bda289b39d437f9015600c9c56d54
@@ -48,7 +48,10 @@ Gem::Specification.new do |spec|
48
48
  spec.add_development_dependency 'yard', '~> 0.9'
49
49
  spec.add_development_dependency 'webmock', '~> 2.0'
50
50
 
51
- unless RUBY_VERSION.match(/^1/)
51
+ if RUBY_VERSION.match(/^1/)
52
+ spec.add_development_dependency 'public_suffix', '~> 1.4.6' # Later versions do not support Ruby 1.9
53
+ else
54
+ spec.add_development_dependency 'coveralls'
52
55
  spec.add_development_dependency 'pry'
53
56
  spec.add_development_dependency 'pry-byebug'
54
57
  end
@@ -40,11 +40,10 @@ Gem::Specification.new do |spec|
40
40
  spec.add_development_dependency 'yard', '~> 0.9'
41
41
  spec.add_development_dependency 'webmock', '~> 2.0'
42
42
 
43
- unless RUBY_VERSION.match(/^1/)
43
+ if RUBY_VERSION.match(/^1/)
44
+ spec.add_development_dependency 'public_suffix', '~> 1.4.6' # Later versions do not support Ruby 1.9
45
+ else
44
46
  spec.add_development_dependency 'coveralls'
45
- end
46
-
47
- unless RUBY_VERSION.match(/^1/)
48
47
  spec.add_development_dependency 'pry'
49
48
  spec.add_development_dependency 'pry-byebug'
50
49
  end
@@ -96,7 +96,8 @@ module Ably::Models::MessageEncoders
96
96
  end
97
97
 
98
98
  # @api private
99
- def self.register_default_encoders(client, binary_protocol: false)
99
+ def self.register_default_encoders(client, options = {})
100
+ binary_protocol = !!options[:binary_protocol]
100
101
  client.register_encoder Ably::Models::MessageEncoders::Utf8
101
102
  client.register_encoder Ably::Models::MessageEncoders::Json
102
103
  client.register_encoder Ably::Models::MessageEncoders::Cipher
@@ -50,18 +50,14 @@ module Ably
50
50
  #
51
51
  # @return [void]
52
52
  def on(*event_names, &block)
53
- event_names.each do |event_name|
54
- callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block)
55
- end
53
+ add_callback event_names, proc_for_block(block)
56
54
  end
57
55
 
58
56
  # Equivalent of {#on} but any exception raised in a block will bubble up and cause this client library to fail.
59
57
  # This method should only be used internally by the client library.
60
58
  # @api private
61
59
  def unsafe_on(*event_names, &block)
62
- event_names.each do |event_name|
63
- callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, unsafe: true)
64
- end
60
+ add_callback event_names, proc_for_block(block, unsafe: true)
65
61
  end
66
62
 
67
63
  # On receiving an event maching the event_name, call the provided block only once and remove the registered callback
@@ -70,24 +66,20 @@ module Ably
70
66
  #
71
67
  # @return [void]
72
68
  def once(*event_names, &block)
73
- event_names.each do |event_name|
74
- callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, delete_once_run: true)
75
- end
69
+ add_callback event_names, proc_for_block(block, delete_once_run: true)
76
70
  end
77
71
 
78
72
  # Equivalent of {#once} but any exception raised in a block will bubble up and cause this client library to fail.
79
73
  # This method should only be used internally by the client library.
80
74
  # @api private
81
75
  def unsafe_once(*event_names, &block)
82
- event_names.each do |event_name|
83
- callbacks[callbacks_event_coerced(event_name)] << proc_for_block(block, delete_once_run: true, unsafe: true)
84
- end
76
+ add_callback event_names, proc_for_block(block, delete_once_run: true, unsafe: true)
85
77
  end
86
78
 
87
79
  # Emit an event with event_name that will in turn call all matching callbacks setup with `on`
88
80
  def emit(event_name, *args)
89
- callbacks[callbacks_event_coerced(event_name)].
90
- clone.
81
+ [callbacks_any, callbacks[callbacks_event_coerced(event_name)]].each do |callback_arr|
82
+ callback_arr.clone.
91
83
  select do |proc_hash|
92
84
  if proc_hash[:unsafe]
93
85
  proc_hash[:emit_proc].call(*args)
@@ -95,8 +87,9 @@ module Ably
95
87
  safe_yield proc_hash[:emit_proc], *args
96
88
  end
97
89
  end.each do |callback|
98
- callbacks[callbacks_event_coerced(event_name)].delete callback
90
+ callback_arr.delete callback
99
91
  end
92
+ end
100
93
  end
101
94
 
102
95
  # Remove all callbacks for event_name.
@@ -121,6 +114,14 @@ module Ably
121
114
  callbacks[callbacks_event_coerced(event_name)].clear
122
115
  end
123
116
  end
117
+
118
+ if event_names.empty?
119
+ if block_given?
120
+ callbacks_any.delete_if { |proc_hash| proc_hash[:block] == block }
121
+ else
122
+ callbacks_any.clear
123
+ end
124
+ end
124
125
  end
125
126
 
126
127
  private
@@ -128,6 +129,16 @@ module Ably
128
129
  klass.extend ClassMethods
129
130
  end
130
131
 
132
+ def add_callback(event_names, proc_block)
133
+ if event_names.empty?
134
+ callbacks_any << proc_block
135
+ else
136
+ event_names.each do |event_name|
137
+ callbacks[callbacks_event_coerced(event_name)] << proc_block
138
+ end
139
+ end
140
+ end
141
+
131
142
  # Create a Hash with a proc that calls the provided block and returns true if option :delete_once_run is set to true.
132
143
  # #emit automatically deletes any blocks that return true thus allowing a block to be run once
133
144
  def proc_for_block(block, options = {})
@@ -145,6 +156,10 @@ module Ably
145
156
  @callbacks ||= Hash.new { |hash, key| hash[key] = [] }
146
157
  end
147
158
 
159
+ def callbacks_any
160
+ @callbacks_any ||= []
161
+ end
162
+
148
163
  def callbacks_event_coerced(event_name)
149
164
  if self.class.event_emitter_coerce_proc
150
165
  self.class.event_emitter_coerce_proc.call(event_name)
@@ -1,3 +1,5 @@
1
+ require 'uri'
2
+
1
3
  module Ably
2
4
  module Realtime
3
5
  # Client for the Ably Realtime API
@@ -68,6 +70,9 @@ module Ably
68
70
  #
69
71
  # @param (see Ably::Rest::Client#initialize)
70
72
  # @option options (see Ably::Rest::Client#initialize)
73
+ # @option options [Proc] :auth_callback when provided, the Proc will be called with the token params hash as the first argument, whenever a new token is required.
74
+ # Whilst the proc is called synchronously, it does not block the EventMachine reactor as it is run in a separate thread.
75
+ # The Proc should return a token string, {Ably::Models::TokenDetails} or JSON equivalent, {Ably::Models::TokenRequest} or JSON equivalent
71
76
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
72
77
  # @option options [Boolean] :echo_messages If false, prevents messages originating from this connection being echoed back on the same connection
73
78
  # @option options [String] :recover When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
@@ -3,12 +3,12 @@ require 'ably/rest/channels'
3
3
  require 'ably/rest/client'
4
4
  require 'ably/rest/presence'
5
5
 
6
+ require 'ably/models/message_encoders/base'
7
+
6
8
  Dir.glob(File.expand_path("models/*.rb", File.dirname(__FILE__))).each do |file|
7
9
  require file
8
10
  end
9
11
 
10
- require 'ably/models/message_encoders/base'
11
-
12
12
  module Ably
13
13
  # Rest provides the top-level class to be instanced for the Ably Rest library
14
14
  #
@@ -1,6 +1,7 @@
1
1
  require 'faraday'
2
2
  require 'json'
3
3
  require 'logger'
4
+ require 'uri'
4
5
 
5
6
  require 'ably/rest/middleware/exceptions'
6
7
 
@@ -1,5 +1,5 @@
1
1
  module Ably
2
- VERSION = '0.9.2'
2
+ VERSION = '0.9.3'
3
3
  PROTOCOL_VERSION = '0.9'
4
4
 
5
5
  # Allow a variant to be configured for all instances of this client library
@@ -186,6 +186,35 @@ describe Ably::Realtime::Auth, :event_machine do
186
186
  end
187
187
  end
188
188
 
189
+ context 'with auth_callback blocking' do
190
+ let(:rest_auth_client) { Ably::Rest::Client.new(default_options.merge(key: api_key)) }
191
+ let(:client_options) { default_options.merge(auth_callback: auth_callback) }
192
+ let(:pause) { 5 }
193
+
194
+ context 'with a slow auth callback response' do
195
+ let(:auth_callback) do
196
+ Proc.new do
197
+ sleep pause
198
+ rest_auth_client.auth.request_token
199
+ end
200
+ end
201
+
202
+ it 'asynchronously authenticates' do
203
+ timers_called = 0
204
+ block = Proc.new do
205
+ timers_called += 1
206
+ EventMachine.add_timer(0.5, &block)
207
+ end
208
+ block.call
209
+ client.connect
210
+ client.connection.on(:connected) do
211
+ expect(timers_called).to be >= (pause-1) / 0.5
212
+ stop_reactor
213
+ end
214
+ end
215
+ end
216
+ end
217
+
189
218
  context 'when implicitly called, with an explicit ClientOptions client_id' do
190
219
  let(:client_id) { random_str }
191
220
  let(:client_options) { default_options.merge(auth_callback: Proc.new { auth_token_object }, client_id: client_id, log_level: :none) }
@@ -1278,6 +1278,22 @@ describe Ably::Realtime::Connection, :event_machine do
1278
1278
  end
1279
1279
 
1280
1280
  context 'connection state change' do
1281
+ # See https://github.com/ably/ably-ruby/issues/103
1282
+ it 'emits event to all and single subscribers' do
1283
+ connected_emitted = []
1284
+ block = Proc.new do |state_change|
1285
+ if state_change.current == :connected
1286
+ connected_emitted << state_change
1287
+ EventMachine.add_timer(0.5) do
1288
+ expect(connected_emitted.length).to eql(2)
1289
+ stop_reactor
1290
+ end
1291
+ end
1292
+ end
1293
+ connection.on(&block)
1294
+ connection.on(:connected, &block)
1295
+ end
1296
+
1281
1297
  it 'emits a ConnectionStateChange object' do
1282
1298
  connection.on(:connected) do |connection_state_change|
1283
1299
  expect(connection_state_change).to be_a(Ably::Models::ConnectionStateChange)
@@ -128,17 +128,34 @@ describe Ably::Modules::EventEmitter do
128
128
  end
129
129
 
130
130
  context '#on' do
131
- it 'calls the block every time an event is emitted only' do
132
- block_called = 0
133
- subject.on('event') { block_called += 1 }
134
- 3.times { subject.emit 'event', 'data' }
135
- expect(block_called).to eql(3)
131
+ context 'with event specified' do
132
+ it 'calls the block every time an event is emitted only' do
133
+ block_called = 0
134
+ subject.on('event') { block_called += 1 }
135
+ 3.times { subject.emit 'event', 'data' }
136
+ expect(block_called).to eql(3)
137
+ end
138
+
139
+ it 'catches exceptions in the provided block, logs the error and continues' do
140
+ expect(subject.logger).to receive(:error).with(/Intentional exception/)
141
+ subject.on(:event) { raise 'Intentional exception' }
142
+ subject.emit :event
143
+ end
136
144
  end
137
145
 
138
- it 'catches exceptions in the provided block, logs the error and continues' do
139
- expect(subject.logger).to receive(:error).with(/Intentional exception/)
140
- subject.on(:event) { raise 'Intentional exception' }
141
- subject.emit :event
146
+ context 'with no event specified' do
147
+ it 'calls the block every time an event is emitted only' do
148
+ block_called = 0
149
+ subject.on { block_called += 1 }
150
+ 3.times { subject.emit 'event', 'data' }
151
+ expect(block_called).to eql(3)
152
+ end
153
+
154
+ it 'catches exceptions in the provided block, logs the error and continues' do
155
+ expect(subject.logger).to receive(:error).with(/Intentional exception/)
156
+ subject.on { raise 'Intentional exception' }
157
+ subject.emit :event
158
+ end
142
159
  end
143
160
  end
144
161
 
@@ -157,25 +174,50 @@ describe Ably::Modules::EventEmitter do
157
174
  end
158
175
 
159
176
  context '#once' do
160
- it 'calls the block the first time an event is emitted only' do
161
- block_called = 0
162
- subject.once('event') { block_called += 1 }
163
- 3.times { subject.emit 'event', 'data' }
164
- expect(block_called).to eql(1)
165
- end
177
+ context 'with event specified' do
178
+ it 'calls the block the first time an event is emitted only' do
179
+ block_called = 0
180
+ subject.once('event') { block_called += 1 }
181
+ 3.times { subject.emit 'event', 'data' }
182
+ expect(block_called).to eql(1)
183
+ end
166
184
 
167
- it 'does not remove other blocks after it is called' do
168
- block_called = 0
169
- subject.once('event') { block_called += 1 }
170
- subject.on('event') { block_called += 1 }
171
- 3.times { subject.emit 'event', 'data' }
172
- expect(block_called).to eql(4)
185
+ it 'does not remove other blocks after it is called' do
186
+ block_called = 0
187
+ subject.once('event') { block_called += 1 }
188
+ subject.on('event') { block_called += 1 }
189
+ 3.times { subject.emit 'event', 'data' }
190
+ expect(block_called).to eql(4)
191
+ end
192
+
193
+ it 'catches exceptions in the provided block, logs the error and continues' do
194
+ expect(subject.logger).to receive(:error).with(/Intentional exception/)
195
+ subject.once(:event) { raise 'Intentional exception' }
196
+ subject.emit :event
197
+ end
173
198
  end
174
199
 
175
- it 'catches exceptions in the provided block, logs the error and continues' do
176
- expect(subject.logger).to receive(:error).with(/Intentional exception/)
177
- subject.once(:event) { raise 'Intentional exception' }
178
- subject.emit :event
200
+ context 'with no event specified' do
201
+ it 'calls the block the first time an event is emitted only' do
202
+ block_called = 0
203
+ subject.once { block_called += 1 }
204
+ 3.times { subject.emit 'event', 'data' }
205
+ expect(block_called).to eql(1)
206
+ end
207
+
208
+ it 'does not remove other blocks after it is called' do
209
+ block_called = 0
210
+ subject.once { block_called += 1 }
211
+ subject.on { block_called += 1 }
212
+ 3.times { subject.emit 'event', 'data' }
213
+ expect(block_called).to eql(4)
214
+ end
215
+
216
+ it 'catches exceptions in the provided block, logs the error and continues' do
217
+ expect(subject.logger).to receive(:error).with(/Intentional exception/)
218
+ subject.once { raise 'Intentional exception' }
219
+ subject.emit :event
220
+ end
179
221
  end
180
222
  end
181
223
 
@@ -196,41 +238,57 @@ describe Ably::Modules::EventEmitter do
196
238
  context '#off' do
197
239
  let(:callback) { Proc.new { |msg| obj.received_message msg } }
198
240
 
199
- before do
200
- subject.on(:message, &callback)
201
- end
202
-
203
- after do
204
- subject.emit :message, msg
205
- end
241
+ context 'with event specified in on handler' do
242
+ before do
243
+ subject.on(:message, &callback)
244
+ end
206
245
 
207
- context 'with event names as arguments' do
208
- it 'deletes matching callbacks' do
209
- expect(obj).to_not receive(:received_message).with(msg)
210
- subject.off(:message, &callback)
246
+ after do
247
+ subject.emit :message, msg
211
248
  end
212
249
 
213
- it 'deletes all callbacks if not block given' do
214
- expect(obj).to_not receive(:received_message).with(msg)
215
- subject.off(:message)
250
+ context 'with event names as arguments' do
251
+ it 'deletes matching callbacks' do
252
+ expect(obj).to_not receive(:received_message).with(msg)
253
+ subject.off(:message, &callback)
254
+ end
255
+
256
+ it 'deletes all callbacks if not block given' do
257
+ expect(obj).to_not receive(:received_message).with(msg)
258
+ subject.off(:message)
259
+ end
260
+
261
+ it 'continues if the block does not exist' do
262
+ expect(obj).to receive(:received_message).with(msg)
263
+ subject.off(:message) { true }
264
+ end
216
265
  end
217
266
 
218
- it 'continues if the block does not exist' do
219
- expect(obj).to receive(:received_message).with(msg)
220
- subject.off(:message) { true }
267
+ context 'without any event names' do
268
+ it 'deletes all matching callbacks' do
269
+ expect(obj).to_not receive(:received_message).with(msg)
270
+ subject.off(&callback)
271
+ end
272
+
273
+ it 'deletes all callbacks if not block given' do
274
+ expect(obj).to_not receive(:received_message).with(msg)
275
+ subject.off
276
+ end
221
277
  end
222
278
  end
223
279
 
224
- context 'without any event names' do
225
- it 'deletes all matching callbacks' do
226
- expect(obj).to_not receive(:received_message).with(msg)
227
- subject.off(&callback)
228
- end
280
+ it 'removes handler added with no event specified' do
281
+ subject.on(&callback)
282
+ expect(obj).to_not receive(:received_message).with(msg)
283
+ subject.off(&callback)
284
+ subject.emit :message, msg
285
+ end
229
286
 
230
- it 'deletes all callbacks if not block given' do
231
- expect(obj).to_not receive(:received_message).with(msg)
232
- subject.off
233
- end
287
+ it 'leaves handler when event specified' do
288
+ subject.on(&callback)
289
+ expect(obj).to receive(:received_message).with(msg)
290
+ subject.off(:foo, &callback)
291
+ subject.emit :message, msg
234
292
  end
235
293
  end
236
294
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew O'Riordan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-17 00:00:00.000000000 Z
11
+ date: 2016-12-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: '2.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: coveralls
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: pry
169
183
  requirement: !ruby/object:Gem::Requirement