ably 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
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