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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +30 -0
- data/LICENSE.md +1 -1
- data/README.md +386 -266
- data/lib/twitter.rb +4 -39
- data/lib/twitter/arguments.rb +11 -0
- data/lib/twitter/base.rb +89 -68
- data/lib/twitter/client.rb +69 -110
- data/lib/twitter/configuration.rb +7 -3
- data/lib/twitter/creatable.rb +2 -4
- data/lib/twitter/cursor.rb +50 -42
- data/lib/twitter/direct_message.rb +2 -11
- data/lib/twitter/entity/uri.rb +13 -0
- data/lib/twitter/enumerable.rb +15 -0
- data/lib/twitter/error.rb +55 -7
- data/lib/twitter/error/already_favorited.rb +1 -1
- data/lib/twitter/error/already_posted.rb +10 -0
- data/lib/twitter/error/already_retweeted.rb +1 -1
- data/lib/twitter/error/bad_gateway.rb +2 -3
- data/lib/twitter/error/bad_request.rb +2 -2
- data/lib/twitter/error/forbidden.rb +2 -2
- data/lib/twitter/error/gateway_timeout.rb +2 -3
- data/lib/twitter/error/internal_server_error.rb +2 -3
- data/lib/twitter/error/not_acceptable.rb +2 -2
- data/lib/twitter/error/not_found.rb +2 -2
- data/lib/twitter/error/service_unavailable.rb +2 -3
- data/lib/twitter/error/too_many_requests.rb +2 -2
- data/lib/twitter/error/unauthorized.rb +2 -2
- data/lib/twitter/error/unprocessable_entity.rb +2 -2
- data/lib/twitter/factory.rb +2 -8
- data/lib/twitter/geo_factory.rb +2 -2
- data/lib/twitter/geo_results.rb +36 -0
- data/lib/twitter/identity.rb +0 -22
- data/lib/twitter/list.rb +18 -4
- data/lib/twitter/media/photo.rb +3 -3
- data/lib/twitter/media_factory.rb +2 -2
- data/lib/twitter/null_object.rb +24 -0
- data/lib/twitter/oembed.rb +3 -2
- data/lib/twitter/place.rb +15 -9
- data/lib/twitter/profile_banner.rb +5 -3
- data/lib/twitter/rate_limit.rb +1 -17
- data/lib/twitter/relationship.rb +2 -10
- data/lib/twitter/rest/api/direct_messages.rb +135 -0
- data/lib/twitter/rest/api/favorites.rb +120 -0
- data/lib/twitter/rest/api/friends_and_followers.rb +290 -0
- data/lib/twitter/rest/api/help.rb +58 -0
- data/lib/twitter/rest/api/lists.rb +491 -0
- data/lib/twitter/rest/api/oauth.rb +45 -0
- data/lib/twitter/rest/api/places_and_geo.rb +104 -0
- data/lib/twitter/rest/api/saved_searches.rb +91 -0
- data/lib/twitter/rest/api/search.rb +37 -0
- data/lib/twitter/rest/api/spam_reporting.rb +29 -0
- data/lib/twitter/rest/api/suggested_users.rb +51 -0
- data/lib/twitter/rest/api/timelines.rb +202 -0
- data/lib/twitter/rest/api/trends.rb +58 -0
- data/lib/twitter/rest/api/tweets.rb +293 -0
- data/lib/twitter/rest/api/undocumented.rb +52 -0
- data/lib/twitter/rest/api/users.rb +383 -0
- data/lib/twitter/rest/api/utils.rb +219 -0
- data/lib/twitter/rest/client.rb +193 -0
- data/lib/twitter/rest/request/multipart_with_file.rb +36 -0
- data/lib/twitter/rest/response/parse_json.rb +27 -0
- data/lib/twitter/{response → rest/response}/raise_error.rb +8 -11
- data/lib/twitter/search_results.rb +33 -21
- data/lib/twitter/settings.rb +1 -6
- data/lib/twitter/size.rb +1 -1
- data/lib/twitter/streaming/client.rb +77 -0
- data/lib/twitter/streaming/connection.rb +22 -0
- data/lib/twitter/streaming/response.rb +30 -0
- data/lib/twitter/suggestion.rb +4 -2
- data/lib/twitter/token.rb +8 -0
- data/lib/twitter/trend.rb +2 -1
- data/lib/twitter/trend_results.rb +59 -0
- data/lib/twitter/tweet.rb +41 -85
- data/lib/twitter/user.rb +51 -41
- data/lib/twitter/version.rb +4 -4
- data/spec/fixtures/already_posted.json +1 -0
- data/spec/fixtures/ids_list.json +1 -1
- data/spec/fixtures/ids_list2.json +1 -1
- data/spec/fixtures/search.json +1 -1
- data/spec/fixtures/search_malformed.json +1 -1
- data/spec/fixtures/track_streaming.json +3 -0
- data/spec/helper.rb +8 -13
- data/spec/twitter/base_spec.rb +25 -99
- data/spec/twitter/configuration_spec.rb +1 -1
- data/spec/twitter/cursor_spec.rb +13 -31
- data/spec/twitter/direct_message_spec.rb +41 -8
- data/spec/twitter/entity/uri_spec.rb +74 -0
- data/spec/twitter/error_spec.rb +59 -11
- data/spec/twitter/geo/point_spec.rb +1 -1
- data/spec/twitter/geo_factory_spec.rb +3 -3
- data/spec/twitter/geo_results_spec.rb +35 -0
- data/spec/twitter/identifiable_spec.rb +0 -21
- data/spec/twitter/list_spec.rb +51 -8
- data/spec/twitter/media/photo_spec.rb +118 -3
- data/spec/twitter/media_factory_spec.rb +2 -2
- data/spec/twitter/null_object_spec.rb +26 -0
- data/spec/twitter/oembed_spec.rb +69 -45
- data/spec/twitter/place_spec.rb +68 -12
- data/spec/twitter/profile_banner_spec.rb +1 -1
- data/spec/twitter/rate_limit_spec.rb +12 -12
- data/spec/twitter/relationship_spec.rb +31 -9
- data/spec/twitter/{api → rest/api}/direct_messages_spec.rb +22 -9
- data/spec/twitter/{api → rest/api}/favorites_spec.rb +80 -7
- data/spec/twitter/{api → rest/api}/friends_and_followers_spec.rb +104 -65
- data/spec/twitter/{api → rest/api}/geo_spec.rb +10 -10
- data/spec/twitter/{api → rest/api}/help_spec.rb +6 -6
- data/spec/twitter/{api → rest/api}/lists_spec.rb +77 -56
- data/spec/twitter/{api → rest/api}/oauth_spec.rb +6 -6
- data/spec/twitter/{api → rest/api}/saved_searches_spec.rb +7 -7
- data/spec/twitter/{api → rest/api}/search_spec.rb +8 -9
- data/spec/twitter/{api → rest/api}/spam_reporting_spec.rb +3 -3
- data/spec/twitter/{api → rest/api}/suggested_users_spec.rb +5 -5
- data/spec/twitter/{api → rest/api}/timelines_spec.rb +9 -9
- data/spec/twitter/{api → rest/api}/trends_spec.rb +6 -6
- data/spec/twitter/rest/api/tweets_spec.rb +503 -0
- data/spec/twitter/{api → rest/api}/undocumented_spec.rb +19 -45
- data/spec/twitter/{api → rest/api}/users_spec.rb +60 -35
- data/spec/twitter/rest/client_spec.rb +193 -0
- data/spec/twitter/saved_search_spec.rb +11 -0
- data/spec/twitter/search_results_spec.rb +29 -42
- data/spec/twitter/settings_spec.rb +17 -6
- data/spec/twitter/streaming/client_spec.rb +75 -0
- data/spec/twitter/token_spec.rb +16 -0
- data/spec/twitter/trend_results_spec.rb +89 -0
- data/spec/twitter/trend_spec.rb +23 -0
- data/spec/twitter/tweet_spec.rb +122 -115
- data/spec/twitter/user_spec.rb +136 -77
- data/spec/twitter_spec.rb +0 -119
- data/twitter.gemspec +8 -5
- metadata +148 -141
- metadata.gz.sig +0 -0
- data/lib/twitter/action/favorite.rb +0 -19
- data/lib/twitter/action/follow.rb +0 -30
- data/lib/twitter/action/list_member_added.rb +0 -39
- data/lib/twitter/action/mention.rb +0 -46
- data/lib/twitter/action/reply.rb +0 -27
- data/lib/twitter/action/retweet.rb +0 -27
- data/lib/twitter/action/tweet.rb +0 -20
- data/lib/twitter/action_factory.rb +0 -22
- data/lib/twitter/api/arguments.rb +0 -13
- data/lib/twitter/api/direct_messages.rb +0 -148
- data/lib/twitter/api/favorites.rb +0 -126
- data/lib/twitter/api/friends_and_followers.rb +0 -334
- data/lib/twitter/api/help.rb +0 -64
- data/lib/twitter/api/lists.rb +0 -618
- data/lib/twitter/api/oauth.rb +0 -44
- data/lib/twitter/api/places_and_geo.rb +0 -121
- data/lib/twitter/api/saved_searches.rb +0 -99
- data/lib/twitter/api/search.rb +0 -37
- data/lib/twitter/api/spam_reporting.rb +0 -30
- data/lib/twitter/api/suggested_users.rb +0 -55
- data/lib/twitter/api/timelines.rb +0 -214
- data/lib/twitter/api/trends.rb +0 -63
- data/lib/twitter/api/tweets.rb +0 -304
- data/lib/twitter/api/undocumented.rb +0 -97
- data/lib/twitter/api/users.rb +0 -439
- data/lib/twitter/api/utils.rb +0 -187
- data/lib/twitter/configurable.rb +0 -96
- data/lib/twitter/default.rb +0 -102
- data/lib/twitter/entity/url.rb +0 -9
- data/lib/twitter/error/client_error.rb +0 -35
- data/lib/twitter/error/decode_error.rb +0 -9
- data/lib/twitter/error/identity_map_key_error.rb +0 -9
- data/lib/twitter/error/server_error.rb +0 -28
- data/lib/twitter/exceptable.rb +0 -36
- data/lib/twitter/identity_map.rb +0 -22
- data/lib/twitter/request/multipart_with_file.rb +0 -34
- data/lib/twitter/response/parse_json.rb +0 -25
- data/spec/fixtures/about_me.json +0 -1
- data/spec/fixtures/activity_summary.json +0 -1
- data/spec/fixtures/bad_gateway.json +0 -1
- data/spec/fixtures/bad_request.json +0 -1
- data/spec/fixtures/by_friends.json +0 -1
- data/spec/fixtures/end_session.json +0 -1
- data/spec/fixtures/forbidden.json +0 -1
- data/spec/fixtures/internal_server_error.json +0 -1
- data/spec/fixtures/not_acceptable.json +0 -1
- data/spec/fixtures/phoenix_search.phoenix +0 -1
- data/spec/fixtures/resolve.json +0 -1
- data/spec/fixtures/service_unavailable.json +0 -1
- data/spec/fixtures/totals.json +0 -1
- data/spec/fixtures/trends.json +0 -1
- data/spec/fixtures/unauthorized.json +0 -1
- data/spec/fixtures/video_facets.json +0 -1
- data/spec/twitter/action/favorite_spec.rb +0 -29
- data/spec/twitter/action/follow_spec.rb +0 -29
- data/spec/twitter/action/list_member_added_spec.rb +0 -41
- data/spec/twitter/action/mention_spec.rb +0 -52
- data/spec/twitter/action/reply_spec.rb +0 -41
- data/spec/twitter/action/retweet_spec.rb +0 -41
- data/spec/twitter/action_factory_spec.rb +0 -35
- data/spec/twitter/action_spec.rb +0 -16
- data/spec/twitter/api/tweets_spec.rb +0 -285
- data/spec/twitter/client_spec.rb +0 -223
- data/spec/twitter/error/client_error_spec.rb +0 -23
- data/spec/twitter/error/server_error_spec.rb +0 -20
data/lib/twitter/user.rb
CHANGED
@@ -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
|
-
:
|
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
|
24
|
-
alias
|
25
|
-
alias
|
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
|
-
|
33
|
-
alias
|
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
|
37
|
-
|
38
|
-
|
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
|
47
|
-
|
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
|
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
|
59
|
-
|
56
|
+
def profile_banner_uri?
|
57
|
+
!!@attrs[:profile_banner_url]
|
60
58
|
end
|
61
|
-
alias
|
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
|
68
|
-
|
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
|
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
|
-
|
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
|
86
|
-
|
87
|
+
def profile_image_uri?
|
88
|
+
!!@attrs[:profile_image_url_https]
|
87
89
|
end
|
88
|
-
alias
|
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 [
|
91
|
-
def
|
92
|
-
@
|
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
|
-
|
96
|
-
|
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
|
102
|
-
|
111
|
+
def parse_encoded_uri(uri)
|
112
|
+
::URI.parse(::URI.encode(uri))
|
103
113
|
end
|
104
114
|
|
105
|
-
def
|
106
|
-
|
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)
|
data/lib/twitter/version.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Twitter
|
2
2
|
class Version
|
3
|
-
MAJOR =
|
4
|
-
MINOR =
|
5
|
-
PATCH =
|
6
|
-
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"}
|
data/spec/fixtures/ids_list.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"previous_cursor":0,"next_cursor_str":"1305102810874389703","ids":[
|
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":[
|
1
|
+
{"previous_cursor":-1305101990888327757,"next_cursor_str":"0","ids":[14100886,23621851,14509199],"previous_cursor_str":"-1305101990888327757","next_cursor":0}
|
data/spec/fixtures/search.json
CHANGED
@@ -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","
|
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","
|
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
|
+
|
data/spec/helper.rb
CHANGED
@@ -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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
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::
|
54
|
+
stub_request(:put, Twitter::REST::Client::ENDPOINT + path)
|
60
55
|
end
|
61
56
|
|
62
57
|
def fixture_path
|
data/spec/twitter/base_spec.rb
CHANGED
@@ -1,116 +1,42 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
describe Twitter::Base do
|
4
|
-
|
5
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
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
|
-
|
92
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
112
|
-
it
|
113
|
-
|
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 =>
|
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
|
data/spec/twitter/cursor_spec.rb
CHANGED
@@ -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
|
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, :
|
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, :
|
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, :
|
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, :
|
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
|