All Files (99.4%)
47 files in total.
1999 relevant lines.
1987 lines covered and
12 lines missed
./lib/twitter.rb91.3 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# |
|
2 |
require('rubygems')
|
1 |
3 |
||
4 |
module Twitter; end |
1 |
5 |
||
6 |
def require_local(suffix) |
1 |
7 |
require(File.expand_path(File.join(File.dirname(__FILE__), suffix))) |
9 |
8 |
end |
|
9 |
||
10 |
# For better unicode support in 1.8 |
|
11 |
if RUBY_VERSION < '1.9.0' |
1 |
12 |
$KCODE = 'u' |
0 |
13 |
require 'jcode' |
0 |
14 |
end |
|
15 |
||
16 |
# External requires |
|
17 |
require('yaml')
|
1 |
18 |
require('date')
|
1 |
19 |
require('time')
|
1 |
20 |
require('net/https')
|
1 |
21 |
require('uri')
|
1 |
22 |
require('cgi')
|
1 |
23 |
require('json')
|
1 |
24 |
require('oauth')
|
1 |
25 |
||
26 |
# Ordering matters...pay attention here! |
|
27 |
require_local('twitter/ext')
|
1 |
28 |
require_local('twitter/version')
|
1 |
29 |
require_local('twitter/meta')
|
1 |
30 |
require_local('twitter/core')
|
1 |
31 |
require_local('twitter/model')
|
1 |
32 |
require_local('twitter/config')
|
1 |
33 |
require_local('twitter/client')
|
1 |
34 |
require_local('twitter/console')
|
1 |
./lib/twitter/client.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# client.rb contains the classes, methods and extends <tt>Twitter4R</tt> |
|
2 |
# features to define client calls to the Twitter REST API. |
|
3 |
# |
|
4 |
# See: |
|
5 |
# * <tt>Twitter::Client</tt> |
|
6 |
||
7 |
# Used to query or post to the Twitter REST API to simplify code. |
|
8 |
class Twitter::Client |
1 |
9 |
include Twitter::ClassUtilMixin |
1 |
10 |
end |
|
11 |
||
12 |
require('twitter/client/base')
|
1 |
13 |
require('twitter/client/timeline')
|
1 |
14 |
require('twitter/client/status')
|
1 |
15 |
require('twitter/client/friendship')
|
1 |
16 |
require('twitter/client/messaging')
|
1 |
17 |
require('twitter/client/user')
|
1 |
18 |
require('twitter/client/auth')
|
1 |
19 |
require('twitter/client/favorites')
|
1 |
20 |
require('twitter/client/blocks')
|
1 |
21 |
require('twitter/client/account')
|
1 |
22 |
require('twitter/client/graph')
|
1 |
23 |
require('twitter/client/profile')
|
1 |
24 |
require('twitter/client/search')
|
1 |
25 |
require('twitter/client/trends')
|
1 |
./lib/twitter/client/account.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@ACCOUNT_URIS = {
|
1 |
3 |
:rate_limit_status => '/account/rate_limit_status', |
|
4 |
} |
|
5 |
|
|
6 |
# Provides access to the Twitter rate limit status API. |
|
7 |
# |
|
8 |
# You can find out information about your account status. Currently the only |
|
9 |
# supported type of account status is the <tt>:rate_limit_status</tt> which |
|
10 |
# returns a <tt>Twitter::RateLimitStatus</tt> object. |
|
11 |
# |
|
12 |
# Example: |
|
13 |
# account_status = client.account_info |
|
14 |
# puts account_status.remaining_hits |
|
15 |
def account_info(type = :rate_limit_status) |
1 |
16 |
response = rest_oauth_connect(:get, @@ACCOUNT_URIS[type]) |
12 |
17 |
bless_models(Twitter::RateLimitStatus.unmarshal(response.body)) |
1 |
18 |
end |
|
19 |
end |
|
./lib/twitter/client/auth.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@AUTHENTICATION_URIS = {
|
1 |
3 |
:verify => '/account/verify_credentials', |
|
4 |
} |
|
5 |
||
6 |
# Provides access to the Twitter verify credentials API. |
|
7 |
# |
|
8 |
# You can verify Twitter user credentials with minimal overhead using this method. |
|
9 |
# |
|
10 |
# Example: |
|
11 |
# client.authenticate?("osxisforlightweights", "l30p@rd_s^cks!")
|
|
12 |
def authenticate?(login, password) |
1 |
13 |
verify_credentials(login, password) |
3 |
14 |
end |
|
15 |
||
16 |
private |
1 |
17 |
def verify_credentials(username, passwd) |
1 |
18 |
response = rest_oauth_connect(:get, "#{@@AUTHENTICATION_URIS[:verify]}.json")
|
3 |
19 |
response.is_a?(Net::HTTPSuccess) ? true : false |
3 |
20 |
end |
|
21 |
end |
|
./lib/twitter/client/base.rb99.09 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
alias :old_inspect :inspect |
1 |
3 |
||
4 |
def inspect |
1 |
5 |
s = old_inspect |
1 |
6 |
s.gsub!(/@password=".*?"/, '@password="XXXX"') |
1 |
7 |
s.gsub!(/"secret"=>".*?"/, '"secret"=>"XXXX"') |
1 |
8 |
s |
1 |
9 |
end |
|
10 |
||
11 |
protected |
1 |
12 |
attr_accessor :login, :oauth_consumer, :oauth_access |
1 |
13 |
||
14 |
# Returns the response of the OAuth/HTTP(s) request for REST API requests (not Search) |
|
15 |
def rest_oauth_connect(method, path, params = {}, headers = {}, require_auth = true)
|
1 |
16 |
atoken = rest_access_token |
53 |
17 |
uri = rest_request_uri(path, params) |
53 |
18 |
if [:get, :delete].include?(method) |
53 |
19 |
response = atoken.send(method, uri, http_header.merge(headers)) |
43 |
20 |
else |
|
21 |
response = atoken.send(method, uri, params, http_header.merge(headers)) |
10 |
22 |
end |
|
23 |
handle_rest_response(response) |
53 |
24 |
response |
24 |
25 |
end |
|
26 |
||
27 |
# Returns the response of the OAuth/HTTP(s) request for Search API requests (not REST) |
|
28 |
def search_oauth_connect(method, path, params = {}, headers = {}, require_auth = true)
|
1 |
29 |
atoken = search_access_token |
5 |
30 |
uri = search_request_uri(path, params) |
5 |
31 |
if method == :get |
5 |
32 |
response = atoken.send(method, uri, http_header.merge(headers)) |
5 |
33 |
end |
|
34 |
handle_rest_response(response) |
5 |
35 |
response |
5 |
36 |
end |
|
37 |
||
38 |
# "Blesses" model object with client information |
|
39 |
def bless_model(model) |
1 |
40 |
model.bless(self) if model |
65 |
41 |
end |
|
42 |
|
|
43 |
def bless_models(list) |
1 |
44 |
return bless_model(list) if list.respond_to?(:client=) |
38 |
45 |
list.collect { |model| bless_model(model) } if list.respond_to?(:collect)
|
28 |
46 |
end |
|
47 |
|
|
48 |
private |
1 |
49 |
@@http_header = nil |
1 |
50 |
||
51 |
def rest_consumer |
1 |
52 |
unless @rest_consumer |
56 |
53 |
consumer = @oauth_consumer |
56 |
54 |
if consumer |
56 |
55 |
key = consumer[:key] || consumer["key"] |
55 |
56 |
secret = consumer[:secret] || consumer["secret"] |
55 |
57 |
end |
|
58 |
cfg = self.class.config |
56 |
59 |
key ||= cfg.oauth_consumer_token |
56 |
60 |
secret ||= cfg.oauth_consumer_secret |
56 |
61 |
@rest_consumer = OAuth::Consumer.new(key, secret, |
56 |
62 |
:site => construct_site_url, |
|
63 |
:proxy => construct_proxy_url) |
|
64 |
http = @rest_consumer.http |
56 |
65 |
http.read_timeout = cfg.timeout |
56 |
66 |
end |
|
67 |
@rest_consumer |
56 |
68 |
end |
|
69 |
||
70 |
def rest_access_token |
1 |
71 |
unless @rest_access_token |
53 |
72 |
access = @oauth_access |
53 |
73 |
if access |
53 |
74 |
key = access[:key] || access["key"] |
53 |
75 |
secret = access[:secret] || access["secret"] |
53 |
76 |
else |
|
77 |
raise Error, "No access tokens are set" |
0 |
78 |
end |
|
79 |
@rest_access_token = OAuth::AccessToken.new(rest_consumer, key, secret) |
53 |
80 |
end |
|
81 |
@rest_access_token |
53 |
82 |
end |
|
83 |
|
|
84 |
def search_consumer |
1 |
85 |
unless @search_consumer |
8 |
86 |
cfg = self.class.config |
8 |
87 |
consumer = @oauth_consumer |
8 |
88 |
if consumer |
8 |
89 |
key = consumer[:key] || consumer["key"] |
7 |
90 |
secret = consumer[:secret] || consumer["secret"] |
7 |
91 |
end |
|
92 |
cfg = self.class.config |
8 |
93 |
key ||= cfg.oauth_consumer_token |
8 |
94 |
secret ||= cfg.oauth_consumer_secret |
8 |
95 |
@search_consumer = OAuth::Consumer.new(key, secret, |
8 |
96 |
:site => construct_site_url(:search), |
|
97 |
:proxy => construct_proxy_url) |
|
98 |
http = @search_consumer.http |
8 |
99 |
http.read_timeout = cfg.timeout |
8 |
100 |
end |
|
101 |
@search_consumer |
8 |
102 |
end |
|
103 |
||
104 |
def search_access_token |
1 |
105 |
unless @search_access_token |
5 |
106 |
key = @oauth_access[:key] || @oauth_access["key"] |
5 |
107 |
secret = @oauth_access[:secret] || @oauth_access["secret"] |
5 |
108 |
@search_access_token = OAuth::AccessToken.new(search_consumer, key, secret) |
5 |
109 |
end |
|
110 |
@search_access_token |
5 |
111 |
end |
|
112 |
||
113 |
def raise_rest_error(response, uri = nil) |
1 |
114 |
map = JSON.parse(response.body) |
29 |
115 |
error = Twitter::RESTError.registry[response.code] |
29 |
116 |
raise error.new(:code => response.code, |
|
117 |
:message => response.message, |
|
118 |
:error => map["error"], |
|
119 |
:uri => uri) |
29 |
120 |
end |
|
121 |
|
|
122 |
def handle_rest_response(response, uri = nil) |
1 |
123 |
unless response.is_a?(Net::HTTPSuccess) |
58 |
124 |
raise_rest_error(response, uri) |
29 |
125 |
end |
|
126 |
end |
|
127 |
|
|
128 |
def http_header |
1 |
129 |
# can cache this in class variable since all "variables" used to |
|
130 |
# create the contents of the HTTP header are determined by other |
|
131 |
# class variables that are not designed to change after instantiation. |
|
132 |
@@http_header ||= {
|
|
133 |
'User-Agent' => "Twitter4R v#{Twitter::Version.to_version} [#{self.class.config.user_agent}]",
|
|
134 |
'Accept' => 'text/x-json', |
|
135 |
'X-Twitter-Client' => self.class.config.application_name, |
|
136 |
'X-Twitter-Client-Version' => self.class.config.application_version, |
|
137 |
'X-Twitter-Client-URL' => self.class.config.application_url, |
|
138 |
} |
90 |
139 |
@@http_header |
90 |
140 |
end |
|
141 |
||
142 |
def rest_request_uri(path, params = nil) |
1 |
143 |
uri = "#{self.class.config.path_prefix}#{path}"
|
53 |
144 |
uri << "?#{params.to_http_str}" if params
|
53 |
145 |
uri |
53 |
146 |
end |
|
147 |
|
|
148 |
def search_request_uri(path, params = nil) |
1 |
149 |
uri = "#{self.class.config.search_path_prefix}#{path}"
|
5 |
150 |
uri << "?#{params.to_http_str}" if params
|
5 |
151 |
uri |
5 |
152 |
end |
|
153 |
|
|
154 |
def uri_components(service = :rest) |
1 |
155 |
case service |
64 |
156 |
when :rest |
|
157 |
return self.class.config.protocol, self.class.config.host, self.class.config.port, |
56 |
158 |
self.class.config.path_prefix |
|
159 |
when :search |
|
160 |
return self.class.config.search_protocol, self.class.config.search_host, |
8 |
161 |
self.class.config.search_port, self.class.config.search_path_prefix |
|
162 |
end |
|
163 |
end |
|
164 |
||
165 |
def construct_site_url(service = :rest) |
1 |
166 |
protocol, host, port, path_prefix = uri_components(service) |
64 |
167 |
"#{(protocol == :ssl ? :https : protocol).to_s}://#{host}:#{port}"
|
64 |
168 |
end |
|
169 |
||
170 |
def construct_proxy_url |
1 |
171 |
cfg = self.class.config |
67 |
172 |
proxy_user, proxy_pass = cfg.proxy_user, cfg.proxy_pass |
67 |
173 |
proxy_host, proxy_port = cfg.proxy_host, cfg.proxy_port |
67 |
174 |
protocol = ((cfg.proxy_protocol == :ssl) ? :https : cfg.proxy_protocol).to_s |
67 |
175 |
url = nil |
67 |
176 |
if proxy_host |
67 |
177 |
url = "#{protocol}://"
|
2 |
178 |
if proxy_user |
2 |
179 |
url << "#{proxy_user}:#{proxy_pass}@"
|
1 |
180 |
end |
|
181 |
url << "#{proxy_host}:#{proxy_port.to_s}"
|
2 |
182 |
else |
|
183 |
url |
65 |
184 |
end |
|
185 |
end |
|
186 |
end |
|
./lib/twitter/client/blocks.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@BLOCK_URIS = {
|
1 |
3 |
:add => '/blocks/create', |
|
4 |
:remove => '/blocks/destroy', |
|
5 |
} |
|
6 |
|
|
7 |
# Provides access to the Twitter Block API. |
|
8 |
# |
|
9 |
# You can add and remove blocks to users using this method. |
|
10 |
# |
|
11 |
# <tt>action</tt> can be any of the following values: |
|
12 |
# * <tt>:add</tt> - to add a block, you would use this <tt>action</tt> value |
|
13 |
# * <tt>:remove</tt> - to remove a block use this. |
|
14 |
# |
|
15 |
# The <tt>value</tt> must be either the user screen name, integer unique user ID or Twitter::User |
|
16 |
# object representation. |
|
17 |
# |
|
18 |
# Examples: |
|
19 |
# screen_name = 'dictionary' |
|
20 |
# client.block(:add, 'dictionary') |
|
21 |
# client.block(:remove, 'dictionary') |
|
22 |
# id = 1260061 |
|
23 |
# client.block(:add, id) |
|
24 |
# client.block(:remove, id) |
|
25 |
# user = Twitter::User.find(id, client) |
|
26 |
# client.block(:add, user) |
|
27 |
# client.block(:remove, user) |
|
28 |
def block(action, value) |
1 |
29 |
raise ArgumentError, "Invalid friend action provided: #{action}" unless @@BLOCK_URIS.keys.member?(action)
|
9 |
30 |
value = value.to_i unless value.is_a?(String) |
8 |
31 |
uri = "#{@@BLOCK_URIS[action]}/#{value}.json"
|
8 |
32 |
response = rest_oauth_connect(:get, uri) |
8 |
33 |
bless_model(Twitter::User.unmarshal(response.body)) |
8 |
34 |
end |
|
35 |
end |
|
./lib/twitter/client/favorites.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
# Why Twitter.com developers can't correctly document their API, I do not know! |
|
3 |
@@FAVORITES_URIS = {
|
1 |
4 |
:add => '/favourings/create', |
|
5 |
:remove => '/favourings/destroy', |
|
6 |
} |
|
7 |
||
8 |
# Provides access to the Twitter list favorites API. |
|
9 |
# |
|
10 |
# You can access the authenticated [Twitter] user's favorites list using this method. |
|
11 |
# |
|
12 |
# By default you will receive the last twenty statuses added to your favorites list. |
|
13 |
# To get a previous page you can provide options to this method. For example, |
|
14 |
# statuses = client.favorites(:page => 2) |
|
15 |
# The above one-liner will get the second page of favorites for the authenticated user. |
|
16 |
def favorites(options = nil) |
1 |
17 |
uri = '/favorites.json' |
8 |
18 |
response = rest_oauth_connect(:get, uri, options) |
8 |
19 |
bless_models(Twitter::Status.unmarshal(response.body)) |
2 |
20 |
end |
|
21 |
|
|
22 |
# Provides access to the Twitter add/remove favorite API. |
|
23 |
# |
|
24 |
# You can add and remove favorite status using this method. |
|
25 |
# |
|
26 |
# <tt>action</tt> can be any of the following values: |
|
27 |
# * <tt>:add</tt> - to add a status to your favorites, you would use this <tt>action</tt> value |
|
28 |
# * <tt>:remove</tt> - to remove an status from your existing favorites list use this. |
|
29 |
# |
|
30 |
# The <tt>value</tt> must be either the status object to add or remove or |
|
31 |
# the integer unique status ID. |
|
32 |
# |
|
33 |
# Examples: |
|
34 |
# id = 126006103423 |
|
35 |
# client.favorite(:add, id) |
|
36 |
# client.favorite(:remove, id) |
|
37 |
# status = Twitter::Status.find(id, client) |
|
38 |
# client.favorite(:add, status) |
|
39 |
# client.favorite(:remove, status) |
|
40 |
def favorite(action, value) |
1 |
41 |
raise ArgumentError, "Invalid favorite action provided: #{action}" unless @@FAVORITES_URIS.keys.member?(action)
|
12 |
42 |
value = value.to_i.to_s unless value.is_a?(String) |
12 |
43 |
uri = "#{@@FAVORITES_URIS[action]}/#{value}.json"
|
12 |
44 |
case action |
12 |
45 |
when :add |
|
46 |
response = rest_oauth_connect(:post, uri) |
6 |
47 |
when :remove |
|
48 |
response = rest_oauth_connect(:delete, uri) |
6 |
49 |
end |
|
50 |
bless_model(Twitter::Status.unmarshal(response.body)) |
4 |
51 |
end |
|
52 |
end |
|
./lib/twitter/client/friendship.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@FRIEND_URIS = {
|
1 |
3 |
:add => '/friendships/create', |
|
4 |
:remove => '/friendships/destroy', |
|
5 |
} |
|
6 |
||
7 |
@@FRIENDSHIP_URIS = {
|
1 |
8 |
:incoming => '/friendships/incoming.json', |
|
9 |
:outgoing => '/friendships/outgoing.json', |
|
10 |
} |
|
11 |
|
|
12 |
# Provides access to the Twitter Friendship API. |
|
13 |
# |
|
14 |
# You can add and remove friends using this method. |
|
15 |
# |
|
16 |
# <tt>action</tt> can be any of the following values: |
|
17 |
# * <tt>:add</tt> - to add a friend, you would use this <tt>action</tt> value |
|
18 |
# * <tt>:remove</tt> - to remove an existing friend from your friends list use this. |
|
19 |
# |
|
20 |
# The <tt>value</tt> must be either the user to befriend or defriend's |
|
21 |
# screen name, integer unique user ID or Twitter::User object representation. |
|
22 |
# |
|
23 |
# Examples: |
|
24 |
# screen_name = 'dictionary' |
|
25 |
# client.friend(:add, 'dictionary') |
|
26 |
# client.friend(:remove, 'dictionary') |
|
27 |
# id = 1260061 |
|
28 |
# client.friend(:add, id) |
|
29 |
# client.friend(:remove, id) |
|
30 |
# user = Twitter::User.find(id, client) |
|
31 |
# client.friend(:add, user) |
|
32 |
# client.friend(:remove, user) |
|
33 |
def friend(action, value) |
1 |
34 |
raise ArgumentError, "Invalid friend action provided: #{action}" unless @@FRIEND_URIS.keys.member?(action)
|
9 |
35 |
value = value.to_i unless value.is_a?(String) |
8 |
36 |
uri = "#{@@FRIEND_URIS[action]}/#{value}.json"
|
8 |
37 |
response = rest_oauth_connect(:post, uri) |
8 |
38 |
bless_model(Twitter::User.unmarshal(response.body)) |
8 |
39 |
end |
|
40 |
||
41 |
# Provides friendship information for the following scenarios: |
|
42 |
# * <tt>:incoming</tt> - returns an array of numeric IDs for every user who has a pending request to follow the authenticating user. |
|
43 |
# * <tt>:outgoing</tt> - returns an array of numeric IDs for every protected user for whom the authenticating user has a pending follow request. |
|
44 |
# |
|
45 |
# Examples: |
|
46 |
# client.friendships(:incoming) |
|
47 |
# #=> { :id_list => { :ids => [30592818, 21249843], :next_cursor => 1288724293877798413, :previous_cursor => -1300794057949944903 }}
|
|
48 |
def friendships(action) |
1 |
49 |
raise ArgumentError, "Invalid friend action provided: #{action}" unless @@FRIENDSHIP_URIS.keys.member?(action)
|
2 |
50 |
uri = @@FRIENDSHIP_URIS[action] |
2 |
51 |
response = rest_oauth_connect(:get, uri) |
2 |
52 |
JSON.parse(response.body) |
2 |
53 |
end |
|
54 |
end |
|
./lib/twitter/client/graph.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@GRAPH_URIS = {
|
1 |
3 |
:friends => '/friends/ids', |
|
4 |
:followers => '/followers/ids', |
|
5 |
} |
|
6 |
|
|
7 |
# Provides access to the Twitter Social Graphing API. |
|
8 |
# |
|
9 |
# You can retrieve the full graph of a user's friends or followers in one method call. |
|
10 |
# |
|
11 |
# <tt>action</tt> can be any of the following values: |
|
12 |
# * <tt>:friends</tt> - retrieves ids of all friends of a given user. |
|
13 |
# * <tt>:followers</tt> - retrieves ids of all followers of a given user. |
|
14 |
# |
|
15 |
# The <tt>value</tt> must be either the user screen name, integer unique user ID or Twitter::User |
|
16 |
# object representation. |
|
17 |
# |
|
18 |
# Examples: |
|
19 |
# screen_name = 'dictionary' |
|
20 |
# client.graph(:friends, 'dictionary') |
|
21 |
# client.graph(:followers, 'dictionary') |
|
22 |
# id = 1260061 |
|
23 |
# client.graph(:friends, id) |
|
24 |
# client.graph(:followers, id) |
|
25 |
# user = Twitter::User.find(id, client) |
|
26 |
# client.graph(:friends, user) |
|
27 |
# client.graph(:followers, user) |
|
28 |
def graph(action, value = nil) |
1 |
29 |
raise ArgumentError, "Invalid friend action provided: #{action}" unless @@GRAPH_URIS.keys.member?(action)
|
7 |
30 |
id = value.to_i unless value.nil? || value.is_a?(String) |
6 |
31 |
id ||= value |
6 |
32 |
id ||= @login |
6 |
33 |
uri = "#{@@GRAPH_URIS[action]}.json"
|
6 |
34 |
response = rest_oauth_connect(:get, uri, :id => id) |
6 |
35 |
JSON.parse(response.body) |
6 |
36 |
end |
|
37 |
end |
|
./lib/twitter/client/messaging.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@MESSAGING_URIS = {
|
1 |
3 |
:received => '/direct_messages.json', |
|
4 |
:sent => '/direct_messages/sent.json', |
|
5 |
:post => '/direct_messages/new.json', |
|
6 |
:delete => '/direct_messages/destroy.json', |
|
7 |
} |
|
8 |
||
9 |
# Provides access to Twitter's Messaging API for received and |
|
10 |
# sent direct messages. |
|
11 |
# |
|
12 |
# Example: |
|
13 |
# received_messages = @twitter.messages(:received) |
|
14 |
# |
|
15 |
# An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt> |
|
16 |
# is given. Valid actions are: |
|
17 |
# * +:received+ |
|
18 |
# * +:sent+ |
|
19 |
def messages(action, options = {})
|
1 |
20 |
raise ArgumentError, "Invalid messaging action: #{action}" unless [:sent, :received].member?(action)
|
8 |
21 |
uri = @@MESSAGING_URIS[action] |
7 |
22 |
response = rest_oauth_connect(:get, uri, options) |
7 |
23 |
bless_models(Twitter::Message.unmarshal(response.body)) |
7 |
24 |
end |
|
25 |
|
|
26 |
# Provides access to Twitter's Messaging API for sending and deleting |
|
27 |
# direct messages to other users. |
|
28 |
# |
|
29 |
# <tt>action</tt> can be: |
|
30 |
# * <tt>:post</tt> - to send a new direct message, <tt>value</tt>, to <tt>user</tt> given. |
|
31 |
# * <tt>:delete</tt> - to delete direct message with message ID <tt>value</tt>. |
|
32 |
# |
|
33 |
# <tt>value</tt> should be: |
|
34 |
# * <tt>String</tt> when action is <tt>:post</tt>. Will be the message text sent to given <tt>user</tt>. |
|
35 |
# * <tt>Integer</tt> or <tt>Twitter::Message</tt> object when action is <tt>:delete</tt>. Will refer to the unique message ID to delete. When passing in an instance of <tt>Twitter::Message</tt> that Status will be |
|
36 |
# |
|
37 |
# <tt>user</tt> should be: |
|
38 |
# * <tt>Twitter::User</tt>, <tt>Integer</tt> or <tt>String</tt> object when <tt>action</tt> is <tt>:post</tt>. The <tt>Integer</tt> must be the unique ID of the Twitter user you wish to send the direct message to and any <tt>String</tt>s passed in must be the screen name of the user you wish to send the direct message to. |
|
39 |
# * totally ignore when <tt>action</tt> is <tt>:delete</tt>. It has no purpose in this use case scenario. |
|
40 |
# |
|
41 |
# Examples: |
|
42 |
# The example below sends the message text 'Are you coming over at 6pm for the BBQ tonight?' to user with screen name 'myfriendslogin'... |
|
43 |
# @twitter.message(:post, 'Are you coming over at 6pm for the BBQ tonight?', 'myfriendslogin') |
|
44 |
# The example below sends the same message text as above to user with unique integer ID of 1234567890... |
|
45 |
# the example below sends the same message text as above to user represented by <tt>user</tt> object instance of <tt>Twitter::User</tt>... |
|
46 |
# @twitter.message(:post, 'Are you coming over at 6pm for the BBQ tonight?', user) |
|
47 |
# message = @twitter.message(:post, 'Are you coming over at 6pm for the BBQ tonight?', 1234567890) |
|
48 |
# the example below delete's the message send directly above to user with unique ID 1234567890... |
|
49 |
# @twitter.message(:delete, message) |
|
50 |
# Or the following can also be done... |
|
51 |
# @twitter.message(:delete, message.id) |
|
52 |
# |
|
53 |
# In both scenarios (<tt>action</tt> is <tt>:post</tt> or |
|
54 |
# <tt>:delete</tt>) a blessed <tt>Twitter::Message</tt> object is |
|
55 |
# returned that represents the newly posted or newly deleted message. |
|
56 |
# |
|
57 |
# An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt> |
|
58 |
# is given. Valid actions are: |
|
59 |
# * +:post+ |
|
60 |
# * +:delete+ |
|
61 |
# |
|
62 |
# An <tt>ArgumentError</tt> is also raised when no user argument is |
|
63 |
# supplied when <tt>action</tt> is +:post+. |
|
64 |
def message(action, value, user = nil) |
1 |
65 |
raise ArgumentError, "Invalid messaging action: #{action}" unless [:post, :delete].member?(action)
|
9 |
66 |
raise ArgumentError, "User argument must be supplied for :post case" if action.eql?(:post) and user.nil? |
8 |
67 |
uri = @@MESSAGING_URIS[action] |
6 |
68 |
user = user.to_i if user and user.is_a?(Twitter::User) |
6 |
69 |
case action |
6 |
70 |
when :post |
|
71 |
response = rest_oauth_connect(:post, uri, {:text => value, :user => user, :source => self.class.config.source})
|
3 |
72 |
when :delete |
|
73 |
response = rest_oauth_connect(:delete, uri, :id => value.to_i) |
3 |
74 |
end |
|
75 |
message = Twitter::Message.unmarshal(response.body) |
6 |
76 |
bless_model(message) |
6 |
77 |
end |
|
78 |
end |
|
./lib/twitter/client/profile.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@PROFILE_URIS = {
|
1 |
3 |
:info => '/account/update_profile', |
|
4 |
:colors => '/account/update_profile_colors', |
|
5 |
:device => '/account/update_delivery_device', |
|
6 |
} |
|
7 |
|
|
8 |
# Provides access to the Twitter Profile API. |
|
9 |
# |
|
10 |
# You can update profile information. You can update the types of profile |
|
11 |
# information: |
|
12 |
# * :info (name, email, url, location, description) |
|
13 |
# * :colors (background_color, text_color, link_color, sidebar_fill_color, |
|
14 |
# sidebar_border_color) |
|
15 |
# * :device (set device to either "sms", "im" or "none") |
|
16 |
# |
|
17 |
# Example: |
|
18 |
# user = client.profile(:info, :location => "University Library") |
|
19 |
# puts user.inspect |
|
20 |
def profile(action, attributes) |
1 |
21 |
response = rest_oauth_connect(:post, @@PROFILE_URIS[action], attributes) |
6 |
22 |
bless_models(Twitter::User.unmarshal(response.body)) |
6 |
23 |
end |
|
24 |
end |
|
./lib/twitter/client/search.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@SEARCH_URIS = {
|
1 |
3 |
:basic => "/search.json", |
|
4 |
} |
|
5 |
||
6 |
# Provides access to Twitter's Search API. |
|
7 |
# |
|
8 |
# Example: |
|
9 |
# # For keyword search |
|
10 |
# iterator = @twitter.search(:q => "coworking") |
|
11 |
# while (tweet = iterator.next) |
|
12 |
# puts tweet.text |
|
13 |
# end |
|
14 |
# |
|
15 |
# All options will be passed on to the Twitter.com Search REST API |
|
16 |
def search(options = {})
|
1 |
17 |
uri = @@SEARCH_URIS[:basic] |
9 |
18 |
response = search_oauth_connect(:get, uri, options) |
9 |
19 |
json = JSON.parse(response.body) |
9 |
20 |
bless_models(Twitter::Status.unmarshal(JSON.dump(json["results"]))) |
9 |
21 |
end |
|
22 |
end |
|
./lib/twitter/client/status.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@STATUS_URIS = {
|
1 |
3 |
:get => '/statuses/show.json', |
|
4 |
:post => '/statuses/update.json', |
|
5 |
:delete => '/statuses/destroy.json', |
|
6 |
:reply => '/statuses/update.json' |
|
7 |
} |
|
8 |
|
|
9 |
# Provides access to individual statuses via Twitter's Status APIs |
|
10 |
# |
|
11 |
# <tt>action</tt> can be of the following values: |
|
12 |
# * <tt>:get</tt> to retrieve status content. Assumes <tt>value</tt> given responds to :to_i message in meaningful way to yield intended status id. |
|
13 |
# * <tt>:post</tt> to publish a new status |
|
14 |
# * <tt>:delete</tt> to remove an existing status. Assumes <tt>value</tt> given responds to :to_i message in meaningful way to yield intended status id. |
|
15 |
# * <tt>:reply</tt> to reply to an existing status. Assumes <tt>value</tt> given is <tt>Hash</tt> which contains <tt>:in_reply_to_status_id</tt> and <tt>:status</tt> |
|
16 |
# |
|
17 |
# <tt>value</tt> should be set to: |
|
18 |
# * the status identifier for <tt>:get</tt> case |
|
19 |
# * the status text message for <tt>:post</tt> case |
|
20 |
# * none necessary for <tt>:delete</tt> case |
|
21 |
# |
|
22 |
# Examples: |
|
23 |
# twitter.status(:get, 107786772) |
|
24 |
# twitter.status(:post, "New Ruby open source project Twitter4R version 0.2.0 released.") |
|
25 |
# twitter.status(:delete, 107790712) |
|
26 |
# twitter.status(:reply, :in_reply_to_status_id => 1390482942342, :status => "@t4ruby This new v0.7.0 release is da bomb! #ruby #twitterapi #twitter4r") |
|
27 |
# twitter.status(:post, "My brand new status in all its glory here tweeted from Greenwich (the real one). #withawesomehashtag #booyah", :lat => 0, :long => 0) |
|
28 |
# |
|
29 |
# An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt> |
|
30 |
# is given. Valid actions are: |
|
31 |
# * +:get+ |
|
32 |
# * +:post+ |
|
33 |
# * +:delete+ |
|
34 |
# |
|
35 |
# The third argument +options+ sends on a Hash to the Twitter API with the following keys allowed: |
|
36 |
# * +:lat+ - latitude (for posting geolocation) |
|
37 |
# * +:long+ - longitude (for posting geolocation) |
|
38 |
# * +:place_id+ - using a place ID give by geo/reverse_geocode |
|
39 |
# * +:display_coordinates+ - whether or not to put a pin in the exact coordinates |
|
40 |
def status(action, value = nil) |
1 |
41 |
return self.timeline_for(action, value || {}) if :replies == action
|
17 |
42 |
raise ArgumentError, "Invalid status action: #{action}" unless @@STATUS_URIS.keys.member?(action)
|
17 |
43 |
return nil unless value |
16 |
44 |
uri = @@STATUS_URIS[action] |
11 |
45 |
response = nil |
11 |
46 |
case action |
11 |
47 |
when :get |
|
48 |
response = rest_oauth_connect(:get, uri, {:id => value.to_i})
|
3 |
49 |
when :post |
|
50 |
if value.is_a?(Hash) |
3 |
51 |
params = value.delete_if { |k, v|
|
2 |
52 |
![:status, :lat, :long, :place_id, :display_coordinates].member?(k) |
5 |
53 |
} |
|
54 |
else |
|
55 |
params = {:status => value}
|
1 |
56 |
end |
|
57 |
response = rest_oauth_connect(:post, uri, params.merge(:source => self.class.config.source)) |
3 |
58 |
when :delete |
|
59 |
response = rest_oauth_connect(:delete, uri, {:id => value.to_i})
|
3 |
60 |
when :reply |
|
61 |
return nil if (!value.is_a?(Hash) || !value[:status] || !value[:in_reply_to_status_id]) |
2 |
62 |
params = value.merge(:source => self.class.config.source) |
1 |
63 |
response = rest_oauth_connect(:post, uri, params) |
1 |
64 |
end |
|
65 |
bless_model(Twitter::Status.unmarshal(response.body)) |
10 |
66 |
end |
|
67 |
end |
|
./lib/twitter/client/timeline.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@TIMELINE_URIS = {
|
1 |
3 |
:public => '/statuses/public_timeline.json', |
|
4 |
:home => '/statuses/home_timeline.json', |
|
5 |
:friends => '/statuses/friends_timeline.json', |
|
6 |
:friend => '/statuses/friends_timeline.json', |
|
7 |
:user => '/statuses/user_timeline.json', |
|
8 |
:me => '/statuses/user_timeline.json', |
|
9 |
:replies => '/statuses/replies.json', |
|
10 |
:mentions => '/statuses/mentions.json', |
|
11 |
:retweetsbyme => '/statuses/retweeted_by_me.json', |
|
12 |
:retweetstome => '/statuses/retweeted_to_me.json', |
|
13 |
:retweetsofme => '/statuses/retweets_of_me.json', |
|
14 |
} |
|
15 |
||
16 |
# Provides access to Twitter's Timeline APIs |
|
17 |
# |
|
18 |
# Returns timeline for given <tt>type</tt>. |
|
19 |
# |
|
20 |
# <tt>type</tt> can take the following values: |
|
21 |
# * <tt>public</tt> |
|
22 |
# * <tt>friends</tt> or <tt>friend</tt> |
|
23 |
# * <tt>user</tt> or <tt>me</tt> |
|
24 |
# |
|
25 |
# <tt>:id</tt> is on key applicable to be defined in </tt>options</tt>: |
|
26 |
# * the id or screen name (aka login) for :friends |
|
27 |
# * the id or screen name (aka login) for :user |
|
28 |
# * meaningless for the :me case, since <tt>twitter.timeline_for(:user, 'mylogin')</tt> and <tt>twitter.timeline_for(:me)</tt> are the same assuming 'mylogin' is the authenticated user's screen name (aka login). |
|
29 |
# |
|
30 |
# Examples: |
|
31 |
# # returns the public statuses since status with id of 6543210 |
|
32 |
# twitter.timeline_for(:public, id => 6543210) |
|
33 |
# # returns the statuses for friend with user id 43210 |
|
34 |
# twitter.timeline_for(:friend, :id => 43210) |
|
35 |
# # returns the statuses for friend with screen name (aka login) of 'otherlogin' |
|
36 |
# twitter.timeline_for(:friend, :id => 'otherlogin') |
|
37 |
# # returns the statuses for user with screen name (aka login) of 'otherlogin' |
|
38 |
# twitter.timeline_for(:user, :id => 'otherlogin') |
|
39 |
# |
|
40 |
# <tt>options</tt> can also include the following keys: |
|
41 |
# * <tt>:id</tt> is the user ID, screen name of Twitter::User representation of a <tt>Twitter</tt> user. |
|
42 |
# * <tt>:since</tt> is a Time object specifying the date-time from which to return results for. Applicable for the :friend, :friends, :user and :me cases. |
|
43 |
# * <tt>:count</tt> specifies the number of statuses to retrieve at a time. Only applicable for the :user case. |
|
44 |
# * <tt>:page</tt> specifies page number to retrieve. |
|
45 |
# * <tt>since_id</tt> is the status id of the public timeline from which to retrieve statuses for <tt>:public</tt>. Only applicable for the :public case. |
|
46 |
# * <tt>include_rts</tt> flags whether to retrieve native retweets in the timeline or not. True values are true, t or 1. |
|
47 |
# |
|
48 |
# You can also pass this method a block, which will iterate through the results |
|
49 |
# of the requested timeline and apply the block logic for each status returned. |
|
50 |
# |
|
51 |
# Example: |
|
52 |
# twitter.timeline_for(:public) do |status| |
|
53 |
# puts status.user.screen_name, status.text |
|
54 |
# end |
|
55 |
# |
|
56 |
# twitter.timeline_for(:friend, :id => 'myfriend', :since => 30.minutes.ago) do |status| |
|
57 |
# puts status.user.screen_name, status.text |
|
58 |
# end |
|
59 |
# |
|
60 |
# timeline = twitter.timeline_for(:me) do |status| |
|
61 |
# puts status.text |
|
62 |
# end |
|
63 |
# |
|
64 |
# An <tt>ArgumentError</tt> will be raised if an invalid <tt>type</tt> |
|
65 |
# is given. Valid types are: |
|
66 |
# * +:public+ |
|
67 |
# * +:friends+ |
|
68 |
# * +:friend+ |
|
69 |
# * +:user+ |
|
70 |
# * +:me+ |
|
71 |
# * +:mentions+ |
|
72 |
# * +:replies+ |
|
73 |
# * +:retweetsbyme+ |
|
74 |
# * +:retweetstome+ |
|
75 |
# * +:retweetsofme+ |
|
76 |
def timeline_for(type, options = {}, &block)
|
1 |
77 |
raise ArgumentError, "Invalid timeline type: #{type}" unless @@TIMELINE_URIS.keys.member?(type)
|
8 |
78 |
uri = @@TIMELINE_URIS[type] |
6 |
79 |
response = rest_oauth_connect(:get, uri, options) |
6 |
80 |
timeline = Twitter::Status.unmarshal(response.body) |
6 |
81 |
timeline.each {|status| bless_model(status); yield status if block_given? }
|
12 |
82 |
timeline |
6 |
83 |
end |
|
84 |
end |
|
./lib/twitter/client/trends.rb87.5 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@TRENDS_URIS = {
|
1 |
3 |
:locations => '/trends/available.json', |
|
4 |
:global => '/trends.json', |
|
5 |
:current => '/trends/current.json', |
|
6 |
:daily => '/trends/daily.json', |
|
7 |
:weekly => '/trends/weekly.json', |
|
8 |
:local => '/trends/', |
|
9 |
} |
|
10 |
||
11 |
# Provides access to the Twitter list trends API. |
|
12 |
# |
|
13 |
# By default you will receive top ten topics that are trending on Twitter. |
|
14 |
def trends(type = :global) |
1 |
15 |
uri = @@TRENDS_URIS[type] |
5 |
16 |
response = rest_oauth_connect(:get, uri) |
5 |
17 |
if type === :locations |
1 |
18 |
bless_models(Twitter::Location.unmarshal(response.body)) |
0 |
19 |
else |
|
20 |
bless_models(Twitter::Trendline.unmarshal(response.body)) |
1 |
21 |
end |
|
22 |
end |
|
23 |
end |
|
./lib/twitter/client/user.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
class Twitter::Client |
1 |
2 |
@@USER_URIS = {
|
1 |
3 |
:info => '/users/show.json', |
|
4 |
:friends => '/statuses/friends.json', |
|
5 |
:followers => '/statuses/followers.json', |
|
6 |
} |
|
7 |
|
|
8 |
# Provides access to Twitter's User APIs |
|
9 |
# |
|
10 |
# Returns user instance for the <tt>id</tt> given. The <tt>id</tt> |
|
11 |
# can either refer to the numeric user ID or the user's screen name. |
|
12 |
# |
|
13 |
# For example, |
|
14 |
# @twitter.user(234943) #=> Twitter::User object instance for user with numeric id of 234943 |
|
15 |
# @twitter.user('mylogin') #=> Twitter::User object instance for user with screen name 'mylogin'
|
|
16 |
# |
|
17 |
# Where <tt>options</tt> is a +Hash+ of options that can include: |
|
18 |
# * <tt>:page</tt> - optional. Retrieves the next set of friends. There are 100 friends per page. Default: 1. |
|
19 |
# * <tt>:lite</tt> - optional. Prevents the inline inclusion of current status. Default: false. |
|
20 |
# * <tt>:since</tt> - optional. Only relevant for <tt>:friends</tt> action. Narrows the results to just those friends added after the date given as value of this option. Must be HTTP-formatted date. |
|
21 |
# |
|
22 |
# An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt> |
|
23 |
# is given. Valid actions are: |
|
24 |
# * +:info+ |
|
25 |
# * +:friends+ |
|
26 |
# |
|
27 |
# +Note:+ You should not use this method to attempt to retrieve the |
|
28 |
# authenticated user's followers. Please use any of the following |
|
29 |
# ways of accessing this list: |
|
30 |
# followers = client.my(:followers) |
|
31 |
# OR |
|
32 |
# followers = client.my(:info).followers |
|
33 |
def user(id, action = :info, options = {})
|
1 |
34 |
raise ArgumentError, "Invalid user action: #{action}" unless @@USER_URIS.keys.member?(action)
|
11 |
35 |
id = id.to_i if id.is_a?(Twitter::User) |
11 |
36 |
id_param = id.is_a?(String) ? :screen_name : :user_id |
11 |
37 |
params = options.merge(id_param => id) |
11 |
38 |
uri = @@USER_URIS[action] |
11 |
39 |
response = rest_oauth_connect(:get, uri, params) |
11 |
40 |
bless_models(Twitter::User.unmarshal(response.body)) |
11 |
41 |
end |
|
42 |
|
|
43 |
# Syntactic sugar for queries relating to authenticated user in Twitter's User API |
|
44 |
# |
|
45 |
# Where <tt>action</tt> is one of the following: |
|
46 |
# * <tt>:info</tt> - Returns user instance for the authenticated user. |
|
47 |
# * <tt>:friends</tt> - Returns Array of users that are authenticated user's friends |
|
48 |
# * <tt>:followers</tt> - Returns Array of users that are authenticated user's followers |
|
49 |
# |
|
50 |
# Where <tt>options</tt> is a +Hash+ of options that can include: |
|
51 |
# * <tt>:page</tt> - optional. Retrieves the next set of friends. There are 100 friends per page. Default: 1. |
|
52 |
# * <tt>:lite</tt> - optional. Prevents the inline inclusion of current status. Default: false. |
|
53 |
# * <tt>:since</tt> - optional. Only relevant for <tt>:friends</tt> action. Narrows the results to just those friends added after the date given as value of this option. Must be HTTP-formatted date. |
|
54 |
# |
|
55 |
# An <tt>ArgumentError</tt> will be raised if an invalid <tt>action</tt> |
|
56 |
# is given. Valid actions are: |
|
57 |
# * +:info+ |
|
58 |
# * +:friends+ |
|
59 |
# * +:followers+ |
|
60 |
def my(action, options = {})
|
1 |
61 |
raise ArgumentError, "Invalid user action: #{action}" unless @@USER_URIS.keys.member?(action)
|
7 |
62 |
params = options.merge(:id => @login) |
6 |
63 |
uri = @@USER_URIS[action] |
6 |
64 |
response = rest_oauth_connect(:get, uri, params) |
6 |
65 |
users = Twitter::User.unmarshal(response.body) |
6 |
66 |
bless_models(users) |
6 |
67 |
end |
|
68 |
end |
|
./lib/twitter/config.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# config.rb contains classes, methods and extends existing Twitter4R classes |
|
2 |
# to provide easy configuration facilities. |
|
3 |
||
4 |
module Twitter |
1 |
5 |
# Represents global configuration for Twitter::Client. |
|
6 |
# Can override the following configuration options: |
|
7 |
# * <tt>protocol</tt> - <tt>:http</tt>, <tt>:https</tt> or <tt>:ssl</tt> supported. <tt>:ssl</tt> is an alias for <tt>:https</tt>. Defaults to <tt>:ssl</tt> |
|
8 |
# * <tt>host</tt> - hostname to connect to for the Twitter service. Defaults to <tt>'twitter.com'</tt>. |
|
9 |
# * <tt>port</tt> - port to connect to for the Twitter service. Defaults to <tt>443</tt>. |
|
10 |
# * <tt>path_prefix</tt> - path to prefix URIs of REST API calls. Defaults to <tt>""</tt>. |
|
11 |
# * <tt>search_protocol</tt> - <tt>:http</tt>, <tt>:https</tt> or <tt>:ssl</tt> supported. <tt>:ssl</tt> is an alias for <tt>:https</tt>. Defaults to <tt>:ssl</tt> |
|
12 |
# * <tt>search_host</tt> - hostname to connect to for the Twitter Search service. Defaults to <tt>'twitter.com'</tt>. |
|
13 |
# * <tt>search_port</tt> - port to connect to for the Twitter Search service. Defaults to <tt>443</tt>. |
|
14 |
# * <tt>search_path_prefix</tt> - path to prefix URIs of Search API calls. Defaults to <tt>""</tt>. |
|
15 |
# * <tt>proxy_protocol</tt> - proxy protocol to use. Defaults to http. |
|
16 |
# * <tt>proxy_host</tt> - proxy host to use. Defaults to nil. |
|
17 |
# * <tt>proxy_port</tt> - proxy host to use. Defaults to 8080. |
|
18 |
# * <tt>proxy_user</tt> - proxy username to use. Defaults to nil. |
|
19 |
# * <tt>proxy_pass</tt> - proxy password to use. Defaults to nil. |
|
20 |
# * <tt>user_agent</tt> - user agent string to use for each request of the HTTP header. |
|
21 |
# * <tt>application_name</tt> - name of your client application. Defaults to 'Twitter4R'. |
|
22 |
# * <tt>application_version</tt> - version of your client application. Defaults to current <tt>Twitter::Version.to_version</tt>. |
|
23 |
# * <tt>application_url</tt> - URL of your client application. Defaults to http://twitter4r.rubyforge.org. |
|
24 |
# * <tt>source</tt> - the source id given to you by Twitter to identify your application in their web interface. Note: you must contact Twitter.com developer directly so they can configure their servers appropriately. |
|
25 |
# * <tt>timeout</tt> - the timeout in second for HTTP requests. |
|
26 |
# * <tt>oauth_consumer_token</tt> - the OAuth consumer token for your application |
|
27 |
# * <tt>oauth_consumer_secret</tt> - the OAuth consumer secret for your application |
|
28 |
# * <tt>oauth_request_token_path</tt> - the URI path for Twitter API's OAuth request token call. Not usually necessary to override. |
|
29 |
# * <tt>oauth_access_token_path</tt> - the URI path for Twitter API's OAuth access token call. Not usually necessary to override. |
|
30 |
# * <tt>oauth_authorize_path</tt> - the URI path for Twitter API's OAuth authorize call. Not usually necessary to override. |
|
31 |
class Config |
1 |
32 |
include ClassUtilMixin |
1 |
33 |
@@ATTRIBUTES = [ |
1 |
34 |
:protocol, |
|
35 |
:host, |
|
36 |
:port, |
|
37 |
:path_prefix, |
|
38 |
:search_protocol, |
|
39 |
:search_host, |
|
40 |
:search_port, |
|
41 |
:search_path_prefix, |
|
42 |
:proxy_protocol, |
|
43 |
:proxy_host, |
|
44 |
:proxy_port, |
|
45 |
:proxy_user, |
|
46 |
:proxy_pass, |
|
47 |
:user_agent, |
|
48 |
:application_name, |
|
49 |
:application_version, |
|
50 |
:application_url, |
|
51 |
:source, |
|
52 |
:timeout, |
|
53 |
:oauth_consumer_token, |
|
54 |
:oauth_consumer_secret, |
|
55 |
:oauth_request_token_path, |
|
56 |
:oauth_access_token_path, |
|
57 |
:oauth_authorize_path, |
|
58 |
:exception_registry, |
|
59 |
] |
|
60 |
||
61 |
attr_accessor(*@@ATTRIBUTES) |
1 |
62 |
|
|
63 |
# Override of Object#eql? to ensure RSpec specifications run |
|
64 |
# correctly. Also done to follow Ruby best practices. |
|
65 |
def eql?(other) |
1 |
66 |
return true if self == other |
9 |
67 |
@@ATTRIBUTES.each do |att| |
6 |
68 |
return false unless self.send(att).eql?(other.send(att)) |
66 |
69 |
end |
|
70 |
true |
2 |
71 |
end |
|
72 |
end |
|
73 |
||
74 |
class Client |
1 |
75 |
@@defaults = { :host => 'twitter.com',
|
1 |
76 |
:port => 443, |
|
77 |
:protocol => :ssl, |
|
78 |
:path_prefix => "", |
|
79 |
:search_host => 'search.twitter.com', |
|
80 |
:search_port => 80, |
|
81 |
:search_protocol => :http, |
|
82 |
:search_path_prefix => "", |
|
83 |
:proxy_protocol => "http", |
|
84 |
:proxy_host => nil, |
|
85 |
:proxy_port => 8080, |
|
86 |
:user_agent => "default", |
|
87 |
:application_name => 'Twitter4R', |
|
88 |
:application_version => Twitter::Version.to_version, |
|
89 |
:application_url => 'http://twitter4r.rubyforge.org', |
|
90 |
:source => 'twitter4r', |
|
91 |
:timeout => 20, |
|
92 |
:oauth_request_token_path => '/oauth/request_token', |
|
93 |
:oauth_access_token_path => '/oauth/access_token', |
|
94 |
:oauth_authorize_path => '/oauth/authorize', |
|
95 |
:exception_registry => Twitter::RESTError.registry, |
|
96 |
} |
|
97 |
@@config = Twitter::Config.new(@@defaults) |
1 |
98 |
||
99 |
# Twitter::Client class methods |
|
100 |
class << self |
1 |
101 |
# returns configuration object |
|
102 |
def config |
1 |
103 |
@@config |
494 |
104 |
end |
|
105 |
||
106 |
# Yields to given <tt>block</tt> to configure the Twitter4R API. |
|
107 |
def configure(&block) |
1 |
108 |
raise ArgumentError, "Block must be provided to configure" unless block_given? |
23 |
109 |
yield config |
22 |
110 |
end # configure |
|
111 |
end # class << self |
|
112 |
end # Client class |
|
113 |
end # Twitter module |
|
./lib/twitter/console.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# Contains hooks for the twitter console |
|
2 |
||
3 |
require('optparse')
|
1 |
4 |
||
5 |
module Twitter |
1 |
6 |
class Client |
1 |
7 |
class << self |
1 |
8 |
# Helper method mostly for irb shell prototyping. |
|
9 |
# |
|
10 |
# Reads in login/password Twitter credentials from YAML file |
|
11 |
# found at the location given by <tt>config_file</tt> that has |
|
12 |
# the following format: |
|
13 |
# envname: |
|
14 |
# login: mytwitterlogin |
|
15 |
# password: mytwitterpassword |
|
16 |
# |
|
17 |
# Where <tt>envname</tt> is the name of the environment like 'test', |
|
18 |
# 'dev' or 'prod'. The <tt>env</tt> argument defaults to 'test'. |
|
19 |
# |
|
20 |
# To use this in the shell you would do something like the following |
|
21 |
# examples: |
|
22 |
# twitter = Twitter::Client.from_config('config/twitter.yml', 'dev')
|
|
23 |
# twitter = Twitter::Client.from_config('config/twitter.yml')
|
|
24 |
def from_config(config_file, env = 'test') |
1 |
25 |
yaml_hash = YAML.load(File.read(config_file)) |
181 |
26 |
self.new yaml_hash[env] |
181 |
27 |
end |
|
28 |
end # class << self |
|
29 |
end |
|
30 |
end |
|
31 |
||
./lib/twitter/core.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# The Twitter4R API provides a nicer Ruby object API to work with |
|
2 |
# instead of coding around the REST API. |
|
3 |
||
4 |
# Module to encapsule the Twitter4R API. |
|
5 |
module Twitter |
1 |
6 |
# Mixin module for classes that need to have a constructor similar to |
|
7 |
# Rails' models, where a <tt>Hash</tt> is provided to set attributes |
|
8 |
# appropriately. |
|
9 |
# |
|
10 |
# To define a class that uses this mixin, use the following code: |
|
11 |
# class FilmActor |
|
12 |
# include ClassUtilMixin |
|
13 |
# end |
|
14 |
module ClassUtilMixin #:nodoc: |
1 |
15 |
def self.included(base) #:nodoc: |
1 |
16 |
base.send(:include, InstanceMethods) |
19 |
17 |
end |
|
18 |
|
|
19 |
# Instance methods defined for <tt>Twitter::ModelMixin</tt> module. |
|
20 |
module InstanceMethods #:nodoc: |
1 |
21 |
# Constructor/initializer that takes a hash of parameters that |
|
22 |
# will initialize *members* or instance attributes to the |
|
23 |
# values given. For example, |
|
24 |
# |
|
25 |
# class FilmActor |
|
26 |
# include Twitter::ClassUtilMixin |
|
27 |
# attr_accessor :name |
|
28 |
# end |
|
29 |
# |
|
30 |
# class Production |
|
31 |
# include Twitter::ClassUtilMixin |
|
32 |
# attr_accessor :title, :year, :actors |
|
33 |
# end |
|
34 |
# |
|
35 |
# # Favorite actress... |
|
36 |
# jodhi = FilmActor.new(:name => "Jodhi May") |
|
37 |
# jodhi.name # => "Jodhi May" |
|
38 |
# |
|
39 |
# # Favorite actor... |
|
40 |
# robert = FilmActor.new(:name => "Robert Lindsay") |
|
41 |
# robert.name # => "Robert Lindsay" |
|
42 |
# |
|
43 |
# # Jane is also an excellent pick...gotta love her accent! |
|
44 |
# jane = FilmActor.new(name => "Jane Horrocks") |
|
45 |
# jane.name # => "Jane Horrocks" |
|
46 |
# |
|
47 |
# # Witty BBC series... |
|
48 |
# mrs_pritchard = Production.new(:title => "The Amazing Mrs. Pritchard", |
|
49 |
# :year => 2005, |
|
50 |
# :actors => [jodhi, jane]) |
|
51 |
# mrs_pritchard.title # => "The Amazing Mrs. Pritchard" |
|
52 |
# mrs_pritchard.year # => 2005 |
|
53 |
# mrs_pritchard.actors # => [#<FilmActor:0xb79d6bbc @name="Jodhi May">, |
|
54 |
# <FilmActor:0xb79d319c @name="Jane Horrocks">] |
|
55 |
# # Any Ros Pritchard's out there to save us from the Tony Blair |
|
56 |
# # and Gordon Brown *New Labour* debacle? You've got my vote! |
|
57 |
# |
|
58 |
# jericho = Production.new(:title => "Jericho", |
|
59 |
# :year => 2005, |
|
60 |
# :actors => [robert]) |
|
61 |
# jericho.title # => "Jericho" |
|
62 |
# jericho.year # => 2005 |
|
63 |
# jericho.actors # => [#<FilmActor:0xc95d3eec @name="Robert Lindsay">] |
|
64 |
# |
|
65 |
# Assuming class <tt>FilmActor</tt> includes |
|
66 |
# <tt>Twitter::ClassUtilMixin</tt> in the class definition |
|
67 |
# and has an attribute of <tt>name</tt>, then that instance |
|
68 |
# attribute will be set to "Jodhi May" for the <tt>actress</tt> |
|
69 |
# object during object initialization (aka construction for |
|
70 |
# you Java heads). |
|
71 |
def initialize(params = {})
|
1 |
72 |
params.each do |key,val| |
474 |
73 |
self.send("#{key}=", val) if self.respond_to? key
|
1285 |
74 |
end |
|
75 |
self.send(:init) if self.respond_to? :init |
474 |
76 |
end |
|
77 |
|
|
78 |
protected |
1 |
79 |
# Helper method to provide an easy and terse way to require |
|
80 |
# a block is provided to a method. |
|
81 |
def require_block(block_given) |
1 |
82 |
raise ArgumentError, "Must provide a block" unless block_given |
2 |
83 |
end |
|
84 |
end |
|
85 |
end # ClassUtilMixin |
|
86 |
|
|
87 |
# Exception API base class raised when there is an error encountered upon |
|
88 |
# querying or posting to the remote Twitter REST API. |
|
89 |
# |
|
90 |
# To consume and query any <tt>RESTError</tt> raised by Twitter4R: |
|
91 |
# begin |
|
92 |
# # Do something with your instance of <tt>Twitter::Client</tt>. |
|
93 |
# # Maybe something like: |
|
94 |
# timeline = twitter.timeline_for(:public) |
|
95 |
# rescue RESTError => re |
|
96 |
# puts re.code, re.message, re.uri |
|
97 |
# end |
|
98 |
# Which on the code raising a <tt>RESTError</tt> will output something like: |
|
99 |
# 404 |
|
100 |
# Resource Not Found |
|
101 |
# /i_am_crap.json |
|
102 |
class RESTError < RuntimeError |
1 |
103 |
class << self |
1 |
104 |
@@REGISTRY = {}
|
1 |
105 |
||
106 |
def registry |
1 |
107 |
@@REGISTRY |
31 |
108 |
end |
|
109 |
||
110 |
def register(status_code) |
1 |
111 |
@@REGISTRY[status_code] = self |
11 |
112 |
end |
|
113 |
end |
|
114 |
||
115 |
include ClassUtilMixin |
1 |
116 |
@@ATTRIBUTES = [:code, :message, :uri, :error] |
1 |
117 |
attr_accessor :code, :message, :uri, :error |
1 |
118 |
|
|
119 |
# Returns string in following format: |
|
120 |
# "HTTP #{@code}: #{@message} at #{@uri}"
|
|
121 |
# For example, |
|
122 |
# "HTTP 404: Resource Not Found at /i_am_crap.json |
|
123 |
# >This is the error message sent back by the Twitter.com API" |
|
124 |
def to_s |
1 |
125 |
"HTTP #{@code}: #{@message} at #{@uri}"
|
1 |
126 |
end |
|
127 |
end # RESTError |
|
128 |
||
129 |
# Runtime error leaf class raised when Twitter.com API has no new results |
|
130 |
# to return from the last query. HTTP code: 304 (aka Not Modified). |
|
131 |
# |
|
132 |
# To handle specifically you would do the following: |
|
133 |
# begin |
|
134 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
135 |
# rescue NotModifiedError => nme |
|
136 |
# timeline = [] |
|
137 |
# end |
|
138 |
class NotModifiedError < RESTError; register('304'); end
|
2 |
139 |
|
|
140 |
# Runtime error leaf class raised when client has reached rate limits. |
|
141 |
# HTTP code: 400 (aka Bad Request). |
|
142 |
# |
|
143 |
# To handle specifically you would do the following: |
|
144 |
# begin |
|
145 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
146 |
# rescue RateLimitError => rlre |
|
147 |
# # do something here... |
|
148 |
# end |
|
149 |
class RateLimitError < RESTError; register('400'); end
|
2 |
150 |
|
|
151 |
# Runtime error leaf class raised when user and/or client credentials |
|
152 |
# are missing or invalid. |
|
153 |
# HTTP code: 401 (aka Unauthorized). |
|
154 |
# |
|
155 |
# To handle specifically you would do the following: |
|
156 |
# begin |
|
157 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
158 |
# rescue UnauthorizedError => uae |
|
159 |
# # do something to prompt for valid credentials to user here. |
|
160 |
# end |
|
161 |
class UnauthorizedError < RESTError; register('401'); end
|
2 |
162 |
|
|
163 |
# Runtime error leaf class raised when update limit reached. |
|
164 |
# HTTP code: 403 (aka Forbidden). |
|
165 |
# |
|
166 |
# To handle specifically you would do the following: |
|
167 |
# begin |
|
168 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
169 |
# rescue ForbiddenError => fe |
|
170 |
# # do something to notify user that update limit has been reached |
|
171 |
# end |
|
172 |
class ForbiddenError < RESTError; register('403'); end
|
2 |
173 |
|
|
174 |
# Runtime error leaf class raised when a resource requested was not found. |
|
175 |
# HTTP code: 404 (aka Not Found). |
|
176 |
# |
|
177 |
# To handle specifically you would do the following: |
|
178 |
# begin |
|
179 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
180 |
# rescue NotFoundError => nfe |
|
181 |
# # do something to notify user that resource was not found. |
|
182 |
# end |
|
183 |
class NotFoundError < RESTError; register('404'); end
|
2 |
184 |
|
|
185 |
# Runtime error leaf class raised when the format specified in the request |
|
186 |
# is not understood by the Twitter.com API. |
|
187 |
# HTTP code: 406 (aka Not Acceptable). |
|
188 |
# |
|
189 |
# To handle specifically you would do the following: |
|
190 |
# begin |
|
191 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
192 |
# rescue NotAcceptableError => nae |
|
193 |
# # |
|
194 |
# end |
|
195 |
class NotAcceptableError < RESTError; register('406'); end
|
2 |
196 |
|
|
197 |
# Runtime error leaf class raised when search rate limit reached. |
|
198 |
# HTTP code: 420. |
|
199 |
# |
|
200 |
# To handle specifically you would do the following: |
|
201 |
# begin |
|
202 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
203 |
# rescue SearchRateLimitError => nme |
|
204 |
# # |
|
205 |
# end |
|
206 |
class SearchRateLimitError < RESTError; register('420'); end
|
2 |
207 |
|
|
208 |
# Runtime error leaf class raised when Twitter.com API is borked for |
|
209 |
# an unknown reason. |
|
210 |
# HTTP code: 500 (aka Internal Server Error). |
|
211 |
# |
|
212 |
# To handle specifically you would do the following: |
|
213 |
# begin |
|
214 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
215 |
# rescue InternalServerError => ise |
|
216 |
# # do something to notify user that an unknown internal server error |
|
217 |
# # has arisen. |
|
218 |
# end |
|
219 |
class InternalServerError < RESTError; register('500'); end
|
2 |
220 |
|
|
221 |
# Runtime error leaf class raised when Twitter.com servers are being |
|
222 |
# upgraded. |
|
223 |
# HTTP code: 502 (aka Bad Gateway). |
|
224 |
# |
|
225 |
# To handle specifically you would do the following: |
|
226 |
# begin |
|
227 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
228 |
# rescue BadGatewayError => bge |
|
229 |
# # |
|
230 |
# end |
|
231 |
class BadGatewayError < RESTError; register('502'); end
|
2 |
232 |
|
|
233 |
# Runtime error leaf class raised when Twitter.com servers are unable |
|
234 |
# to respond to the current load. |
|
235 |
# HTTP code: 502 (aka Service Unavailable). |
|
236 |
# |
|
237 |
# To handle specifically you would do the following: |
|
238 |
# begin |
|
239 |
# timeline = twitter.timeline_for(:friends, :since => tweet) |
|
240 |
# rescue ServiceUnavailableError => sue |
|
241 |
# # |
|
242 |
# end |
|
243 |
class ServiceUnavailableError < RESTError; register('503'); end
|
2 |
244 |
end |
|
./lib/twitter/ext.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
||
2 |
require_local('twitter/ext/stdlib')
|
1 |
./lib/twitter/ext/stdlib.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# Contains Ruby standard library extensions specific to <tt>Twitter4R</tt> library. |
|
2 |
||
3 |
# Extension to Hash to create URL encoded string from key-values |
|
4 |
class Hash |
1 |
5 |
# Returns string formatted for HTTP URL encoded name-value pairs. |
|
6 |
# For example, |
|
7 |
# {:id => 'thomas_hardy'}.to_http_str
|
|
8 |
# # => "id=thomas_hardy" |
|
9 |
# {:id => 23423, :since => Time.now}.to_http_str
|
|
10 |
# # => "since=Thu,%2021%20Jun%202007%2012:10:05%20-0500&id=23423" |
|
11 |
def to_http_str |
1 |
12 |
result = '' |
56 |
13 |
return result if self.empty? |
56 |
14 |
self.each do |key, val| |
25 |
15 |
result << "#{key}=#{CGI.escape(val.to_s)}&"
|
36 |
16 |
end |
|
17 |
result.chop # remove the last '&' character, since it can be discarded |
25 |
18 |
end |
|
19 |
end |
|
20 |
||
21 |
# Extension to Time that outputs RFC2822 compliant string on #to_s |
|
22 |
class Time |
1 |
23 |
alias :old_to_s :to_s |
1 |
24 |
|
|
25 |
# Returns RFC2822 compliant string for <tt>Time</tt> object. |
|
26 |
# For example, |
|
27 |
# # Tony Blair's last day in office (hopefully) |
|
28 |
# best_day_ever = Time.local(2007, 6, 27) |
|
29 |
# best_day_ever.to_s # => "Wed, 27 Jun 2007 00:00:00 +0100" |
|
30 |
# You can also pass in an option <tt>format</tt> argument that |
|
31 |
# corresponds to acceptable values according to ActiveSupport's |
|
32 |
# +Time#to_formatted_s+ method. |
|
33 |
def to_s(format = nil) |
1 |
34 |
format ? self.to_formatted_s(format) : self.rfc2822 |
2 |
35 |
end |
|
36 |
end |
|
37 |
||
./lib/twitter/extras.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# extra.rb contains features that are not considered part of the core library. |
|
2 |
# This file is not imported by doing <tt>require('twitter')</tt>, so you will
|
|
3 |
# need to import this file separately like: |
|
4 |
# require('twitter')
|
|
5 |
# require('twitter/extras')
|
|
6 |
||
7 |
require('twitter')
|
1 |
8 |
||
9 |
class Twitter::Client |
1 |
10 |
@@FEATURED_URIS = {
|
1 |
11 |
:users => 'http://twitter.com/statuses/featured.json' |
|
12 |
} |
|
13 |
|
|
14 |
# Provides access to the Featured Twitter API. |
|
15 |
# |
|
16 |
# Currently the only value for <tt>type</tt> accepted is <tt>:users</tt>, |
|
17 |
# which will return an Array of blessed Twitter::User objects that |
|
18 |
# represent Twitter's featured users. |
|
19 |
def featured(type) |
1 |
20 |
uri = @@FEATURED_URIS[type] |
2 |
21 |
response = rest_oauth_connect(:get, uri) |
2 |
22 |
bless_models(Twitter::User.unmarshal(response.body)) |
2 |
23 |
end |
|
24 |
end |
|
25 |
||
26 |
class Twitter::User |
1 |
27 |
class << self |
1 |
28 |
# Provides access to the Featured Twitter API via the Twitter4R Model |
|
29 |
# interface. |
|
30 |
# |
|
31 |
# The following lines of code are equivalent to each other: |
|
32 |
# users1 = Twitter::User.features(client) |
|
33 |
# users2 = client.featured(:users) |
|
34 |
# where <tt>users1</tt> and <tt>users2</tt> would be logically equivalent. |
|
35 |
def featured(client) |
1 |
36 |
client.featured(:users) |
1 |
37 |
end |
|
38 |
end |
|
39 |
end |
|
./lib/twitter/meta.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# meta.rb contains <tt>Twitter::Meta</tt> and related classes that |
|
2 |
# help define the metadata of the <tt>Twitter4R</tt> project. |
|
3 |
||
4 |
require('rubygems')
|
1 |
5 |
require('erb')
|
1 |
6 |
||
7 |
class Twitter::Meta #:nodoc: |
1 |
8 |
attr_accessor :root_dir |
1 |
9 |
attr_reader :gem_spec, :project_files, :spec_files |
1 |
10 |
||
11 |
# Initializer for Twitter::Meta class. Takes <tt>root_dir</tt> as parameter. |
|
12 |
def initialize(root_dir) |
1 |
13 |
@root_dir = root_dir |
7 |
14 |
end |
|
15 |
||
16 |
# Returns package information defined in <tt>root_dir</tt>/pkg-info.yml |
|
17 |
def pkg_info |
1 |
18 |
yaml_file = File.join(@root_dir, 'pkg-info.yml') |
5 |
19 |
ryaml = ERB.new(File.read(yaml_file), 0) |
5 |
20 |
s = ryaml.result(binding) |
5 |
21 |
YAML.load(s) |
5 |
22 |
end |
|
23 |
|
|
24 |
# Returns RubyGems spec information |
|
25 |
def spec_info |
1 |
26 |
self.pkg_info['spec'] if self.pkg_info |
2 |
27 |
end |
|
28 |
|
|
29 |
# Returns list of project files |
|
30 |
def project_files |
1 |
31 |
@project_files ||= Dir.glob(File.join(@root_dir, 'lib/**/*.rb')) |
8 |
32 |
@project_files |
8 |
33 |
end |
|
34 |
|
|
35 |
# Returns list of specification files |
|
36 |
def spec_files |
1 |
37 |
@spec_files ||= Dir.glob(File.join(@root_dir, 'spec/**/*_spec.rb')) |
8 |
38 |
@spec_files |
8 |
39 |
end |
|
40 |
|
|
41 |
# Returns RubyGem specification for Twitter4R project |
|
42 |
def gem_spec |
1 |
43 |
@gem_spec ||= Gem::Specification.new do |spec| |
|
44 |
self.spec_info.each do |key, val| |
1 |
45 |
if val.is_a?(Hash) |
17 |
46 |
val.each do |k, v| |
1 |
47 |
spec.send(key, k, v) |
2 |
48 |
end |
|
49 |
else |
|
50 |
spec.send("#{key}=", val)
|
16 |
51 |
end |
|
52 |
end |
|
53 |
end |
1 |
54 |
@gem_spec |
1 |
55 |
end |
|
56 |
end |
|
./lib/twitter/model.rb95.21 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# Contains Twitter4R Model API. |
|
2 |
||
3 |
module Twitter |
1 |
4 |
# Mixin module for model classes. Includes generic class methods like |
|
5 |
# unmarshal. |
|
6 |
# |
|
7 |
# To create a new model that includes this mixin's features simply: |
|
8 |
# class NewModel |
|
9 |
# include Twitter::ModelMixin |
|
10 |
# end |
|
11 |
# |
|
12 |
# This mixin module automatically includes <tt>Twitter::ClassUtilMixin</tt> |
|
13 |
# features. |
|
14 |
# |
|
15 |
# The contract for models to use this mixin correctly is that the class |
|
16 |
# including this mixin must provide an class method named <tt>attributes</tt> |
|
17 |
# that will return an Array of attribute symbols that will be checked |
|
18 |
# in #eql? override method. The following would be sufficient: |
|
19 |
# def self.attributes; @@ATTRIBUTES; end |
|
20 |
module ModelMixin #:nodoc: |
1 |
21 |
def self.included(base) #:nodoc: |
1 |
22 |
base.send(:include, Twitter::ClassUtilMixin) |
10 |
23 |
base.send(:include, InstanceMethods) |
10 |
24 |
base.extend(ClassMethods) |
10 |
25 |
end |
|
26 |
||
27 |
# Class methods defined for <tt>Twitter::ModelMixin</tt> module. |
|
28 |
module ClassMethods #:nodoc: |
1 |
29 |
# Unmarshal object singular or plural array of model objects |
|
30 |
# from JSON serialization. Currently JSON is only supported |
|
31 |
# since this is all <tt>Twitter4R</tt> needs. |
|
32 |
def unmarshal(raw) |
1 |
33 |
input = JSON.parse(raw) if raw.is_a?(String) |
21 |
34 |
def unmarshal_model(hash) |
21 |
35 |
self.new(hash) |
21 |
36 |
end |
|
37 |
return unmarshal_model(input) if input.is_a?(Hash) # singular case |
21 |
38 |
result = [] |
7 |
39 |
input.each do |hash| |
|
40 |
model = unmarshal_model(hash) if hash.is_a?(Hash) |
7 |
41 |
result << model |
7 |
42 |
end if input.is_a?(Array) |
7 |
43 |
result # plural case |
7 |
44 |
end |
|
45 |
end |
|
46 |
|
|
47 |
# Instance methods defined for <tt>Twitter::ModelMixin</tt> module. |
|
48 |
module InstanceMethods #:nodoc: |
1 |
49 |
attr_accessor :client |
1 |
50 |
# Equality method override of Object#eql? default. |
|
51 |
# |
|
52 |
# Relies on the class using this mixin to provide a <tt>attributes</tt> |
|
53 |
# class method that will return an Array of attributes to check are |
|
54 |
# equivalent in this #eql? override. |
|
55 |
# |
|
56 |
# It is by design that the #eql? method will raise a NoMethodError |
|
57 |
# if no <tt>attributes</tt> class method exists, to alert you that |
|
58 |
# you must provide it for a meaningful result from this #eql? override. |
|
59 |
# Otherwise this will return a meaningless result. |
|
60 |
def eql?(other) |
1 |
61 |
attrs = self.class.attributes |
37 |
62 |
attrs.each do |att| |
37 |
63 |
return false unless self.send(att).eql?(other.send(att)) |
714 |
64 |
end |
|
65 |
true |
34 |
66 |
end |
|
67 |
|
|
68 |
# Returns integer representation of model object instance. |
|
69 |
# |
|
70 |
# For example, |
|
71 |
# status = Twitter::Status.new(:id => 234343) |
|
72 |
# status.to_i #=> 234343 |
|
73 |
def to_i |
1 |
74 |
@id |
31 |
75 |
end |
|
76 |
|
|
77 |
# Returns string representation of model object instance. |
|
78 |
# |
|
79 |
# For example, |
|
80 |
# status = Twitter::Status.new(:text => 'my status message') |
|
81 |
# status.to_s #=> 'my status message' |
|
82 |
# |
|
83 |
# If a model class doesn't have a @text attribute defined |
|
84 |
# the default Object#to_s will be returned as the result. |
|
85 |
def to_s |
1 |
86 |
self.respond_to?(:text) ? @text : super.to_s |
3 |
87 |
end |
|
88 |
|
|
89 |
# Returns hash representation of model object instance. |
|
90 |
# |
|
91 |
# For example, |
|
92 |
# u = Twitter::User.new(:id => 2342342, :screen_name => 'tony_blair_is_the_devil') |
|
93 |
# u.to_hash #=> {:id => 2342342, :screen_name => 'tony_blair_is_the_devil'}
|
|
94 |
# |
|
95 |
# This method also requires that the class method <tt>attributes</tt> be |
|
96 |
# defined to return an Array of attributes for the class. |
|
97 |
def to_hash |
1 |
98 |
attrs = self.class.attributes |
43 |
99 |
result = {}
|
43 |
100 |
attrs.each do |att| |
43 |
101 |
value = self.send(att) |
932 |
102 |
value = value.to_hash if value.respond_to?(:to_hash) |
932 |
103 |
result[att] = value if value |
932 |
104 |
end |
|
105 |
result |
43 |
106 |
end |
|
107 |
|
|
108 |
# "Blesses" model object. |
|
109 |
# |
|
110 |
# Should be overridden by model class if special behavior is expected |
|
111 |
# |
|
112 |
# Expected to return blessed object (usually <tt>self</tt>) |
|
113 |
def bless(client) |
1 |
114 |
self.basic_bless(client) |
26 |
115 |
end |
|
116 |
|
|
117 |
protected |
1 |
118 |
# Basic "blessing" of model object |
|
119 |
def basic_bless(client) |
1 |
120 |
self.client = client |
66 |
121 |
self |
66 |
122 |
end |
|
123 |
end |
|
124 |
end |
|
125 |
|
|
126 |
module AuthenticatedUserMixin |
1 |
127 |
def self.included(base) |
1 |
128 |
base.send(:include, InstanceMethods) |
1 |
129 |
end |
|
130 |
|
|
131 |
module InstanceMethods |
1 |
132 |
# Returns an Array of user objects that represents the authenticated |
|
133 |
# user's friends on Twitter. |
|
134 |
def followers(options = {})
|
1 |
135 |
@client.my(:followers, options) |
1 |
136 |
end |
|
137 |
|
|
138 |
# Adds given user as a friend. Returns user object as given by |
|
139 |
# <tt>Twitter</tt> REST server response. |
|
140 |
# |
|
141 |
# For <tt>user</tt> argument you may pass in the unique integer |
|
142 |
# user ID, screen name or Twitter::User object representation. |
|
143 |
def befriend(user) |
1 |
144 |
@client.friend(:add, user) |
1 |
145 |
end |
|
146 |
|
|
147 |
# Removes given user as a friend. Returns user object as given by |
|
148 |
# <tt>Twitter</tt> REST server response. |
|
149 |
# |
|
150 |
# For <tt>user</tt> argument you may pass in the unique integer |
|
151 |
# user ID, screen name or Twitter::User object representation. |
|
152 |
def defriend(user) |
1 |
153 |
@client.friend(:remove, user) |
1 |
154 |
end |
|
155 |
end |
|
156 |
end |
|
157 |
||
158 |
# Represents a location in Twitter |
|
159 |
class Location |
1 |
160 |
include ModelMixin |
1 |
161 |
||
162 |
@@ATTRIBUTES = [:name, :woeid, :country, :url, :countryCode, :parentid, :placeType] |
1 |
163 |
attr_accessor(*@@ATTRIBUTES) |
1 |
164 |
||
165 |
class << self |
1 |
166 |
def attributes; @@ATTRIBUTES; end |
1 |
167 |
end |
|
168 |
||
169 |
# Alias to +countryCode+ for those wanting to use consistent naming |
|
170 |
# convention for attribute |
|
171 |
def country_code |
1 |
172 |
@countryCode |
0 |
173 |
end |
|
174 |
||
175 |
# Alias to +parentid+ for those wanting to use consistent naming |
|
176 |
# convention for attribute |
|
177 |
def parent_id |
1 |
178 |
@parentid |
0 |
179 |
end |
|
180 |
||
181 |
# Alias to +placeType+ for those wanting to use consistent naming |
|
182 |
# convention for attribute |
|
183 |
def place_type |
1 |
184 |
@place_type |
0 |
185 |
end |
|
186 |
||
187 |
# Convenience method to output meaningful representation to STDOUT as per |
|
188 |
# Ruby convention |
|
189 |
def inspect |
1 |
190 |
"#{name} / #{woeid} / #{countryCode}\n#{url}\n"
|
0 |
191 |
end |
|
192 |
||
193 |
protected |
1 |
194 |
def init |
1 |
195 |
puts @placeType |
0 |
196 |
@placeType = ::Twitter::PlaceType.new(:name => @placeType["name"], |
0 |
197 |
:code => @placeType["code"]) if @placeType.is_a?(Hash) |
0 |
198 |
end |
|
199 |
end |
|
200 |
||
201 |
# Represents a type of a place. |
|
202 |
class PlaceType |
1 |
203 |
include ModelMixin |
1 |
204 |
||
205 |
@@ATTRIBUTES = [:name, :code] |
1 |
206 |
attr_accessor(*@@ATTRIBUTES) |
1 |
207 |
||
208 |
class << self |
1 |
209 |
def attributes; @@ATTRIBUTES; end |
1 |
210 |
end |
|
211 |
end |
|
212 |
||
213 |
# Represents a sorted, dated and typed list of trends. |
|
214 |
# |
|
215 |
# To find out when this +Trendline+ was created query the +as_of+ attribute. |
|
216 |
# To find out what type +Trendline+ is use the +type+ attribute. |
|
217 |
# You can iterator over the trends in the +Trendline+ with +each+ or by |
|
218 |
# index, whichever you prefer. |
|
219 |
class Trendline |
1 |
220 |
include ModelMixin |
1 |
221 |
include Enumerable |
1 |
222 |
include Comparable |
1 |
223 |
||
224 |
@@ATTRIBUTES = [:as_of, :type] |
1 |
225 |
attr_accessor(*@@ATTRIBUTES) |
1 |
226 |
||
227 |
class << self |
1 |
228 |
def attributes; @@ATTRIBUTES; end |
1 |
229 |
end |
|
230 |
||
231 |
# Spaceship operator definition needed by Comparable mixin |
|
232 |
# for sort, etc. |
|
233 |
def <=>(other) |
1 |
234 |
self.type === other.type && self.as_of <=> other.as_of |
0 |
235 |
end |
|
236 |
||
237 |
# each definition needed by Enumerable mixin for first, ... |
|
238 |
def each |
1 |
239 |
trends.each do |t| |
2 |
240 |
yield t |
3 |
241 |
end |
|
242 |
end |
|
243 |
||
244 |
# index operator definition needed to iterate over trends |
|
245 |
# in the +::Twitter::Trendline+ object using for or otherwise |
|
246 |
def [](index) |
1 |
247 |
trends[index] |
1 |
248 |
end |
|
249 |
||
250 |
protected |
1 |
251 |
attr_accessor(:trends) |
1 |
252 |
# Constructor callback |
|
253 |
def init |
1 |
254 |
@trends = @trends.collect do |trend| |
1 |
255 |
::Twitter::Trend.new(trend) if trend.is_a?(Hash) |
2 |
256 |
end if @trends.is_a?(Array) |
2 |
257 |
end |
|
258 |
end |
|
259 |
||
260 |
class Trend |
1 |
261 |
include ModelMixin |
1 |
262 |
@@ATTRIBUTES = [:name, :url] |
1 |
263 |
attr_accessor(*@@ATTRIBUTES) |
1 |
264 |
||
265 |
class << self |
1 |
266 |
def attributes; @@ATTRIBUTES; end |
1 |
267 |
end |
|
268 |
end |
|
269 |
||
270 |
# Represents a <tt>Twitter</tt> user |
|
271 |
class User |
1 |
272 |
include ModelMixin |
1 |
273 |
@@ATTRIBUTES = [:id, :name, :description, :location, :screen_name, :url, |
1 |
274 |
:protected, :profile_image_url, :profile_background_color, |
|
275 |
:profile_text_color, :profile_link_color, :profile_sidebar_fill_color, |
|
276 |
:profile_sidebar_border_color, :profile_background_image_url, |
|
277 |
:profile_background_tile, :utc_offset, :time_zone, |
|
278 |
:following, :notifications, :favourites_count, :followers_count, |
|
279 |
:friends_count, :statuses_count, :created_at ] |
|
280 |
attr_accessor(*@@ATTRIBUTES) |
1 |
281 |
||
282 |
class << self |
1 |
283 |
# Used as factory method callback |
|
284 |
def attributes; @@ATTRIBUTES; end |
60 |
285 |
||
286 |
# Returns user model object with given <tt>id</tt> using the configuration |
|
287 |
# and credentials of the <tt>client</tt> object passed in. |
|
288 |
# |
|
289 |
# You can pass in either the user's unique integer ID or the user's |
|
290 |
# screen name. |
|
291 |
def find(id, client) |
1 |
292 |
client.user(id) |
2 |
293 |
end |
|
294 |
end |
|
295 |
|
|
296 |
# Override of ModelMixin#bless method. |
|
297 |
# |
|
298 |
# Adds #followers instance method when user object represents |
|
299 |
# authenticated user. Otherwise just do basic bless. |
|
300 |
# |
|
301 |
# This permits applications using <tt>Twitter4R</tt> to write |
|
302 |
# Rubyish code like this: |
|
303 |
# followers = user.followers if user.is_me? |
|
304 |
# Or: |
|
305 |
# followers = user.followers if user.respond_to?(:followers) |
|
306 |
def bless(client) |
1 |
307 |
basic_bless(client) |
41 |
308 |
self.instance_eval(%{
|
|
309 |
self.class.send(:include, Twitter::AuthenticatedUserMixin) |
|
310 |
}) if self.is_me? and not self.respond_to?(:followers) |
41 |
311 |
self |
41 |
312 |
end |
|
313 |
|
|
314 |
# Returns whether this <tt>Twitter::User</tt> model object |
|
315 |
# represents the authenticated user of the <tt>client</tt> |
|
316 |
# that blessed it. |
|
317 |
def is_me? |
1 |
318 |
# TODO: Determine whether we should cache this or not? |
|
319 |
# Might be dangerous to do so, but do we want to support |
|
320 |
# the edge case where this would cause a problem? i.e. |
|
321 |
# changing authenticated user after initial use of |
|
322 |
# authenticated API. |
|
323 |
# TBD: To cache or not to cache. That is the question! |
|
324 |
# Since this is an implementation detail we can leave this for |
|
325 |
# subsequent 0.2.x releases. It doesn't have to be decided before |
|
326 |
# the 0.2.0 launch. |
|
327 |
@screen_name == @client.instance_eval("@login")
|
43 |
328 |
end |
|
329 |
|
|
330 |
# Returns an Array of user objects that represents the authenticated |
|
331 |
# user's friends on Twitter. |
|
332 |
def friends |
1 |
333 |
@client.user(@id, :friends) |
1 |
334 |
end |
|
335 |
end # User |
|
336 |
|
|
337 |
# Represents a status posted to <tt>Twitter</tt> by a <tt>Twitter</tt> user. |
|
338 |
class Status |
1 |
339 |
include ModelMixin |
1 |
340 |
@@ATTRIBUTES = [:id, :id_str, :text, :source, :truncated, :created_at, :user, |
1 |
341 |
:from_user, :to_user, :favorited, :in_reply_to_status_id, |
|
342 |
:in_reply_to_user_id, :in_reply_to_screen_name, :geo] |
|
343 |
attr_accessor(*@@ATTRIBUTES) |
1 |
344 |
||
345 |
class << self |
1 |
346 |
# Used as factory method callback |
|
347 |
def attributes; @@ATTRIBUTES; end |
21 |
348 |
|
|
349 |
# Returns status model object with given <tt>status</tt> using the |
|
350 |
# configuration and credentials of the <tt>client</tt> object passed in. |
|
351 |
def find(id, client) |
1 |
352 |
client.status(:get, id) |
1 |
353 |
end |
|
354 |
|
|
355 |
# Creates a new status for the authenticated user of the given |
|
356 |
# <tt>client</tt> context. |
|
357 |
# |
|
358 |
# You MUST include a valid/authenticated <tt>client</tt> context |
|
359 |
# in the given <tt>params</tt> argument. |
|
360 |
# |
|
361 |
# For example: |
|
362 |
# status = Twitter::Status.create( |
|
363 |
# :text => 'I am shopping for flip flops', |
|
364 |
# :client => client) |
|
365 |
# |
|
366 |
# An <tt>ArgumentError</tt> will be raised if no valid client context |
|
367 |
# is given in the <tt>params</tt> Hash. For example, |
|
368 |
# status = Twitter::Status.create(:text => 'I am shopping for flip flops') |
|
369 |
# The above line of code will raise an <tt>ArgumentError</tt>. |
|
370 |
# |
|
371 |
# The same is true when you do not provide a <tt>:text</tt> key-value |
|
372 |
# pair in the <tt>params</tt> argument given. |
|
373 |
# |
|
374 |
# The Twitter::Status object returned after the status successfully |
|
375 |
# updates on the Twitter server side is returned from this method. |
|
376 |
def create(params) |
1 |
377 |
client, text = params[:client], params[:text] |
5 |
378 |
raise ArgumentError, 'Valid client context must be provided' unless client.is_a?(Twitter::Client) |
5 |
379 |
raise ArgumentError, 'Must provide text for the status to update' unless text.is_a?(String) |
2 |
380 |
client.status(:post, text) |
1 |
381 |
end |
|
382 |
end |
|
383 |
||
384 |
def reply? |
1 |
385 |
!!@in_reply_to_status_id |
2 |
386 |
end |
|
387 |
||
388 |
# Convenience method to allow client developers to not have to worry about |
|
389 |
# setting the +in_reply_to_status_id+ attribute or prefixing the status |
|
390 |
# text with the +screen_name+ being replied to. |
|
391 |
def reply(reply) |
1 |
392 |
status_reply = "@#{user.screen_name} #{reply}"
|
1 |
393 |
client.status(:reply, :status => status_reply, |
1 |
394 |
:in_reply_to_status_id => @id) |
|
395 |
end |
|
396 |
|
|
397 |
protected |
1 |
398 |
# Constructor callback |
|
399 |
def init |
1 |
400 |
@user = User.new(@user) if @user.is_a?(Hash) |
70 |
401 |
@created_at = Time.parse(@created_at) if @created_at.is_a?(String) |
70 |
402 |
end |
|
403 |
end # Status |
|
404 |
|
|
405 |
# Represents a direct message on <tt>Twitter</tt> between <tt>Twitter</tt> users. |
|
406 |
class Message |
1 |
407 |
include ModelMixin |
1 |
408 |
@@ATTRIBUTES = [:id, :recipient, :sender, :text, :geo, :created_at] |
1 |
409 |
attr_accessor(*@@ATTRIBUTES) |
1 |
410 |
|
|
411 |
class << self |
1 |
412 |
# Used as factory method callback |
|
413 |
def attributes; @@ATTRIBUTES; end |
1 |
414 |
|
|
415 |
# Raises <tt>NotImplementedError</tt> because currently |
|
416 |
# <tt>Twitter</tt> doesn't provide a facility to retrieve |
|
417 |
# one message by unique ID. |
|
418 |
def find(id, client) |
1 |
419 |
raise NotImplementedError, 'Twitter has yet to implement a REST API for this. This is not a Twitter4R library limitation.' |
1 |
420 |
end |
|
421 |
|
|
422 |
# Creates a new direct message from the authenticated user of the |
|
423 |
# given <tt>client</tt> context. |
|
424 |
# |
|
425 |
# You MUST include a valid/authenticated <tt>client</tt> context |
|
426 |
# in the given <tt>params</tt> argument. |
|
427 |
# |
|
428 |
# For example: |
|
429 |
# status = Twitter::Message.create( |
|
430 |
# :text => 'I am shopping for flip flops', |
|
431 |
# :recipient => 'anotherlogin', |
|
432 |
# :client => client) |
|
433 |
# |
|
434 |
# An <tt>ArgumentError</tt> will be raised if no valid client context |
|
435 |
# is given in the <tt>params</tt> Hash. For example, |
|
436 |
# status = Twitter::Status.create(:text => 'I am shopping for flip flops') |
|
437 |
# The above line of code will raise an <tt>ArgumentError</tt>. |
|
438 |
# |
|
439 |
# The same is true when you do not provide any of the following |
|
440 |
# key-value pairs in the <tt>params</tt> argument given: |
|
441 |
# * <tt>text</tt> - the String that will be the message text to send to <tt>user</tt> |
|
442 |
# * <tt>recipient</tt> - the user ID, screen_name or Twitter::User object representation of the recipient of the direct message |
|
443 |
# |
|
444 |
# The Twitter::Message object returned after the direct message is |
|
445 |
# successfully sent on the Twitter server side is returned from |
|
446 |
# this method. |
|
447 |
def create(params) |
1 |
448 |
client, text, recipient = params[:client], params[:text], params[:recipient] |
7 |
449 |
raise ArgumentError, 'Valid client context must be given' unless client.is_a?(Twitter::Client) |
7 |
450 |
raise ArgumentError, 'Message text must be supplied to send direct message' unless text.is_a?(String) |
3 |
451 |
raise ArgumentError, 'Recipient user must be specified to send direct message' unless [Twitter::User, Integer, String].member?(recipient.class) |
1 |
452 |
client.message(:post, text, recipient) |
1 |
453 |
end |
|
454 |
end |
|
455 |
|
|
456 |
protected |
1 |
457 |
# Constructor callback |
|
458 |
def init |
1 |
459 |
@sender = User.new(@sender) if @sender.is_a?(Hash) |
17 |
460 |
@recipient = User.new(@recipient) if @recipient.is_a?(Hash) |
17 |
461 |
@created_at = Time.parse(@created_at) if @created_at.is_a?(String) |
17 |
462 |
end |
|
463 |
end # Message |
|
464 |
|
|
465 |
# RateLimitStatus provides information about how many requests you have left |
|
466 |
# and when you can resume more requests if your remaining_hits count is zero. |
|
467 |
class RateLimitStatus |
1 |
468 |
include ModelMixin |
1 |
469 |
@@ATTRIBUTES = [:remaining_hits, :hourly_limit, :reset_time_in_seconds, :reset_time] |
1 |
470 |
attr_accessor(*@@ATTRIBUTES) |
1 |
471 |
|
|
472 |
class << self |
1 |
473 |
# Used as factory method callback |
|
474 |
def attributes; @@ATTRIBUTES; end |
1 |
475 |
end |
|
476 |
end |
|
477 |
end # Twitter |
|
./lib/twitter/version.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
# version.rb contains <tt>Twitter::Version</tt> that provides helper |
|
2 |
# methods related to versioning of the <tt>Twitter4R</tt> project. |
|
3 |
||
4 |
module Twitter::Version #:nodoc: |
1 |
5 |
MAJOR = 0 |
1 |
6 |
MINOR = 7 |
1 |
7 |
REVISION = 1 |
1 |
8 |
class << self |
1 |
9 |
# Returns X.Y.Z formatted version string |
|
10 |
def to_version |
1 |
11 |
"#{MAJOR}.#{MINOR}.#{REVISION}"
|
19 |
12 |
end |
|
13 |
|
|
14 |
# Returns X-Y-Z formatted version name |
|
15 |
def to_name |
1 |
16 |
"#{MAJOR}_#{MINOR}_#{REVISION}"
|
1 |
17 |
end |
|
18 |
end |
|
19 |
end |
|
./spec/twitter/client/account_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#account_info" do |
1 |
4 |
before(:each) do |
1 |
5 |
@uri = Twitter::Client.class_eval("@@ACCOUNT_URIS[:rate_limit_status]")
|
2 |
6 |
@request = mas_net_http_get |
2 |
7 |
@twitter = client_context |
2 |
8 |
@default_header = @twitter.send(:http_header) |
2 |
9 |
@response = mas_net_http_response(:success) |
2 |
10 |
@connection = mas_net_http(@response) |
2 |
11 |
@response.stub!(:body).and_return("{}")
|
2 |
12 |
@rate_limit_status = mock(Twitter::RateLimitStatus) |
2 |
13 |
@twitter.stub!(:bless_models).and_return({})
|
2 |
14 |
end |
|
15 |
||
16 |
it "should create expected HTTP GET request" do |
1 |
17 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uri).and_return(@response) |
1 |
18 |
@twitter.account_info |
1 |
19 |
end |
|
20 |
||
21 |
it "should raise Twitter::RESTError when 500 HTTP response received when giving page options" do |
1 |
22 |
@connection = mas_net_http(mas_net_http_response(:server_error)) |
1 |
23 |
lambda {
|
1 |
24 |
@twitter.account_info |
1 |
25 |
}.should raise_error(Twitter::RESTError) |
|
26 |
end |
|
27 |
end |
|
./spec/twitter/client/auth_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#authenticate?" do |
1 |
4 |
before(:each) do |
1 |
5 |
@uri = '/account/verify_credentials.json' |
3 |
6 |
@request = mas_net_http_get(:basic_auth => nil) |
3 |
7 |
@twitter = client_context |
3 |
8 |
@default_header = @twitter.send(:http_header) |
3 |
9 |
@response = mas_net_http_response(:success) |
3 |
10 |
@error_response = mas_net_http_response(404, "Resource Not Found") |
3 |
11 |
@connection = mas_net_http(@response) |
3 |
12 |
@access_key = "applestillsucks" |
3 |
13 |
@access_secret = "linuxstillrocks" |
3 |
14 |
end |
|
15 |
|
|
16 |
it "creates expected HTTP GET request" do |
1 |
17 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uri).and_return(@request) |
1 |
18 |
@twitter.authenticate?(@access_key, @access_secret) |
1 |
19 |
end |
|
20 |
|
|
21 |
it "should return true if HTTP response is 20X" do |
1 |
22 |
@twitter.authenticate?(@access_key, @access_secret).should be(true) |
1 |
23 |
end |
|
24 |
|
|
25 |
it "should return false if HTTP response is not 20X" do |
1 |
26 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uri).and_return(@error_response) |
1 |
27 |
@twitter.authenticate?(@access_key, @access_secret).should be(false) |
1 |
28 |
end |
|
29 |
|
|
30 |
after(:each) do |
1 |
31 |
nilize(@uri, @request, @twitter, @default_header, @response, @error_response, @connection, @access_key, @access_secret) |
3 |
32 |
end |
|
33 |
end |
|
./spec/twitter/client/base_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
shared_examples_for "consumer initialization with timeout" do |
1 |
4 |
before(:each) do |
2 |
5 |
@old_timeout = nil |
2 |
6 |
Twitter::Client.configure do |conf| |
2 |
7 |
@old_timeout = conf.timeout |
2 |
8 |
conf.timeout = @timeout |
2 |
9 |
end |
|
10 |
@client = client_context |
2 |
11 |
end |
|
12 |
||
13 |
it "should set timeout on underlying HTTP object" do |
2 |
14 |
consumer = get_consumer |
2 |
15 |
http = consumer.http |
2 |
16 |
http.read_timeout.should == timeout |
2 |
17 |
end |
|
18 |
||
19 |
after(:each) do |
2 |
20 |
Twitter::Client.configure do |conf| |
2 |
21 |
conf.timeout = @old_timeout |
2 |
22 |
end |
|
23 |
end |
|
24 |
end |
|
25 |
||
26 |
describe "Twitter::Client" do |
1 |
27 |
before(:each) do |
1 |
28 |
@init_hash = { :login => 'user', :password => 'pass' }
|
1 |
29 |
end |
|
30 |
||
31 |
it ".new should accept login and password as initializer hash keys and set the values to instance values" do |
1 |
32 |
client = nil |
1 |
33 |
lambda do |
1 |
34 |
client = Twitter::Client.new(@init_hash) |
1 |
35 |
end.should_not raise_error |
|
36 |
client.send(:login).should eql(@init_hash[:login]) |
1 |
37 |
end |
|
38 |
end |
|
39 |
||
40 |
describe Twitter::Client, "#inspect" do |
1 |
41 |
before(:each) do |
1 |
42 |
@client = Twitter::Client.new(:login => "NippleEquality", :password => "3rdnipple") |
1 |
43 |
end |
|
44 |
||
45 |
it "should block out password attribute values" do |
1 |
46 |
@client.inspect.should_not match(/@password="3rdnipple"/) |
1 |
47 |
end |
|
48 |
end |
|
49 |
||
50 |
describe Twitter::Client, "#http_header" do |
1 |
51 |
before(:each) do |
1 |
52 |
@user_agent = 'myapp' |
2 |
53 |
@application_name = @user_agent |
2 |
54 |
@application_version = '1.2.3' |
2 |
55 |
@application_url = 'http://myapp.url' |
2 |
56 |
Twitter::Client.configure do |conf| |
2 |
57 |
conf.user_agent = @user_agent |
2 |
58 |
conf.application_name = @application_name |
2 |
59 |
conf.application_version = @application_version |
2 |
60 |
conf.application_url = @application_url |
2 |
61 |
end |
|
62 |
@expected_headers = {
|
2 |
63 |
'Accept' => 'text/x-json', |
|
64 |
'X-Twitter-Client' => @application_name, |
|
65 |
'X-Twitter-Client-Version' => @application_version, |
|
66 |
'X-Twitter-Client-URL' => @application_url, |
|
67 |
'User-Agent' => "Twitter4R v#{Twitter::Version.to_version} [#{@user_agent}]",
|
|
68 |
} |
|
69 |
@twitter = client_context |
2 |
70 |
# reset @@http_header class variable in Twitter::Client class |
|
71 |
Twitter::Client.class_eval("@@http_header = nil")
|
2 |
72 |
end |
|
73 |
|
|
74 |
it "should always return expected HTTP headers" do |
1 |
75 |
headers = @twitter.send(:http_header) |
1 |
76 |
headers.should === @expected_headers |
1 |
77 |
end |
|
78 |
|
|
79 |
it "should cache HTTP headers Hash in class variable after first invocation" do |
1 |
80 |
cache = Twitter::Client.class_eval("@@http_header")
|
1 |
81 |
cache.should be_nil |
1 |
82 |
@twitter.send(:http_header) |
1 |
83 |
cache = Twitter::Client.class_eval("@@http_header")
|
1 |
84 |
cache.should_not be_nil |
1 |
85 |
cache.should === @expected_headers |
1 |
86 |
end |
|
87 |
|
|
88 |
after(:each) do |
1 |
89 |
nilize(@user_agent, @application_name, @application_version, @application_url, @twitter, @expected_headers) |
2 |
90 |
end |
|
91 |
end |
|
92 |
||
93 |
describe Twitter::Client, "#bless_model" do |
1 |
94 |
before(:each) do |
1 |
95 |
@twitter = client_context |
4 |
96 |
@model = Twitter::User.new |
4 |
97 |
end |
|
98 |
|
|
99 |
it "should recieve #client= message on given model to self" do |
1 |
100 |
@model.should_receive(:client=).with(@twitter) |
1 |
101 |
model = @twitter.send(:bless_model, @model) |
1 |
102 |
end |
|
103 |
|
|
104 |
it "should set client attribute on given model to self" do |
1 |
105 |
model = @twitter.send(:bless_model, @model) |
1 |
106 |
model.client.should eql(@twitter) |
1 |
107 |
end |
|
108 |
||
109 |
# if model is nil, it doesn't not necessarily signify an exceptional case for this method's usage. |
|
110 |
it "should return nil when receiving nil and not raise any exceptions" do |
1 |
111 |
model = @twitter.send(:bless_model, nil) |
1 |
112 |
model.should be_nil |
1 |
113 |
end |
|
114 |
|
|
115 |
# needed to alert developer that the model needs to respond to #client= messages appropriately. |
|
116 |
it "should raise an error if passing in a non-nil object that doesn't not respond to the :client= message" do |
1 |
117 |
lambda {
|
1 |
118 |
@twitter.send(:bless_model, Object.new) |
1 |
119 |
}.should raise_error(NoMethodError) |
|
120 |
end |
|
121 |
|
|
122 |
after(:each) do |
1 |
123 |
nilize(@twitter) |
4 |
124 |
end |
|
125 |
end |
|
126 |
||
127 |
describe Twitter::Client, "#bless_models" do |
1 |
128 |
before(:each) do |
1 |
129 |
@twitter = client_context |
4 |
130 |
@models = [ |
4 |
131 |
Twitter::Status.new(:text => 'message #1'), |
|
132 |
Twitter::Status.new(:text => 'message #2'), |
|
133 |
] |
|
134 |
end |
|
135 |
||
136 |
it "should set client attributes for each model in given Array to self" do |
1 |
137 |
models = @twitter.send(:bless_models, @models) |
1 |
138 |
models.each {|model| model.client.should eql(@twitter) }
|
3 |
139 |
end |
|
140 |
|
|
141 |
it "should set client attribute for singular model given to self" do |
1 |
142 |
model = @twitter.send(:bless_models, @models[0]) |
1 |
143 |
model.client.should eql(@twitter) |
1 |
144 |
end |
|
145 |
|
|
146 |
it "should delegate to bless_model for singular model case" do |
1 |
147 |
model = @models[0] |
1 |
148 |
@twitter.should_receive(:bless_model).with(model).and_return(model) |
1 |
149 |
@twitter.send(:bless_models, model) |
1 |
150 |
end |
|
151 |
|
|
152 |
it "should return nil when receiving nil and not raise any exceptions" do |
1 |
153 |
lambda {
|
1 |
154 |
value = @twitter.send(:bless_models, nil) |
1 |
155 |
value.should be_nil |
1 |
156 |
}.should_not raise_error |
|
157 |
end |
|
158 |
|
|
159 |
after(:each) do |
1 |
160 |
nilize(@twitter, @models) |
4 |
161 |
end |
|
162 |
end |
|
163 |
||
164 |
shared_examples_for "consumer token overrides" do |
1 |
165 |
before(:each) do |
2 |
166 |
@config_key = "234ufmewroi23o43SFsf" |
4 |
167 |
@config_secret = "kfgIYFOasdfsfg236GSka" |
4 |
168 |
@key_override = "#{@config_key}-1234"
|
4 |
169 |
@secret_override = "#{@config_secret}-1234"
|
4 |
170 |
Twitter::Client.configure do |conf| |
4 |
171 |
conf.oauth_consumer_token = @config_key |
4 |
172 |
conf.oauth_consumer_secret = @config_secret |
4 |
173 |
end |
|
174 |
@overridded_client = Twitter::Client.new(:oauth_consumer => { :key => @key_override, :secret => @secret_override })
|
4 |
175 |
@plain_client = Twitter::Client.new |
4 |
176 |
end |
|
177 |
||
178 |
it "should be set to key/secret pair passed into constructor when passed in and configuration object already has key/secret set" do |
2 |
179 |
consumer = get_consumer(@overridded_client) |
2 |
180 |
consumer.instance_eval("@key").should eql(@key_override)
|
2 |
181 |
consumer.instance_eval("@secret").should eql(@secret_override)
|
2 |
182 |
end |
|
183 |
||
184 |
it "should be set to key/secret pair set in configuration object when none passed into constructor" do |
2 |
185 |
consumer = get_consumer(@plain_client) |
2 |
186 |
consumer.instance_eval("@key").should eql(@config_key)
|
2 |
187 |
consumer.instance_eval("@secret").should eql(@config_secret)
|
2 |
188 |
end |
|
189 |
||
190 |
after(:each) do |
2 |
191 |
Twitter::Client.configure do |conf| |
4 |
192 |
conf.oauth_consumer_token = nil |
4 |
193 |
conf.oauth_consumer_secret = nil |
4 |
194 |
end |
|
195 |
end |
|
196 |
end |
|
197 |
||
198 |
describe Twitter::Client, "rest consumer token" do |
1 |
199 |
it_should_behave_like "consumer token overrides" |
1 |
200 |
||
201 |
def get_consumer(client) |
1 |
202 |
client.send(:rest_consumer) |
2 |
203 |
end |
|
204 |
end |
|
205 |
||
206 |
describe Twitter::Client, "search consumer token" do |
1 |
207 |
it_should_behave_like "consumer token overrides" |
1 |
208 |
||
209 |
def get_consumer(client) |
1 |
210 |
client.send(:search_consumer) |
2 |
211 |
end |
|
212 |
end |
|
213 |
||
214 |
describe Twitter::Client, "#construct_proxy_url" do |
1 |
215 |
before(:each) do |
1 |
216 |
@host = "localhost" |
3 |
217 |
@port = "8080" |
3 |
218 |
@user = "user" |
3 |
219 |
@pass = "pass123" |
3 |
220 |
@client = client_context |
3 |
221 |
end |
|
222 |
||
223 |
def configure_host_and_port |
1 |
224 |
Twitter::Client.configure do |conf| |
2 |
225 |
conf.proxy_host = @host |
2 |
226 |
conf.proxy_port = @port |
2 |
227 |
end |
|
228 |
end |
|
229 |
||
230 |
def configure_user_and_password |
1 |
231 |
Twitter::Client.configure do |conf| |
1 |
232 |
conf.proxy_user = @user |
1 |
233 |
conf.proxy_pass = @pass |
1 |
234 |
end |
|
235 |
end |
|
236 |
||
237 |
it "should return the full proxy URL when proxy host and port given" do |
1 |
238 |
configure_host_and_port |
1 |
239 |
url = "http://#{@host}:#{@port}"
|
1 |
240 |
@client.send(:construct_proxy_url).should eql(url) |
1 |
241 |
end |
|
242 |
||
243 |
it "should return the full proxy URL when proxy host, port, username and password given" do |
1 |
244 |
configure_host_and_port |
1 |
245 |
configure_user_and_password |
1 |
246 |
url = "http://#{@user}:#{@pass}@#{@host}:#{@port}"
|
1 |
247 |
@client.send(:construct_proxy_url).should eql(url) |
1 |
248 |
end |
|
249 |
||
250 |
it "should return nil when no proxy host is given" do |
1 |
251 |
@client.send(:construct_proxy_url).should eql(nil) |
1 |
252 |
end |
|
253 |
||
254 |
after(:each) do |
1 |
255 |
Twitter::Client.configure do |conf| |
3 |
256 |
conf.proxy_user = nil |
3 |
257 |
conf.proxy_pass = nil |
3 |
258 |
conf.proxy_host = nil |
3 |
259 |
conf.proxy_port = nil |
3 |
260 |
end |
|
261 |
end |
|
262 |
end |
|
263 |
||
264 |
describe Twitter::Client, "#rest_consumer" do |
1 |
265 |
it_should_behave_like "consumer initialization with timeout" |
1 |
266 |
before(:each) do |
1 |
267 |
@timeout = 49 |
1 |
268 |
end |
|
269 |
||
270 |
def timeout |
1 |
271 |
@timeout |
1 |
272 |
end |
|
273 |
||
274 |
def get_consumer |
1 |
275 |
@client.send(:rest_consumer) |
1 |
276 |
end |
|
277 |
end |
|
278 |
||
279 |
describe Twitter::Client, "#search_consumer" do |
1 |
280 |
it_should_behave_like "consumer initialization with timeout" |
1 |
281 |
before(:each) do |
1 |
282 |
@timeout = 96 |
1 |
283 |
end |
|
284 |
||
285 |
def timeout |
1 |
286 |
@timeout |
1 |
287 |
end |
|
288 |
||
289 |
def get_consumer |
1 |
290 |
@client.send(:search_consumer) |
1 |
291 |
end |
|
292 |
end |
|
./spec/twitter/client/blocks_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#block" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
9 |
6 |
@id = 1234567 |
9 |
7 |
@screen_name = 'dummylogin' |
9 |
8 |
@friend = Twitter::User.new(:id => @id, :screen_name => @screen_name) |
9 |
9 |
@uris = Twitter::Client.class_eval("@@BLOCK_URIS")
|
9 |
10 |
@request = mas_net_http_get(:basic_auth => nil) |
9 |
11 |
@response = mas_net_http_response(:success) |
9 |
12 |
@connection = mas_net_http(@response) |
9 |
13 |
Twitter::User.stub!(:unmarshal).and_return(@friend) |
9 |
14 |
end |
|
15 |
|
|
16 |
def create_uri(action, id) |
1 |
17 |
"#{@uris[action]}/#{id}.json"
|
6 |
18 |
end |
|
19 |
|
|
20 |
it "should create expected HTTP GET request for :add case using integer user ID" do |
1 |
21 |
# the integer user ID scenario... |
|
22 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:add, @id)).and_return(@response) |
1 |
23 |
@twitter.block(:add, @id) |
1 |
24 |
end |
|
25 |
|
|
26 |
it "should create expected HTTP GET request for :add case using screen name" do |
1 |
27 |
# the screen name scenario... |
|
28 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:add, @screen_name)).and_return(@response) |
1 |
29 |
@twitter.block(:add, @screen_name) |
1 |
30 |
end |
|
31 |
||
32 |
it "should create expected HTTP GET request for :add case using Twitter::User object" do |
1 |
33 |
# the Twitter::User object scenario... |
|
34 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:add, @friend.to_i)).and_return(@response) |
1 |
35 |
@twitter.block(:add, @friend) |
1 |
36 |
end |
|
37 |
|
|
38 |
it "should create expected HTTP GET request for :remove case using integer user ID" do |
1 |
39 |
# the integer user ID scenario... |
|
40 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:remove, @id)).and_return(@response) |
1 |
41 |
@twitter.block(:remove, @id) |
1 |
42 |
end |
|
43 |
||
44 |
it "should create expected HTTP GET request for :remove case using screen name" do |
1 |
45 |
# the screen name scenario... |
|
46 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:remove, @screen_name)).and_return(@response) |
1 |
47 |
@twitter.block(:remove, @screen_name) |
1 |
48 |
end |
|
49 |
||
50 |
it "should create expected HTTP GET request for :remove case using Twitter::User object" do |
1 |
51 |
# the Twitter::User object scenario... |
|
52 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:remove, @friend.to_i)).and_return(@response) |
1 |
53 |
@twitter.block(:remove, @friend) |
1 |
54 |
end |
|
55 |
|
|
56 |
it "should bless user model returned for :add case" do |
1 |
57 |
@twitter.should_receive(:bless_model).with(@friend) |
1 |
58 |
@twitter.block(:add, @friend) |
1 |
59 |
end |
|
60 |
|
|
61 |
it "should bless user model returned for :remove case" do |
1 |
62 |
@twitter.should_receive(:bless_model).with(@friend) |
1 |
63 |
@twitter.block(:remove, @friend) |
1 |
64 |
end |
|
65 |
|
|
66 |
it "should raise ArgumentError if action given is not valid" do |
1 |
67 |
lambda {
|
1 |
68 |
@twitter.block(:crap, @friend) |
1 |
69 |
}.should raise_error(ArgumentError) |
|
70 |
end |
|
71 |
|
|
72 |
after(:each) do |
1 |
73 |
nilize(@twitter, @id, @uris, @request, @response, @connection) |
9 |
74 |
end |
|
75 |
end |
|
./spec/twitter/client/favorites_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#favorites" do |
1 |
4 |
before(:each) do |
1 |
5 |
@uri = '/favorites.json' |
8 |
6 |
@request = mas_net_http_get(:basic_auth => nil) |
8 |
7 |
@twitter = client_context |
8 |
8 |
@default_header = @twitter.send(:http_header) |
8 |
9 |
@response = mas_net_http_response(:success) |
8 |
10 |
@connection = mas_net_http(@response) |
8 |
11 |
@options = { :page => 4 }
|
8 |
12 |
@favorites = [] |
8 |
13 |
Twitter::Status.stub!(:unmarshal).and_return(@favorites) |
8 |
14 |
end |
|
15 |
|
|
16 |
it "should create expected HTTP GET request when not giving options" do |
1 |
17 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uri, nil).and_return(@response) |
1 |
18 |
@twitter.favorites |
1 |
19 |
end |
|
20 |
|
|
21 |
it "should create expected HTTP GET request when giving :page options" do |
1 |
22 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uri, @options).and_return(@response) |
1 |
23 |
@twitter.favorites(@options) |
1 |
24 |
end |
|
25 |
|
|
26 |
it "should raise Twitter::RESTError when 401 HTTP response received without giving options" do |
1 |
27 |
@connection = mas_net_http(mas_net_http_response(:not_authorized)) |
1 |
28 |
lambda {
|
1 |
29 |
@twitter.favorites |
1 |
30 |
}.should raise_error(Twitter::RESTError) |
|
31 |
end |
|
32 |
|
|
33 |
it "should raise Twitter::RESTError when 401 HTTP response received when giving page options" do |
1 |
34 |
@connection = mas_net_http(mas_net_http_response(:not_authorized)) |
1 |
35 |
lambda {
|
1 |
36 |
@twitter.favorites(@options) |
1 |
37 |
}.should raise_error(Twitter::RESTError) |
|
38 |
end |
|
39 |
|
|
40 |
it "should raise Twitter::RESTError when 403 HTTP response received without giving options" do |
1 |
41 |
@connection = mas_net_http(mas_net_http_response(:forbidden)) |
1 |
42 |
lambda {
|
1 |
43 |
@twitter.favorites |
1 |
44 |
}.should raise_error(Twitter::RESTError) |
|
45 |
end |
|
46 |
|
|
47 |
it "should raise Twitter::RESTError when 403 HTTP response received when giving page options" do |
1 |
48 |
@connection = mas_net_http(mas_net_http_response(:forbidden)) |
1 |
49 |
lambda {
|
1 |
50 |
@twitter.favorites(@options) |
1 |
51 |
}.should raise_error(Twitter::RESTError) |
|
52 |
end |
|
53 |
|
|
54 |
it "should raise Twitter::RESTError when 500 HTTP response received without giving options" do |
1 |
55 |
@connection = mas_net_http(mas_net_http_response(:server_error)) |
1 |
56 |
lambda {
|
1 |
57 |
@twitter.favorites |
1 |
58 |
}.should raise_error(Twitter::RESTError) |
|
59 |
end |
|
60 |
|
|
61 |
it "should raise Twitter::RESTError when 500 HTTP response received when giving page options" do |
1 |
62 |
@connection = mas_net_http(mas_net_http_response(:server_error)) |
1 |
63 |
lambda {
|
1 |
64 |
@twitter.favorites(@options) |
1 |
65 |
}.should raise_error(Twitter::RESTError) |
|
66 |
end |
|
67 |
|
|
68 |
after(:each) do |
1 |
69 |
nilize(@uri, @request, @twitter, @default_header, @response, @error_response, @connection) |
8 |
70 |
end |
|
71 |
end |
|
72 |
||
73 |
module FavoriteSpecMixin |
1 |
74 |
def init |
1 |
75 |
@base_uri = '/favourings' |
12 |
76 |
@request = mas_net_http_get(:basic_auth => nil) |
12 |
77 |
@twitter = client_context |
12 |
78 |
@default_header = @twitter.send(:http_header) |
12 |
79 |
@response = mas_net_http_response(:success) |
12 |
80 |
@connection = mas_net_http(@response) |
12 |
81 |
@id = 234923423 |
12 |
82 |
@status = mas_twitter_status(:id => @id, :to_i => @id) |
12 |
83 |
Twitter::Status.stub!(:unmarshal).and_return(@status) |
12 |
84 |
end |
|
85 |
|
|
86 |
def create_uri(method, id) |
1 |
87 |
"#{@base_uri}/#{method.to_s}/#{id.to_i.to_s}.json"
|
4 |
88 |
end |
|
89 |
|
|
90 |
def finalize |
1 |
91 |
nilize(@uri, @request, @twitter, @default_header, @response, @error_response, @connection) |
12 |
92 |
end |
|
93 |
end |
|
94 |
||
95 |
shared_examples_for "Twitter::Client#favorite error handling" do |
1 |
96 |
it "should raise a Twitter::RESTError exception when a 401 HTTP response is received" do |
2 |
97 |
connection = mas_net_http(mas_net_http_response(:not_authorized)) |
2 |
98 |
lambda {
|
2 |
99 |
execute_method |
2 |
100 |
}.should raise_error(Twitter::RESTError) |
|
101 |
end |
|
102 |
||
103 |
it "should raise a Twitter::RESTError exception when a 403 HTTP response is received" do |
2 |
104 |
connection = mas_net_http(mas_net_http_response(:forbidden)) |
2 |
105 |
lambda {
|
2 |
106 |
execute_method |
2 |
107 |
}.should raise_error(Twitter::RESTError) |
|
108 |
end |
|
109 |
||
110 |
it "should raise a Twitter::RESTError exception when a 404 HTTP response is received" do |
2 |
111 |
connection = mas_net_http(mas_net_http_response(:file_not_found)) |
2 |
112 |
lambda {
|
2 |
113 |
execute_method |
2 |
114 |
}.should raise_error(Twitter::RESTError) |
|
115 |
end |
|
116 |
||
117 |
it "should raise a Twitter::RESTError exception when a 500 HTTP response is received" do |
2 |
118 |
connection = mas_net_http(mas_net_http_response(:server_error)) |
2 |
119 |
lambda {
|
2 |
120 |
execute_method |
2 |
121 |
}.should raise_error(Twitter::RESTError) |
|
122 |
end |
|
123 |
end |
|
124 |
||
125 |
describe Twitter::Client, "#favorite(:add, status)" do |
1 |
126 |
include FavoriteSpecMixin |
1 |
127 |
it_should_behave_like "Twitter::Client#favorite error handling" |
1 |
128 |
|
|
129 |
before(:each) do |
1 |
130 |
init |
6 |
131 |
end |
|
132 |
|
|
133 |
def execute_method |
1 |
134 |
@twitter.favorite(:add, @id) |
4 |
135 |
end |
|
136 |
|
|
137 |
it "should create expected POST request for :add action supplying integer id of status" do |
1 |
138 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:create, @id)).and_return(@request) |
1 |
139 |
@twitter.favorite(:add, @id) |
1 |
140 |
end |
|
141 |
|
|
142 |
it "should create expected POST request for :add action supplying status object" do |
1 |
143 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:create, @id)).and_return(@request) |
1 |
144 |
@twitter.favorite(:add, @status) |
1 |
145 |
end |
|
146 |
|
|
147 |
after(:each) do |
1 |
148 |
finalize |
6 |
149 |
end |
|
150 |
end |
|
151 |
||
152 |
describe Twitter::Client, "#favorite(:remove, status)" do |
1 |
153 |
include FavoriteSpecMixin |
1 |
154 |
it_should_behave_like "Twitter::Client#favorite error handling" |
1 |
155 |
||
156 |
before(:each) do |
1 |
157 |
init |
6 |
158 |
end |
|
159 |
|
|
160 |
def execute_method |
1 |
161 |
@twitter.favorite(:remove, @id) |
5 |
162 |
end |
|
163 |
|
|
164 |
it "should create expected DELETE request for :remove action supplying integer id of status" do |
1 |
165 |
@twitter.should_receive(:rest_oauth_connect).with(:delete, create_uri(:destroy, @id)).and_return(@request) |
1 |
166 |
execute_method |
1 |
167 |
end |
|
168 |
|
|
169 |
it "should create expected DELETE request for :remove action supplying status object" do |
1 |
170 |
@twitter.should_receive(:rest_oauth_connect).with(:delete, create_uri(:destroy, @id)).and_return(@request) |
1 |
171 |
@twitter.favorite(:remove, @status) |
1 |
172 |
end |
|
173 |
|
|
174 |
after(:each) do |
1 |
175 |
finalize |
6 |
176 |
end |
|
177 |
end |
|
./spec/twitter/client/friendship_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#friendships" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
2 |
6 |
@uris = Twitter::Client.class_eval("@@FRIENDSHIP_URIS")
|
2 |
7 |
@response = mas_net_http_response(:success) |
2 |
8 |
@connection = mas_net_http(@response) |
2 |
9 |
@result = { :id_list => { :ids => [] } }
|
2 |
10 |
JSON.stub!(:parse).and_return(@result) |
2 |
11 |
end |
|
12 |
||
13 |
it "should create expected HTTP GET request for :incoming case" do |
1 |
14 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:incoming]).and_return(@response) |
1 |
15 |
@twitter.friendships(:incoming) |
1 |
16 |
end |
|
17 |
||
18 |
it "should create expected HTTP GET request for :outgoing case" do |
1 |
19 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:outgoing]).and_return(@response) |
1 |
20 |
@twitter.friendships(:outgoing) |
1 |
21 |
end |
|
22 |
end |
|
23 |
||
24 |
describe Twitter::Client, "#friend" do |
1 |
25 |
before(:each) do |
1 |
26 |
@twitter = client_context |
9 |
27 |
@id = 1234567 |
9 |
28 |
@screen_name = 'dummylogin' |
9 |
29 |
@friend = Twitter::User.new(:id => @id, :screen_name => @screen_name) |
9 |
30 |
@uris = Twitter::Client.class_eval("@@FRIEND_URIS")
|
9 |
31 |
@response = mas_net_http_response(:success) |
9 |
32 |
@connection = mas_net_http(@response) |
9 |
33 |
Twitter::User.stub!(:unmarshal).and_return(@friend) |
9 |
34 |
end |
|
35 |
||
36 |
def create_uri(action, id) |
1 |
37 |
"#{@uris[action]}/#{id}.json"
|
6 |
38 |
end |
|
39 |
||
40 |
it "should create expected HTTP POST request for :add case using integer user ID" do |
1 |
41 |
# the integer user ID scenario... |
|
42 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:add, @id)).and_return(@response) |
1 |
43 |
@twitter.friend(:add, @id) |
1 |
44 |
end |
|
45 |
||
46 |
it "should create expected HTTP POST request for :add case using screen name" do |
1 |
47 |
# the screen name scenario... |
|
48 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:add, @screen_name)).and_return(@response) |
1 |
49 |
@twitter.friend(:add, @screen_name) |
1 |
50 |
end |
|
51 |
||
52 |
it "should create expected HTTP GET request for :add case using Twitter::User object" do |
1 |
53 |
# the Twitter::User object scenario... |
|
54 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:add, @friend.to_i)).and_return(@response) |
1 |
55 |
@twitter.friend(:add, @friend) |
1 |
56 |
end |
|
57 |
||
58 |
it "should create expected HTTP GET request for :remove case using integer user ID" do |
1 |
59 |
# the integer user ID scenario... |
|
60 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:remove, @id)).and_return(@response) |
1 |
61 |
@twitter.friend(:remove, @id) |
1 |
62 |
end |
|
63 |
||
64 |
it "should create expected HTTP GET request for :remove case using screen name" do |
1 |
65 |
# the screen name scenario... |
|
66 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:remove, @screen_name)).and_return(@response) |
1 |
67 |
@twitter.friend(:remove, @screen_name) |
1 |
68 |
end |
|
69 |
||
70 |
it "should create expected HTTP GET request for :remove case using Twitter::User object" do |
1 |
71 |
# the Twitter::User object scenario... |
|
72 |
@twitter.should_receive(:rest_oauth_connect).with(:post, create_uri(:remove, @friend.to_i)).and_return(@response) |
1 |
73 |
@twitter.friend(:remove, @friend) |
1 |
74 |
end |
|
75 |
||
76 |
it "should bless user model returned for :add case" do |
1 |
77 |
@twitter.should_receive(:bless_model).with(@friend) |
1 |
78 |
@twitter.friend(:add, @friend) |
1 |
79 |
end |
|
80 |
||
81 |
it "should bless user model returned for :remove case" do |
1 |
82 |
@twitter.should_receive(:bless_model).with(@friend) |
1 |
83 |
@twitter.friend(:remove, @friend) |
1 |
84 |
end |
|
85 |
||
86 |
it "should raise ArgumentError if action given is not valid" do |
1 |
87 |
lambda {
|
1 |
88 |
@twitter.friend(:crap, @friend) |
1 |
89 |
}.should raise_error(ArgumentError) |
|
90 |
end |
|
91 |
||
92 |
after(:each) do |
1 |
93 |
nilize(@twitter, @id, @uris, @response, @connection) |
9 |
94 |
end |
|
95 |
end |
|
./spec/twitter/client/graph_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#graph(:friends...)" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
7 |
6 |
@id = 1234567 |
7 |
7 |
@screen_name = 'dummylogin' |
7 |
8 |
@friend = Twitter::User.new(:id => @id, :screen_name => @screen_name) |
7 |
9 |
@uris = Twitter::Client.class_eval("@@GRAPH_URIS")
|
7 |
10 |
@request = mas_net_http_get(:basic_auth => nil) |
7 |
11 |
@response = mas_net_http_response(:success) |
7 |
12 |
@response.stub!(:body).and_return("[1, 2, 3, 4, 5, 6]")
|
7 |
13 |
@connection = mas_net_http(@response) |
7 |
14 |
Twitter::User.stub!(:unmarshal).and_return(@friend) |
7 |
15 |
end |
|
16 |
|
|
17 |
def create_uri(action) |
1 |
18 |
"#{@uris[action]}.json"
|
6 |
19 |
end |
|
20 |
|
|
21 |
it "should create expected HTTP GET request for :friends case using integer user ID" do |
1 |
22 |
# the integer user ID scenario... |
|
23 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:friends), :id => @id).and_return(@response) |
1 |
24 |
@twitter.graph(:friends, @id) |
1 |
25 |
end |
|
26 |
|
|
27 |
it "should create expected HTTP GET request for :friends case using screen name" do |
1 |
28 |
# the screen name scenario... |
|
29 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:friends), :id => @screen_name).and_return(@response) |
1 |
30 |
@twitter.graph(:friends, @screen_name) |
1 |
31 |
end |
|
32 |
||
33 |
it "should create expected HTTP GET request for :friends case using Twitter::User object" do |
1 |
34 |
# the Twitter::User object scenario... |
|
35 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:friends), :id => @friend.to_i).and_return(@response) |
1 |
36 |
@twitter.graph(:friends, @friend) |
1 |
37 |
end |
|
38 |
|
|
39 |
it "should create expected HTTP GET request for :followers case using integer user ID" do |
1 |
40 |
# the integer user ID scenario... |
|
41 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:followers), :id => @id).and_return(@response) |
1 |
42 |
@twitter.graph(:followers, @id) |
1 |
43 |
end |
|
44 |
||
45 |
it "should create expected HTTP GET request for :followers case using screen name" do |
1 |
46 |
# the screen name scenario... |
|
47 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:followers), :id => @screen_name).and_return(@response) |
1 |
48 |
@twitter.graph(:followers, @screen_name) |
1 |
49 |
end |
|
50 |
||
51 |
it "should create expected HTTP GET request for :followers case using Twitter::User object" do |
1 |
52 |
# the Twitter::User object scenario... |
|
53 |
@twitter.should_receive(:rest_oauth_connect).with(:get, create_uri(:followers), :id => @friend.to_i).and_return(@response) |
1 |
54 |
@twitter.graph(:followers, @friend) |
1 |
55 |
end |
|
56 |
|
|
57 |
it "should raise ArgumentError if action given is not valid" do |
1 |
58 |
lambda {
|
1 |
59 |
@twitter.graph(:crap, @friend) |
1 |
60 |
}.should raise_error(ArgumentError) |
|
61 |
end |
|
62 |
|
|
63 |
after(:each) do |
1 |
64 |
nilize(@twitter, @id, @uris, @request, @response, @connection) |
7 |
65 |
end |
|
66 |
end |
|
./spec/twitter/client/messaging_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#messages" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
8 |
6 |
@uris = Twitter::Client.class_eval("@@MESSAGING_URIS")
|
8 |
7 |
@request = mas_net_http_get(:basic_auth => nil) |
8 |
8 |
@response = mas_net_http_response(:success, "[]") |
8 |
9 |
@connection = mas_net_http(@response) |
8 |
10 |
@messages = [] |
8 |
11 |
Twitter::Message.stub!(:unmarshal).and_return(@messages) |
8 |
12 |
@page = 2 |
8 |
13 |
end |
|
14 |
|
|
15 |
it "should create expected HTTP GET request for :received case" do |
1 |
16 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:received], {}).and_return(@request)
|
1 |
17 |
@twitter.messages(:received) |
1 |
18 |
end |
|
19 |
|
|
20 |
it "should bless the Array returned from Twitter for :received case" do |
1 |
21 |
@twitter.should_receive(:bless_models).with(@messages).and_return(@messages) |
1 |
22 |
@twitter.messages(:received) |
1 |
23 |
end |
|
24 |
|
|
25 |
it "should create expected HTTP GET request for :sent case" do |
1 |
26 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:sent], {}).and_return(@request)
|
1 |
27 |
@twitter.messages(:sent) |
1 |
28 |
end |
|
29 |
|
|
30 |
it "should bless the Array returned from Twitter for :sent case" do |
1 |
31 |
@twitter.should_receive(:bless_models).with(@messages).and_return(@messages) |
1 |
32 |
@twitter.messages(:sent) |
1 |
33 |
end |
|
34 |
|
|
35 |
it "should raise an ArgumentError when giving an invalid messaging action" do |
1 |
36 |
lambda {
|
1 |
37 |
@twitter.messages(:crap) |
1 |
38 |
}.should raise_error(ArgumentError) |
|
39 |
end |
|
40 |
||
41 |
it "should accept an options Hash for paging" do |
1 |
42 |
lambda {
|
1 |
43 |
@twitter.messages(:sent, :page => @page) |
1 |
44 |
}.should_not raise_error(Exception) |
|
45 |
end |
|
46 |
||
47 |
it "should generate expected GET HTTP request for paging case" do |
1 |
48 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:received], {:page => @page}).and_return(@request)
|
1 |
49 |
@twitter.messages(:received, :page => @page) |
1 |
50 |
end |
|
51 |
||
52 |
it "should bless models for paging case" do |
1 |
53 |
@twitter.should_receive(:bless_models).with(@messages).and_return(@messages) |
1 |
54 |
@twitter.messages(:sent, :page => @page) |
1 |
55 |
end |
|
56 |
|
|
57 |
after(:each) do |
1 |
58 |
nilize(@twitter, @uris, @request, @response, @connection, @messages) |
8 |
59 |
end |
|
60 |
end |
|
61 |
||
62 |
describe Twitter::Client, "#message" do |
1 |
63 |
before(:each) do |
1 |
64 |
@twitter = client_context |
9 |
65 |
@attributes = {
|
9 |
66 |
:id => 34324, |
|
67 |
:text => 'Randy, are you coming over later?', |
|
68 |
:sender => {:id => 123, :screen_name => 'mylogin'},
|
|
69 |
:recipient => {:id => 1234, :screen_name => 'randy'},
|
|
70 |
} |
|
71 |
@message = Twitter::Message.new(@attributes) |
9 |
72 |
@uris = Twitter::Client.class_eval("@@MESSAGING_URIS")
|
9 |
73 |
@request = mas_net_http_get(:basic_auth => nil) |
9 |
74 |
@json = JSON.unparse(@attributes) |
9 |
75 |
@response = mas_net_http_response(:success, @json) |
9 |
76 |
@connection = mas_net_http(@response) |
9 |
77 |
@source = Twitter::Client.class_eval("@@defaults[:source]")
|
9 |
78 |
||
79 |
Twitter::Message.stub!(:unmarshal).and_return(@message) |
9 |
80 |
end |
|
81 |
|
|
82 |
it "should invoke #http_connect with expected arguments for :post case" do |
1 |
83 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:post], {:text => @message.text, :user => @message.recipient.to_i, :source => @source}).and_return(@response)
|
1 |
84 |
@twitter.message(:post, @message.text, @message.recipient) |
1 |
85 |
end |
|
86 |
|
|
87 |
it "should create expected HTTP POST request for :post case" do |
1 |
88 |
params = {:source => @source, :user => @attributes[:recipient][:id], :text => @attributes[:text]}
|
1 |
89 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:post], params).and_return(@request) |
1 |
90 |
@twitter.message(:post, @message.text, @message.recipient) |
1 |
91 |
end |
|
92 |
|
|
93 |
it "should bless returned Twitter::Message object for :post case" do |
1 |
94 |
@twitter.should_receive(:bless_model).with(@message) |
1 |
95 |
@twitter.message(:post, @message.text, @message.recipient) |
1 |
96 |
end |
|
97 |
|
|
98 |
it "should create expected HTTP DELETE request for :delete case" do |
1 |
99 |
@twitter.should_receive(:rest_oauth_connect).with(:delete, @uris[:delete], :id => @message.to_i).and_return(@request) |
1 |
100 |
@twitter.message(:delete, @message) |
1 |
101 |
end |
|
102 |
|
|
103 |
it "should bless returned Twitter::Message object for :delete case" do |
1 |
104 |
@twitter.should_receive(:bless_model).with(@message) |
1 |
105 |
@twitter.message(:delete, @message) |
1 |
106 |
end |
|
107 |
|
|
108 |
it "should invoke #to_i on message object passed in for :delete case" do |
1 |
109 |
@message.should_receive(:to_i).and_return(@message.id) |
1 |
110 |
@twitter.message(:delete, @message) |
1 |
111 |
end |
|
112 |
|
|
113 |
it "should raise an ArgumentError when giving an invalid messaging action" do |
1 |
114 |
lambda {
|
1 |
115 |
@twitter.message(:crap, @message) |
1 |
116 |
}.should raise_error(ArgumentError) |
|
117 |
end |
|
118 |
|
|
119 |
it "should raise an ArgumentError for :post case if user argument is not supplied" do |
1 |
120 |
lambda {
|
1 |
121 |
@twitter.message(:post, @message) |
1 |
122 |
}.should raise_error(ArgumentError) |
|
123 |
end |
|
124 |
|
|
125 |
it "should raise an ArgumentError for :post case if user argument is nil" do |
1 |
126 |
lambda {
|
1 |
127 |
@twitter.message(:post, @message, nil) |
1 |
128 |
}.should raise_error(ArgumentError) |
|
129 |
end |
|
130 |
||
131 |
after(:each) do |
1 |
132 |
nilize(@twitter, @uris, @request, @response, @connection, @sender, @recipient, @message, @attributes) |
9 |
133 |
end |
|
134 |
end |
|
./spec/twitter/client/profile_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#profile" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
6 |
6 |
@user_attrs = {
|
6 |
7 |
:id => "JaneEyre", |
|
8 |
:login => "Jane Eyre", |
|
9 |
:url => "http://janeeyrerocks.co.uk", |
|
10 |
:location => "Thornfield Manor", |
|
11 |
} |
|
12 |
# name, email, url, location, description |
|
13 |
@info_attrs = {
|
6 |
14 |
:name => "Jane Eyre", |
|
15 |
:email => "jane.eyre@gmail.co.uk", |
|
16 |
:url => "http://janeeyrerocks.co.uk", |
|
17 |
:location => "Thornfield Manor", |
|
18 |
:description => "Governess who falls for slave-trade aristocrat with French lovechild he doesn't acknowledge & wife locked in damp attic with keeper.", |
|
19 |
} |
|
20 |
# background_color, text_color, link_color, sidebar_fill_color, sidebar_border_color |
|
21 |
@colors_attrs = {
|
6 |
22 |
:background_color => "#ffffff", |
|
23 |
:text_color => "#101010", |
|
24 |
:link_color => "#990000", |
|
25 |
} |
|
26 |
# value |
|
27 |
@device_attrs = {
|
6 |
28 |
:value => "sms", |
|
29 |
} |
|
30 |
@user = Twitter::User.new |
6 |
31 |
@uris = Twitter::Client.class_eval("@@PROFILE_URIS")
|
6 |
32 |
@request = mas_net_http_get(:basic_auth => nil) |
6 |
33 |
@json = JSON.unparse(@user_attrs) |
6 |
34 |
@response = mas_net_http_response(:success, @json) |
6 |
35 |
@connection = mas_net_http(@response) |
6 |
36 |
||
37 |
Twitter::User.stub!(:unmarshal).and_return(@user) |
6 |
38 |
end |
|
39 |
|
|
40 |
it "should invoke #rest_oauth_connect with expected arguments for :info case" do |
1 |
41 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:info], @info_attrs).and_return(@response) |
1 |
42 |
@twitter.profile(:info, @info_attrs) |
1 |
43 |
end |
|
44 |
||
45 |
it "should invoke #rest_oauth_connect with expected arguments for :colors case" do |
1 |
46 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:colors], @colors_attrs).and_return(@response) |
1 |
47 |
@twitter.profile(:colors, @colors_attrs) |
1 |
48 |
end |
|
49 |
|
|
50 |
it "should invoke #rest_oauth_connect with expected arguments for :device case" do |
1 |
51 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:device], @device_attrs).and_return(@response) |
1 |
52 |
@twitter.profile(:device, @device_attrs) |
1 |
53 |
end |
|
54 |
|
|
55 |
it "should bless returned Twitter::User object for :info case" do |
1 |
56 |
@twitter.should_receive(:bless_model).with(@user) |
1 |
57 |
@twitter.profile(:info, @info_attrs) |
1 |
58 |
end |
|
59 |
||
60 |
it "should bless returned Twitter::User object for :colors case" do |
1 |
61 |
@twitter.should_receive(:bless_model).with(@user) |
1 |
62 |
@twitter.profile(:colors, @colors_attrs) |
1 |
63 |
end |
|
64 |
||
65 |
it "should bless returned Twitter::User object for :device case" do |
1 |
66 |
@twitter.should_receive(:bless_model).with(@user) |
1 |
67 |
@twitter.profile(:device, @device_attrs) |
1 |
68 |
end |
|
69 |
|
|
70 |
after(:each) do |
1 |
71 |
nilize(@twitter, @uris, @request, @response, @connection, @sender, @recipient, @user, @attributes) |
6 |
72 |
end |
|
73 |
end |
|
./spec/twitter/client/search_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#search" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
9 |
6 |
@uris = Twitter::Client.class_eval("@@SEARCH_URIS")
|
9 |
7 |
@request = mas_net_http_get(:basic_auth => nil) |
9 |
8 |
@response = mas_net_http_response(:success, "{\"results\": [], \"refresh_url\":\"?since_id=1768746401&q=blabla\"}")
|
9 |
9 |
@connection = mas_net_http(@response) |
9 |
10 |
@statuses = [] |
9 |
11 |
Twitter::Status.stub!(:unmarshal).and_return(@statuses) |
9 |
12 |
@page = 2 |
9 |
13 |
@keywords = "twitter4r" |
9 |
14 |
@to = "SusanPotter" |
9 |
15 |
@from = "twitter4r" |
9 |
16 |
end |
|
17 |
|
|
18 |
it "should create expected HTTP GET request using :to" do |
1 |
19 |
@twitter.should_receive(:search_oauth_connect).with(:get, @uris[:basic], {:to => @to}).and_return(@response)
|
1 |
20 |
@twitter.search(:to => @to) |
1 |
21 |
end |
|
22 |
|
|
23 |
it "should bless the Array returned from Twitter for :to case" do |
1 |
24 |
@twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses) |
1 |
25 |
@twitter.search(:to => @to) |
1 |
26 |
end |
|
27 |
|
|
28 |
it "should create expected HTTP GET request using :from" do |
1 |
29 |
@twitter.should_receive(:search_oauth_connect).with(:get, @uris[:basic], {:from => @from}).and_return(@response)
|
1 |
30 |
@twitter.search(:from => @from) |
1 |
31 |
end |
|
32 |
|
|
33 |
it "should bless the Array returned from Twitter for :to case" do |
1 |
34 |
@twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses) |
1 |
35 |
@twitter.search(:from => @from) |
1 |
36 |
end |
|
37 |
|
|
38 |
it "should create expected HTTP GET request using :keywords" do |
1 |
39 |
@twitter.should_receive(:search_oauth_connect).with(:get, @uris[:basic], {:keywords => @keywords}).and_return(@response)
|
1 |
40 |
@twitter.search(:keywords => @keywords) |
1 |
41 |
end |
|
42 |
|
|
43 |
it "should bless the Array returned from Twitter for :keywords case" do |
1 |
44 |
@twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses) |
1 |
45 |
@twitter.search(:keywords => @keywords) |
1 |
46 |
end |
|
47 |
|
|
48 |
it "should accept paging option" do |
1 |
49 |
lambda {
|
1 |
50 |
@twitter.search(:keywords => @keywords, :page => @page) |
1 |
51 |
}.should_not raise_error(Exception) |
|
52 |
end |
|
53 |
||
54 |
it "should generate expected GET HTTP request for paging case" do |
1 |
55 |
@twitter.should_receive(:search_oauth_connect).with(:get, @uris[:basic], {:page => @page}).and_return(@response)
|
1 |
56 |
@twitter.search(:page => @page) |
1 |
57 |
end |
|
58 |
||
59 |
it "should bless models for paging case" do |
1 |
60 |
@twitter.should_receive(:bless_models).with(@statuses).and_return(@statuses) |
1 |
61 |
@twitter.search(:page => @page) |
1 |
62 |
end |
|
63 |
|
|
64 |
after(:each) do |
1 |
65 |
nilize(@twitter, @uris, @request, @response, @connection, @statuses) |
9 |
66 |
end |
|
67 |
end |
|
./spec/twitter/client/status_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#status" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
15 |
6 |
@message = 'This is my unique message' |
15 |
7 |
@uris = Twitter::Client.class_eval("@@STATUS_URIS")
|
15 |
8 |
@options = {:id => 666666}
|
15 |
9 |
@request = mas_net_http_get(:basic_auth => nil) |
15 |
10 |
@response = mas_net_http_response(:success, '{}')
|
15 |
11 |
@connection = mas_net_http(@response) |
15 |
12 |
@float = 43.3434 |
15 |
13 |
@status = Twitter::Status.new(:id => 2349343) |
15 |
14 |
@reply_to_status_id = 3495293 |
15 |
15 |
@source = Twitter::Client.class_eval("@@defaults[:source]")
|
15 |
16 |
end |
|
17 |
||
18 |
it "should return nil if nil is passed as value argument for :get case" do |
1 |
19 |
status = @twitter.status(:get, nil) |
1 |
20 |
status.should be_nil |
1 |
21 |
end |
|
22 |
|
|
23 |
it "should not call @twitter#http_connect when passing nil for value argument in :get case" do |
1 |
24 |
@twitter.should_not_receive(:http_connect) |
1 |
25 |
@twitter.status(:get, nil) |
1 |
26 |
end |
|
27 |
|
|
28 |
it "should create expected HTTP GET request for :get case" do |
1 |
29 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:get], @options).and_return(@response) |
1 |
30 |
@twitter.status(:get, @options[:id]) |
1 |
31 |
end |
|
32 |
|
|
33 |
it "should invoke @twitter#rest_oauth_connect with given parameters equivalent to {:id => value.to_i} for :get case" do
|
1 |
34 |
# Float case |
|
35 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:get], {:id => @float.to_i}).and_return(@response)
|
1 |
36 |
@twitter.status(:get, @float) |
1 |
37 |
||
38 |
# Twitter::Status object case |
|
39 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:get], {:id => @status.to_i}).and_return(@response)
|
1 |
40 |
@twitter.status(:get, @status) |
1 |
41 |
end |
|
42 |
|
|
43 |
it "should create expected HTTP POST request for :post case" do |
1 |
44 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:post], :status => @message, :source => @source).and_return(@response) |
1 |
45 |
@twitter.status(:post, @message) |
1 |
46 |
end |
|
47 |
||
48 |
it "should create expected HTTP POST request for :post case when passing Hash with lat/long instead of String" do |
1 |
49 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:post], :lat => 0, :long => 0, :status => @message, :source => @source).and_return(@response) |
1 |
50 |
@twitter.status(:post, :status => @message, :lat => 0, :long => 0) |
1 |
51 |
end |
|
52 |
||
53 |
it "should create expected HTTP POST request for :post case when passing Hash with place_idinstead of String" do |
1 |
54 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:post], :place_id => 1234, :status => @message, :source => @source).and_return(@response) |
1 |
55 |
@twitter.status(:post, :status => @message, :place_id => 1234) |
1 |
56 |
end |
|
57 |
||
58 |
it "should return nil if nil is passed as value argument for :post case" do |
1 |
59 |
status = @twitter.status(:post, nil) |
1 |
60 |
status.should be_nil |
1 |
61 |
end |
|
62 |
|
|
63 |
it "should return nil if no :status key-value given in the value argument for :reply case" do |
1 |
64 |
status = @twitter.status(:reply, {})
|
1 |
65 |
status.should be_nil |
1 |
66 |
end |
|
67 |
|
|
68 |
it "should return nil if nil is passed as value argument for :reply case" do |
1 |
69 |
status = @twitter.status(:reply, nil) |
1 |
70 |
status.should be_nil |
1 |
71 |
end |
|
72 |
|
|
73 |
it "should create expected HTTP POST request for :reply case" do |
1 |
74 |
@twitter.should_receive(:rest_oauth_connect).with(:post, @uris[:reply], :status => @message, :source => @source, :in_reply_to_status_id => @reply_to_status_id).and_return(@response) |
1 |
75 |
@twitter.status(:reply, :status => @message, :in_reply_to_status_id => @reply_to_status_id) |
1 |
76 |
end |
|
77 |
|
|
78 |
it "should return nil if nil is passed as value argument for :delete case" do |
1 |
79 |
status = @twitter.status(:delete, nil) |
1 |
80 |
status.should be_nil |
1 |
81 |
end |
|
82 |
|
|
83 |
it "should create expected HTTP DELETE request for :delete case" do |
1 |
84 |
@twitter.should_receive(:rest_oauth_connect).with(:delete, @uris[:delete], @options).and_return(@response) |
1 |
85 |
@twitter.status(:delete, @options[:id]) |
1 |
86 |
end |
|
87 |
||
88 |
it "should invoke @twitter#rest_oauth_connect with given parameters equivalent to {:id => value.to_i} for :delete case" do
|
1 |
89 |
# Float case |
|
90 |
@twitter.should_receive(:rest_oauth_connect).with(:delete, @uris[:delete], {:id => @float.to_i}).and_return(@response)
|
1 |
91 |
@twitter.status(:delete, @float) |
1 |
92 |
||
93 |
# Twitter::Status object case |
|
94 |
@twitter.should_receive(:rest_oauth_connect).with(:delete, @uris[:delete], {:id => @status.to_i}).and_return(@response)
|
1 |
95 |
@twitter.status(:delete, @status) |
1 |
96 |
end |
|
97 |
|
|
98 |
it "should raise an ArgumentError when given an invalid status action" do |
1 |
99 |
lambda {
|
1 |
100 |
@twitter.status(:crap, nil) |
1 |
101 |
}.should raise_error(ArgumentError) |
|
102 |
end |
|
103 |
|
|
104 |
after(:each) do |
1 |
105 |
nilize(@twitter) |
15 |
106 |
end |
|
107 |
end |
|
./spec/twitter/client/timeline_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "Timeline API" do |
1 |
4 |
before(:each) do |
1 |
5 |
@client = client_context |
8 |
6 |
@uris = Twitter::Client.class_eval("@@TIMELINE_URIS")
|
8 |
7 |
@user = Twitter::User.new(:screen_name => 'mylogin') |
8 |
8 |
@status = Twitter::Status.new(:id => 23343443, :text => 'I love Lucy!', :user => @user) |
8 |
9 |
@timeline = [@status] |
8 |
10 |
@json = JSON.unparse([@status.to_hash]) |
8 |
11 |
@request = mas_net_http_get(:basic_auth => nil) |
8 |
12 |
@response = mas_net_http_response(:success, @json) |
8 |
13 |
@connection = mas_net_http(@response) |
8 |
14 |
@params = {
|
8 |
15 |
:public => {:since_id => 3249328},
|
|
16 |
:friends => {:id => 'myfriend'},
|
|
17 |
:user => {:id => 'auser'},
|
|
18 |
:me => {},
|
|
19 |
} |
|
20 |
end |
|
21 |
|
|
22 |
it "should respond to instance method #timeline_for" do |
1 |
23 |
@client.should respond_to(:timeline_for) |
1 |
24 |
end |
|
25 |
|
|
26 |
it "should call #http_get with expected parameters for :public case" do |
1 |
27 |
@client.should_receive(:rest_oauth_connect).and_return(mas_net_http_response(:success, @json)) |
1 |
28 |
@client.timeline_for(:public) |
1 |
29 |
end |
|
30 |
|
|
31 |
it "should yield to block for each status in timeline" do |
1 |
32 |
@client.should_receive(:rest_oauth_connect).and_return(mas_net_http_response(:success, @json)) |
1 |
33 |
Twitter::Status.should_receive(:unmarshal).and_return(@timeline) |
1 |
34 |
count = 0 |
1 |
35 |
@client.timeline_for(:public) do |status| |
1 |
36 |
status.should eql(@status) |
1 |
37 |
count += 1 |
1 |
38 |
end |
|
39 |
count.should eql(@timeline.size) |
1 |
40 |
end |
|
41 |
|
|
42 |
it "should generate expected HTTP GET request for generic :public case" do |
1 |
43 |
@client.should_receive(:rest_oauth_connect).with(:get, @uris[:public], {}).and_return(@response)
|
1 |
44 |
timeline = @client.timeline_for(:public) |
1 |
45 |
timeline.should eql(@timeline) |
1 |
46 |
end |
|
47 |
|
|
48 |
it "should generate expected HTTP GET request for :public case with expected parameters" do |
1 |
49 |
@client.should_receive(:rest_oauth_connect).with(:get, @uris[:public], @params[:public]).and_return(@response) |
1 |
50 |
timeline = @client.timeline_for(:public, @params[:public]) |
1 |
51 |
timeline.should eql(@timeline) |
1 |
52 |
end |
|
53 |
|
|
54 |
it "should generate expected HTTP GET request for generic :friends case" do |
1 |
55 |
@client.should_receive(:rest_oauth_connect).with(:get, @uris[:friends], {}).and_return(@response)
|
1 |
56 |
timeline = @client.timeline_for(:friends) |
1 |
57 |
timeline.should eql(@timeline) |
1 |
58 |
end |
|
59 |
|
|
60 |
it "should generate expected HTTP GET request for :friends case with expected parameters" do |
1 |
61 |
@client.should_receive(:rest_oauth_connect).with(:get, @uris[:friends], @params[:friends]).and_return(@response) |
1 |
62 |
timeline = @client.timeline_for(:friends, @params[:friends]) |
1 |
63 |
timeline.should eql(@timeline) |
1 |
64 |
end |
|
65 |
|
|
66 |
it "should raise an ArgumentError if type given is not valid" do |
1 |
67 |
lambda {
|
1 |
68 |
@client.timeline_for(:crap) |
1 |
69 |
}.should raise_error(ArgumentError) |
|
70 |
|
|
71 |
lambda {
|
1 |
72 |
@client.timeline_for(:crap, @params[:friends]) |
1 |
73 |
}.should raise_error(ArgumentError) |
|
74 |
end |
|
75 |
|
|
76 |
after(:each) do |
1 |
77 |
nilize(@client) |
8 |
78 |
end |
|
79 |
end |
|
./spec/twitter/client/trends_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#trends" do |
1 |
4 |
before(:each) do |
1 |
5 |
@uri = '/trends.json' |
5 |
6 |
@request = mas_net_http_get |
5 |
7 |
@twitter = client_context |
5 |
8 |
@default_header = @twitter.send(:http_header) |
5 |
9 |
@response = mas_net_http_response(:success) |
5 |
10 |
@connection = mas_net_http(@response) |
5 |
11 |
@favorites = [] |
5 |
12 |
Twitter::Status.stub!(:unmarshal).and_return(@favorites) |
5 |
13 |
end |
|
14 |
|
|
15 |
it "should create expected HTTP GET request when not giving options" do |
1 |
16 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uri).and_return(@response) |
1 |
17 |
@twitter.trends |
1 |
18 |
end |
|
19 |
|
|
20 |
it "should raise Twitter::RESTError when 401 HTTP response received without giving options" do |
1 |
21 |
@connection = mas_net_http(mas_net_http_response(:not_authorized)) |
1 |
22 |
lambda {
|
1 |
23 |
@twitter.trends |
1 |
24 |
}.should raise_error(Twitter::RESTError) |
|
25 |
end |
|
26 |
|
|
27 |
it "should raise Twitter::RESTError when 401 HTTP response received" do |
1 |
28 |
@connection = mas_net_http(mas_net_http_response(:not_authorized)) |
1 |
29 |
lambda {
|
1 |
30 |
@twitter.trends |
1 |
31 |
}.should raise_error(Twitter::RESTError) |
|
32 |
end |
|
33 |
|
|
34 |
it "should raise Twitter::RESTError when 403 HTTP response received" do |
1 |
35 |
@connection = mas_net_http(mas_net_http_response(:forbidden)) |
1 |
36 |
lambda {
|
1 |
37 |
@twitter.trends |
1 |
38 |
}.should raise_error(Twitter::RESTError) |
|
39 |
end |
|
40 |
|
|
41 |
it "should raise Twitter::RESTError when 500 HTTP response received" do |
1 |
42 |
@connection = mas_net_http(mas_net_http_response(:server_error)) |
1 |
43 |
lambda {
|
1 |
44 |
@twitter.trends |
1 |
45 |
}.should raise_error(Twitter::RESTError) |
|
46 |
end |
|
47 |
|
|
48 |
after(:each) do |
1 |
49 |
nilize(@uri, @request, @twitter, @default_header, @response, @error_response, @connection) |
5 |
50 |
end |
|
51 |
end |
|
./spec/twitter/client/user_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#user(id, :info)" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
4 |
6 |
@id = 395783 |
4 |
7 |
@screen_name = 'boris_johnson_is_funny_as_hell' |
4 |
8 |
@user = Twitter::User.new( |
4 |
9 |
:id => @id, |
|
10 |
:screen_name => @screen_name, |
|
11 |
:location => 'London' |
|
12 |
) |
|
13 |
@json = JSON.unparse(@user.to_hash) |
4 |
14 |
@response = mas_net_http_response(:success, @json) |
4 |
15 |
@connection = mas_net_http(@response) |
4 |
16 |
@uris = Twitter::Client.class_eval("@@USER_URIS")
|
4 |
17 |
Twitter::User.stub!(:unmarshal).and_return(@user) |
4 |
18 |
end |
|
19 |
|
|
20 |
it "should create expected HTTP GET request when giving numeric user id" do |
1 |
21 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:info], {:user_id => @id}).and_return(@response)
|
1 |
22 |
@twitter.user(@id) |
1 |
23 |
end |
|
24 |
|
|
25 |
it "should create expected HTTP GET request when giving screen name" do |
1 |
26 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:info], {:screen_name => @screen_name}).and_return(@response)
|
1 |
27 |
@twitter.user(@screen_name) |
1 |
28 |
end |
|
29 |
|
|
30 |
it "should bless model returned when giving numeric user id" do |
1 |
31 |
@twitter.should_receive(:bless_model).with(@user).and_return(@user) |
1 |
32 |
@twitter.user(@id) |
1 |
33 |
end |
|
34 |
|
|
35 |
it "should bless model returned when giving screen name" do |
1 |
36 |
@twitter.should_receive(:bless_model).with(@user).and_return(@user) |
1 |
37 |
@twitter.user(@screen_name) |
1 |
38 |
end |
|
39 |
||
40 |
after(:each) do |
1 |
41 |
nilize(@response, @connection, @twitter, @id, @screen_name, @user) |
4 |
42 |
end |
|
43 |
end |
|
44 |
||
45 |
# TODO: Add specs for new Twitter::Client#user(id, :friends) and |
|
46 |
# Twitter::Client#user(id, :followers) use cases. |
|
47 |
describe Twitter::Client, "#user(id, :friends)" do |
1 |
48 |
before(:each) do |
1 |
49 |
@twitter = client_context |
7 |
50 |
@id = 395784 |
7 |
51 |
@screen_name = 'cafe_paradiso' |
7 |
52 |
@user = Twitter::User.new( |
7 |
53 |
:id => @id, |
|
54 |
:screen_name => @screen_name, |
|
55 |
:location => 'Urbana, IL' |
|
56 |
) |
|
57 |
@json = JSON.unparse(@user.to_hash) |
7 |
58 |
@response = mas_net_http_response(:success, @json) |
7 |
59 |
@connection = mas_net_http(@response) |
7 |
60 |
@uris = Twitter::Client.class_eval("@@USER_URIS")
|
7 |
61 |
Twitter::User.stub!(:unmarshal).and_return(@user) |
7 |
62 |
end |
|
63 |
|
|
64 |
it "should create expected HTTP GET request when giving numeric user id" do |
1 |
65 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:friends], {:user_id => @id}).and_return(@response)
|
1 |
66 |
@twitter.user(@id, :friends) |
1 |
67 |
end |
|
68 |
|
|
69 |
it "should invoke #to_i on Twitter::User objecct given" do |
1 |
70 |
@user.should_receive(:to_i).and_return(@id) |
1 |
71 |
@twitter.user(@user, :friends) |
1 |
72 |
end |
|
73 |
|
|
74 |
it "should create expected HTTP GET request when giving Twitter::User object" do |
1 |
75 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:friends], {:user_id => @user.to_i}).and_return(@response)
|
1 |
76 |
@twitter.user(@user, :friends) |
1 |
77 |
end |
|
78 |
|
|
79 |
it "should create expected HTTP GET request when giving screen name" do |
1 |
80 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:friends], {:screen_name => @screen_name}).and_return(@response)
|
1 |
81 |
@twitter.user(@screen_name, :friends) |
1 |
82 |
end |
|
83 |
|
|
84 |
it "should bless model returned when giving numeric id" do |
1 |
85 |
@twitter.should_receive(:bless_model).with(@user).and_return(@user) |
1 |
86 |
@twitter.user(@id, :friends) |
1 |
87 |
end |
|
88 |
|
|
89 |
it "should bless model returned when giving Twitter::User object" do |
1 |
90 |
@twitter.should_receive(:bless_model).with(@user).and_return(@user) |
1 |
91 |
@twitter.user(@user, :friends) |
1 |
92 |
end |
|
93 |
|
|
94 |
it "should bless model returned when giving screen name" do |
1 |
95 |
@twitter.should_receive(:bless_model).with(@user).and_return(@user) |
1 |
96 |
@twitter.user(@screen_name, :friends) |
1 |
97 |
end |
|
98 |
|
|
99 |
after(:each) do |
1 |
100 |
nilize(@response, @connection, @twitter, @id, @screen_name, @user) |
7 |
101 |
end |
|
102 |
end |
|
103 |
||
104 |
describe Twitter::Client, "#my(:info)" do |
1 |
105 |
before(:each) do |
1 |
106 |
@twitter = client_context |
3 |
107 |
@screen_name = @twitter.instance_eval("@login")
|
3 |
108 |
@user = Twitter::User.new( |
3 |
109 |
:id => 2394393, |
|
110 |
:screen_name => @screen_name, |
|
111 |
:location => 'Glamorous Urbana' |
|
112 |
) |
|
113 |
@json = JSON.unparse(@user.to_hash) |
3 |
114 |
@response = mas_net_http_response(:success, @json) |
3 |
115 |
@connection = mas_net_http(@response) |
3 |
116 |
@uris = Twitter::Client.class_eval("@@USER_URIS")
|
3 |
117 |
@twitter.stub!(:rest_oauth_connect).and_return(@response) |
3 |
118 |
Twitter::User.stub!(:unmarshal).and_return(@user) |
3 |
119 |
end |
|
120 |
|
|
121 |
it "should create expected HTTP GET request" do |
1 |
122 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:info], {:id => @screen_name}).and_return(@response)
|
1 |
123 |
@twitter.my(:info) |
1 |
124 |
end |
|
125 |
|
|
126 |
it "should bless the model object returned" do |
1 |
127 |
@twitter.should_receive(:bless_models).with(@user).and_return(@user) |
1 |
128 |
@twitter.my(:info) |
1 |
129 |
end |
|
130 |
|
|
131 |
it "should return expected user object" do |
1 |
132 |
user = @twitter.my(:info) |
1 |
133 |
user.should eql(@user) |
1 |
134 |
end |
|
135 |
||
136 |
after(:each) do |
1 |
137 |
nilize(@response, @connection, @twitter, @user, @screen_name) |
3 |
138 |
end |
|
139 |
end |
|
140 |
||
141 |
describe Twitter::Client, "#my(:friends)" do |
1 |
142 |
before(:each) do |
1 |
143 |
@twitter = client_context |
3 |
144 |
@screen_name = @twitter.instance_eval("@login")
|
3 |
145 |
@friends = [ |
3 |
146 |
Twitter::User.new(:screen_name => 'lucy_snowe'), |
|
147 |
Twitter::User.new(:screen_name => 'jane_eyre'), |
|
148 |
Twitter::User.new(:screen_name => 'tess_derbyfield'), |
|
149 |
Twitter::User.new(:screen_name => 'elizabeth_jane_newson'), |
|
150 |
] |
|
151 |
@json = JSON.unparse(@friends.collect {|f| f.to_hash })
|
15 |
152 |
@response = mas_net_http_response(:success, @json) |
3 |
153 |
@connection = mas_net_http(@response) |
3 |
154 |
@uris = Twitter::Client.class_eval("@@USER_URIS")
|
3 |
155 |
Twitter::User.stub!(:unmarshal).and_return(@friends) |
3 |
156 |
end |
|
157 |
|
|
158 |
it "should create expected HTTP GET request" do |
1 |
159 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:friends], {:id => @screen_name}).and_return(@response)
|
1 |
160 |
@twitter.my(:friends) |
1 |
161 |
end |
|
162 |
|
|
163 |
it "should bless models returned" do |
1 |
164 |
@twitter.should_receive(:bless_models).with(@friends).and_return(@friends) |
1 |
165 |
@twitter.my(:friends) |
1 |
166 |
end |
|
167 |
|
|
168 |
it "should return expected Array of friends" do |
1 |
169 |
friends = @twitter.my(:friends) |
1 |
170 |
friends.should eql(@friends) |
1 |
171 |
end |
|
172 |
|
|
173 |
after(:each) do |
1 |
174 |
nilize(@response, @connection, @twitter, @friends, @screen_name) |
3 |
175 |
end |
|
176 |
end |
|
177 |
||
178 |
describe Twitter::Client, "#my(:invalid_action)" do |
1 |
179 |
before(:each) do |
1 |
180 |
@twitter = client_context |
1 |
181 |
end |
|
182 |
|
|
183 |
it "should raise ArgumentError for invalid user action" do |
1 |
184 |
lambda {
|
1 |
185 |
@twitter.my(:crap) |
1 |
186 |
}.should raise_error(ArgumentError) |
|
187 |
end |
|
188 |
|
|
189 |
after(:each) do |
1 |
190 |
nilize(@twitter) |
1 |
191 |
end |
|
192 |
end |
|
./spec/twitter/client_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
./spec/twitter/config_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, ".configure" do |
1 |
4 |
it "should respond to :configure class method" do |
1 |
5 |
Twitter::Client.respond_to?(:configure).should be(true) |
1 |
6 |
end |
|
7 |
||
8 |
it "should not accept calls that do not specify blocks" do |
1 |
9 |
lambda {
|
1 |
10 |
Twitter::Client.configure() |
1 |
11 |
}.should raise_error(ArgumentError) |
|
12 |
end |
|
13 |
end |
|
14 |
||
15 |
describe Twitter::Client, ".configure with mocked @config" do |
1 |
16 |
before(:each) do |
1 |
17 |
@block_invoked = false |
2 |
18 |
@conf_yielded = false |
2 |
19 |
@conf = mock(Twitter::Config) |
2 |
20 |
@block = Proc.new do |conf| |
2 |
21 |
@block_invoked = true |
2 |
22 |
@conf_yielded = true if conf.is_a?(Twitter::Config) |
2 |
23 |
end |
|
24 |
Twitter::Config.stub!(:new).and_return(@conf) |
2 |
25 |
end |
|
26 |
|
|
27 |
it "should not raise an error when passing block" do |
1 |
28 |
lambda {
|
1 |
29 |
Twitter::Client.configure(&@block) |
1 |
30 |
}.should_not raise_error |
|
31 |
end |
|
32 |
|
|
33 |
it "should yield a Twitter::Client object to block" do |
1 |
34 |
Twitter::Client.configure(&@block) |
1 |
35 |
@block_invoked.should be(true) |
1 |
36 |
@conf_yielded.should be(true) |
1 |
37 |
end |
|
38 |
|
|
39 |
after(:each) do |
1 |
40 |
nilize(@block, @block_invoked, @conf, @conf_yielded) |
2 |
41 |
end |
|
42 |
end |
|
43 |
||
44 |
describe Twitter::Config, "#eql?" do |
1 |
45 |
before(:each) do |
1 |
46 |
@protocol = :ssl |
3 |
47 |
@host = 'twitter.com' |
3 |
48 |
@port = 443 |
3 |
49 |
@proxy_host = 'myproxy.host' |
3 |
50 |
@proxy_port = 8080 |
3 |
51 |
attrs = {
|
3 |
52 |
:protocol => @protocol, |
|
53 |
:host => @host, |
|
54 |
:port => @port, |
|
55 |
:proxy_host => @proxy_host, |
|
56 |
:proxy_port => @proxy_port, |
|
57 |
} |
|
58 |
@obj = Twitter::Config.new(attrs) |
3 |
59 |
@other = Twitter::Config.new(attrs) |
3 |
60 |
|
|
61 |
@different = stubbed_twitter_config(Twitter::Config.new, attrs.merge(:proxy_host => 'different.proxy')) |
3 |
62 |
@same = @obj |
3 |
63 |
end |
|
64 |
|
|
65 |
it "should return true for two logically equivalent objects" do |
1 |
66 |
@obj.should be_eql(@other) |
1 |
67 |
@other.should be_eql(@obj) |
1 |
68 |
end |
|
69 |
|
|
70 |
it "should return false for two logically different objects" do |
1 |
71 |
@obj.should_not be_eql(@different) |
1 |
72 |
@different.should_not be_eql(@obj) |
1 |
73 |
@other.should_not be_eql(@different) |
1 |
74 |
@different.should_not be_eql(@other) |
1 |
75 |
end |
|
76 |
|
|
77 |
it "should return true for references to the same object in memory" do |
1 |
78 |
@obj.should eql(@same) |
1 |
79 |
@same.should eql(@obj) |
1 |
80 |
@other.should eql(@other) |
1 |
81 |
end |
|
82 |
|
|
83 |
after(:each) do |
1 |
84 |
nilize(@protocol, @host, @port, @proxy_host, @proxy_port, @obj, @other, @different, @same) |
3 |
85 |
end |
|
86 |
end |
|
./spec/twitter/console_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, ".from_config" do |
1 |
4 |
before(:each) do |
1 |
5 |
|
|
6 |
end |
|
7 |
|
|
8 |
it "should load YAML file for instance configuration" do |
1 |
9 |
|
|
10 |
end |
|
11 |
|
|
12 |
after(:each) do |
1 |
13 |
|
|
14 |
end |
|
15 |
end |
|
./spec/twitter/core_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe "Twitter::ClassUtilMixin mixed-in class" do |
1 |
4 |
before(:each) do |
1 |
5 |
class TestClass |
3 |
6 |
include Twitter::ClassUtilMixin |
3 |
7 |
attr_accessor :var1, :var2, :var3 |
3 |
8 |
end |
|
9 |
@init_hash = { :var1 => 'val1', :var2 => 'val2', :var3 => 'val3' }
|
3 |
10 |
end |
|
11 |
|
|
12 |
it "should have Twitter::ClassUtilMixin as an included module" do |
1 |
13 |
TestClass.included_modules.member?(Twitter::ClassUtilMixin).should be(true) |
1 |
14 |
end |
|
15 |
||
16 |
it "should set attributes passed in the hash to TestClass.new" do |
1 |
17 |
test = TestClass.new(@init_hash) |
1 |
18 |
@init_hash.each do |key, val| |
1 |
19 |
test.send(key).should eql(val) |
3 |
20 |
end |
|
21 |
end |
|
22 |
|
|
23 |
it "should not set attributes passed in the hash that are not attributes in TestClass.new" do |
1 |
24 |
test = nil |
1 |
25 |
lambda { test = TestClass.new(@init_hash.merge(:var4 => 'val4')) }.should_not raise_error
|
2 |
26 |
test.respond_to?(:var4).should be(false) |
1 |
27 |
end |
|
28 |
end |
|
29 |
||
30 |
describe Twitter::RESTError do |
1 |
31 |
describe "#to_s" do |
1 |
32 |
before(:each) do |
1 |
33 |
@hash = { :code => 200, :message => 'OK', :uri => 'http://test.host/bla' }
|
1 |
34 |
@error = Twitter::RESTError.new(@hash) |
1 |
35 |
@expected_message = "HTTP #{@hash[:code]}: #{@hash[:message]} at #{@hash[:uri]}"
|
1 |
36 |
end |
|
37 |
|
|
38 |
it "should return @expected_message" do |
1 |
39 |
@error.to_s.should eql(@expected_message) |
1 |
40 |
end |
|
41 |
end |
|
42 |
||
43 |
describe ".register" do |
1 |
44 |
before(:each) do |
1 |
45 |
@status_code = '999' |
1 |
46 |
class MyCustomError < Twitter::RESTError; register('999'); end
|
2 |
47 |
end |
|
48 |
||
49 |
it "should register a new RESTError subclass with a status code" do |
1 |
50 |
described_class.registry[@status_code].should eql(MyCustomError) |
1 |
51 |
end |
|
52 |
end |
|
53 |
end |
|
54 |
||
55 |
describe "Twitter::Status#eql?" do |
1 |
56 |
before(:each) do |
1 |
57 |
@id = 34329594003 |
3 |
58 |
@attr_hash = { :text => 'Status', :id => @id,
|
3 |
59 |
:user => { :name => 'Tess',
|
|
60 |
:description => "Unfortunate D'Urberville", |
|
61 |
:location => 'Dorset', |
|
62 |
:url => nil, |
|
63 |
:id => 34320304, |
|
64 |
:screen_name => 'maiden_no_more' }, |
|
65 |
:created_at => 'Wed May 02 03:04:54 +0000 2007'} |
|
66 |
@obj = Twitter::Status.new @attr_hash |
3 |
67 |
@other = Twitter::Status.new @attr_hash |
3 |
68 |
end |
|
69 |
|
|
70 |
it "should return true when non-transient object attributes are eql?" do |
1 |
71 |
@obj.should eql(@other) |
1 |
72 |
end |
|
73 |
||
74 |
it "should return false when not all non-transient object attributes are eql?" do |
1 |
75 |
@other.created_at = Time.now.to_s |
1 |
76 |
@obj.should_not eql(@other) |
1 |
77 |
end |
|
78 |
|
|
79 |
it "should return true when comparing same object to itself" do |
1 |
80 |
@obj.should eql(@obj) |
1 |
81 |
@other.should eql(@other) |
1 |
82 |
end |
|
83 |
end |
|
84 |
||
85 |
describe "Twitter::User#eql?" do |
1 |
86 |
before(:each) do |
1 |
87 |
@attr_hash = { :name => 'Elizabeth Jane Newson-Henshard',
|
3 |
88 |
:description => "Wronged 'Daughter'", |
|
89 |
:location => 'Casterbridge', |
|
90 |
:url => nil, |
|
91 |
:id => 6748302, |
|
92 |
:screen_name => 'mayors_daughter_or_was_she?' } |
|
93 |
@obj = Twitter::User.new @attr_hash |
3 |
94 |
@other = Twitter::User.new @attr_hash |
3 |
95 |
end |
|
96 |
|
|
97 |
it "should return true when non-transient object attributes are eql?" do |
1 |
98 |
@obj.should eql(@other) |
1 |
99 |
end |
|
100 |
|
|
101 |
it "should return false when not all non-transient object attributes are eql?" do |
1 |
102 |
@other.id = 1 |
1 |
103 |
@obj.should_not eql(@other) |
1 |
104 |
@obj.eql?(@other).should be(false) |
1 |
105 |
end |
|
106 |
|
|
107 |
it "should return true when comparing same object to itself" do |
1 |
108 |
@obj.should eql(@obj) |
1 |
109 |
@other.should eql(@other) |
1 |
110 |
end |
|
111 |
end |
|
112 |
||
113 |
describe "Twitter::ClassUtilMixin#require_block" do |
1 |
114 |
before(:each) do |
1 |
115 |
class TestClass |
3 |
116 |
include Twitter::ClassUtilMixin |
3 |
117 |
end |
|
118 |
@test_subject = TestClass.new |
3 |
119 |
end |
|
120 |
|
|
121 |
it "should respond to :require_block" do |
1 |
122 |
@test_subject.should respond_to(:require_block) |
1 |
123 |
end |
|
124 |
|
|
125 |
it "should raise ArgumentError when block not given" do |
1 |
126 |
lambda {
|
1 |
127 |
@test_subject.send(:require_block, false) |
1 |
128 |
}.should raise_error(ArgumentError) |
|
129 |
end |
|
130 |
|
|
131 |
it "should not raise ArgumentError when block is given" do |
1 |
132 |
lambda {
|
1 |
133 |
@test_subject.send(:require_block, true) |
1 |
134 |
}.should_not raise_error(ArgumentError) |
|
135 |
end |
|
136 |
|
|
137 |
after(:each) do |
1 |
138 |
@test_subject = nil |
3 |
139 |
end |
|
140 |
end |
|
141 |
||
142 |
shared_examples_for "REST error returned" do |
1 |
143 |
before(:each) do |
10 |
144 |
@twitter = client_context |
10 |
145 |
@connection = mas_net_http(mas_net_http_response(error_response_code)) |
10 |
146 |
end |
|
147 |
||
148 |
it "should raise relevant RuntimeError subclass" do |
10 |
149 |
lambda {
|
10 |
150 |
@twitter.account_info |
10 |
151 |
}.should raise_error(described_class) |
|
152 |
end |
|
153 |
end |
|
154 |
||
155 |
describe Twitter::NotModifiedError do |
1 |
156 |
def error_response_code; :not_modified; end |
2 |
157 |
it_should_behave_like "REST error returned" |
1 |
158 |
end |
|
159 |
||
160 |
describe Twitter::RateLimitError do |
1 |
161 |
def error_response_code; :bad_request; end |
2 |
162 |
it_should_behave_like "REST error returned" |
1 |
163 |
end |
|
164 |
||
165 |
describe Twitter::UnauthorizedError do |
1 |
166 |
def error_response_code; :not_authorized; end |
2 |
167 |
it_should_behave_like "REST error returned" |
1 |
168 |
end |
|
169 |
||
170 |
describe Twitter::ForbiddenError do |
1 |
171 |
def error_response_code; :forbidden; end |
2 |
172 |
it_should_behave_like "REST error returned" |
1 |
173 |
end |
|
174 |
||
175 |
describe Twitter::NotFoundError do |
1 |
176 |
def error_response_code; :file_not_found; end |
2 |
177 |
it_should_behave_like "REST error returned" |
1 |
178 |
end |
|
179 |
||
180 |
describe Twitter::NotAcceptableError do |
1 |
181 |
def error_response_code; :not_acceptable; end |
2 |
182 |
it_should_behave_like "REST error returned" |
1 |
183 |
end |
|
184 |
||
185 |
describe Twitter::SearchRateLimitError do |
1 |
186 |
def error_response_code; :search_rate_limit; end |
2 |
187 |
it_should_behave_like "REST error returned" |
1 |
188 |
end |
|
189 |
||
190 |
describe Twitter::InternalServerError do |
1 |
191 |
def error_response_code; :server_error; end |
2 |
192 |
it_should_behave_like "REST error returned" |
1 |
193 |
end |
|
194 |
||
195 |
describe Twitter::BadGatewayError do |
1 |
196 |
def error_response_code; :bad_gateway; end |
2 |
197 |
it_should_behave_like "REST error returned" |
1 |
198 |
end |
|
199 |
||
200 |
describe Twitter::ServiceUnavailableError do |
1 |
201 |
def error_response_code; :service_unavailable; end |
2 |
202 |
it_should_behave_like "REST error returned" |
1 |
203 |
end |
|
204 |
||
./spec/twitter/ext/stdlib_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Hash, "#to_http_str" do |
1 |
4 |
before(:each) do |
1 |
5 |
@http_params = {:id => 'otherlogin', :since_id => 3953743, :full_name => 'Lucy Cross'}
|
1 |
6 |
@id_regexp = Regexp.new("id=#{CGI.escape(@http_params[:id].to_s)}")
|
1 |
7 |
@since_id_regexp = Regexp.new("since_id=#{CGI.escape(@http_params[:since_id].to_s)}")
|
1 |
8 |
@full_name_regexp = Regexp.new("full_name=Lucy\\+Cross")
|
1 |
9 |
end |
|
10 |
|
|
11 |
it "should generate expected URL encoded string" do |
1 |
12 |
http_str = @http_params.to_http_str |
1 |
13 |
http_str.should match(@id_regexp) |
1 |
14 |
http_str.should match(@since_id_regexp) |
1 |
15 |
http_str.should match(@full_name_regexp) |
1 |
16 |
end |
|
17 |
|
|
18 |
after(:each) do |
1 |
19 |
@http_params = nil |
1 |
20 |
@id_kv_str, @since_id_kv_str, @full_name_kv_str = nil |
1 |
21 |
end |
|
22 |
end |
|
23 |
||
24 |
describe Time, "#to_s" do |
1 |
25 |
before(:each) do |
1 |
26 |
@time = Time.now |
2 |
27 |
@expected_string = @time.rfc2822 |
2 |
28 |
end |
|
29 |
|
|
30 |
it "should output RFC2822 compliant string" do |
1 |
31 |
time_string = @time.to_s |
1 |
32 |
time_string.should eql(@expected_string) |
1 |
33 |
end |
|
34 |
|
|
35 |
it "should respond to #old_to_s" do |
1 |
36 |
@time.should respond_to(:old_to_s) |
1 |
37 |
end |
|
38 |
|
|
39 |
after(:each) do |
1 |
40 |
nilize(@time, @expected_string) |
2 |
41 |
end |
|
42 |
end |
|
./spec/twitter/extras_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
3 |
describe Twitter::Client, "#featured(:users)" do |
1 |
4 |
before(:each) do |
1 |
5 |
@twitter = client_context |
2 |
6 |
@uris = Twitter::Client.class_eval("@@FEATURED_URIS")
|
2 |
7 |
@response = mas_net_http_response(:success) |
2 |
8 |
@connection = mas_net_http(@response) |
2 |
9 |
@users = [ |
2 |
10 |
Twitter::User.new(:screen_name => 'twitter4r'), |
|
11 |
Twitter::User.new(:screen_name => 'dictionary'), |
|
12 |
] |
|
13 |
Twitter::User.stub!(:unmarshal).and_return(@users) |
2 |
14 |
end |
|
15 |
|
|
16 |
it "should create expected HTTP GET request" do |
1 |
17 |
@twitter.should_receive(:rest_oauth_connect).with(:get, @uris[:users]).and_return(@response) |
1 |
18 |
@twitter.featured(:users) |
1 |
19 |
end |
|
20 |
|
|
21 |
it "should bless Twitter::User models returned" do |
1 |
22 |
@twitter.should_receive(:bless_models).with(@users).and_return(@users) |
1 |
23 |
@twitter.featured(:users) |
1 |
24 |
end |
|
25 |
|
|
26 |
after(:each) do |
1 |
27 |
nilize(@twitter, @uris, @response, @connection) |
2 |
28 |
end |
|
29 |
end |
|
30 |
||
31 |
describe Twitter::User, ".featured" do |
1 |
32 |
before(:each) do |
1 |
33 |
@twitter = client_context |
1 |
34 |
end |
|
35 |
|
|
36 |
it "should delegate #featured(:users) message to given client context" do |
1 |
37 |
@twitter.should_receive(:featured).with(:users).and_return([]) |
1 |
38 |
Twitter::User.featured(@twitter) |
1 |
39 |
end |
|
40 |
|
|
41 |
after(:each) do |
1 |
42 |
nilize(@twitter) |
1 |
43 |
end |
|
44 |
end |
|
./spec/twitter/meta_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
3 |
def glob_files(*path_elements) |
1 |
4 |
Dir.glob(File.join(*path_elements)) |
28 |
5 |
end |
|
6 |
||
7 |
def load_erb_yaml(path, context) |
1 |
8 |
ryaml = ERB.new(File.read(path), 0) |
7 |
9 |
YAML.load(ryaml.result(context)) |
7 |
10 |
end |
|
11 |
||
12 |
module ERBMetaMixin |
1 |
13 |
# Needed to make the YAML load work... |
|
14 |
def project_files |
1 |
15 |
glob_files(@root_dir, 'lib', '**/*.rb') |
14 |
16 |
end |
|
17 |
||
18 |
# Needed to make the YAML load work... |
|
19 |
def spec_files |
1 |
20 |
glob_files(@root_dir, 'spec', '**/*_spec.rb') |
14 |
21 |
end |
|
22 |
end |
|
23 |
||
24 |
describe "Twitter::Meta cache policy" do |
1 |
25 |
include ERBMetaMixin |
1 |
26 |
before(:each) do |
1 |
27 |
@root_dir = project_root_dir |
2 |
28 |
@meta = Twitter::Meta.new(@root_dir) |
2 |
29 |
@expected_pkg_info = load_erb_yaml(File.join(@root_dir, 'pkg-info.yml'), binding) |
2 |
30 |
@expected_project_files = project_files |
2 |
31 |
@expected_spec_files = spec_files |
2 |
32 |
end |
|
33 |
|
|
34 |
it "should store value returned from project_files in @project_files after first glob" do |
1 |
35 |
@meta.instance_eval("@project_files").should eql(nil)
|
1 |
36 |
@meta.project_files |
1 |
37 |
@meta.instance_eval("@project_files").should eql(@expected_project_files)
|
1 |
38 |
@meta.project_files |
1 |
39 |
@meta.instance_eval("@project_files").should eql(@expected_project_files)
|
1 |
40 |
end |
|
41 |
|
|
42 |
it "should store value returned from spec_files in @spec_files after first glob" do |
1 |
43 |
@meta.instance_eval("@spec_files").should eql(nil)
|
1 |
44 |
@meta.spec_files |
1 |
45 |
@meta.instance_eval("@spec_files").should eql(@expected_spec_files)
|
1 |
46 |
@meta.spec_files |
1 |
47 |
@meta.instance_eval("@spec_files").should eql(@expected_spec_files)
|
1 |
48 |
end |
|
49 |
end |
|
50 |
||
51 |
describe "Twitter::Meta" do |
1 |
52 |
include ERBMetaMixin |
1 |
53 |
before(:each) do |
1 |
54 |
@root_dir = project_root_dir |
5 |
55 |
@meta = Twitter::Meta.new(@root_dir) |
5 |
56 |
@expected_yaml_hash = load_erb_yaml(File.join(@root_dir, 'pkg-info.yml'), binding) |
5 |
57 |
@expected_project_files = project_files |
5 |
58 |
@expected_spec_files = spec_files |
5 |
59 |
end |
|
60 |
|
|
61 |
it "should load and return YAML file into Hash object upon #pkg_info call" do |
1 |
62 |
yaml_hash = @meta.pkg_info |
1 |
63 |
yaml_hash.should.eql? @expected_yaml_hash |
1 |
64 |
end |
|
65 |
|
|
66 |
it "should return the embedded hash responding to key 'spec' of #pkg_info call upon #spec_info call" do |
1 |
67 |
yaml_hash = @meta.spec_info |
1 |
68 |
yaml_hash.should.eql? @expected_yaml_hash['spec'] |
1 |
69 |
end |
|
70 |
|
|
71 |
it "should return list of files matching ROOT_DIR/lib/**/*.rb upon #project_files call" do |
1 |
72 |
project_files = @meta.project_files |
1 |
73 |
project_files.should.eql? @expected_project_files |
1 |
74 |
end |
|
75 |
|
|
76 |
it "should return list of files matching ROOT_DIR/spec/**/*.rb upon #spec_files call" do |
1 |
77 |
spec_files = @meta.spec_files |
1 |
78 |
spec_files.should.eql? @expected_spec_files |
1 |
79 |
end |
|
80 |
|
|
81 |
it "should return Gem specification based on YAML file contents and #project_files and #spec_files return values" do |
1 |
82 |
spec = @meta.gem_spec |
1 |
83 |
expected_spec_hash = @expected_yaml_hash['spec'] |
1 |
84 |
expected_spec_hash.each do |key, val| |
1 |
85 |
unless val.is_a?(Hash) |
17 |
86 |
spec.send(key).should.eql? expected_spec_hash[key] |
16 |
87 |
end |
|
88 |
end |
|
89 |
end |
|
90 |
end |
|
./spec/twitter/model_spec.rb100.0 % covered |
||
| # | Hits | |
|---|---|---|
1 |
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper')) |
1 |
2 |
||
3 |
module Test |
1 |
4 |
class Model |
1 |
5 |
include Twitter::ModelMixin |
1 |
6 |
end |
|
7 |
end |
|
8 |
||
9 |
describe Twitter::Status, "unmarshaling" do |
1 |
10 |
before(:each) do |
1 |
11 |
@json_hash = { "text" => "Thinking Zipcar is lame...",
|
3 |
12 |
"id" => 46672912, |
|
13 |
"user" => {"name" => "Angie",
|
|
14 |
"description" => "TV junkie...", |
|
15 |
"location" => "NoVA", |
|
16 |
"profile_image_url" => "http:\/\/assets0.twitter.com\/system\/user\/profile_image\/5483072\/normal\/eye.jpg?1177462492", |
|
17 |
"url" => nil, |
|
18 |
"id" => 5483072, |
|
19 |
"protected" => false, |
|
20 |
"screen_name" => "ang_410"}, |
|
21 |
"created_at" => "Wed May 02 03:04:54 +0000 2007"} |
|
22 |
@user = Twitter::User.new @json_hash["user"] |
3 |
23 |
@status = Twitter::Status.new @json_hash |
3 |
24 |
@status.user = @user |
3 |
25 |
end |
|
26 |
|
|
27 |
it "should respond to unmarshal class method" do |
1 |
28 |
Twitter::Status.should respond_to(:unmarshal) |
1 |
29 |
end |
|
30 |
|
|
31 |
it "should return expected Twitter::Status object for singular case" do |
1 |
32 |
status = Twitter::Status.unmarshal(JSON.unparse(@json_hash)) |
1 |
33 |
status.should_not be(nil) |
1 |
34 |
status.should eql(@status) |
1 |
35 |
end |
|
36 |
|
|
37 |
it "should return expected array of Twitter::Status objects for plural case" do |
1 |
38 |
statuses = Twitter::Status.unmarshal(JSON.unparse([@json_hash])) |
1 |
39 |
statuses.should_not be(nil) |
1 |
40 |
statuses.should have(1).entries |
1 |
41 |
statuses.first.should eql(@status) |
1 |
42 |
end |
|
43 |
end |
|
44 |
||
45 |
describe Twitter::User, "unmarshaling" do |
1 |
46 |
before(:each) do |
1 |
47 |
@json_hash = { "name" => "Lucy Snowe",
|
3 |
48 |
"description" => "School Mistress Entrepreneur", |
|
49 |
"location" => "Villette", |
|
50 |
"url" => "http://villetteschoolforgirls.com", |
|
51 |
"id" => 859303, |
|
52 |
"protected" => true, |
|
53 |
"screen_name" => "LucyDominatrix", } |
|
54 |
@user = Twitter::User.new @json_hash |
3 |
55 |
end |
|
56 |
|
|
57 |
it "should respond to unmarshal class method" do |
1 |
58 |
Twitter::User.should respond_to(:unmarshal) |
1 |
59 |
end |
|
60 |
|
|
61 |
it "should return expected arry of Twitter::User objects for plural case" do |
1 |
62 |
users = Twitter::User.unmarshal(JSON.unparse([@json_hash])) |
1 |
63 |
users.should have(1).entries |
1 |
64 |
users.first.should eql(@user) |
1 |
65 |
end |
|
66 |
|
|
67 |
it "should return expected Twitter::User object for singular case" do |
1 |
68 |
user = Twitter::User.unmarshal(JSON.unparse(@json_hash)) |
1 |
69 |
user.should_not be(nil) |
1 |
70 |
user.should eql(@user) |
1 |
71 |
end |
|
72 |
end |
|
73 |
||
74 |
describe "Twitter::ModelMixin#to_hash" do |
1 |
75 |
before(:all) do |
1 |
76 |
class Model |
1 |
77 |
include Twitter::ModelMixin |
1 |
78 |
@@ATTRIBUTES = [:id, :name, :value, :unused_attr] |
1 |
79 |
attr_accessor *@@ATTRIBUTES |
1 |
80 |
def self.attributes; @@ATTRIBUTES; end |
2 |
81 |
end |
|
82 |
|
|
83 |
class Hash |
1 |
84 |
def eql?(other) |
1 |
85 |
return false unless other # trivial nil case. |
1 |
86 |
return false unless self.keys.eql?(other.keys) |
1 |
87 |
self.each do |key,val| |
1 |
88 |
return false unless self[key].eql?(other[key]) |
3 |
89 |
end |
|
90 |
true |
1 |
91 |
end |
|
92 |
end |
|
93 |
end |
|
94 |
||
95 |
before(:each) do |
1 |
96 |
@attributes = {:id => 14, :name => 'State', :value => 'Illinois'}
|
1 |
97 |
@model = Model.new(@attributes) |
1 |
98 |
end |
|
99 |
|
|
100 |
it "should return expected hash representation of given model object" do |
1 |
101 |
@model.to_hash.should eql(@attributes) |
1 |
102 |
end |
|
103 |
|
|
104 |
after(:each) do |
1 |
105 |
nilize(@attributes, @model) |
1 |
106 |
end |
|
107 |
end |
|
108 |
||
109 |
describe Twitter::User, ".find" do |
1 |
110 |
before(:each) do |
1 |
111 |
@twitter = Twitter::Client.from_config 'config/twitter.yml' |
1 |
112 |
@id = 2423423 |
1 |
113 |
@screen_name = 'ascreenname' |
1 |
114 |
@expected_user = Twitter::User.new(:id => @id, :screen_name => @screen_name) |
1 |
115 |
end |
|
116 |
|
|
117 |
it "should invoke given Twitter::Client's #user method with expected arguments" do |
1 |
118 |
# case where id => @id |
|
119 |
@twitter.should_receive(:user).with(@id).and_return(@expected_user) |
1 |
120 |
user = Twitter::User.find(@id, @twitter) |
1 |
121 |
user.should eql(@expected_user) |
1 |
122 |
|
|
123 |
# case where id => @screen_name, which is also valid |
|
124 |
@twitter.should_receive(:user).with(@screen_name).and_return(@expected_user) |
1 |
125 |
user = Twitter::User.find(@screen_name, @twitter) |
1 |
126 |
user.should eql(@expected_user) |
1 |
127 |
end |
|
128 |
|
|
129 |
after(:each) do |
1 |
130 |
nilize(@twitter, @id, @screen_name, @expected_user) |
1 |
131 |
end |
|
132 |
end |
|
133 |
||
134 |
describe Twitter::Status, ".find" do |
1 |
135 |
before(:each) do |
1 |
136 |
@twitter = Twitter::Client.from_config 'config/twitter.yml' |
1 |
137 |
@id = 9439843 |
1 |
138 |
@text = 'My crummy status message' |
1 |
139 |
@user = Twitter::User.new(:id => @id, :screen_name => @screen_name) |
1 |
140 |
@expected_status = Twitter::Status.new(:id => @id, :text => @text, :user => @user) |
1 |
141 |
end |
|
142 |
|
|
143 |
it "should invoke given Twitter::Client's #status method with expected arguments" do |
1 |
144 |
@twitter.should_receive(:status).with(:get, @id).and_return(@expected_status) |
1 |
145 |
status = Twitter::Status.find(@id, @twitter) |
1 |
146 |
status.should eql(@expected_status) |
1 |
147 |
end |
|
148 |
|
|
149 |
after(:each) do |
1 |
150 |
nilize(@twitter, @id, @text, @user, @expected_status) |
1 |
151 |
end |
|
152 |
end |
|
153 |
||
154 |
describe Test::Model, "#bless" do |
1 |
155 |
before(:each) do |
1 |
156 |
@twitter = Twitter::Client.from_config('config/twitter.yml')
|
2 |
157 |
@model = Test::Model.new |
2 |
158 |
end |
|
159 |
|
|
160 |
it "should delegate to #basic_bless" do |
1 |
161 |
@model.should_receive(:basic_bless).and_return(@twitter) |
1 |
162 |
@model.bless(@twitter) |
1 |
163 |
end |
|
164 |
|
|
165 |
it "should set client attribute of self" do |
1 |
166 |
@model.should_receive(:client=).once |
1 |
167 |
@model.bless(@twitter) |
1 |
168 |
end |
|
169 |
|
|
170 |
after(:each) do |
1 |
171 |
nilize(@model, @twitter) |
2 |
172 |
end |
|
173 |
end |
|
174 |
||
175 |
describe Twitter::User, "#is_me?" do |
1 |
176 |
before(:each) do |
1 |
177 |
@twitter = Twitter::Client.from_config('config/twitter.yml')
|
2 |
178 |
@user_not_me = Twitter::User.new(:screen_name => 'notmylogin') |
2 |
179 |
@user_me = Twitter::User.new(:screen_name => @twitter.instance_eval("@login"))
|
2 |
180 |
@user_not_me.bless(@twitter) |
2 |
181 |
@user_me.bless(@twitter) |
2 |
182 |
end |
|
183 |
|
|
184 |
it "should return true when Twitter::User object represents authenticated user of client context" do |
1 |
185 |
@user_me.is_me?.should be_true |
1 |
186 |
end |
|
187 |
|
|
188 |
it "should return false when Twitter::User object does not represent authenticated user of client context" do |
1 |
189 |
@user_not_me.is_me?.should be_false |
1 |
190 |
end |
|
191 |
|
|
192 |
after(:each) do |
1 |
193 |
nilize(@twitter, @user_not_me, @user_me) |
2 |
194 |
end |
|
195 |
end |
|
196 |
||
197 |
describe Twitter::User, "#friends" do |
1 |
198 |
before(:each) do |
1 |
199 |
@twitter = Twitter::Client.from_config('config/twitter.yml')
|
1 |
200 |
@id = 5701682 |
1 |
201 |
@user = Twitter::User.new(:id => @id, :screen_name => 'twitter4r') |
1 |
202 |
@user.bless(@twitter) |
1 |
203 |
end |
|
204 |
|
|
205 |
it "should delegate to @client.user(@id, :friends)" do |
1 |
206 |
@twitter.should_receive(:user).with(@id, :friends) |
1 |
207 |
@user.friends |
1 |
208 |
end |
|
209 |
|
|
210 |
after(:each) do |
1 |
211 |
nilize(@twitter, @id, @user) |
1 |
212 |
end |
|
213 |
end |
|
214 |
||
215 |
describe Twitter::User, "#followers" do |
1 |
216 |
before(:each) do |
1 |
217 |
@twitter = Twitter::Client.from_config('config/twitter.yml')
|
1 |
218 |
@id = 5701682 |
1 |
219 |
@user = Twitter::User.new(:id => @id, :screen_name => 'twitter4r') |
1 |
220 |
@user.bless(@twitter) |
1 |
221 |
end |
|
222 |
|
|
223 |
it "should delegate to @client.my(:followers)" do |
1 |
224 |
@twitter.should_receive(:my).with(:followers, {})
|
1 |
225 |
@user.followers |
1 |
226 |
end |
|
227 |
|
|
228 |
after(:each) do |
1 |
229 |
nilize(@twitter, @id, @user) |
1 |
230 |
end |
|
231 |
end |
|
232 |
||
233 |
describe Test::Model, "#to_i" do |
1 |
234 |
before(:each) do |
1 |
235 |
@id = 234324285 |
1 |
236 |
class Test::Model |
1 |
237 |
attr_accessor :id |
1 |
238 |
end |
|
239 |
@model = Test::Model.new(:id => @id) |
1 |
240 |
end |
|
241 |
|
|
242 |
it "should return @id attribute" do |
1 |
243 |
@model.to_i.should eql(@id) |
1 |
244 |
end |
|
245 |
|
|
246 |
after(:each) do |
1 |
247 |
nilize(@model, @id) |
1 |
248 |
end |
|
249 |
end |
|
250 |
||
251 |
describe Test::Model, "#to_s" do |
1 |
252 |
before(:each) do |
1 |
253 |
class Test::Model |
1 |
254 |
attr_accessor :text |
1 |
255 |
end |
|
256 |
@text = 'Some text for the message body here' |
1 |
257 |
@model = Test::Model.new(:text => @text) |
1 |
258 |
end |
|
259 |
|
|
260 |
it "should return expected text when a @text attribute exists for the model" do |
1 |
261 |
@model.to_s.should eql(@text) |
1 |
262 |
end |
|
263 |
|
|
264 |
after(:each) do |
1 |
265 |
nilize(@model) |
1 |
266 |
end |
|
267 |
end |
|
268 |
||
269 |
describe Twitter::Message, ".find" do |
1 |
270 |
it "should raise NotImplementedError due to Twitter (as opposed to Twitter4R) API limitation" do |
1 |
271 |
lambda {
|
1 |
272 |
Twitter::Message.find(123, nil) |
1 |
273 |
}.should raise_error(NotImplementedError) |
|
274 |
end |
|
275 |
end |
|
276 |
||
277 |
describe Twitter::Status, ".create" do |
1 |
278 |
before(:each) do |
1 |
279 |
@twitter = client_context |
5 |
280 |
@text = 'My status update' |
5 |
281 |
@status = Twitter::Status.new(:text => @text, :client => @twitter) |
5 |
282 |
end |
|
283 |
|
|
284 |
it "should invoke #status(:post, text) on client context given" do |
1 |
285 |
@twitter.should_receive(:status).with(:post, @text).and_return(@status) |
1 |
286 |
Twitter::Status.create(:text => @text, :client => @twitter) |
1 |
287 |
end |
|
288 |
|
|
289 |
it "should raise an ArgumentError when no client is given in params" do |
1 |
290 |
lambda {
|
1 |
291 |
Twitter::Status.create(:text => @text) |
1 |
292 |
}.should raise_error(ArgumentError) |
|
293 |
end |
|
294 |
|
|
295 |
it "should raise an ArgumentError when no text is given in params" do |
1 |
296 |
@twitter.should_receive(:is_a?).with(Twitter::Client) |
1 |
297 |
lambda {
|
1 |
298 |
Twitter::Status.create(:client => @twitter) |
1 |
299 |
}.should raise_error(ArgumentError) |
|
300 |
end |
|
301 |
|
|
302 |
it "should raise an ArgumentError when text given in params is not a String" do |
1 |
303 |
lambda {
|
1 |
304 |
Twitter::Status.create(:client => @twitter, :text => 234493) |
1 |
305 |
}.should raise_error(ArgumentError) |
|
306 |
end |
|
307 |
|
|
308 |
it "should raise an ArgumentError when client context given in params is not a Twitter::Client object" do |
1 |
309 |
lambda {
|
1 |
310 |
Twitter::Status.create(:client => 'a string instead of a Twitter::Client', :text => @text) |
1 |
311 |
}.should raise_error(ArgumentError) |
|
312 |
end |
|
313 |
|
|
314 |
after(:each) do |
1 |
315 |
nilize(@twitter, @text, @status) |
5 |
316 |
end |
|
317 |
end |
|
318 |
||
319 |
describe Twitter::Message, ".create" do |
1 |
320 |
before(:each) do |
1 |
321 |
@twitter = client_context |
7 |
322 |
@text = 'Just between you and I, Lantana and Gosford Park are two of my favorite movies' |
7 |
323 |
@recipient = Twitter::User.new(:id => 234958) |
7 |
324 |
@message = Twitter::Message.new(:text => @text, :recipient => @recipient) |
7 |
325 |
end |
|
326 |
|
|
327 |
it "should invoke #message(:post, text, recipient) on client context given" do |
1 |
328 |
@twitter.should_receive(:message).with(:post, @text, @recipient).and_return(@message) |
1 |
329 |
Twitter::Message.create(:client => @twitter, :text => @text, :recipient => @recipient) |
1 |
330 |
end |
|
331 |
|
|
332 |
it "should raise an ArgumentError if no client context is given in params" do |
1 |
333 |
lambda {
|
1 |
334 |
Twitter::Message.create(:text => @text, :recipient => @recipient) |
1 |
335 |
}.should raise_error(ArgumentError) |
|
336 |
end |
|
337 |
|
|
338 |
it "should raise an ArgumentError if client conext given in params is not a Twitter::Client object" do |
1 |
339 |
lambda {
|
1 |
340 |
Twitter::Message.create( |
1 |
341 |
:client => 3.14159, |
|
342 |
:text => @text, |
|
343 |
:recipient => @recipient) |
|
344 |
}.should raise_error(ArgumentError) |
|
345 |
end |
|
346 |
|
|
347 |
it "should raise an ArgumentError if no text is given in params" do |
1 |
348 |
@twitter.should_receive(:is_a?).with(Twitter::Client) |
1 |
349 |
lambda {
|
1 |
350 |
Twitter::Message.create( |
1 |
351 |
:client => @twitter, |
|
352 |
:recipient => @recipient) |
|
353 |
}.should raise_error(ArgumentError) |
|
354 |
end |
|
355 |
|
|
356 |
it "should raise an ArgumentError if text given in params is not a String" do |
1 |
357 |
@twitter.should_receive(:is_a?).with(Twitter::Client) |
1 |
358 |
lambda {
|
1 |
359 |
Twitter::Message.create( |
1 |
360 |
:client => @twitter, |
|
361 |
:text => Object.new, |
|
362 |
:recipient => @recipient) |
|
363 |
}.should raise_error(ArgumentError) |
|
364 |
end |
|
365 |
|
|
366 |
it "should raise an ArgumentError if no recipient is given in params" do |
1 |
367 |
@text.should_receive(:is_a?).with(String) |
1 |
368 |
lambda {
|
1 |
369 |
Twitter::Message.create( |
1 |
370 |
:client => @twitter, |
|
371 |
:text => @text) |
|
372 |
}.should raise_error(ArgumentError) |
|
373 |
end |
|
374 |
|
|
375 |
it "should raise an ArgumentError if recipient given in params is not a Twitter::User, Integer or String object" do |
1 |
376 |
@text.should_receive(:is_a?).with(String) |
1 |
377 |
lambda {
|
1 |
378 |
Twitter::Message.create( |
1 |
379 |
:client => @twitter, |
|
380 |
:text => @text, |
|
381 |
:recipient => 3.14159) |
|
382 |
}.should raise_error(ArgumentError) |
|
383 |
end |
|
384 |
|
|
385 |
after(:each) do |
1 |
386 |
nilize(@twitter, @text, @recipient, @message) |
7 |
387 |
end |
|
388 |
end |
|
389 |
||
390 |
describe Twitter::User, "#befriend" do |
1 |
391 |
before(:each) do |
1 |
392 |
@twitter = client_context |
1 |
393 |
@user = Twitter::User.new( |
1 |
394 |
:id => 1234, |
|
395 |
:screen_name => 'mylogin', |
|
396 |
:client => @twitter) |
|
397 |
@friend = Twitter::User.new( |
1 |
398 |
:id => 5678, |
|
399 |
:screen_name => 'friend', |
|
400 |
:client => @twitter) |
|
401 |
end |
|
402 |
|
|
403 |
it "should invoke #friend(:add, user) on client context" do |
1 |
404 |
@twitter.should_receive(:friend).with(:add, @friend).and_return(@friend) |
1 |
405 |
@user.befriend(@friend) |
1 |
406 |
end |
|
407 |
|
|
408 |
after(:each) do |
1 |
409 |
nilize(@twitter, @user, @friend) |
1 |
410 |
end |
|
411 |
end |
|
412 |
||
413 |
describe Twitter::User, "#defriend" do |
1 |
414 |
before(:each) do |
1 |
415 |
@twitter = client_context |
1 |
416 |
@user = Twitter::User.new( |
1 |
417 |
:id => 1234, |
|
418 |
:screen_name => 'mylogin', |
|
419 |
:client => @twitter) |
|
420 |
@friend = Twitter::User.new( |
1 |
421 |
:id => 5678, |
|
422 |
:screen_name => 'friend', |
|
423 |
:client => @twitter) |
|
424 |
end |
|
425 |
|
|
426 |
it "should invoke #friend(:remove, user) on client context" do |
1 |
427 |
@twitter.should_receive(:friend).with(:remove, @friend).and_return(@friend) |
1 |
428 |
@user.defriend(@friend) |
1 |
429 |
end |
|
430 |
|
|
431 |
after(:each) do |
1 |
432 |
nilize(@twitter, @user, @friend) |
1 |
433 |
end |
|
434 |
end |
|
435 |
||
436 |
describe Twitter::Status, "#reply?" do |
1 |
437 |
before(:each) do |
1 |
438 |
@status = Twitter::Status.new( |
2 |
439 |
:id => 123456789, |
|
440 |
:text => "Wazzup?", |
|
441 |
:user => mock(Twitter::User) |
|
442 |
) |
|
443 |
@reply = Twitter::Status.new( |
2 |
444 |
:text => "No much bro. You?", |
|
445 |
:user => mock(Twitter::User), |
|
446 |
:in_reply_to_status_id => @status.id |
|
447 |
) |
|
448 |
end |
|
449 |
||
450 |
it "should return false for the original status" do |
1 |
451 |
@status.reply?.should be(false) |
1 |
452 |
end |
|
453 |
||
454 |
it "should return true for the reply to the original status" do |
1 |
455 |
@reply.reply?.should be(true) |
1 |
456 |
end |
|
457 |
end |
|
458 |
||
459 |
describe Twitter::Status, "#reply(status_text)" do |
1 |
460 |
before(:each) do |
1 |
461 |
@twitter = client_context |
1 |
462 |
@user = Twitter::User.new(:screen_name => "ilovephpnot") |
1 |
463 |
@status = Twitter::Status.new( |
1 |
464 |
:id => 1234, |
|
465 |
:text => "The status text", |
|
466 |
:user => @user, |
|
467 |
:client => @twitter) |
|
468 |
@reply_text = "Reply text goes here" |
1 |
469 |
@reply_status = Twitter::Status.new() |
1 |
470 |
end |
|
471 |
||
472 |
it "should invoke #status(:reply, :status => ..., :in_reply_to_status_id => ...) on client context" do |
1 |
473 |
@twitter.should_receive(:status).with(:reply, :status => "@#{@user.screen_name} #{@reply_text}",
|
1 |
474 |
:in_reply_to_status_id => @status.id).and_return(@reply_status) |
|
475 |
@status.reply(@reply_text) |
1 |
476 |
end |
|
477 |
||
478 |
after(:each) do |
1 |
479 |
nilize(@twitter, @status) |
1 |
480 |
end |
|
481 |
end |
|
482 |
||
483 |
describe Twitter::Status, "#to_s" do |
1 |
484 |
before(:each) do |
1 |
485 |
@text = 'Aloha' |
1 |
486 |
@status = Twitter::Status.new(:text => @text) |
1 |
487 |
end |
|
488 |
|
|
489 |
it "should render text attribute" do |
1 |
490 |
@status.to_s.should be(@text) |
1 |
491 |
end |
|
492 |
|
|
493 |
after(:each) do |
1 |
494 |
nilize(@text, @status) |
1 |
495 |
end |
|
496 |
end |
|
497 |
||
498 |
describe Twitter::Message, "#to_s" do |
1 |
499 |
before(:each) do |
1 |
500 |
@text = 'Aloha' |
1 |
501 |
@message = Twitter::Message.new(:text => @text) |
1 |
502 |
end |
|
503 |
|
|
504 |
it "should render text attribute" do |
1 |
505 |
@message.to_s.should be(@text) |
1 |
506 |
end |
|
507 |
|
|
508 |
after(:each) do |
1 |
509 |
nilize(@text, @message) |
1 |
510 |
end |
|
511 |
end |
|
512 |
||
513 |
describe Twitter::Trendline, ".new" do |
1 |
514 |
it "should initialize trends into an Array of Twitter::Trend objects" do |
1 |
515 |
trendline = Twitter::Trendline.new(:trends => [ |
1 |
516 |
{:name => "booyah", :url => "http://twitter.com/search?q=booyah"},
|
|
517 |
{:name => "twitter4r", :url => "http://twitter.com/search?q=twitter4r"},
|
|
518 |
]) |
|
519 |
trendline.each do |t| |
1 |
520 |
t.should be_a(Twitter::Trend) |
2 |
521 |
end |
|
522 |
booyah = trendline.first |
1 |
523 |
booyah.name.should === "booyah" |
1 |
524 |
twitter4r = trendline[-1] |
1 |
525 |
twitter4r.name.should === "twitter4r" |
1 |
526 |
end |
|
527 |
end |
|