ably 1.1.4 → 1.1.8

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check.yml +15 -1
  3. data/CHANGELOG.md +109 -0
  4. data/COPYRIGHT +1 -1
  5. data/README.md +23 -9
  6. data/SPEC.md +289 -228
  7. data/ably.gemspec +14 -9
  8. data/lib/ably/agent.rb +3 -0
  9. data/lib/ably/exceptions.rb +6 -0
  10. data/lib/ably/models/connection_details.rb +8 -0
  11. data/lib/ably/models/delta_extras.rb +29 -0
  12. data/lib/ably/models/error_info.rb +6 -2
  13. data/lib/ably/models/message.rb +25 -0
  14. data/lib/ably/models/presence_message.rb +14 -0
  15. data/lib/ably/models/protocol_message.rb +13 -8
  16. data/lib/ably/modules/ably.rb +11 -1
  17. data/lib/ably/realtime/channel/channel_manager.rb +2 -2
  18. data/lib/ably/realtime/channel/channel_state_machine.rb +5 -1
  19. data/lib/ably/realtime/channel/publisher.rb +6 -0
  20. data/lib/ably/realtime/channel.rb +2 -0
  21. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
  22. data/lib/ably/realtime/client.rb +1 -0
  23. data/lib/ably/realtime/connection/connection_manager.rb +13 -4
  24. data/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
  25. data/lib/ably/realtime/connection.rb +2 -2
  26. data/lib/ably/rest/channel.rb +11 -3
  27. data/lib/ably/rest/client.rb +37 -18
  28. data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -1
  29. data/lib/ably/version.rb +1 -13
  30. data/lib/ably.rb +1 -0
  31. data/spec/acceptance/realtime/auth_spec.rb +1 -1
  32. data/spec/acceptance/realtime/channel_history_spec.rb +25 -0
  33. data/spec/acceptance/realtime/channel_spec.rb +220 -1
  34. data/spec/acceptance/realtime/connection_failures_spec.rb +85 -13
  35. data/spec/acceptance/realtime/connection_spec.rb +263 -32
  36. data/spec/acceptance/realtime/presence_history_spec.rb +3 -1
  37. data/spec/acceptance/realtime/presence_spec.rb +31 -159
  38. data/spec/acceptance/rest/base_spec.rb +8 -4
  39. data/spec/acceptance/rest/channel_spec.rb +84 -9
  40. data/spec/acceptance/rest/channels_spec.rb +1 -1
  41. data/spec/acceptance/rest/client_spec.rb +72 -33
  42. data/spec/shared/client_initializer_behaviour.rb +131 -0
  43. data/spec/shared/model_behaviour.rb +1 -1
  44. data/spec/spec_helper.rb +11 -2
  45. data/spec/support/test_app.rb +1 -1
  46. data/spec/unit/models/delta_extras_spec.rb +14 -0
  47. data/spec/unit/models/error_info_spec.rb +17 -1
  48. data/spec/unit/models/message_spec.rb +83 -0
  49. data/spec/unit/models/presence_message_spec.rb +49 -0
  50. data/spec/unit/models/protocol_message_spec.rb +72 -20
  51. data/spec/unit/realtime/channel_spec.rb +3 -2
  52. data/spec/unit/realtime/channels_spec.rb +3 -3
  53. data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
  54. data/spec/unit/rest/channel_spec.rb +44 -1
  55. data/spec/unit/rest/client_spec.rb +47 -0
  56. metadata +48 -36
@@ -220,6 +220,55 @@ describe Ably::Models::PresenceMessage do
220
220
  end
221
221
  end
222
222
 
223
+ describe '#size' do
224
+ let(:model) { subject.new({ action: 'enter', data: data, client_id: client_id }, protocol_message: protocol_message) }
225
+
226
+ context 'String (#TO3l8a)' do
227
+ let(:data) { 'example string data' }
228
+ let(:client_id) { '1' }
229
+
230
+ it 'should return 20 bytes' do
231
+ expect(model.size).to eq(20)
232
+ end
233
+ end
234
+
235
+ context 'Object (#TO3l8b)' do
236
+ let(:data) { Object.new }
237
+ let(:client_id) { '10' }
238
+
239
+ it 'should return 32 bytes' do
240
+ expect(model.size).to eq(32)
241
+ end
242
+ end
243
+
244
+ context 'Array (#TO3l8b)' do
245
+ let(:data) { [1, 'two', :three] }
246
+ let(:client_id) { '2' }
247
+
248
+ it 'should return 18 bytes' do
249
+ expect(model.size).to eq(18)
250
+ end
251
+ end
252
+
253
+ context 'extras (#TO3l8d)' do
254
+ let(:data) { { example: 'value', score: 1, hash: { test: true } } }
255
+ let(:client_id) { '3' }
256
+
257
+ it 'should return 51 bytes' do
258
+ expect(model.size).to eq(51)
259
+ end
260
+ end
261
+
262
+ context 'nil (#TO3l8e)' do
263
+ let(:data) { nil }
264
+ let(:client_id) { '4' }
265
+
266
+ it 'should return 1 bytes' do
267
+ expect(model.size).to eq(1)
268
+ end
269
+ end
270
+ end
271
+
223
272
  context 'from REST request with embedded fields', :api_private do
224
273
  let(:id) { random_str }
225
274
  let(:message_time) { Time.now + 60 }
@@ -10,9 +10,9 @@ describe Ably::Models::ProtocolMessage do
10
10
  subject.new({ action: 1 }.merge(options))
11
11
  end
12
12
 
13
- # TR4n, TR4b, TR4c, TR4d, TR4e
13
+ # TR4n, TR4b, TR4c, TR4d
14
14
  it_behaves_like 'a model',
15
- with_simple_attributes: %w(id channel channel_serial connection_id connection_key),
15
+ with_simple_attributes: %w(id channel channel_serial connection_id),
16
16
  base_model_options: { action: 1 } do
17
17
 
18
18
  let(:model_args) { [] }
@@ -176,6 +176,28 @@ describe Ably::Models::ProtocolMessage do
176
176
  end
177
177
  end
178
178
 
179
+ context 'when attach resumed flag' do
180
+ context 'flags is 34' do
181
+ let(:protocol_message) { new_protocol_message(flags: 34) }
182
+
183
+ it '#has_attach_resume_flag? is true' do
184
+ expect(protocol_message.has_attach_resume_flag?).to be_truthy
185
+ end
186
+
187
+ it '#has_attach_presence_flag? is false' do
188
+ expect(protocol_message.has_attach_presence_flag?).to be_falsey
189
+ end
190
+ end
191
+
192
+ context 'flags is 0' do
193
+ let(:protocol_message) { new_protocol_message(flags: 0) }
194
+
195
+ it 'should raise an exception if flags is a float number' do
196
+ expect(protocol_message.has_attach_resume_flag?).to be_falsy
197
+ end
198
+ end
199
+ end
200
+
179
201
  context 'when channel resumed and presence flags present' do
180
202
  let(:protocol_message) { new_protocol_message(flags: 5) }
181
203
 
@@ -318,6 +340,54 @@ describe Ably::Models::ProtocolMessage do
318
340
  end
319
341
  end
320
342
 
343
+ context '#message_size (#TO3l8)' do
344
+ context 'on presence' do
345
+ let(:protocol_message) do
346
+ new_protocol_message(presence: [{ action: 1, data: 'test342343', client_id: 'sdf' }])
347
+ end
348
+
349
+ it 'should return 13 bytes (sum in bytes: data and client_id)' do
350
+ expect(protocol_message.message_size).to eq(13)
351
+ end
352
+ end
353
+
354
+ context 'on message' do
355
+ let(:protocol_message) do
356
+ new_protocol_message(messages: [{ action: 1, unknown: 'test', data: 'test342343', client_id: 'sdf', name: 'sf23ewrew', extras: { time: Time.now, time_zone: 'UTC' } }])
357
+ end
358
+
359
+ it 'should return 76 bytes (sum in bytes: data, client_id, name, extras)' do
360
+ expect(protocol_message.message_size).to eq(76)
361
+ end
362
+ end
363
+ end
364
+
365
+ context '#has_correct_message_size? (#TO3l8)' do
366
+ context 'on presence' do
367
+ it 'should return true when a message has correct size' do
368
+ protocol_message = new_protocol_message(presence: [{ action: 1, data: 'x' * 100 }])
369
+ expect(protocol_message.has_correct_message_size?).to eq(true)
370
+ end
371
+
372
+ it 'should return false when a message has not correct size' do
373
+ protocol_message = new_protocol_message(presence: [{ action: 1, data: 'x' * 65537 }])
374
+ expect(protocol_message.has_correct_message_size?).to eq(false)
375
+ end
376
+ end
377
+
378
+ context 'on message' do
379
+ it 'should return true when a message has correct size' do
380
+ protocol_message = new_protocol_message(messages: [{ name: 'x' * 100 }])
381
+ expect(protocol_message.has_correct_message_size?).to eq(true)
382
+ end
383
+
384
+ it 'should return false when a message has not correct size' do
385
+ protocol_message = new_protocol_message(messages: [{ name: 'x' * 65537 }])
386
+ expect(protocol_message.has_correct_message_size?).to eq(false)
387
+ end
388
+ end
389
+ end
390
+
321
391
  context '#connection_details (#TR4o)' do
322
392
  let(:connection_details) { protocol_message.connection_details }
323
393
 
@@ -369,24 +439,6 @@ describe Ably::Models::ProtocolMessage do
369
439
  end
370
440
  end
371
441
  end
372
-
373
- context '#connection_key (#TR4e)' do
374
- context 'existing only in #connection_details.connection_key' do
375
- let(:protocol_message) { new_protocol_message(connectionDetails: { connectionKey: 'key' }) }
376
-
377
- it 'is returned' do
378
- expect(protocol_message.connection_key).to eql('key')
379
- end
380
- end
381
-
382
- context 'existing in both #connection_key and #connection_details.connection_key' do
383
- let(:protocol_message) { new_protocol_message(connectionKey: 'deprecated', connectionDetails: { connectionKey: 'key' }) }
384
-
385
- it 'returns #connection_details.connection_key as #connection_key will be deprecated > 0.8' do
386
- expect(protocol_message.connection_key).to eql('key')
387
- end
388
- end
389
- end
390
442
  end
391
443
 
392
444
  context '#to_json', :api_private do
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  require 'shared/protocol_msgbus_behaviour'
4
4
 
5
5
  describe Ably::Realtime::Channel do
6
- let(:client) { double('client').as_null_object }
6
+ let(:client) { Ably::Realtime::Client.new(token: 'valid') }
7
7
  let(:channel_name) { 'test' }
8
8
 
9
9
  subject do
@@ -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
+ let(:message) { instance_double('Ably::Models::Message', client_id: nil, size: 0) }
72
72
 
73
73
  before do
74
+ allow(subject).to receive(:enqueue_messages_on_connection).and_return(message)
74
75
  allow(subject).to receive(:create_message).and_return(message)
75
76
  allow(subject).to receive(:attach).and_return(:true)
76
77
  end
@@ -11,19 +11,19 @@ describe Ably::Realtime::Channels do
11
11
 
12
12
  context 'creating channels' do
13
13
  context '#get' do
14
- it 'creates a channel if it does not exist' do
14
+ it 'creates a channel if it does not exist (RSN3a)' do
15
15
  expect(Ably::Realtime::Channel).to receive(:new).with(client, channel_name, options)
16
16
  subject.get(channel_name, options)
17
17
  end
18
18
 
19
19
  context 'when an existing channel exists' do
20
- it 'will reuse a channel object if it exists' do
20
+ it 'will reuse a channel object if it exists (RSN3a)' do
21
21
  channel = subject.get(channel_name, options)
22
22
  expect(channel).to be_a(Ably::Realtime::Channel)
23
23
  expect(subject.get(channel_name, options).object_id).to eql(channel.object_id)
24
24
  end
25
25
 
26
- it 'will update the options on the channel if provided' do
26
+ it 'will update the options on the channel if provided (RSN3c)' do
27
27
  channel = subject.get(channel_name, options)
28
28
  expect(channel.options).to eql(options)
29
29
  expect(channel.options).to_not include(:encrypted)
@@ -32,5 +32,43 @@ describe Ably::Realtime::Client::IncomingMessageDispatcher, :api_private do
32
32
  expect(subject).to receive_message_chain(:logger, :warn)
33
33
  msgbus.publish :protocol_message, Ably::Models::ProtocolMessage.new(:action => :attached, channel: 'unknown')
34
34
  end
35
+
36
+ context 'TO3l8' do
37
+ context 'on action presence' do
38
+ let(:presence) { 101.times.map { { data: 'x' * 655 } } }
39
+
40
+ let(:protocol_message) do
41
+ Ably::Models::ProtocolMessage.new(action: :presence, channel: 'default', presence: presence, connection_serial: 123123123)
42
+ end
43
+
44
+ it 'should raise a protocol error when message size exceeded 65536 bytes' do
45
+ allow(connection).to receive(:serial).and_return(12312312)
46
+ allow(subject).to receive(:update_connection_recovery_info)
47
+ allow(subject).to receive_message_chain(:logger, :debug)
48
+ allow(subject).to receive_message_chain(:logger, :warn)
49
+ expect(subject).to receive_message_chain(:logger, :fatal)
50
+
51
+ msgbus.publish :protocol_message, protocol_message
52
+ end
53
+ end
54
+
55
+ context 'on action message' do
56
+ let(:messages) { 101.times.map { { data: 'x' * 655 } } }
57
+
58
+ let(:protocol_message) do
59
+ Ably::Models::ProtocolMessage.new(action: :message, channel: 'default', messages: messages, connection_serial: 123123123)
60
+ end
61
+
62
+ it 'should raise a protocol error when message size exceeded 65536 bytes' do
63
+ allow(connection).to receive(:serial).and_return(12312312)
64
+ allow(subject).to receive(:update_connection_recovery_info)
65
+ allow(subject).to receive_message_chain(:logger, :debug)
66
+ allow(subject).to receive_message_chain(:logger, :warn)
67
+ expect(subject).to receive_message_chain(:logger, :fatal)
68
+
69
+ msgbus.publish :protocol_message, protocol_message
70
+ end
71
+ end
72
+ end
35
73
  end
36
74
  end
@@ -7,10 +7,11 @@ describe Ably::Rest::Channel do
7
7
  'Ably::Rest::Client',
8
8
  encoders: [],
9
9
  post: instance_double('Faraday::Response', status: 201),
10
- idempotent_rest_publishing: false,
10
+ idempotent_rest_publishing: false, max_message_size: max_message_size
11
11
  )
12
12
  end
13
13
  let(:channel_name) { 'unique' }
14
+ let(:max_message_size) { nil }
14
15
 
15
16
  subject { Ably::Rest::Channel.new(client, channel_name) }
16
17
 
@@ -126,5 +127,47 @@ describe Ably::Rest::Channel do
126
127
  expect { subject.publish(encoded_value, 'data') }.to raise_error ArgumentError, /must be a String/
127
128
  end
128
129
  end
130
+
131
+ context 'max message size exceeded' do
132
+ context 'when max_message_size is nil' do
133
+ context 'and a message size is 65537 bytes' do
134
+ it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
135
+ expect { subject.publish('x' * 65537, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
136
+ end
137
+ end
138
+ end
139
+
140
+ context 'when max_message_size is 65536 bytes' do
141
+ let(:max_message_size) { 65536 }
142
+
143
+ context 'and a message size is 65537 bytes' do
144
+ it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
145
+ expect { subject.publish('x' * 65537, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
146
+ end
147
+ end
148
+
149
+ context 'and a message size is 10 bytes' do
150
+ it 'should send a message' do
151
+ expect(subject.publish('x' * 10, 'data')).to eq(true)
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'when max_message_size is 10 bytes' do
157
+ let(:max_message_size) { 10 }
158
+
159
+ context 'and a message size is 11 bytes' do
160
+ it 'should raise Ably::Exceptions::MaxMessageSizeExceeded' do
161
+ expect { subject.publish('x' * 11, 'data') }.to raise_error Ably::Exceptions::MaxMessageSizeExceeded
162
+ end
163
+ end
164
+
165
+ context 'and a message size is 2 bytes' do
166
+ it 'should send a message' do
167
+ expect(subject.publish('x' * 2, 'data')).to eq(true)
168
+ end
169
+ end
170
+ end
171
+ end
129
172
  end
130
173
  end
@@ -38,6 +38,26 @@ describe Ably::Rest::Client do
38
38
  end
39
39
  end
40
40
 
41
+ context 'use agent' do
42
+ context 'set agent to non-default value' do
43
+ context 'default agent' do
44
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
45
+
46
+ it 'should return default ably agent' do
47
+ expect(subject.agent).to eq(Ably::AGENT)
48
+ end
49
+ end
50
+
51
+ context 'custom agent' do
52
+ let(:client_options) { { key: 'appid.keyuid:keysecret', agent: 'example-gem/1.1.4 ably-ruby/1.1.5 ruby/3.0.0' } }
53
+
54
+ it 'should overwrite client.agent' do
55
+ expect(subject.agent).to eq('example-gem/1.1.4 ably-ruby/1.1.5 ruby/3.0.0')
56
+ end
57
+ end
58
+ end
59
+ end
60
+
41
61
  context ':use_token_auth' do
42
62
  context 'set to false' do
43
63
  context 'with a key and :tls => false' do
@@ -67,6 +87,33 @@ describe Ably::Rest::Client do
67
87
  end
68
88
  end
69
89
  end
90
+
91
+ context 'max_message_size' do
92
+ context 'is not present' do
93
+ let(:client_options) { { key: 'appid.keyuid:keysecret' } }
94
+
95
+ it 'should return default 65536 (#TO3l8)' do
96
+ expect(subject.max_message_size).to eq(Ably::Rest::Client::MAX_MESSAGE_SIZE)
97
+ end
98
+ end
99
+
100
+ context 'is nil' do
101
+ let(:client_options) { { key: 'appid.keyuid:keysecret', max_message_size: nil } }
102
+
103
+ it 'should return default 65536 (#TO3l8)' do
104
+ expect(Ably::Rest::Client::MAX_MESSAGE_SIZE).to eq(65536)
105
+ expect(subject.max_message_size).to eq(Ably::Rest::Client::MAX_MESSAGE_SIZE)
106
+ end
107
+ end
108
+
109
+ context 'is customized 131072 bytes' do
110
+ let(:client_options) { { key: 'appid.keyuid:keysecret', max_message_size: 131072 } }
111
+
112
+ it 'should return 131072' do
113
+ expect(subject.max_message_size).to eq(131072)
114
+ end
115
+ end
116
+ end
70
117
  end
71
118
 
72
119
  context 'request_id generation' do
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: 1.1.4
4
+ version: 1.1.8
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: 2021-04-16 00:00:00.000000000 Z
12
+ date: 2022-02-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -45,48 +45,42 @@ dependencies:
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '7.4'
48
+ version: '8.0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '7.4'
55
+ version: '8.0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: faraday
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: '0.12'
63
- - - "<"
60
+ - - "~>"
64
61
  - !ruby/object:Gem::Version
65
- version: 2.0.0
62
+ version: '1.0'
66
63
  type: :runtime
67
64
  prerelease: false
68
65
  version_requirements: !ruby/object:Gem::Requirement
69
66
  requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: '0.12'
73
- - - "<"
67
+ - - "~>"
74
68
  - !ruby/object:Gem::Version
75
- version: 2.0.0
69
+ version: '1.0'
76
70
  - !ruby/object:Gem::Dependency
77
- name: excon
71
+ name: typhoeus
78
72
  requirement: !ruby/object:Gem::Requirement
79
73
  requirements:
80
74
  - - "~>"
81
75
  - !ruby/object:Gem::Version
82
- version: '0.55'
76
+ version: '1.4'
83
77
  type: :runtime
84
78
  prerelease: false
85
79
  version_requirements: !ruby/object:Gem::Requirement
86
80
  requirements:
87
81
  - - "~>"
88
82
  - !ruby/object:Gem::Version
89
- version: '0.55'
83
+ version: '1.4'
90
84
  - !ruby/object:Gem::Dependency
91
85
  name: json
92
86
  requirement: !ruby/object:Gem::Requirement
@@ -149,14 +143,14 @@ dependencies:
149
143
  requirements:
150
144
  - - "~>"
151
145
  - !ruby/object:Gem::Version
152
- version: '11.3'
146
+ version: '13.0'
153
147
  type: :development
154
148
  prerelease: false
155
149
  version_requirements: !ruby/object:Gem::Requirement
156
150
  requirements:
157
151
  - - "~>"
158
152
  - !ruby/object:Gem::Version
159
- version: '11.3'
153
+ version: '13.0'
160
154
  - !ruby/object:Gem::Dependency
161
155
  name: redcarpet
162
156
  requirement: !ruby/object:Gem::Requirement
@@ -177,14 +171,14 @@ dependencies:
177
171
  requirements:
178
172
  - - "~>"
179
173
  - !ruby/object:Gem::Version
180
- version: 3.3.0
174
+ version: 3.10.0
181
175
  type: :development
182
176
  prerelease: false
183
177
  version_requirements: !ruby/object:Gem::Requirement
184
178
  requirements:
185
179
  - - "~>"
186
180
  - !ruby/object:Gem::Version
187
- version: 3.3.0
181
+ version: 3.10.0
188
182
  - !ruby/object:Gem::Dependency
189
183
  name: rspec-retry
190
184
  requirement: !ruby/object:Gem::Requirement
@@ -256,61 +250,75 @@ dependencies:
256
250
  - !ruby/object:Gem::Version
257
251
  version: '3.11'
258
252
  - !ruby/object:Gem::Dependency
259
- name: coveralls
253
+ name: simplecov
260
254
  requirement: !ruby/object:Gem::Requirement
261
255
  requirements:
262
- - - ">="
256
+ - - "~>"
263
257
  - !ruby/object:Gem::Version
264
- version: '0'
258
+ version: 0.21.2
265
259
  type: :development
266
260
  prerelease: false
267
261
  version_requirements: !ruby/object:Gem::Requirement
268
262
  requirements:
269
- - - ">="
263
+ - - "~>"
270
264
  - !ruby/object:Gem::Version
271
- version: '0'
265
+ version: 0.21.2
266
+ - !ruby/object:Gem::Dependency
267
+ name: simplecov-lcov
268
+ requirement: !ruby/object:Gem::Requirement
269
+ requirements:
270
+ - - "~>"
271
+ - !ruby/object:Gem::Version
272
+ version: 0.8.0
273
+ type: :development
274
+ prerelease: false
275
+ version_requirements: !ruby/object:Gem::Requirement
276
+ requirements:
277
+ - - "~>"
278
+ - !ruby/object:Gem::Version
279
+ version: 0.8.0
272
280
  - !ruby/object:Gem::Dependency
273
281
  name: parallel_tests
274
282
  requirement: !ruby/object:Gem::Requirement
275
283
  requirements:
276
284
  - - "~>"
277
285
  - !ruby/object:Gem::Version
278
- version: '2.22'
286
+ version: '3.7'
279
287
  type: :development
280
288
  prerelease: false
281
289
  version_requirements: !ruby/object:Gem::Requirement
282
290
  requirements:
283
291
  - - "~>"
284
292
  - !ruby/object:Gem::Version
285
- version: '2.22'
293
+ version: '3.7'
286
294
  - !ruby/object:Gem::Dependency
287
295
  name: pry
288
296
  requirement: !ruby/object:Gem::Requirement
289
297
  requirements:
290
- - - ">="
298
+ - - "~>"
291
299
  - !ruby/object:Gem::Version
292
- version: '0'
300
+ version: 0.14.1
293
301
  type: :development
294
302
  prerelease: false
295
303
  version_requirements: !ruby/object:Gem::Requirement
296
304
  requirements:
297
- - - ">="
305
+ - - "~>"
298
306
  - !ruby/object:Gem::Version
299
- version: '0'
307
+ version: 0.14.1
300
308
  - !ruby/object:Gem::Dependency
301
309
  name: pry-byebug
302
310
  requirement: !ruby/object:Gem::Requirement
303
311
  requirements:
304
- - - ">="
312
+ - - "~>"
305
313
  - !ruby/object:Gem::Version
306
- version: '0'
314
+ version: 3.8.0
307
315
  type: :development
308
316
  prerelease: false
309
317
  version_requirements: !ruby/object:Gem::Requirement
310
318
  requirements:
311
- - - ">="
319
+ - - "~>"
312
320
  - !ruby/object:Gem::Version
313
- version: '0'
321
+ version: 3.8.0
314
322
  description: A Ruby client library for ably.io realtime messaging
315
323
  email:
316
324
  - lewis@lmars.net
@@ -334,6 +342,7 @@ files:
334
342
  - SPEC.md
335
343
  - ably.gemspec
336
344
  - lib/ably.rb
345
+ - lib/ably/agent.rb
337
346
  - lib/ably/auth.rb
338
347
  - lib/ably/exceptions.rb
339
348
  - lib/ably/logger.rb
@@ -342,6 +351,7 @@ files:
342
351
  - lib/ably/models/cipher_params.rb
343
352
  - lib/ably/models/connection_details.rb
344
353
  - lib/ably/models/connection_state_change.rb
354
+ - lib/ably/models/delta_extras.rb
345
355
  - lib/ably/models/device_details.rb
346
356
  - lib/ably/models/device_push_details.rb
347
357
  - lib/ably/models/error_info.rb
@@ -479,6 +489,7 @@ files:
479
489
  - spec/unit/models/cipher_params_spec.rb
480
490
  - spec/unit/models/connection_details_spec.rb
481
491
  - spec/unit/models/connection_state_change_spec.rb
492
+ - spec/unit/models/delta_extras_spec.rb
482
493
  - spec/unit/models/device_details_spec.rb
483
494
  - spec/unit/models/device_push_details_spec.rb
484
495
  - spec/unit/models/error_info_spec.rb
@@ -594,6 +605,7 @@ test_files:
594
605
  - spec/unit/models/cipher_params_spec.rb
595
606
  - spec/unit/models/connection_details_spec.rb
596
607
  - spec/unit/models/connection_state_change_spec.rb
608
+ - spec/unit/models/delta_extras_spec.rb
597
609
  - spec/unit/models/device_details_spec.rb
598
610
  - spec/unit/models/device_push_details_spec.rb
599
611
  - spec/unit/models/error_info_spec.rb