ably 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +42 -48
  4. data/SPEC.md +1099 -640
  5. data/ably.gemspec +10 -4
  6. data/lib/ably/auth.rb +155 -47
  7. data/lib/ably/exceptions.rb +2 -0
  8. data/lib/ably/models/channel_state_change.rb +2 -3
  9. data/lib/ably/models/connection_details.rb +54 -0
  10. data/lib/ably/models/protocol_message.rb +14 -4
  11. data/lib/ably/models/token_details.rb +13 -7
  12. data/lib/ably/models/token_request.rb +1 -2
  13. data/lib/ably/modules/ably.rb +3 -2
  14. data/lib/ably/modules/message_emitter.rb +1 -3
  15. data/lib/ably/modules/state_emitter.rb +2 -2
  16. data/lib/ably/realtime/auth.rb +6 -0
  17. data/lib/ably/realtime/channel/channel_manager.rb +2 -0
  18. data/lib/ably/realtime/channel.rb +15 -4
  19. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +11 -1
  20. data/lib/ably/realtime/client.rb +10 -3
  21. data/lib/ably/realtime/connection/connection_manager.rb +58 -54
  22. data/lib/ably/realtime/connection.rb +62 -6
  23. data/lib/ably/realtime/presence.rb +18 -5
  24. data/lib/ably/rest/channel.rb +9 -1
  25. data/lib/ably/rest/client.rb +32 -14
  26. data/lib/ably/rest/presence.rb +1 -1
  27. data/lib/ably/version.rb +1 -1
  28. data/lib/ably.rb +2 -0
  29. data/spec/acceptance/realtime/auth_spec.rb +251 -11
  30. data/spec/acceptance/realtime/channel_history_spec.rb +12 -2
  31. data/spec/acceptance/realtime/channel_spec.rb +316 -24
  32. data/spec/acceptance/realtime/client_spec.rb +93 -1
  33. data/spec/acceptance/realtime/connection_failures_spec.rb +177 -86
  34. data/spec/acceptance/realtime/connection_spec.rb +284 -60
  35. data/spec/acceptance/realtime/message_spec.rb +45 -6
  36. data/spec/acceptance/realtime/presence_history_spec.rb +4 -0
  37. data/spec/acceptance/realtime/presence_spec.rb +181 -49
  38. data/spec/acceptance/realtime/time_spec.rb +13 -0
  39. data/spec/acceptance/rest/auth_spec.rb +222 -4
  40. data/spec/acceptance/rest/channel_spec.rb +132 -1
  41. data/spec/acceptance/rest/client_spec.rb +129 -28
  42. data/spec/acceptance/rest/presence_spec.rb +7 -7
  43. data/spec/acceptance/rest/time_spec.rb +10 -0
  44. data/spec/shared/client_initializer_behaviour.rb +41 -17
  45. data/spec/spec_helper.rb +1 -0
  46. data/spec/support/debug_failure_helper.rb +16 -0
  47. data/spec/unit/models/connection_details_spec.rb +60 -0
  48. data/spec/unit/models/protocol_message_spec.rb +45 -0
  49. data/spec/unit/modules/event_emitter_spec.rb +3 -1
  50. data/spec/unit/realtime/channel_spec.rb +6 -5
  51. data/spec/unit/realtime/client_spec.rb +5 -1
  52. data/spec/unit/realtime/connection_spec.rb +5 -1
  53. data/spec/unit/realtime/realtime_spec.rb +5 -1
  54. metadata +54 -7
@@ -76,7 +76,7 @@ describe Ably::Rest::Presence do
76
76
  end
77
77
  let!(:get_stub) {
78
78
  query_params = query_options.map { |k, v| "#{k}=#{v}" }.join('&')
79
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence?#{query_params}").
79
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence?#{query_params}").
80
80
  to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
81
81
  }
82
82
  let(:channel_name) { random_str }
@@ -200,7 +200,7 @@ describe Ably::Rest::Presence do
200
200
  context 'limit options', :webmock do
201
201
  let!(:history_stub) {
202
202
  query_params = history_options.map { |k, v| "#{k}=#{v}" }.join('&')
203
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?#{query_params}").
203
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?#{query_params}").
204
204
  to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
205
205
  }
206
206
 
@@ -240,7 +240,7 @@ describe Ably::Rest::Presence do
240
240
  }
241
241
  let!(:history_stub) {
242
242
  query_params = history_options.map { |k, v| "#{k}=#{v}" }.join('&')
243
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?#{query_params}").
243
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?#{query_params}").
244
244
  to_return(:body => '{}', :headers => { 'Content-Type' => 'application/json' })
245
245
  }
246
246
 
@@ -347,7 +347,7 @@ describe Ably::Rest::Presence do
347
347
 
348
348
  context '#get' do
349
349
  let!(:get_stub) {
350
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence?limit=100").
350
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence?limit=100").
351
351
  to_return(:body => serialized_encoded_message, :headers => { 'Content-Type' => content_type })
352
352
  }
353
353
 
@@ -364,7 +364,7 @@ describe Ably::Rest::Presence do
364
364
 
365
365
  context '#history' do
366
366
  let!(:history_stub) {
367
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?direction=backwards&limit=100").
367
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?direction=backwards&limit=100").
368
368
  to_return(:body => serialized_encoded_message, :headers => { 'Content-Type' => content_type })
369
369
  }
370
370
 
@@ -394,7 +394,7 @@ describe Ably::Rest::Presence do
394
394
  context '#get' do
395
395
  let(:client_options) { default_options.merge(log_level: :fatal) }
396
396
  let!(:get_stub) {
397
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence?limit=100").
397
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence?limit=100").
398
398
  to_return(:body => serialized_encoded_message_with_invalid_encoding, :headers => { 'Content-Type' => content_type })
399
399
  }
400
400
  let(:presence_message) { presence.get.items.first }
@@ -418,7 +418,7 @@ describe Ably::Rest::Presence do
418
418
  context '#history' do
419
419
  let(:client_options) { default_options.merge(log_level: :fatal) }
420
420
  let!(:history_stub) {
421
- stub_request(:get, "#{endpoint}/channels/#{CGI.escape(channel_name)}/presence/history?direction=backwards&limit=100").
421
+ stub_request(:get, "#{endpoint}/channels/#{Addressable::URI.encode(channel_name)}/presence/history?direction=backwards&limit=100").
422
422
  to_return(:body => serialized_encoded_message_with_invalid_encoding, :headers => { 'Content-Type' => content_type })
423
423
  }
424
424
  let(:presence_message) { presence.history.items.first }
@@ -10,6 +10,16 @@ describe Ably::Rest::Client, '#time' do
10
10
  it 'should return the service time as a Time object' do
11
11
  expect(client.time).to be_within(2).of(Time.now)
12
12
  end
13
+
14
+ context 'with reconfigured HTTP timeout' do
15
+ let(:client) do
16
+ Ably::Rest::Client.new(http_request_timeout: 0.0001, key: api_key, environment: environment, protocol: protocol)
17
+ end
18
+
19
+ it 'should raise a timeout exception' do
20
+ expect { client.time }.to raise_error Ably::Exceptions::ConnectionTimeout
21
+ end
22
+ end
13
23
  end
14
24
  end
15
25
  end
@@ -74,13 +74,13 @@ shared_examples 'a client initializer' do
74
74
  let(:client_options) { { client_id: 'valid' } }
75
75
 
76
76
  it 'requires a valid key' do
77
- expect { subject }.to raise_error(ArgumentError, /client_id cannot be provided without a complete API key/)
77
+ expect { subject }.to raise_error(ArgumentError, /client_id cannot be provided without a complete API key or means to authenticate/)
78
78
  end
79
79
  end
80
80
  end
81
81
 
82
82
  context 'with valid arguments' do
83
- let(:default_options) { { key: 'appid.keyuid:keysecret' } }
83
+ let(:default_options) { { key: 'appid.keyuid:keysecret', auto_connect: false } }
84
84
  let(:client_options) { default_options }
85
85
 
86
86
  context 'key only' do
@@ -94,7 +94,7 @@ shared_examples 'a client initializer' do
94
94
  end
95
95
 
96
96
  context 'key_name and key_secret', api_private: true do
97
- let(:client_options) { { key_name: 'id', key_secret: 'secret' } }
97
+ let(:client_options) { { key_name: 'id', key_secret: 'secret', auto_connect: false } }
98
98
 
99
99
  it 'constructs a key' do
100
100
  expect(subject.auth.key).to eql('id:secret')
@@ -102,6 +102,10 @@ shared_examples 'a client initializer' do
102
102
  end
103
103
 
104
104
  context 'with a string key instead of options hash' do
105
+ before do
106
+ allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
107
+ end
108
+
105
109
  let(:client_options) { 'app.key:secret' }
106
110
 
107
111
  it 'sets the key' do
@@ -122,31 +126,35 @@ shared_examples 'a client initializer' do
122
126
  end
123
127
 
124
128
  context 'with a string token key instead of options hash' do
129
+ before do
130
+ allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
131
+ end
132
+
125
133
  let(:client_options) { 'app.kjhkasjhdsakdh127g7g1271' }
126
134
 
127
135
  it 'sets the token' do
128
- expect(subject.auth.token).to eql(client_options)
136
+ expect(subject.auth.current_token_details.token).to eql(client_options)
129
137
  end
130
138
  end
131
139
 
132
140
  context 'with token' do
133
- let(:client_options) { { token: 'token' } }
141
+ let(:client_options) { { token: 'token', auth_connect: false } }
134
142
 
135
143
  it 'sets the token' do
136
- expect(subject.auth.token).to eql('token')
144
+ expect(subject.auth.current_token_details.token).to eql('token')
137
145
  end
138
146
  end
139
147
 
140
148
  context 'with token_details' do
141
- let(:client_options) { { token_details: Ably::Models::TokenDetails.new(token: 'token') } }
149
+ let(:client_options) { { token_details: Ably::Models::TokenDetails.new(token: 'token'), auto_connect: false } }
142
150
 
143
151
  it 'sets the token' do
144
- expect(subject.auth.token).to eql('token')
152
+ expect(subject.auth.current_token_details.token).to eql('token')
145
153
  end
146
154
  end
147
155
 
148
156
  context 'with token_params' do
149
- let(:client_options) { { token_params: { ttl: 777, client_id: 'john' }, token: 'token' } }
157
+ let(:client_options) { { token_params: { ttl: 777, client_id: 'john' }, token: 'token', auto_connect: false } }
150
158
 
151
159
  it 'configures the default token_params' do
152
160
  expect(subject.auth.token_params.fetch(:ttl)).to eql(777)
@@ -155,12 +163,16 @@ shared_examples 'a client initializer' do
155
163
  end
156
164
 
157
165
  context 'endpoint' do
166
+ before do
167
+ allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
168
+ end
169
+
158
170
  it 'defaults to production' do
159
171
  expect(subject.endpoint.to_s).to eql("#{protocol}s://#{subdomain}.ably.io")
160
172
  end
161
173
 
162
174
  context 'with environment option' do
163
- let(:client_options) { default_options.merge(environment: 'sandbox') }
175
+ let(:client_options) { default_options.merge(environment: 'sandbox', auto_connect: false) }
164
176
 
165
177
  it 'uses an alternate endpoint' do
166
178
  expect(subject.endpoint.to_s).to eql("#{protocol}s://sandbox-#{subdomain}.ably.io")
@@ -168,7 +180,7 @@ shared_examples 'a client initializer' do
168
180
  end
169
181
 
170
182
  context 'with rest_host option' do
171
- let(:client_options) { default_options.merge(rest_host: 'custom-rest.host.com') }
183
+ let(:client_options) { default_options.merge(rest_host: 'custom-rest.host.com', auto_connect: false) }
172
184
 
173
185
  it 'uses an alternate endpoint for REST clients' do
174
186
  skip 'does not apply as testing a Realtime client' unless rest?
@@ -177,7 +189,7 @@ shared_examples 'a client initializer' do
177
189
  end
178
190
 
179
191
  context 'with realtime_host option' do
180
- let(:client_options) { default_options.merge(realtime_host: 'custom-realtime.host.com') }
192
+ let(:client_options) { default_options.merge(realtime_host: 'custom-realtime.host.com', auto_connect: false) }
181
193
 
182
194
  it 'uses an alternate endpoint for Realtime clients' do
183
195
  skip 'does not apply as testing a REST client' if rest?
@@ -186,7 +198,7 @@ shared_examples 'a client initializer' do
186
198
  end
187
199
 
188
200
  context 'with port option and non-TLS connections' do
189
- let(:client_options) { default_options.merge(port: 999, tls: false) }
201
+ let(:client_options) { default_options.merge(port: 999, tls: false, auto_connect: false) }
190
202
 
191
203
  it 'uses the custom port for non-TLS requests' do
192
204
  expect(subject.endpoint.to_s).to include(":999")
@@ -194,7 +206,7 @@ shared_examples 'a client initializer' do
194
206
  end
195
207
 
196
208
  context 'with tls_port option and a TLS connection' do
197
- let(:client_options) { default_options.merge(tls_port: 666, tls: true) }
209
+ let(:client_options) { default_options.merge(tls_port: 666, tls: true, auto_connect: false) }
198
210
 
199
211
  it 'uses the custom port for TLS requests' do
200
212
  expect(subject.endpoint.to_s).to include(":666")
@@ -203,8 +215,12 @@ shared_examples 'a client initializer' do
203
215
  end
204
216
 
205
217
  context 'tls' do
218
+ before do
219
+ allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
220
+ end
221
+
206
222
  context 'set to false' do
207
- let(:client_options) { default_options.merge(tls: false) }
223
+ let(:client_options) { default_options.merge(tls: false, auto_connect: false) }
208
224
 
209
225
  it 'uses plain text' do
210
226
  expect(subject.use_tls?).to eql(false)
@@ -221,6 +237,10 @@ shared_examples 'a client initializer' do
221
237
  end
222
238
 
223
239
  context 'logger' do
240
+ before do
241
+ allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
242
+ end
243
+
224
244
  context 'default' do
225
245
  it 'uses Ruby Logger' do
226
246
  expect(subject.logger.logger).to be_a(::Logger)
@@ -232,7 +252,7 @@ shared_examples 'a client initializer' do
232
252
  end
233
253
 
234
254
  context 'with log_level :none' do
235
- let(:client_options) { default_options.merge(log_level: :none) }
255
+ let(:client_options) { default_options.merge(log_level: :none, auto_connect: false) }
236
256
 
237
257
  it 'silences all logging with a NilLogger' do
238
258
  expect(subject.logger.logger.class).to eql(Ably::Models::NilLogger)
@@ -250,7 +270,7 @@ shared_examples 'a client initializer' do
250
270
  def_delegators :@logger, :fatal, :error, :warn, :info, :debug, :level, :level=
251
271
  end
252
272
  end
253
- let(:client_options) { default_options.merge(logger: custom_logger.new, log_level: Logger::DEBUG) }
273
+ let(:client_options) { default_options.merge(logger: custom_logger.new, log_level: Logger::DEBUG, auto_connect: false) }
254
274
 
255
275
  it 'uses the custom logger' do
256
276
  expect(subject.logger.logger.class).to eql(custom_logger)
@@ -264,6 +284,10 @@ shared_examples 'a client initializer' do
264
284
  end
265
285
 
266
286
  context 'delegators' do
287
+ before do
288
+ allow_any_instance_of(subject.class).to receive(:auto_connect).and_return(false)
289
+ end
290
+
267
291
  let(:client_options) { 'app.key:secret' }
268
292
 
269
293
  it 'delegates :client_id to .auth' do
data/spec/spec_helper.rb CHANGED
@@ -12,6 +12,7 @@ require 'webmock/rspec'
12
12
  require 'ably'
13
13
 
14
14
  require 'support/api_helper'
15
+ require 'support/debug_failure_helper'
15
16
  require 'support/private_api_formatter'
16
17
  require 'support/protocol_helper'
17
18
  require 'support/random_helper'
@@ -0,0 +1,16 @@
1
+ RSpec.configure do |config|
2
+ config.before(:example) do
3
+ @log_output = []
4
+ %w(fatal error warn info debug).each do |method_name|
5
+ allow_any_instance_of(Ably::Logger).to receive(method_name.to_sym).and_wrap_original do |method, *args|
6
+ @log_output << "#{Time.now.strftime('%H:%M:%S.%L')} [\e[33m#{method_name}\e[0m] #{args[0]}"
7
+ method.call(*args)
8
+ end
9
+ end
10
+ end
11
+
12
+ config.after(:example) do |example|
13
+ exception = example.exception
14
+ puts "\n#{'-'*34}\n\e[36mVerbose Ably log from test failure\e[0m\n#{'-'*34}\n#{@log_output.join("\n")}\n\n" if exception
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'shared/model_behaviour'
3
+
4
+ describe Ably::Models::ConnectionDetails do
5
+ include Ably::Modules::Conversions
6
+
7
+ subject { Ably::Models::ConnectionDetails }
8
+
9
+ it_behaves_like 'a model', with_simple_attributes: %w(client_id connection_key max_message_size max_frame_size max_inbound_rate) do
10
+ let(:model_args) { [] }
11
+ end
12
+
13
+ context 'attributes' do
14
+ let(:connection_state_ttl_ms) { 5_000 }
15
+
16
+ context '#connection_state_ttl' do
17
+ subject { Ably::Models::ConnectionDetails.new({ connection_state_ttl: connection_state_ttl_ms }) }
18
+
19
+ it 'retrieves attribute :connection_state_ttl and converts it from ms to s' do
20
+ expect(subject.connection_state_ttl).to eql(connection_state_ttl_ms / 1000)
21
+ end
22
+ end
23
+ end
24
+
25
+ context '==' do
26
+ let(:attributes) { { client_id: 'unique' } }
27
+
28
+ it 'is true when attributes are the same' do
29
+ connection_details = -> { Ably::Models::ConnectionDetails.new(attributes) }
30
+ expect(connection_details.call).to eq(connection_details.call)
31
+ end
32
+
33
+ it 'is false when attributes are not the same' do
34
+ expect(Ably::Models::ConnectionDetails.new(client_id: '1')).to_not eq(Ably::Models::ConnectionDetails.new(client_id: '2'))
35
+ end
36
+
37
+ it 'is false when class type differs' do
38
+ expect(Ably::Models::ConnectionDetails.new(client_id: '1')).to_not eq(nil)
39
+ end
40
+ end
41
+
42
+ context 'ConnectionDetails conversion methods', :api_private do
43
+ context 'with a ConnectionDetails object' do
44
+ let(:details) { Ably::Models::ConnectionDetails.new(client_id: random_str) }
45
+
46
+ it 'returns the ConnectionDetails object' do
47
+ expect(Ably::Models::ConnectionDetails(details)).to eql(details)
48
+ end
49
+ end
50
+
51
+ context 'with a JSON object' do
52
+ let(:client_id) { random_str }
53
+ let(:details_json) { { client_id: client_id } }
54
+
55
+ it 'returns a new ConnectionDetails object from the JSON' do
56
+ expect(Ably::Models::ConnectionDetails(details_json).client_id).to eql(client_id)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -284,6 +284,51 @@ describe Ably::Models::ProtocolMessage do
284
284
  expect(protocol_message.presence.first.data).to eql('test')
285
285
  end
286
286
  end
287
+
288
+ context '#connection_details' do
289
+ let(:connection_details) { protocol_message.connection_details }
290
+
291
+ context 'with a JSON value' do
292
+ let(:protocol_message) { new_protocol_message(connectionDetails: { clientId: '1', connectionKey: 'key' }) }
293
+
294
+ it 'contains a ConnectionDetails object' do
295
+ expect(connection_details).to be_a(Ably::Models::ConnectionDetails)
296
+ end
297
+
298
+ it 'contains the attributes from the JSON connectionDetails' do
299
+ expect(connection_details.client_id).to eql('1')
300
+ expect(connection_details.connection_key).to eql('key')
301
+ end
302
+ end
303
+
304
+ context 'without a JSON value' do
305
+ let(:protocol_message) { new_protocol_message({}) }
306
+
307
+ it 'contains an empty ConnectionDetails object' do
308
+ expect(connection_details).to be_a(Ably::Models::ConnectionDetails)
309
+ expect(connection_details.client_id).to eql(nil)
310
+ expect(connection_details.connection_key).to eql(nil)
311
+ end
312
+ end
313
+ end
314
+
315
+ context '#connection_key' do
316
+ context 'existing only in #connection_details.connection_key' do
317
+ let(:protocol_message) { new_protocol_message(connectionDetails: { connectionKey: 'key' }) }
318
+
319
+ it 'is returned' do
320
+ expect(protocol_message.connection_key).to eql('key')
321
+ end
322
+ end
323
+
324
+ context 'existing in both #connection_key and #connection_details.connection_key' do
325
+ let(:protocol_message) { new_protocol_message(connectionKey: 'deprecated', connectionDetails: { connectionKey: 'key' }) }
326
+
327
+ it 'returns #connection_details.connection_key as #connection_key will be deprecated > 0.8' do
328
+ expect(protocol_message.connection_key).to eql('key')
329
+ end
330
+ end
331
+ end
287
332
  end
288
333
 
289
334
  context '#to_json', :api_private do
@@ -7,7 +7,9 @@ describe Ably::Modules::EventEmitter do
7
7
  Class.new do
8
8
  include Ably::Modules::EventEmitter
9
9
  configure_event_emitter callback_opts
10
- def logger; end
10
+ def logger
11
+ @logger ||= Ably::Models::NilLogger.new
12
+ end
11
13
  end
12
14
  end
13
15
  let(:obj) { double('example') }
@@ -68,9 +68,10 @@ describe Ably::Realtime::Channel do
68
68
 
69
69
  describe '#publish name argument' do
70
70
  let(:encoded_value) { random_str.encode(encoding) }
71
+ let(:message) { instance_double('Ably::Models::Message', client_id: nil) }
71
72
 
72
73
  before do
73
- allow(subject).to receive(:create_message).and_return('message_stubbed')
74
+ allow(subject).to receive(:create_message).and_return(message)
74
75
  allow(subject).to receive(:attach).and_return(:true)
75
76
  end
76
77
 
@@ -78,7 +79,7 @@ describe Ably::Realtime::Channel do
78
79
  let(:encoding) { Encoding::UTF_8 }
79
80
 
80
81
  it 'is permitted' do
81
- expect(subject.publish(encoded_value, 'data')).to eql('message_stubbed')
82
+ expect(subject.publish(encoded_value, 'data')).to eql(message)
82
83
  end
83
84
  end
84
85
 
@@ -86,7 +87,7 @@ describe Ably::Realtime::Channel do
86
87
  let(:encoding) { Encoding::SHIFT_JIS }
87
88
 
88
89
  it 'is permitted' do
89
- expect(subject.publish(encoded_value, 'data')).to eql('message_stubbed')
90
+ expect(subject.publish(encoded_value, 'data')).to eql(message)
90
91
  end
91
92
  end
92
93
 
@@ -94,7 +95,7 @@ describe Ably::Realtime::Channel do
94
95
  let(:encoding) { Encoding::ASCII_8BIT }
95
96
 
96
97
  it 'is permitted' do
97
- expect(subject.publish(encoded_value, 'data')).to eql('message_stubbed')
98
+ expect(subject.publish(encoded_value, 'data')).to eql(message)
98
99
  end
99
100
  end
100
101
 
@@ -110,7 +111,7 @@ describe Ably::Realtime::Channel do
110
111
  let(:encoded_value) { nil }
111
112
 
112
113
  it 'is permitted' do
113
- expect(subject.publish(encoded_value, 'data')).to eql('message_stubbed')
114
+ expect(subject.publish(encoded_value, 'data')).to eql(message)
114
115
  end
115
116
  end
116
117
  end
@@ -10,7 +10,7 @@ describe Ably::Realtime::Client do
10
10
  it_behaves_like 'a client initializer'
11
11
 
12
12
  context 'delegation to the REST Client' do
13
- let(:client_options) { { key: 'appid.keyuid:keysecret' } }
13
+ let(:client_options) { { key: 'appid.keyuid:keysecret', auto_connect: false } }
14
14
 
15
15
  it 'passes on the options to the initializer' do
16
16
  rest_client = instance_double('Ably::Rest::Client', auth: instance_double('Ably::Auth'), options: client_options)
@@ -27,4 +27,8 @@ describe Ably::Realtime::Client do
27
27
  end
28
28
  end
29
29
  end
30
+
31
+ after(:all) do
32
+ sleep 1 # let realtime library shut down any open clients
33
+ end
30
34
  end
@@ -5,7 +5,7 @@ describe Ably::Realtime::Connection do
5
5
  let(:client) { instance_double('Ably::Realtime::Client', logger: double('logger').as_null_object) }
6
6
 
7
7
  subject do
8
- Ably::Realtime::Connection.new(client)
8
+ Ably::Realtime::Connection.new(client, {})
9
9
  end
10
10
 
11
11
  before do
@@ -60,4 +60,8 @@ describe Ably::Realtime::Connection do
60
60
  end
61
61
  end
62
62
  end
63
+
64
+ after(:all) do
65
+ sleep 1 # let realtime library shut down any open clients
66
+ end
63
67
  end
@@ -1,9 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ably::Realtime do
4
- let(:options) { { key: 'app.key:secret' } }
4
+ let(:options) { { key: 'app.key:secret', auto_connect: false } }
5
5
 
6
6
  specify 'constructor returns an Ably::Realtime::Client' do
7
7
  expect(Ably::Realtime.new(options)).to be_instance_of(Ably::Realtime::Client)
8
8
  end
9
+
10
+ after(:all) do
11
+ sleep 1 # let realtime library shut down any open clients
12
+ end
9
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lewis Marshall
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-10-08 00:00:00.000000000 Z
12
+ date: 2015-12-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -109,6 +109,20 @@ dependencies:
109
109
  - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: 0.6.2
112
+ - !ruby/object:Gem::Dependency
113
+ name: addressable
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 2.0.0
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: 2.0.0
112
126
  - !ruby/object:Gem::Dependency
113
127
  name: bundler
114
128
  requirement: !ruby/object:Gem::Requirement
@@ -157,14 +171,14 @@ dependencies:
157
171
  requirements:
158
172
  - - "~>"
159
173
  - !ruby/object:Gem::Version
160
- version: 3.1.0
174
+ version: 3.2.0
161
175
  type: :development
162
176
  prerelease: false
163
177
  version_requirements: !ruby/object:Gem::Requirement
164
178
  requirements:
165
179
  - - "~>"
166
180
  - !ruby/object:Gem::Version
167
- version: 3.1.0
181
+ version: 3.2.0
168
182
  - !ruby/object:Gem::Dependency
169
183
  name: rspec-retry
170
184
  requirement: !ruby/object:Gem::Requirement
@@ -221,7 +235,35 @@ dependencies:
221
235
  - - ">="
222
236
  - !ruby/object:Gem::Version
223
237
  version: '0'
224
- description: A Ruby client library for ably.io, the realtime messaging service
238
+ - !ruby/object:Gem::Dependency
239
+ name: pry
240
+ requirement: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - ">="
243
+ - !ruby/object:Gem::Version
244
+ version: '0'
245
+ type: :development
246
+ prerelease: false
247
+ version_requirements: !ruby/object:Gem::Requirement
248
+ requirements:
249
+ - - ">="
250
+ - !ruby/object:Gem::Version
251
+ version: '0'
252
+ - !ruby/object:Gem::Dependency
253
+ name: pry-byebug
254
+ requirement: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: '0'
259
+ type: :development
260
+ prerelease: false
261
+ version_requirements: !ruby/object:Gem::Requirement
262
+ requirements:
263
+ - - ">="
264
+ - !ruby/object:Gem::Version
265
+ version: '0'
266
+ description: A Ruby client library for ably.io realtime messaging
225
267
  email:
226
268
  - lewis@lmars.net
227
269
  - matt@ably.io
@@ -245,6 +287,7 @@ files:
245
287
  - lib/ably/exceptions.rb
246
288
  - lib/ably/logger.rb
247
289
  - lib/ably/models/channel_state_change.rb
290
+ - lib/ably/models/connection_details.rb
248
291
  - lib/ably/models/connection_state_change.rb
249
292
  - lib/ably/models/error_info.rb
250
293
  - lib/ably/models/idiomatic_ruby_wrapper.rb
@@ -343,6 +386,7 @@ files:
343
386
  - spec/shared/safe_deferrable_behaviour.rb
344
387
  - spec/spec_helper.rb
345
388
  - spec/support/api_helper.rb
389
+ - spec/support/debug_failure_helper.rb
346
390
  - spec/support/event_machine_helper.rb
347
391
  - spec/support/markdown_spec_formatter.rb
348
392
  - spec/support/private_api_formatter.rb
@@ -353,6 +397,7 @@ files:
353
397
  - spec/unit/auth_spec.rb
354
398
  - spec/unit/logger_spec.rb
355
399
  - spec/unit/models/channel_state_change_spec.rb
400
+ - spec/unit/models/connection_details_spec.rb
356
401
  - spec/unit/models/connection_state_change_spec.rb
357
402
  - spec/unit/models/error_info_spec.rb
358
403
  - spec/unit/models/idiomatic_ruby_wrapper_spec.rb
@@ -389,7 +434,7 @@ files:
389
434
  - spec/unit/util/pub_sub_spec.rb
390
435
  homepage: http://github.com/ably/ably-ruby
391
436
  licenses:
392
- - MIT
437
+ - Apache 2
393
438
  metadata: {}
394
439
  post_install_message:
395
440
  rdoc_options: []
@@ -410,7 +455,7 @@ rubyforge_project:
410
455
  rubygems_version: 2.4.6
411
456
  signing_key:
412
457
  specification_version: 4
413
- summary: A Ruby client library for ably.io, the realtime messaging service
458
+ summary: A Ruby client library for ably.io realtime messaging implemented using EventMachine
414
459
  test_files:
415
460
  - spec/acceptance/realtime/auth_spec.rb
416
461
  - spec/acceptance/realtime/channel_history_spec.rb
@@ -441,6 +486,7 @@ test_files:
441
486
  - spec/shared/safe_deferrable_behaviour.rb
442
487
  - spec/spec_helper.rb
443
488
  - spec/support/api_helper.rb
489
+ - spec/support/debug_failure_helper.rb
444
490
  - spec/support/event_machine_helper.rb
445
491
  - spec/support/markdown_spec_formatter.rb
446
492
  - spec/support/private_api_formatter.rb
@@ -451,6 +497,7 @@ test_files:
451
497
  - spec/unit/auth_spec.rb
452
498
  - spec/unit/logger_spec.rb
453
499
  - spec/unit/models/channel_state_change_spec.rb
500
+ - spec/unit/models/connection_details_spec.rb
454
501
  - spec/unit/models/connection_state_change_spec.rb
455
502
  - spec/unit/models/error_info_spec.rb
456
503
  - spec/unit/models/idiomatic_ruby_wrapper_spec.rb