twitter 4.8.1 → 5.0.0.rc.1

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 (197) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG.md +30 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +386 -266
  5. data/lib/twitter.rb +4 -39
  6. data/lib/twitter/arguments.rb +11 -0
  7. data/lib/twitter/base.rb +89 -68
  8. data/lib/twitter/client.rb +69 -110
  9. data/lib/twitter/configuration.rb +7 -3
  10. data/lib/twitter/creatable.rb +2 -4
  11. data/lib/twitter/cursor.rb +50 -42
  12. data/lib/twitter/direct_message.rb +2 -11
  13. data/lib/twitter/entity/uri.rb +13 -0
  14. data/lib/twitter/enumerable.rb +15 -0
  15. data/lib/twitter/error.rb +55 -7
  16. data/lib/twitter/error/already_favorited.rb +1 -1
  17. data/lib/twitter/error/already_posted.rb +10 -0
  18. data/lib/twitter/error/already_retweeted.rb +1 -1
  19. data/lib/twitter/error/bad_gateway.rb +2 -3
  20. data/lib/twitter/error/bad_request.rb +2 -2
  21. data/lib/twitter/error/forbidden.rb +2 -2
  22. data/lib/twitter/error/gateway_timeout.rb +2 -3
  23. data/lib/twitter/error/internal_server_error.rb +2 -3
  24. data/lib/twitter/error/not_acceptable.rb +2 -2
  25. data/lib/twitter/error/not_found.rb +2 -2
  26. data/lib/twitter/error/service_unavailable.rb +2 -3
  27. data/lib/twitter/error/too_many_requests.rb +2 -2
  28. data/lib/twitter/error/unauthorized.rb +2 -2
  29. data/lib/twitter/error/unprocessable_entity.rb +2 -2
  30. data/lib/twitter/factory.rb +2 -8
  31. data/lib/twitter/geo_factory.rb +2 -2
  32. data/lib/twitter/geo_results.rb +36 -0
  33. data/lib/twitter/identity.rb +0 -22
  34. data/lib/twitter/list.rb +18 -4
  35. data/lib/twitter/media/photo.rb +3 -3
  36. data/lib/twitter/media_factory.rb +2 -2
  37. data/lib/twitter/null_object.rb +24 -0
  38. data/lib/twitter/oembed.rb +3 -2
  39. data/lib/twitter/place.rb +15 -9
  40. data/lib/twitter/profile_banner.rb +5 -3
  41. data/lib/twitter/rate_limit.rb +1 -17
  42. data/lib/twitter/relationship.rb +2 -10
  43. data/lib/twitter/rest/api/direct_messages.rb +135 -0
  44. data/lib/twitter/rest/api/favorites.rb +120 -0
  45. data/lib/twitter/rest/api/friends_and_followers.rb +290 -0
  46. data/lib/twitter/rest/api/help.rb +58 -0
  47. data/lib/twitter/rest/api/lists.rb +491 -0
  48. data/lib/twitter/rest/api/oauth.rb +45 -0
  49. data/lib/twitter/rest/api/places_and_geo.rb +104 -0
  50. data/lib/twitter/rest/api/saved_searches.rb +91 -0
  51. data/lib/twitter/rest/api/search.rb +37 -0
  52. data/lib/twitter/rest/api/spam_reporting.rb +29 -0
  53. data/lib/twitter/rest/api/suggested_users.rb +51 -0
  54. data/lib/twitter/rest/api/timelines.rb +202 -0
  55. data/lib/twitter/rest/api/trends.rb +58 -0
  56. data/lib/twitter/rest/api/tweets.rb +293 -0
  57. data/lib/twitter/rest/api/undocumented.rb +52 -0
  58. data/lib/twitter/rest/api/users.rb +383 -0
  59. data/lib/twitter/rest/api/utils.rb +219 -0
  60. data/lib/twitter/rest/client.rb +193 -0
  61. data/lib/twitter/rest/request/multipart_with_file.rb +36 -0
  62. data/lib/twitter/rest/response/parse_json.rb +27 -0
  63. data/lib/twitter/{response → rest/response}/raise_error.rb +8 -11
  64. data/lib/twitter/search_results.rb +33 -21
  65. data/lib/twitter/settings.rb +1 -6
  66. data/lib/twitter/size.rb +1 -1
  67. data/lib/twitter/streaming/client.rb +77 -0
  68. data/lib/twitter/streaming/connection.rb +22 -0
  69. data/lib/twitter/streaming/response.rb +30 -0
  70. data/lib/twitter/suggestion.rb +4 -2
  71. data/lib/twitter/token.rb +8 -0
  72. data/lib/twitter/trend.rb +2 -1
  73. data/lib/twitter/trend_results.rb +59 -0
  74. data/lib/twitter/tweet.rb +41 -85
  75. data/lib/twitter/user.rb +51 -41
  76. data/lib/twitter/version.rb +4 -4
  77. data/spec/fixtures/already_posted.json +1 -0
  78. data/spec/fixtures/ids_list.json +1 -1
  79. data/spec/fixtures/ids_list2.json +1 -1
  80. data/spec/fixtures/search.json +1 -1
  81. data/spec/fixtures/search_malformed.json +1 -1
  82. data/spec/fixtures/track_streaming.json +3 -0
  83. data/spec/helper.rb +8 -13
  84. data/spec/twitter/base_spec.rb +25 -99
  85. data/spec/twitter/configuration_spec.rb +1 -1
  86. data/spec/twitter/cursor_spec.rb +13 -31
  87. data/spec/twitter/direct_message_spec.rb +41 -8
  88. data/spec/twitter/entity/uri_spec.rb +74 -0
  89. data/spec/twitter/error_spec.rb +59 -11
  90. data/spec/twitter/geo/point_spec.rb +1 -1
  91. data/spec/twitter/geo_factory_spec.rb +3 -3
  92. data/spec/twitter/geo_results_spec.rb +35 -0
  93. data/spec/twitter/identifiable_spec.rb +0 -21
  94. data/spec/twitter/list_spec.rb +51 -8
  95. data/spec/twitter/media/photo_spec.rb +118 -3
  96. data/spec/twitter/media_factory_spec.rb +2 -2
  97. data/spec/twitter/null_object_spec.rb +26 -0
  98. data/spec/twitter/oembed_spec.rb +69 -45
  99. data/spec/twitter/place_spec.rb +68 -12
  100. data/spec/twitter/profile_banner_spec.rb +1 -1
  101. data/spec/twitter/rate_limit_spec.rb +12 -12
  102. data/spec/twitter/relationship_spec.rb +31 -9
  103. data/spec/twitter/{api → rest/api}/direct_messages_spec.rb +22 -9
  104. data/spec/twitter/{api → rest/api}/favorites_spec.rb +80 -7
  105. data/spec/twitter/{api → rest/api}/friends_and_followers_spec.rb +104 -65
  106. data/spec/twitter/{api → rest/api}/geo_spec.rb +10 -10
  107. data/spec/twitter/{api → rest/api}/help_spec.rb +6 -6
  108. data/spec/twitter/{api → rest/api}/lists_spec.rb +77 -56
  109. data/spec/twitter/{api → rest/api}/oauth_spec.rb +6 -6
  110. data/spec/twitter/{api → rest/api}/saved_searches_spec.rb +7 -7
  111. data/spec/twitter/{api → rest/api}/search_spec.rb +8 -9
  112. data/spec/twitter/{api → rest/api}/spam_reporting_spec.rb +3 -3
  113. data/spec/twitter/{api → rest/api}/suggested_users_spec.rb +5 -5
  114. data/spec/twitter/{api → rest/api}/timelines_spec.rb +9 -9
  115. data/spec/twitter/{api → rest/api}/trends_spec.rb +6 -6
  116. data/spec/twitter/rest/api/tweets_spec.rb +503 -0
  117. data/spec/twitter/{api → rest/api}/undocumented_spec.rb +19 -45
  118. data/spec/twitter/{api → rest/api}/users_spec.rb +60 -35
  119. data/spec/twitter/rest/client_spec.rb +193 -0
  120. data/spec/twitter/saved_search_spec.rb +11 -0
  121. data/spec/twitter/search_results_spec.rb +29 -42
  122. data/spec/twitter/settings_spec.rb +17 -6
  123. data/spec/twitter/streaming/client_spec.rb +75 -0
  124. data/spec/twitter/token_spec.rb +16 -0
  125. data/spec/twitter/trend_results_spec.rb +89 -0
  126. data/spec/twitter/trend_spec.rb +23 -0
  127. data/spec/twitter/tweet_spec.rb +122 -115
  128. data/spec/twitter/user_spec.rb +136 -77
  129. data/spec/twitter_spec.rb +0 -119
  130. data/twitter.gemspec +8 -5
  131. metadata +148 -141
  132. metadata.gz.sig +0 -0
  133. data/lib/twitter/action/favorite.rb +0 -19
  134. data/lib/twitter/action/follow.rb +0 -30
  135. data/lib/twitter/action/list_member_added.rb +0 -39
  136. data/lib/twitter/action/mention.rb +0 -46
  137. data/lib/twitter/action/reply.rb +0 -27
  138. data/lib/twitter/action/retweet.rb +0 -27
  139. data/lib/twitter/action/tweet.rb +0 -20
  140. data/lib/twitter/action_factory.rb +0 -22
  141. data/lib/twitter/api/arguments.rb +0 -13
  142. data/lib/twitter/api/direct_messages.rb +0 -148
  143. data/lib/twitter/api/favorites.rb +0 -126
  144. data/lib/twitter/api/friends_and_followers.rb +0 -334
  145. data/lib/twitter/api/help.rb +0 -64
  146. data/lib/twitter/api/lists.rb +0 -618
  147. data/lib/twitter/api/oauth.rb +0 -44
  148. data/lib/twitter/api/places_and_geo.rb +0 -121
  149. data/lib/twitter/api/saved_searches.rb +0 -99
  150. data/lib/twitter/api/search.rb +0 -37
  151. data/lib/twitter/api/spam_reporting.rb +0 -30
  152. data/lib/twitter/api/suggested_users.rb +0 -55
  153. data/lib/twitter/api/timelines.rb +0 -214
  154. data/lib/twitter/api/trends.rb +0 -63
  155. data/lib/twitter/api/tweets.rb +0 -304
  156. data/lib/twitter/api/undocumented.rb +0 -97
  157. data/lib/twitter/api/users.rb +0 -439
  158. data/lib/twitter/api/utils.rb +0 -187
  159. data/lib/twitter/configurable.rb +0 -96
  160. data/lib/twitter/default.rb +0 -102
  161. data/lib/twitter/entity/url.rb +0 -9
  162. data/lib/twitter/error/client_error.rb +0 -35
  163. data/lib/twitter/error/decode_error.rb +0 -9
  164. data/lib/twitter/error/identity_map_key_error.rb +0 -9
  165. data/lib/twitter/error/server_error.rb +0 -28
  166. data/lib/twitter/exceptable.rb +0 -36
  167. data/lib/twitter/identity_map.rb +0 -22
  168. data/lib/twitter/request/multipart_with_file.rb +0 -34
  169. data/lib/twitter/response/parse_json.rb +0 -25
  170. data/spec/fixtures/about_me.json +0 -1
  171. data/spec/fixtures/activity_summary.json +0 -1
  172. data/spec/fixtures/bad_gateway.json +0 -1
  173. data/spec/fixtures/bad_request.json +0 -1
  174. data/spec/fixtures/by_friends.json +0 -1
  175. data/spec/fixtures/end_session.json +0 -1
  176. data/spec/fixtures/forbidden.json +0 -1
  177. data/spec/fixtures/internal_server_error.json +0 -1
  178. data/spec/fixtures/not_acceptable.json +0 -1
  179. data/spec/fixtures/phoenix_search.phoenix +0 -1
  180. data/spec/fixtures/resolve.json +0 -1
  181. data/spec/fixtures/service_unavailable.json +0 -1
  182. data/spec/fixtures/totals.json +0 -1
  183. data/spec/fixtures/trends.json +0 -1
  184. data/spec/fixtures/unauthorized.json +0 -1
  185. data/spec/fixtures/video_facets.json +0 -1
  186. data/spec/twitter/action/favorite_spec.rb +0 -29
  187. data/spec/twitter/action/follow_spec.rb +0 -29
  188. data/spec/twitter/action/list_member_added_spec.rb +0 -41
  189. data/spec/twitter/action/mention_spec.rb +0 -52
  190. data/spec/twitter/action/reply_spec.rb +0 -41
  191. data/spec/twitter/action/retweet_spec.rb +0 -41
  192. data/spec/twitter/action_factory_spec.rb +0 -35
  193. data/spec/twitter/action_spec.rb +0 -16
  194. data/spec/twitter/api/tweets_spec.rb +0 -285
  195. data/spec/twitter/client_spec.rb +0 -223
  196. data/spec/twitter/error/client_error_spec.rb +0 -23
  197. data/spec/twitter/error/server_error_spec.rb +0 -20
@@ -1,12 +1,10 @@
1
1
  require 'twitter/basic_user'
2
2
  require 'twitter/creatable'
3
- require 'twitter/exceptable'
4
3
 
5
4
  module Twitter
6
5
  class User < Twitter::BasicUser
7
6
  PROFILE_IMAGE_SUFFIX_REGEX = /_normal(\.gif|\.jpe?g|\.png)$/i
8
7
  include Twitter::Creatable
9
- include Twitter::Exceptable
10
8
  attr_reader :connections, :contributors_enabled, :default_profile,
11
9
  :default_profile_image, :description, :favourites_count,
12
10
  :follow_request_sent, :followers_count, :friends_count, :geo_enabled,
@@ -16,94 +14,106 @@ module Twitter
16
14
  :profile_link_color, :profile_sidebar_border_color,
17
15
  :profile_sidebar_fill_color, :profile_text_color,
18
16
  :profile_use_background_image, :protected, :statuses_count, :time_zone,
19
- :url, :utc_offset, :verified
20
- alias favorite_count favourites_count
21
- alias favoriters_count favourites_count
17
+ :utc_offset, :verified
22
18
  alias favorites_count favourites_count
23
- alias favourite_count favourites_count
24
- alias favouriters_count favourites_count
25
- alias follower_count followers_count
26
- alias friend_count friends_count
27
- alias status_count statuses_count
28
- alias translator is_translator
29
- alias translator? is_translator?
30
- alias tweet_count statuses_count
19
+ alias profile_background_image_uri profile_background_image_url
20
+ alias profile_background_image_uri_https profile_background_image_url_https
21
+ alias translator? is_translator
31
22
  alias tweets_count statuses_count
32
- alias update_count statuses_count
33
- alias updates_count statuses_count
23
+ object_attr_reader :Tweet, :status, :user
24
+ alias tweet status
25
+ alias tweet? status?
26
+ alias tweeted? status?
34
27
 
35
28
  # @return [Array<Twitter::Entity::Url>]
36
- def description_urls
37
- @description_urls ||= Array(@attrs[:entities][:description][:urls]).map do |entity|
38
- Twitter::Entity::Url.fetch_or_new(entity)
29
+ def description_uris
30
+ memoize(:description_urls) do
31
+ Array(@attrs[:entities][:description][:urls]).map do |entity|
32
+ Twitter::Entity::Url.new(entity)
33
+ end
39
34
  end
40
35
  end
36
+ alias description_urls description_uris
41
37
 
42
38
  # Return the URL to the user's profile banner image
43
39
  #
44
40
  # @param size [String, Symbol] The size of the image. Must be one of: 'mobile', 'mobile_retina', 'web', 'web_retina', 'ipad', or 'ipad_retina'
45
41
  # @return [String]
46
- def profile_banner_url(size=:web)
47
- insecure_url([@attrs[:profile_banner_url], size].join('/')) if profile_banner_url?
42
+ def profile_banner_uri(size=:web)
43
+ parse_encoded_uri(insecure_uri([@attrs[:profile_banner_url], size].join('/'))) if @attrs[:profile_banner_url]
48
44
  end
45
+ alias profile_banner_url profile_banner_uri
49
46
 
50
47
  # Return the secure URL to the user's profile banner image
51
48
  #
52
49
  # @param size [String, Symbol] The size of the image. Must be one of: 'mobile', 'mobile_retina', 'web', 'web_retina', 'ipad', or 'ipad_retina'
53
50
  # @return [String]
54
- def profile_banner_url_https(size=:web)
55
- [@attrs[:profile_banner_url], size].join('/') if profile_banner_url?
51
+ def profile_banner_uri_https(size=:web)
52
+ parse_encoded_uri([@attrs[:profile_banner_url], size].join('/')) if @attrs[:profile_banner_url]
56
53
  end
54
+ alias profile_banner_url_https profile_banner_uri_https
57
55
 
58
- def profile_banner_url?
59
- !@attrs[:profile_banner_url].nil?
56
+ def profile_banner_uri?
57
+ !!@attrs[:profile_banner_url]
60
58
  end
61
- alias profile_banner_url_https? profile_banner_url?
59
+ alias profile_banner_url? profile_banner_uri?
60
+ alias profile_banner_uri_https? profile_banner_uri?
61
+ alias profile_banner_url_https? profile_banner_uri?
62
62
 
63
63
  # Return the URL to the user's profile image
64
64
  #
65
65
  # @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
66
66
  # @return [String]
67
- def profile_image_url(size=:normal)
68
- insecure_url(profile_image_url_https(size)) if profile_image_url?
67
+ def profile_image_uri(size=:normal)
68
+ parse_encoded_uri(insecure_uri(profile_image_uri_https(size))) if @attrs[:profile_image_url_https]
69
69
  end
70
+ alias profile_image_url profile_image_uri
70
71
 
71
72
  # Return the secure URL to the user's profile image
72
73
  #
73
74
  # @param size [String, Symbol] The size of the image. Must be one of: 'mini', 'normal', 'bigger' or 'original'
74
75
  # @return [String]
75
- def profile_image_url_https(size=:normal)
76
+ def profile_image_uri_https(size=:normal)
76
77
  # The profile image URL comes in looking like like this:
77
78
  # https://a0.twimg.com/profile_images/1759857427/image1326743606_normal.png
78
79
  # It can be converted to any of the following sizes:
79
80
  # https://a0.twimg.com/profile_images/1759857427/image1326743606.png
80
81
  # https://a0.twimg.com/profile_images/1759857427/image1326743606_mini.png
81
82
  # https://a0.twimg.com/profile_images/1759857427/image1326743606_bigger.png
82
- resize_profile_image_url(@attrs[:profile_image_url_https], size) if profile_image_url?
83
+ parse_encoded_uri(@attrs[:profile_image_url_https].sub(PROFILE_IMAGE_SUFFIX_REGEX, profile_image_suffix(size))) if @attrs[:profile_image_url_https]
83
84
  end
85
+ alias profile_image_url_https profile_image_uri_https
84
86
 
85
- def profile_image_url?
86
- !@attrs[:profile_image_url_https].nil?
87
+ def profile_image_uri?
88
+ !!@attrs[:profile_image_url_https]
87
89
  end
88
- alias profile_image_url_https? profile_image_url?
90
+ alias profile_image_url? profile_image_uri?
91
+ alias profile_image_uri_https? profile_image_uri?
92
+ alias profile_image_url_https? profile_image_uri?
89
93
 
90
- # @return [Twitter::Tweet]
91
- def status
92
- @status ||= fetch_or_new_without_self(Twitter::Tweet, @attrs, :status, :user)
94
+ # @return [String] The URL to the user.
95
+ def uri
96
+ @uri ||= ::URI.parse("https://twitter.com/#{screen_name}")
93
97
  end
98
+ alias url uri
94
99
 
95
- def status?
96
- !@attrs[:status].nil?
100
+ # @return [String] The URL to the user's website.
101
+ def website
102
+ @website ||= ::URI.parse(@attrs[:url]) if @attrs[:url]
103
+ end
104
+
105
+ def website?
106
+ !!@attrs[:url]
97
107
  end
98
108
 
99
109
  private
100
110
 
101
- def insecure_url(url)
102
- url.sub(/^https/i, 'http')
111
+ def parse_encoded_uri(uri)
112
+ ::URI.parse(::URI.encode(uri))
103
113
  end
104
114
 
105
- def resize_profile_image_url(url, size)
106
- url.sub(PROFILE_IMAGE_SUFFIX_REGEX, profile_image_suffix(size))
115
+ def insecure_uri(uri)
116
+ uri.to_s.sub(/^https/i, 'http')
107
117
  end
108
118
 
109
119
  def profile_image_suffix(size)
@@ -1,9 +1,9 @@
1
1
  module Twitter
2
2
  class Version
3
- MAJOR = 4 unless defined? Twitter::Version::MAJOR
4
- MINOR = 8 unless defined? Twitter::Version::MINOR
5
- PATCH = 1 unless defined? Twitter::Version::PATCH
6
- PRE = nil unless defined? Twitter::Version::PRE
3
+ MAJOR = 5
4
+ MINOR = 0
5
+ PATCH = 0
6
+ PRE = "rc.1"
7
7
 
8
8
  class << self
9
9
 
@@ -0,0 +1 @@
1
+ {"errors":"Status is a duplicate"}
@@ -1 +1 @@
1
- {"previous_cursor":0,"next_cursor_str":"1305102810874389703","ids":[14100886,22469930,351223419],"previous_cursor_str":"0","next_cursor":1305102810874389703}
1
+ {"previous_cursor":0,"next_cursor_str":"1305102810874389703","ids":[20009713,22469930,351223419],"previous_cursor_str":"0","next_cursor":1305102810874389703}
@@ -1 +1 @@
1
- {"previous_cursor":-1305101990888327757,"next_cursor_str":"0","ids":[20009713,23621851,14509199],"previous_cursor_str":"-1305101990888327757","next_cursor":0}
1
+ {"previous_cursor":-1305101990888327757,"next_cursor_str":"0","ids":[14100886,23621851,14509199],"previous_cursor_str":"-1305101990888327757","next_cursor":0}
@@ -1 +1 @@
1
- {"statuses":[{"metadata":{"result_type":"recent","iso_language_code":"en"},"created_at":"Mon Sep 17 22:41:52 +0000 2012","id":247827742178021376,"id_str":"247827742178021376","text":"Bubble Mailer #freebandnames","source":"\u003ca href=\"http:\/\/tapbots.com\" rel=\"nofollow\"\u003eTweetbot for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":671293,"id_str":"671293","name":"Richard Allen","screen_name":"richrad","location":"Kansas City","url":"http:\/\/richardallen.me","description":"Give me a break, Jeffery.","protected":false,"followers_count":174,"friends_count":273,"listed_count":2,"created_at":"Sat Jan 20 16:02:45 +0000 2007","favourites_count":383,"utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":1370,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"0099B9","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_link_color":"0099B9","profile_sidebar_border_color":"5ED4DC","profile_sidebar_fill_color":"95E8EC","profile_text_color":"3C3940","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[{"text":"freebandnames","indices":[14,28]}],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}],"search_metadata":{"completed_in":0.029,"max_id":250126199840518145,"max_id_str":"250126199840518145","next_page":"?page=2&max_id=250126199840518145&q=%23freebandnames&rpp=4&include_entities=1&result_type=mixed","page":1,"query":"%23freebandnames","refresh_url":"?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1","results_per_page":4,"since_id":24012619984051000,"since_id_str":"24012619984051000"}}
1
+ {"statuses":[{"metadata":{"result_type":"recent","iso_language_code":"en"},"created_at":"Mon Sep 17 22:41:52 +0000 2012","id":247827742178021376,"id_str":"247827742178021376","text":"Bubble Mailer #freebandnames","source":"\u003ca href=\"http:\/\/tapbots.com\" rel=\"nofollow\"\u003eTweetbot for Mac\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":671293,"id_str":"671293","name":"Richard Allen","screen_name":"richrad","location":"Kansas City","url":"http:\/\/richardallen.me","description":"Give me a break, Jeffery.","protected":false,"followers_count":174,"friends_count":273,"listed_count":2,"created_at":"Sat Jan 20 16:02:45 +0000 2007","favourites_count":383,"utc_offset":-21600,"time_zone":"Central Time (US & Canada)","geo_enabled":false,"verified":false,"statuses_count":1370,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"0099B9","profile_background_image_url":"http:\/\/a0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_image_url_https":"https:\/\/si0.twimg.com\/images\/themes\/theme4\/bg.gif","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1399177739\/notlookingup_normal.jpeg","profile_link_color":"0099B9","profile_sidebar_border_color":"5ED4DC","profile_sidebar_fill_color":"95E8EC","profile_text_color":"3C3940","profile_use_background_image":true,"show_all_inline_media":true,"default_profile":false,"default_profile_image":false,"following":null,"follow_request_sent":null,"notifications":null},"geo":null,"coordinates":null,"place":null,"contributors":null,"retweet_count":0,"entities":{"hashtags":[{"text":"freebandnames","indices":[14,28]}],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}],"search_metadata":{"completed_in":0.029,"max_id":250126199840518145,"max_id_str":"250126199840518145","next_page":"?page=2&max_id=250126199840518145&q=%23freebandnames&rpp=4&include_entities=1&result_type=mixed","page":1,"query":"%23freebandnames","refresh_url":"?since_id=250126199840518145&q=%23freebandnames&result_type=mixed&include_entities=1","count":4,"since_id":24012619984051000,"since_id_str":"24012619984051000"}}
@@ -1 +1 @@
1
- {"max_id":28857935752,"since_id":0,"refresh_url":"?since_id=28857935752&q=twitter","next_page":"?page=2&max_id=28857935752&q=twitter","results_per_page":15,"page":1,"completed_in":0.017349,"since_id_str":"0","max_id_str":"28857935752","query":"twitter"}
1
+ {"max_id":28857935752,"since_id":0,"refresh_url":"?since_id=28857935752&q=twitter","next_page":"?page=2&max_id=28857935752&q=twitter","count":15,"page":1,"completed_in":0.017349,"since_id_str":"0","max_id_str":"28857935752","query":"twitter"}
@@ -0,0 +1,3 @@
1
+ {"created_at":"Wed Apr 06 19:13:37 +0000 2011","id":55709764298092545,"id_str":"55709764298092545","text":"The problem with your code is that it's doing exactly what you told it to do.","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"San Francisco","description":"Write code. Not too much. Mostly Ruby.","url":"https:\/\/github.com\/sferik","entities":{"url":{"urls":[{"url":"https:\/\/github.com\/sferik","expanded_url":null,"indices":[0,25]}]},"description":{"urls":[]}},"protected":false,"followers_count":2479,"friends_count":200,"listed_count":132,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":4421,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":8730,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_banner_url":"https:\/\/si0.twimg.com\/profile_banners\/7505382\/1349499693","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"geo":{"type":"Point","coordinates":[37.78349999,-122.39362884]},"coordinates":{"type":"Point","coordinates":[-122.39362884,37.78349999]},"place":{"id":"5c92ab5379de3839","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/5c92ab5379de3839.json","place_type":"neighborhood","name":"South Beach","full_name":"South Beach, San Francisco","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-122.403482,37.777529],[-122.387436,37.777529],[-122.387436,37.794486],[-122.403482,37.794486]]]},"attributes":{}},"contributors":null,"retweet_count":316,"entities":{"hashtags":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}
2
+ {"created_at":"Wed Apr 06 19:13:37 +0000 2011","id":55709764298092545,"id_str":"55709764298092545","text":"The problem with your code is that it's doing exactly what you told it to do.","source":"\u003ca href=\"http:\/\/twitter.com\/download\/iphone\" rel=\"nofollow\"\u003eTwitter for iPhone\u003c\/a\u003e","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":7505382,"id_str":"7505382","name":"Erik Michaels-Ober","screen_name":"sferik","location":"San Francisco","description":"Write code. Not too much. Mostly Ruby.","url":"https:\/\/github.com\/sferik","entities":{"url":{"urls":[{"url":"https:\/\/github.com\/sferik","expanded_url":null,"indices":[0,25]}]},"description":{"urls":[]}},"protected":false,"followers_count":2479,"friends_count":200,"listed_count":132,"created_at":"Mon Jul 16 12:59:01 +0000 2007","favourites_count":4421,"utc_offset":-28800,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":false,"statuses_count":8730,"lang":"en","contributors_enabled":false,"is_translator":false,"profile_background_color":"000000","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/677717672\/bb0b3653dcf0644e344823e0a2eb3382.png","profile_background_tile":false,"profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1759857427\/image1326743606_normal.png","profile_banner_url":"https:\/\/si0.twimg.com\/profile_banners\/7505382\/1349499693","profile_link_color":"0084B4","profile_sidebar_border_color":"000000","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false},"geo":{"type":"Point","coordinates":[37.78349999,-122.39362884]},"coordinates":{"type":"Point","coordinates":[-122.39362884,37.78349999]},"place":{"id":"5c92ab5379de3839","url":"https:\/\/api.twitter.com\/1.1\/geo\/id\/5c92ab5379de3839.json","place_type":"neighborhood","name":"South Beach","full_name":"South Beach, San Francisco","country_code":"US","country":"United States","bounding_box":{"type":"Polygon","coordinates":[[[-122.403482,37.777529],[-122.387436,37.777529],[-122.387436,37.794486],[-122.403482,37.794486]]]},"attributes":{}},"contributors":null,"retweet_count":316,"entities":{"hashtags":[],"urls":[],"user_mentions":[]},"favorited":false,"retweeted":false}
3
+
@@ -8,7 +8,6 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
8
  SimpleCov.start
9
9
 
10
10
  require 'twitter'
11
- require 'twitter/identity_map'
12
11
  require 'rspec'
13
12
  require 'stringio'
14
13
  require 'tempfile'
@@ -21,42 +20,38 @@ RSpec.configure do |config|
21
20
  config.expect_with :rspec do |c|
22
21
  c.syntax = :expect
23
22
  end
24
-
25
- config.before(:each) do
26
- stub_post("/oauth2/token").with(:body => "grant_type=client_credentials").to_return(:body => fixture("bearer_token.json"), :headers => {:content_type => "application/json; charset=utf-8"})
27
- end
28
23
  end
29
24
 
30
25
  def a_delete(path)
31
- a_request(:delete, Twitter::Default::ENDPOINT + path)
26
+ a_request(:delete, Twitter::REST::Client::ENDPOINT + path)
32
27
  end
33
28
 
34
29
  def a_get(path)
35
- a_request(:get, Twitter::Default::ENDPOINT + path)
30
+ a_request(:get, Twitter::REST::Client::ENDPOINT + path)
36
31
  end
37
32
 
38
33
  def a_post(path)
39
- a_request(:post, Twitter::Default::ENDPOINT + path)
34
+ a_request(:post, Twitter::REST::Client::ENDPOINT + path)
40
35
  end
41
36
 
42
37
  def a_put(path)
43
- a_request(:put, Twitter::Default::ENDPOINT + path)
38
+ a_request(:put, Twitter::REST::Client::ENDPOINT + path)
44
39
  end
45
40
 
46
41
  def stub_delete(path)
47
- stub_request(:delete, Twitter::Default::ENDPOINT + path)
42
+ stub_request(:delete, Twitter::REST::Client::ENDPOINT + path)
48
43
  end
49
44
 
50
45
  def stub_get(path)
51
- stub_request(:get, Twitter::Default::ENDPOINT + path)
46
+ stub_request(:get, Twitter::REST::Client::ENDPOINT + path)
52
47
  end
53
48
 
54
49
  def stub_post(path)
55
- stub_request(:post, Twitter::Default::ENDPOINT + path)
50
+ stub_request(:post, Twitter::REST::Client::ENDPOINT + path)
56
51
  end
57
52
 
58
53
  def stub_put(path)
59
- stub_request(:put, Twitter::Default::ENDPOINT + path)
54
+ stub_request(:put, Twitter::REST::Client::ENDPOINT + path)
60
55
  end
61
56
 
62
57
  def fixture_path
@@ -1,116 +1,42 @@
1
1
  require 'helper'
2
2
 
3
3
  describe Twitter::Base do
4
-
5
- context "identity map enabled" do
6
- before do
7
- Twitter.identity_map = Twitter::IdentityMap
8
- object = Twitter::Base.new(:id => 1)
9
- @base = Twitter::Base.store(object)
10
- end
11
-
12
- after do
13
- Twitter.identity_map = false
14
- end
15
-
16
- describe ".identity_map" do
17
- it "returns an instance of the identity map" do
18
- expect(Twitter::Base.identity_map).to be_a Twitter::IdentityMap
19
- end
20
- end
21
-
22
- describe ".fetch" do
23
- it "returns existing objects" do
24
- expect(Twitter::Base.fetch(:id => 1)).to be
25
- end
26
-
27
- it "raises an error on objects that don't exist" do
28
- expect{Twitter::Base.fetch(:id => 6)}.to raise_error Twitter::Error::IdentityMapKeyError
29
- end
30
- end
31
-
32
- describe ".store" do
33
- it "stores Twitter::Base objects" do
34
- object = Twitter::Base.new(:id => 4)
35
- expect(Twitter::Base.store(object)).to be_a Twitter::Base
36
- end
37
- end
38
-
39
- describe ".fetch_or_new" do
40
- it "returns existing objects" do
41
- expect(Twitter::Base.fetch_or_new(:id => 1)).to be
42
- end
43
- it "creates new objects and stores them" do
44
- expect(Twitter::Base.fetch_or_new(:id => 2)).to be
45
- expect(Twitter::Base.fetch(:id => 2)).to be
46
- end
47
- end
48
-
49
- describe "#[]" do
50
- it "calls methods using [] with symbol" do
51
- expect(@base[:object_id]).to be_an Integer
52
- end
53
- it "calls methods using [] with string" do
54
- expect(@base['object_id']).to be_an Integer
55
- end
56
- it "returns nil for missing method" do
57
- expect(@base[:foo]).to be_nil
58
- expect(@base['foo']).to be_nil
59
- end
60
- end
61
-
62
- describe "#to_hash" do
63
- it "returns a hash" do
64
- expect(@base.to_hash).to be_a Hash
65
- expect(@base.to_hash[:id]).to eq 1
66
- end
67
- end
68
-
69
- describe "identical objects" do
70
- it "have the same object_id" do
71
- expect(@base.object_id).to eq Twitter::Base.fetch(:id => 1).object_id
72
- end
73
- end
74
-
4
+ before do
5
+ @base = Twitter::Base.new(:id => 1)
75
6
  end
76
7
 
77
- context "identity map disabled" do
78
- before(:all) do
79
- Twitter.identity_map = false
80
- end
81
- after(:all) do
82
- Twitter.identity_map = Twitter::IdentityMap
8
+ describe "#[]" do
9
+ it "calls methods using [] with symbol" do
10
+ expect(@base[:object_id]).to be_an Integer
83
11
  end
84
-
85
- describe ".identity_map" do
86
- it "returns nil" do
87
- expect(Twitter::Base.identity_map).to be_nil
88
- end
12
+ it "calls methods using [] with string" do
13
+ expect(@base["object_id"]).to be_an Integer
89
14
  end
90
-
91
- describe ".fetch" do
92
- it "returns nil" do
93
- expect(Twitter::Base.fetch(:id => 1)).to be_nil
94
- end
15
+ it "returns nil for missing method" do
16
+ expect(@base[:foo]).to be_nil
17
+ expect(@base["foo"]).to be_nil
95
18
  end
19
+ end
96
20
 
97
- describe ".store" do
98
- it "returns an instance of the object" do
99
- expect(Twitter::Base.store(Twitter::Base.new(:id => 1))).to be_a Twitter::Base
100
- end
21
+ describe "#attrs" do
22
+ it "returns a hash of attributes" do
23
+ expect(@base.attrs).to eq({:id => 1})
101
24
  end
25
+ end
102
26
 
103
- describe ".fetch_or_new" do
104
- it "creates new objects" do
105
- expect(Twitter::Base.fetch_or_new(:id => 2)).to be
106
- expect(Twitter.identity_map).to be_false
107
- end
27
+ describe "#delete" do
28
+ it "deletes an attribute and returns its value" do
29
+ base = Twitter::Base.new(:id => 1)
30
+ expect(base.delete(:id)).to eq(1)
31
+ expect(base.attrs[:id]).to be_nil
108
32
  end
109
33
  end
110
34
 
111
- describe '#attrs' do
112
- it 'returns a hash of attributes' do
113
- expect(Twitter::Base.new(:id => 1).attrs).to eq({:id => 1})
35
+ describe "#update" do
36
+ it "returns a hash of attributes" do
37
+ base = Twitter::Base.new(:id => 1)
38
+ base.update(:id => 2)
39
+ expect(base.attrs[:id]).to eq(2)
114
40
  end
115
41
  end
116
42
 
@@ -4,7 +4,7 @@ describe Twitter::Configuration do
4
4
 
5
5
  describe "#photo_sizes" do
6
6
  it "returns a hash of sizes when photo_sizes is set" do
7
- photo_sizes = Twitter::Configuration.new(:photo_sizes => {:small => {:h => 226, :w => 340, :resize => 'fit'}, :large => {:h => 466, :w => 700, :resize => 'fit'}, :medium => {:h => 399, :w => 600, :resize => 'fit'}, :thumb => {:h => 150, :w => 150, :resize => 'crop'}}).photo_sizes
7
+ photo_sizes = Twitter::Configuration.new(:photo_sizes => {:small => {:h => 226, :w => 340, :resize => "fit"}, :large => {:h => 466, :w => 700, :resize => "fit"}, :medium => {:h => 399, :w => 600, :resize => "fit"}, :thumb => {:h => 150, :w => 150, :resize => "crop"}}).photo_sizes
8
8
  expect(photo_sizes).to be_a Hash
9
9
  expect(photo_sizes[:small]).to be_a Twitter::Size
10
10
  end
@@ -2,34 +2,9 @@ require 'helper'
2
2
 
3
3
  describe Twitter::Cursor do
4
4
 
5
- describe "#collection" do
6
- it "returns a collection" do
7
- collection = Twitter::Cursor.new({:ids => [1, 2, 3, 4, 5]}, :ids, nil, Twitter::Client.new, :follower_ids, {}).collection
8
- expect(collection).to be_an Array
9
- expect(collection.first).to be_a Fixnum
10
- end
11
- end
12
-
13
- describe "#all" do
14
- before do
15
- @client = Twitter::Client.new
16
- stub_get("/1.1/followers/ids.json").with(:query => {:cursor => "-1", :screen_name => "sferik"}).to_return(:body => fixture("ids_list.json"), :headers => {:content_type => "application/json; charset=utf-8"})
17
- stub_get("/1.1/followers/ids.json").with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"}).to_return(:body => fixture("ids_list2.json"), :headers => {:content_type => "application/json; charset=utf-8"})
18
- end
19
- it "requests the correct resources" do
20
- @client.follower_ids("sferik").all
21
- expect(a_get("/1.1/followers/ids.json").with(:query => {:cursor => "-1", :screen_name => "sferik"})).to have_been_made
22
- expect(a_get("/1.1/followers/ids.json").with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"})).to have_been_made
23
- end
24
- it "fetches all" do
25
- follower_ids = @client.follower_ids("sferik").all
26
- expect(follower_ids.size).to eq 6
27
- end
28
- end
29
-
30
5
  describe "#each" do
31
6
  before do
32
- @client = Twitter::Client.new
7
+ @client = Twitter::REST::Client.new(:consumer_key => "CK", :consumer_secret => "CS", :access_token => "AT", :access_token_secret => "AS")
33
8
  stub_get("/1.1/followers/ids.json").with(:query => {:cursor => "-1", :screen_name => "sferik"}).to_return(:body => fixture("ids_list.json"), :headers => {:content_type => "application/json; charset=utf-8"})
34
9
  stub_get("/1.1/followers/ids.json").with(:query => {:cursor => "1305102810874389703", :screen_name => "sferik"}).to_return(:body => fixture("ids_list2.json"), :headers => {:content_type => "application/json; charset=utf-8"})
35
10
  end
@@ -41,14 +16,21 @@ describe Twitter::Cursor do
41
16
  it "iterates" do
42
17
  count = 0
43
18
  @client.follower_ids("sferik").each{count += 1}
44
- expect(count).to eq 6
19
+ expect(count).to eq(6)
20
+ end
21
+ context "with start" do
22
+ it "iterates" do
23
+ count = 0
24
+ @client.follower_ids("sferik").each(5){count += 1}
25
+ expect(count).to eq(1)
26
+ end
45
27
  end
46
28
  end
47
29
 
48
30
  describe "#first?" do
49
31
  context "when previous cursor equals zero" do
50
32
  before do
51
- @cursor = Twitter::Cursor.new({:previous_cursor => 0}, :ids, nil, Twitter::Client.new, :follower_ids, {})
33
+ @cursor = Twitter::Cursor.new({:previous_cursor => 0}, :ids, nil, Twitter::REST::Client.new, :get, "/1.1/followers/ids.json", {})
52
34
  end
53
35
  it "returns true" do
54
36
  expect(@cursor.first?).to be_true
@@ -56,7 +38,7 @@ describe Twitter::Cursor do
56
38
  end
57
39
  context "when previous cursor does not equal zero" do
58
40
  before do
59
- @cursor = Twitter::Cursor.new({:previous_cursor => 1}, :ids, nil, Twitter::Client.new, :follower_ids, {})
41
+ @cursor = Twitter::Cursor.new({:previous_cursor => 1}, :ids, nil, Twitter::REST::Client.new, :get, "/1.1/followers/ids.json", {})
60
42
  end
61
43
  it "returns true" do
62
44
  expect(@cursor.first?).to be_false
@@ -67,7 +49,7 @@ describe Twitter::Cursor do
67
49
  describe "#last?" do
68
50
  context "when next cursor equals zero" do
69
51
  before do
70
- @cursor = Twitter::Cursor.new({:next_cursor => 0}, :ids, nil, Twitter::Client.new, :follower_ids, {})
52
+ @cursor = Twitter::Cursor.new({:next_cursor => 0}, :ids, nil, Twitter::REST::Client.new, :get, "/1.1/followers/ids.json", {})
71
53
  end
72
54
  it "returns true" do
73
55
  expect(@cursor.last?).to be_true
@@ -75,7 +57,7 @@ describe Twitter::Cursor do
75
57
  end
76
58
  context "when next cursor does not equal zero" do
77
59
  before do
78
- @cursor = Twitter::Cursor.new({:next_cursor => 1}, :ids, nil, Twitter::Client.new, :follower_ids, {})
60
+ @cursor = Twitter::Cursor.new({:next_cursor => 1}, :ids, nil, Twitter::REST::Client.new, :get, "/1.1/followers/ids.json", {})
79
61
  end
80
62
  it "returns false" do
81
63
  expect(@cursor.last?).to be_false