ably 0.7.1 → 0.7.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b651a5ed9326c5950e3aec0232ef8b96b548021b
4
+ data.tar.gz: 1b6db9eb56d925b901e8e26e6e15863820562234
5
+ SHA512:
6
+ metadata.gz: 80518f8fb55cef422fe8da8c96c314bc63e95ece705b9851dcf4613862d6b5b804285535bb0303750636b7db55529301c1c00a32bf50f9e13332c9c4c828c709
7
+ data.tar.gz: 19619184eb6ebe32608e5f642b158b5e9a1bae3e9d713422174ec5082aadcbcc15845e5351ee395bd3c5f978f8d8c6ea88461eb944b509fab914d97c06ff3b27
data/.travis.yml CHANGED
@@ -1,7 +1,10 @@
1
1
  env: RSPEC_RETRY=true
2
2
  language: ruby
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0.0
6
- - 2.2.0
7
-
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.2.0
7
+ script: bundle exec rspec
8
+ notifications:
9
+ slack:
10
+ secure: Xe8MwDcV2C8XLGk6O6Co31LpQiRSxsmS7Toy5vM7rHds5fnVRBNn5iX6Q5mXMdLOlnsMhjKLt7zl4fsBOZv+siQ+Us0omZSIYpXCYSCIj8nofReF0Lj8M4oa6lFSL5OuygO7PH+wLKTRxQURGZ6Pi1nHU+RE5izRmsewQHkhtY0=
data/SPEC.md CHANGED
@@ -209,84 +209,90 @@ _(see [spec/acceptance/realtime/connection_spec.rb](./spec/acceptance/realtime/c
209
209
  * [uses the primary host for subsequent connection and auth requests](./spec/acceptance/realtime/connection_spec.rb#L117)
210
210
  * when connected with a valid non-expired token
211
211
  * that then expires following the connection being opened
212
- * PENDING: *[retains connection state](./spec/acceptance/realtime/connection_spec.rb#L164)*
213
- * PENDING: *[changes state to failed if a new token cannot be issued](./spec/acceptance/realtime/connection_spec.rb#L165)*
212
+ * PENDING: *[retains connection state](./spec/acceptance/realtime/connection_spec.rb#L167)*
213
+ * PENDING: *[changes state to failed if a new token cannot be issued](./spec/acceptance/realtime/connection_spec.rb#L168)*
214
214
  * the server
215
- * [disconnects the client, and the client automatically renews the token and then reconnects](./spec/acceptance/realtime/connection_spec.rb#L141)
215
+ * [disconnects the client, and the client automatically renews the token and then reconnects](./spec/acceptance/realtime/connection_spec.rb#L144)
216
216
  * for non-renewable tokens
217
217
  * that are expired
218
218
  * opening a new connection
219
- * [transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#L180)
219
+ * [transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#L183)
220
220
  * when connected
221
- * PENDING: *[transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#L193)*
221
+ * PENDING: *[transitions state to failed](./spec/acceptance/realtime/connection_spec.rb#L196)*
222
222
  * initialization state changes
223
223
  * with implicit #connect
224
- * [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#L221)
224
+ * [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#L223)
225
225
  * with explicit #connect
226
- * [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#L227)
226
+ * [are triggered in order](./spec/acceptance/realtime/connection_spec.rb#L229)
227
227
  * #connect
228
- * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L235)
229
- * [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#L240)
228
+ * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L237)
229
+ * [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#L242)
230
230
  * when already connected
231
- * [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#L249)
231
+ * [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#L251)
232
232
  * once connected
233
233
  * connection#id
234
- * [is a string](./spec/acceptance/realtime/connection_spec.rb#L266)
235
- * [is unique from the connection#key](./spec/acceptance/realtime/connection_spec.rb#L273)
236
- * [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#L280)
234
+ * [is a string](./spec/acceptance/realtime/connection_spec.rb#L268)
235
+ * [is unique from the connection#key](./spec/acceptance/realtime/connection_spec.rb#L275)
236
+ * [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#L282)
237
237
  * connection#key
238
- * [is a string](./spec/acceptance/realtime/connection_spec.rb#L289)
239
- * [is unique from the connection#id](./spec/acceptance/realtime/connection_spec.rb#L296)
240
- * [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#L303)
238
+ * [is a string](./spec/acceptance/realtime/connection_spec.rb#L291)
239
+ * [is unique from the connection#id](./spec/acceptance/realtime/connection_spec.rb#L298)
240
+ * [is unique for every connection](./spec/acceptance/realtime/connection_spec.rb#L305)
241
241
  * following a previous connection being opened and closed
242
- * [reconnects and is provided with a new connection ID and connection key from the server](./spec/acceptance/realtime/connection_spec.rb#L313)
242
+ * [reconnects and is provided with a new connection ID and connection key from the server](./spec/acceptance/realtime/connection_spec.rb#L315)
243
+ * #serial connection serial
244
+ * [is set to -1 when a new connection is opened](./spec/acceptance/realtime/connection_spec.rb#L335)
245
+ * [is set to 0 when a message sent ACK is received](./spec/acceptance/realtime/connection_spec.rb#L357)
246
+ * [is set to 1 when the second message sent ACK is received](./spec/acceptance/realtime/connection_spec.rb#L364)
247
+ * when a message is sent but the ACK has not yet been received
248
+ * [the sent message msgSerial is 0 but the connection serial remains at -1](./spec/acceptance/realtime/connection_spec.rb#L344)
243
249
  * #close
244
- * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L331)
245
- * [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#L338)
250
+ * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L375)
251
+ * [calls the Deferrable callback on success](./spec/acceptance/realtime/connection_spec.rb#L382)
246
252
  * when already closed
247
- * [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#L349)
253
+ * [does nothing and no further state changes are emitted](./spec/acceptance/realtime/connection_spec.rb#L393)
248
254
  * when connection state is
249
255
  * :initialized
250
- * [changes the connection state to :closing and then immediately :closed without sending a ProtocolMessage CLOSE](./spec/acceptance/realtime/connection_spec.rb#L377)
256
+ * [changes the connection state to :closing and then immediately :closed without sending a ProtocolMessage CLOSE](./spec/acceptance/realtime/connection_spec.rb#L421)
251
257
  * :connected
252
- * [changes the connection state to :closing and waits for the server to confirm connection is :closed with a ProtocolMessage](./spec/acceptance/realtime/connection_spec.rb#L395)
258
+ * [changes the connection state to :closing and waits for the server to confirm connection is :closed with a ProtocolMessage](./spec/acceptance/realtime/connection_spec.rb#L439)
253
259
  * with an unresponsive connection
254
- * [force closes the connection when a :closed ProtocolMessage response is not received](./spec/acceptance/realtime/connection_spec.rb#L425)
260
+ * [force closes the connection when a :closed ProtocolMessage response is not received](./spec/acceptance/realtime/connection_spec.rb#L469)
255
261
  * #ping
256
- * [echoes a heart beat](./spec/acceptance/realtime/connection_spec.rb#L448)
262
+ * [echoes a heart beat](./spec/acceptance/realtime/connection_spec.rb#L492)
257
263
  * when not connected
258
- * [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L458)
264
+ * [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L502)
259
265
  * recovery
260
266
  * #recovery_key
261
- * [is composed of connection id and serial that is kept up to date with each message sent](./spec/acceptance/realtime/connection_spec.rb#L491)
262
- * [is available when connection is in one of the states: connecting, connected, disconnected, suspended, failed](./spec/acceptance/realtime/connection_spec.rb#L512)
263
- * [is nil when connection is explicitly CLOSED](./spec/acceptance/realtime/connection_spec.rb#L536)
267
+ * [is composed of connection id and serial that is kept up to date with each message ACK received](./spec/acceptance/realtime/connection_spec.rb#L535)
268
+ * [is available when connection is in one of the states: connecting, connected, disconnected, suspended, failed](./spec/acceptance/realtime/connection_spec.rb#L556)
269
+ * [is nil when connection is explicitly CLOSED](./spec/acceptance/realtime/connection_spec.rb#L580)
264
270
  * opening a new connection using a recently disconnected connection's #recovery_key
265
271
  * connection#id and connection#key after recovery
266
- * [remain the same](./spec/acceptance/realtime/connection_spec.rb#L550)
272
+ * [remain the same](./spec/acceptance/realtime/connection_spec.rb#L594)
267
273
  * when messages have been sent whilst the old connection is disconnected
268
274
  * the new connection
269
- * [recovers server-side queued messages](./spec/acceptance/realtime/connection_spec.rb#L575)
275
+ * [recovers server-side queued messages](./spec/acceptance/realtime/connection_spec.rb#L619)
270
276
  * with :recover option
271
277
  * with invalid syntax
272
- * [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L600)
278
+ * [raises an exception](./spec/acceptance/realtime/connection_spec.rb#L644)
273
279
  * with invalid formatted value sent to server
274
- * [triggers a fatal error on the connection object, sets the #error_reason and disconnects](./spec/acceptance/realtime/connection_spec.rb#L609)
280
+ * [triggers a fatal error on the connection object, sets the #error_reason and disconnects](./spec/acceptance/realtime/connection_spec.rb#L653)
275
281
  * with expired (missing) value sent to server
276
- * [triggers an error on the connection object, sets the #error_reason, yet will connect anyway](./spec/acceptance/realtime/connection_spec.rb#L623)
282
+ * [triggers an error on the connection object, sets the #error_reason, yet will connect anyway](./spec/acceptance/realtime/connection_spec.rb#L667)
277
283
  * with many connections simultaneously
278
- * [opens each with a unique connection#id and connection#key](./spec/acceptance/realtime/connection_spec.rb#L641)
284
+ * [opens each with a unique connection#id and connection#key](./spec/acceptance/realtime/connection_spec.rb#L685)
279
285
  * when a state transition is unsupported
280
- * [emits a StateChangeError](./spec/acceptance/realtime/connection_spec.rb#L661)
286
+ * [emits a StateChangeError](./spec/acceptance/realtime/connection_spec.rb#L705)
281
287
  * undocumented method
282
288
  * #internet_up?
283
- * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L676)
289
+ * [returns a Deferrable](./spec/acceptance/realtime/connection_spec.rb#L720)
284
290
  * when the Internet is up
285
- * [calls the block with true](./spec/acceptance/realtime/connection_spec.rb#L682)
286
- * [calls the success callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L689)
291
+ * [calls the block with true](./spec/acceptance/realtime/connection_spec.rb#L726)
292
+ * [calls the success callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L733)
287
293
  * when the Internet is down
288
- * [calls the block with false](./spec/acceptance/realtime/connection_spec.rb#L701)
289
- * [calls the failure callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L708)
294
+ * [calls the block with false](./spec/acceptance/realtime/connection_spec.rb#L745)
295
+ * [calls the failure callback of the Deferrable](./spec/acceptance/realtime/connection_spec.rb#L752)
290
296
 
291
297
  ### Ably::Realtime::Channel Message
292
298
  _(see [spec/acceptance/realtime/message_spec.rb](./spec/acceptance/realtime/message_spec.rb))_
@@ -506,7 +512,7 @@ _(see [spec/acceptance/realtime/presence_spec.rb](./spec/acceptance/realtime/pre
506
512
  _(see [spec/acceptance/realtime/stats_spec.rb](./spec/acceptance/realtime/stats_spec.rb))_
507
513
  * using JSON and MsgPack protocol
508
514
  * fetching stats
509
- * [should return a Hash](./spec/acceptance/realtime/stats_spec.rb#L10)
515
+ * [should return a PaginatedResource](./spec/acceptance/realtime/stats_spec.rb#L10)
510
516
  * [should return a Deferrable object](./spec/acceptance/realtime/stats_spec.rb#L17)
511
517
 
512
518
  ### Ably::Realtime::Client#time
@@ -738,29 +744,29 @@ _(see [spec/acceptance/rest/encoders_spec.rb](./spec/acceptance/rest/encoders_sp
738
744
  * with binary data
739
745
  * [does not apply any encoding](./spec/acceptance/rest/encoders_spec.rb#L52)
740
746
  * with JSON data
741
- * [stringifies the JSON and sets the json encoding type](./spec/acceptance/rest/encoders_spec.rb#L63)
747
+ * [stringifies the JSON and sets the encoding attribute to "json"](./spec/acceptance/rest/encoders_spec.rb#L63)
742
748
  * with encryption
743
749
  * with UTF-8 data
744
- * [applies utf-8 and cipher encoding](./spec/acceptance/rest/encoders_spec.rb#L78)
750
+ * [applies utf-8 and cipher encoding and sets the encoding attribute to "utf-8/cipher+aes-128-cbc"](./spec/acceptance/rest/encoders_spec.rb#L78)
745
751
  * with binary data
746
- * [applies cipher encoding](./spec/acceptance/rest/encoders_spec.rb#L89)
752
+ * [applies cipher encoding and sets the encoding attribute to "cipher+aes-128-cbc"](./spec/acceptance/rest/encoders_spec.rb#L89)
747
753
  * with JSON data
748
- * [applies json, utf-8 and cipher encoding](./spec/acceptance/rest/encoders_spec.rb#L100)
754
+ * [applies json, utf-8 and cipher encoding and sets the encoding attribute to "json/utf-8/cipher+aes-128-cbc"](./spec/acceptance/rest/encoders_spec.rb#L100)
749
755
  * with text transport protocol
750
756
  * without encryption
751
757
  * with UTF-8 data
752
758
  * [does not apply any encoding](./spec/acceptance/rest/encoders_spec.rb#L117)
753
759
  * with binary data
754
- * [applies a base64 encoding](./spec/acceptance/rest/encoders_spec.rb#L128)
760
+ * [applies a base64 encoding and sets the encoding attribute to "base64"](./spec/acceptance/rest/encoders_spec.rb#L128)
755
761
  * with JSON data
756
- * [stringifies the JSON and sets the json encoding type](./spec/acceptance/rest/encoders_spec.rb#L139)
762
+ * [stringifies the JSON and sets the encoding attribute to "json"](./spec/acceptance/rest/encoders_spec.rb#L139)
757
763
  * with encryption
758
764
  * with UTF-8 data
759
- * [applies utf-8, cipher and base64 encodings](./spec/acceptance/rest/encoders_spec.rb#L154)
765
+ * [applies utf-8, cipher and base64 encodings and sets the encoding attribute to "utf-8/cipher+aes-128-cbc/base64"](./spec/acceptance/rest/encoders_spec.rb#L154)
760
766
  * with binary data
761
- * [applies cipher and base64 encoding](./spec/acceptance/rest/encoders_spec.rb#L165)
767
+ * [applies cipher and base64 encoding and sets the encoding attribute to "utf-8/cipher+aes-128-cbc/base64"](./spec/acceptance/rest/encoders_spec.rb#L165)
762
768
  * with JSON data
763
- * [applies json, utf-8, cipher and base64 encoding](./spec/acceptance/rest/encoders_spec.rb#L176)
769
+ * [applies json, utf-8, cipher and base64 encoding and sets the encoding attribute to "json/utf-8/cipher+aes-128-cbc/base64"](./spec/acceptance/rest/encoders_spec.rb#L176)
764
770
 
765
771
  ### Ably::Rest::Channel messages
766
772
  _(see [spec/acceptance/rest/message_spec.rb](./spec/acceptance/rest/message_spec.rb))_
@@ -867,13 +873,32 @@ _(see [spec/acceptance/rest/stats_spec.rb](./spec/acceptance/rest/stats_spec.rb)
867
873
  * using JSON and MsgPack protocol
868
874
  * fetching application stats
869
875
  * by minute
870
- * [should return all the stats for the application](./spec/acceptance/rest/stats_spec.rb#L49)
876
+ * with :from set to last interval and :limit set to 1
877
+ * [retrieves only one stat](./spec/acceptance/rest/stats_spec.rb#L51)
878
+ * [returns accurate all aggregated message data](./spec/acceptance/rest/stats_spec.rb#L55)
879
+ * [returns accurate inbound realtime all data](./spec/acceptance/rest/stats_spec.rb#L60)
880
+ * [returns accurate inbound realtime message data](./spec/acceptance/rest/stats_spec.rb#L65)
881
+ * [returns accurate outbound realtime all data](./spec/acceptance/rest/stats_spec.rb#L70)
882
+ * [returns accurate persisted presence all data](./spec/acceptance/rest/stats_spec.rb#L75)
883
+ * [returns accurate connections all data](./spec/acceptance/rest/stats_spec.rb#L80)
884
+ * [returns accurate channels all data](./spec/acceptance/rest/stats_spec.rb#L85)
885
+ * [returns accurate api_requests data](./spec/acceptance/rest/stats_spec.rb#L90)
886
+ * [returns accurate token_requests data](./spec/acceptance/rest/stats_spec.rb#L95)
887
+ * [returns stat objects with #interval_granularity equal to :minute](./spec/acceptance/rest/stats_spec.rb#L100)
888
+ * [returns stat objects with #interval_id matching :start](./spec/acceptance/rest/stats_spec.rb#L104)
889
+ * [returns stat objects with #interval_time matching :start Time](./spec/acceptance/rest/stats_spec.rb#L108)
890
+ * with :start set to first interval, :limit set to 1 and direction :forwards
891
+ * [returns the first interval stats as stats are provided forwards from :start](./spec/acceptance/rest/stats_spec.rb#L118)
892
+ * [returns 3 pages of stats](./spec/acceptance/rest/stats_spec.rb#L122)
893
+ * with :end set to last interval, :limit set to 1 and direction :backwards
894
+ * [returns the 3rd interval stats first as stats are provided backwards from :end](./spec/acceptance/rest/stats_spec.rb#L135)
895
+ * [returns 3 pages of stats](./spec/acceptance/rest/stats_spec.rb#L139)
871
896
  * by hour
872
- * [should return all the stats for the application](./spec/acceptance/rest/stats_spec.rb#L49)
897
+ * [should aggregate the stats for that period](./spec/acceptance/rest/stats_spec.rb#L163)
873
898
  * by day
874
- * [should return all the stats for the application](./spec/acceptance/rest/stats_spec.rb#L49)
899
+ * [should aggregate the stats for that period](./spec/acceptance/rest/stats_spec.rb#L163)
875
900
  * by month
876
- * [should return all the stats for the application](./spec/acceptance/rest/stats_spec.rb#L49)
901
+ * [should aggregate the stats for that period](./spec/acceptance/rest/stats_spec.rb#L163)
877
902
 
878
903
  ### Ably::Rest::Client#time
879
904
  _(see [spec/acceptance/rest/time_spec.rb](./spec/acceptance/rest/time_spec.rb))_
@@ -1337,6 +1362,63 @@ _(see [spec/unit/models/protocol_message_spec.rb](./spec/unit/models/protocol_me
1337
1362
  * with error
1338
1363
  * [returns a valid ErrorInfo object](./spec/unit/models/protocol_message_spec.rb#L261)
1339
1364
 
1365
+ ### Ably::Models::Stat
1366
+ _(see [spec/unit/models/stat_spec.rb](./spec/unit/models/stat_spec.rb))_
1367
+ * behaves like a model
1368
+ * attributes
1369
+ * #interval_id
1370
+ * [retrieves attribute :interval_id](./spec/shared/model_behaviour.rb#L15)
1371
+ * #all
1372
+ * [retrieves attribute :all](./spec/shared/model_behaviour.rb#L15)
1373
+ * #inbound
1374
+ * [retrieves attribute :inbound](./spec/shared/model_behaviour.rb#L15)
1375
+ * #outbound
1376
+ * [retrieves attribute :outbound](./spec/shared/model_behaviour.rb#L15)
1377
+ * #persisted
1378
+ * [retrieves attribute :persisted](./spec/shared/model_behaviour.rb#L15)
1379
+ * #connections
1380
+ * [retrieves attribute :connections](./spec/shared/model_behaviour.rb#L15)
1381
+ * #channels
1382
+ * [retrieves attribute :channels](./spec/shared/model_behaviour.rb#L15)
1383
+ * #api_requests
1384
+ * [retrieves attribute :api_requests](./spec/shared/model_behaviour.rb#L15)
1385
+ * #token_requests
1386
+ * [retrieves attribute :token_requests](./spec/shared/model_behaviour.rb#L15)
1387
+ * #==
1388
+ * [is true when attributes are the same](./spec/shared/model_behaviour.rb#L41)
1389
+ * [is false when attributes are not the same](./spec/shared/model_behaviour.rb#L46)
1390
+ * [is false when class type differs](./spec/shared/model_behaviour.rb#L50)
1391
+ * is immutable
1392
+ * [prevents changes](./spec/shared/model_behaviour.rb#L76)
1393
+ * [dups options](./spec/shared/model_behaviour.rb#L80)
1394
+ * #interval_granularity
1395
+ * [returns the granularity of the interval_id](./spec/unit/models/stat_spec.rb#L17)
1396
+ * #interval_time
1397
+ * [returns a Time object representing the start of the interval](./spec/unit/models/stat_spec.rb#L25)
1398
+ * class methods
1399
+ * #to_interval_id
1400
+ * when time zone of time argument is UTC
1401
+ * [converts time 2014-02-03:05:06 with granularity :month into 2014-02](./spec/unit/models/stat_spec.rb#L33)
1402
+ * [converts time 2014-02-03:05:06 with granularity :day into 2014-02-03](./spec/unit/models/stat_spec.rb#L37)
1403
+ * [converts time 2014-02-03:05:06 with granularity :hour into 2014-02-03:05](./spec/unit/models/stat_spec.rb#L41)
1404
+ * [converts time 2014-02-03:05:06 with granularity :minute into 2014-02-03:05:06](./spec/unit/models/stat_spec.rb#L45)
1405
+ * [fails with invalid granularity](./spec/unit/models/stat_spec.rb#L49)
1406
+ * [fails with invalid time](./spec/unit/models/stat_spec.rb#L53)
1407
+ * when time zone of time argument is +02:00
1408
+ * [converts time 2014-02-03:06 with granularity :hour into 2014-02-03:04 at UTC +00:00](./spec/unit/models/stat_spec.rb#L59)
1409
+ * #from_interval_id
1410
+ * [converts a month interval_id 2014-02 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L66)
1411
+ * [converts a day interval_id 2014-02-03 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L71)
1412
+ * [converts an hour interval_id 2014-02-03:05 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L76)
1413
+ * [converts a minute interval_id 2014-02-03:05:06 into a Time object in UTC 0](./spec/unit/models/stat_spec.rb#L81)
1414
+ * [fails with an invalid interval_id 14-20](./spec/unit/models/stat_spec.rb#L86)
1415
+ * #granularity_from_interval_id
1416
+ * [returns a :month interval_id for 2014-02](./spec/unit/models/stat_spec.rb#L92)
1417
+ * [returns a :day interval_id for 2014-02-03](./spec/unit/models/stat_spec.rb#L96)
1418
+ * [returns a :hour interval_id for 2014-02-03:05](./spec/unit/models/stat_spec.rb#L100)
1419
+ * [returns a :minute interval_id for 2014-02-03:05:06](./spec/unit/models/stat_spec.rb#L104)
1420
+ * [fails with an invalid interval_id 14-20](./spec/unit/models/stat_spec.rb#L108)
1421
+
1340
1422
  ### Ably::Models::Token
1341
1423
  _(see [spec/unit/models/token_spec.rb](./spec/unit/models/token_spec.rb))_
1342
1424
  * behaves like a model
@@ -1703,10 +1785,10 @@ _(see [spec/unit/util/pub_sub_spec.rb](./spec/unit/util/pub_sub_spec.rb))_
1703
1785
  * [deletes all callbacks if not block given](./spec/unit/util/pub_sub_spec.rb#L76)
1704
1786
  * [continues if the block does not exist](./spec/unit/util/pub_sub_spec.rb#L81)
1705
1787
 
1706
- -------
1788
+ -------
1707
1789
 
1708
- ## Test summary
1790
+ ## Test summary
1709
1791
 
1710
- * Passing tests: 811
1711
- * Pending tests: 11
1712
- * Failing tests: 0
1792
+ * Passing tests: 864
1793
+ * Pending tests: 11
1794
+ * Failing tests: 0
data/ably.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency 'bundler', '~> 1.3'
30
30
  spec.add_development_dependency 'rake'
31
31
  spec.add_development_dependency 'redcarpet'
32
- spec.add_development_dependency 'rspec', '~> 3.1.0' # version lock, see event_machine_helper.rb#patch_example_block_with_surrounding_eventmachine_reactor
32
+ spec.add_development_dependency 'rspec', '~> 3.1.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
33
33
  spec.add_development_dependency 'rspec-retry'
34
34
  spec.add_development_dependency 'yard'
35
35
  spec.add_development_dependency 'webmock'
@@ -0,0 +1,161 @@
1
+ module Ably::Models
2
+ # Convert stat argument to a {Stat} object
3
+ #
4
+ # @param stat [Stat,Hash] A Stat object or Hash of stat properties
5
+ #
6
+ # @return [Stat]
7
+ def self.Stat(stat)
8
+ case stat
9
+ when Stat
10
+ stat
11
+ else
12
+ Stat.new(stat)
13
+ end
14
+ end
15
+
16
+ # A class representing an individual statistic for a specified {#interval_id}
17
+ #
18
+ # @!attribute [r] all
19
+ # @return [Hash] Breakdown of summary stats for all message types
20
+ # @!attribute [r] inbound
21
+ # @return [Hash] Breakdown of summary stats for traffic over various transport types for all inbound messages
22
+ # @!attribute [r] outbound
23
+ # @return [Hash] Breakdown of summary stats for traffic over various transport types for all outbound messages
24
+ # @!attribute [r] persisted
25
+ # @return [Hash] Breakdown of summary stats for all persisted messages
26
+ # @!attribute [r] connections
27
+ # @return [Hash] A breakdown of summary stats data for different (TLS vs non-TLS) connection types.
28
+ # @!attribute [r] channels
29
+ # @return [Hash] Aggregate data for usage of Channels
30
+ # @!attribute [r] api_requests
31
+ # @return [Hash] Aggregate data for numbers of API requests
32
+ # @!attribute [r] token_requests
33
+ # @return [Hash] Aggregate data for numbers of Token requests
34
+ #
35
+ class Stat
36
+ include Ably::Modules::ModelCommon
37
+ extend Ably::Modules::Enum
38
+
39
+ GRANULARITY = ruby_enum('GRANULARITY',
40
+ :minute,
41
+ :hour,
42
+ :day,
43
+ :month
44
+ )
45
+
46
+ INTERVAL_FORMAT_STRING = [
47
+ '%Y-%m-%d:%H:%M',
48
+ '%Y-%m-%d:%H',
49
+ '%Y-%m-%d',
50
+ '%Y-%m'
51
+ ]
52
+
53
+ class << self
54
+ # Convert a Time with the specified Granularity into an interval ID based on UTC 0 time
55
+ # @example
56
+ # Stat.to_interval_id(Time.now, :hour) # => '2015-01-01:10'
57
+ #
58
+ # @param time [Time] Time used to determine the interval
59
+ # @param granularity [GRANULARITY] Granularity of the metrics such as :hour, :day
60
+ #
61
+ # @return [String] interval ID used for stats
62
+ #
63
+ def to_interval_id(time, granularity)
64
+ raise ArgumentError, 'Time object required as first argument' unless time.kind_of?(Time)
65
+
66
+ granularity = GRANULARITY(granularity)
67
+ format = INTERVAL_FORMAT_STRING[granularity.to_i]
68
+
69
+ time.utc.strftime(format)
70
+ end
71
+
72
+ # Returns the UTC 0 start Time of an interval_id
73
+ # @example
74
+ # Stat.from_interval_id('2015-01-01:10') # => 2015-01-01 10:00:00 +0000
75
+ #
76
+ # @param interval_id [String]
77
+ #
78
+ # @return [Time] start time of the provided interval_id
79
+ #
80
+ def from_interval_id(interval_id)
81
+ raise ArgumentError, 'Interval ID must be a string' unless interval_id.kind_of?(String)
82
+
83
+ format = INTERVAL_FORMAT_STRING.find { |format| expected_length(format) == interval_id.length }
84
+ raise ArgumentError, 'Interval ID is an invalid length' unless format
85
+
86
+ Time.strptime("#{interval_id} +0000", "#{format} %z").utc
87
+ end
88
+
89
+ # Returns the {GRANULARITY} determined from the interval_id
90
+ # @example
91
+ # Stat.granularity_from_interval_id('2015-01-01:10') # => :hour
92
+ #
93
+ # @param interval_id [String]
94
+ #
95
+ # @return [GRANULARITY] Granularity Enum for the interval_id
96
+ #
97
+ def granularity_from_interval_id(interval_id)
98
+ raise ArgumentError, 'Interval ID must be a string' unless interval_id.kind_of?(String)
99
+
100
+ format = INTERVAL_FORMAT_STRING.find { |format| expected_length(format) == interval_id.length }
101
+ raise ArgumentError, 'Interval ID is an invalid length' unless format
102
+
103
+ GRANULARITY[INTERVAL_FORMAT_STRING.index(format)]
104
+ end
105
+
106
+ private
107
+ def expected_length(format)
108
+ format.gsub('%Y', 'YYYY').length
109
+ end
110
+ end
111
+
112
+ # {Stat} initializer
113
+ #
114
+ # @param hash_object [Hash] object with the underlying stat details
115
+ #
116
+ def initialize(hash_object)
117
+ @raw_hash_object = hash_object
118
+
119
+ set_hash_object hash_object
120
+ end
121
+
122
+ %w( all inbound outbound persisted connections channels api_requests token_requests ).each do |attribute|
123
+ define_method attribute do
124
+ hash[attribute.to_sym]
125
+ end
126
+ end
127
+
128
+ # @!attribute [r] interval_id
129
+ # @return [String] The interval that this statistic applies to, see {GRANULARITY} and {INTERVAL_FORMAT_STRING}
130
+ def interval_id
131
+ hash.fetch(:interval_id)
132
+ end
133
+
134
+ # @!attribute [r] interval_time
135
+ # @return [Time] A Time object representing the start of the interval
136
+ def interval_time
137
+ self.class.from_interval_id(interval_id)
138
+ end
139
+
140
+ # @!attribute [r] interval_granularity
141
+ # @return [GRANULARITY] The granularity of the interval for the stat such as :day, :hour, :minute, see {GRANULARITY}
142
+ def interval_granularity
143
+ self.class.granularity_from_interval_id(interval_id)
144
+ end
145
+
146
+ def hash
147
+ @hash_object
148
+ end
149
+
150
+ def as_json(*args)
151
+ hash.as_json(*args)
152
+ end
153
+
154
+ private
155
+ attr_reader :raw_hash_object
156
+
157
+ def set_hash_object(hash)
158
+ @hash_object = IdiomaticRubyWrapper(hash.clone.freeze)
159
+ end
160
+ end
161
+ end