twitter 4.8.1 → 5.0.0.rc.1

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