rcarver-twitter 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History +154 -0
- data/License +20 -0
- data/Notes +33 -0
- data/README.rdoc +9 -0
- data/Rakefile +103 -0
- data/VERSION.yml +4 -0
- data/examples/connect.rb +30 -0
- data/examples/friendship_existance.rb +13 -0
- data/examples/helpers/config_store.rb +38 -0
- data/examples/search.rb +15 -0
- data/examples/timeline.rb +19 -0
- data/examples/update.rb +11 -0
- data/lib/twitter/base.rb +163 -0
- data/lib/twitter/oauth.rb +31 -0
- data/lib/twitter/request.rb +101 -0
- data/lib/twitter/search.rb +101 -0
- data/lib/twitter.rb +40 -0
- data/test/fixtures/firehose.json +1 -0
- data/test/fixtures/friends_timeline.json +1 -0
- data/test/fixtures/rate_limit_exceeded.json +1 -0
- data/test/fixtures/replies.json +1 -0
- data/test/fixtures/search.json +1 -0
- data/test/fixtures/search_from_jnunemaker.json +1 -0
- data/test/fixtures/status.json +1 -0
- data/test/fixtures/user_timeline.json +1 -0
- data/test/test_helper.rb +34 -0
- data/test/twitter/base_test.rb +80 -0
- data/test/twitter/oauth_test.rb +55 -0
- data/test/twitter/request_test.rb +203 -0
- data/test/twitter/search_test.rb +138 -0
- data/test/twitter_test.rb +12 -0
- metadata +173 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class BaseTest < Test::Unit::TestCase
|
4
|
+
context "base" do
|
5
|
+
setup do
|
6
|
+
oauth = Twitter::OAuth.new('token', 'secret')
|
7
|
+
@access_token = OAuth::AccessToken.new(oauth.consumer, 'atoken', 'asecret')
|
8
|
+
oauth.stubs(:access_token).returns(@access_token)
|
9
|
+
@twitter = Twitter::Base.new(oauth)
|
10
|
+
end
|
11
|
+
|
12
|
+
context "initialize" do
|
13
|
+
should "require an oauth object" do
|
14
|
+
@twitter.instance_variable_get('@client').should == @access_token
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
should "delegate get to the client" do
|
19
|
+
@access_token.expects(:get).with('/foo').returns(nil)
|
20
|
+
@twitter.get('/foo')
|
21
|
+
end
|
22
|
+
|
23
|
+
should "delegate post to the client" do
|
24
|
+
@access_token.expects(:post).with('/foo', {:bar => 'baz'}).returns(nil)
|
25
|
+
@twitter.post('/foo', {:bar => 'baz'})
|
26
|
+
end
|
27
|
+
|
28
|
+
context "hitting the api" do
|
29
|
+
should "be able to get friends timeline" do
|
30
|
+
stub_get('/statuses/friends_timeline.json', 'friends_timeline.json')
|
31
|
+
timeline = @twitter.friends_timeline
|
32
|
+
timeline.size.should == 20
|
33
|
+
first = timeline.first
|
34
|
+
first.source.should == '<a href="http://www.atebits.com/software/tweetie/">Tweetie</a>'
|
35
|
+
first.user.name.should == 'John Nunemaker'
|
36
|
+
first.user.url.should == 'http://railstips.org/about'
|
37
|
+
first.id.should == 1441588944
|
38
|
+
first.favorited.should be(false)
|
39
|
+
end
|
40
|
+
|
41
|
+
should "be able to get user timeline" do
|
42
|
+
stub_get('/statuses/user_timeline.json', 'user_timeline.json')
|
43
|
+
timeline = @twitter.user_timeline
|
44
|
+
timeline.size.should == 20
|
45
|
+
first = timeline.first
|
46
|
+
first.text.should == 'Colder out today than expected. Headed to the Beanery for some morning wakeup drink. Latte or coffee...hmmm...'
|
47
|
+
first.user.name.should == 'John Nunemaker'
|
48
|
+
end
|
49
|
+
|
50
|
+
should "be able to get a status" do
|
51
|
+
stub_get('/statuses/show/1441588944.json', 'status.json')
|
52
|
+
status = @twitter.status(1441588944)
|
53
|
+
status.user.name.should == 'John Nunemaker'
|
54
|
+
status.id.should == 1441588944
|
55
|
+
end
|
56
|
+
|
57
|
+
should "be able to update status" do
|
58
|
+
stub_post('/statuses/update.json', 'status.json')
|
59
|
+
status = @twitter.update('Rob Dyrdek is the funniest man alive. That is all.')
|
60
|
+
status.user.name.should == 'John Nunemaker'
|
61
|
+
status.text.should == 'Rob Dyrdek is the funniest man alive. That is all.'
|
62
|
+
end
|
63
|
+
|
64
|
+
should "be able to get replies" do
|
65
|
+
stub_get('/statuses/replies.json', 'replies.json')
|
66
|
+
replies = @twitter.replies
|
67
|
+
replies.size.should == 19
|
68
|
+
first = replies.first
|
69
|
+
first.user.name.should == '-oAk-'
|
70
|
+
first.text.should == '@jnunemaker cold out today. cold yesterday. even colder today.'
|
71
|
+
end
|
72
|
+
|
73
|
+
should "correctly hash statuses" do
|
74
|
+
stub_get('/statuses/friends_timeline.json', 'friends_timeline.json')
|
75
|
+
hashes = @twitter.friends_timeline.map{ |s| s.hash }
|
76
|
+
hashes.should == @twitter.friends_timeline.map{ |s| s.hash }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class OAuthTest < Test::Unit::TestCase
|
4
|
+
should "initialize with consumer token and secret" do
|
5
|
+
twitter = Twitter::OAuth.new('token', 'secret')
|
6
|
+
|
7
|
+
twitter.ctoken.should == 'token'
|
8
|
+
twitter.csecret.should == 'secret'
|
9
|
+
end
|
10
|
+
|
11
|
+
should "have a consumer" do
|
12
|
+
consumer = mock('oauth consumer')
|
13
|
+
OAuth::Consumer.expects(:new).with('token', 'secret', {:site => 'http://twitter.com'}).returns(consumer)
|
14
|
+
twitter = Twitter::OAuth.new('token', 'secret')
|
15
|
+
|
16
|
+
twitter.consumer.should == consumer
|
17
|
+
end
|
18
|
+
|
19
|
+
should "have a request token from the consumer" do
|
20
|
+
consumer = mock('oauth consumer')
|
21
|
+
request_token = mock('request token')
|
22
|
+
consumer.expects(:get_request_token).returns(request_token)
|
23
|
+
OAuth::Consumer.expects(:new).with('token', 'secret', {:site => 'http://twitter.com'}).returns(consumer)
|
24
|
+
twitter = Twitter::OAuth.new('token', 'secret')
|
25
|
+
|
26
|
+
twitter.request_token.should == request_token
|
27
|
+
end
|
28
|
+
|
29
|
+
should "be able to create access token from request token and secret" do
|
30
|
+
twitter = Twitter::OAuth.new('token', 'secret')
|
31
|
+
consumer = OAuth::Consumer.new('token', 'secret', {:site => 'http://twitter.com'})
|
32
|
+
twitter.stubs(:consumer).returns(consumer)
|
33
|
+
|
34
|
+
access_token = mock('access token', :token => 'atoken', :secret => 'asecret')
|
35
|
+
request_token = mock('request token')
|
36
|
+
request_token.expects(:get_access_token).returns(access_token)
|
37
|
+
OAuth::RequestToken.expects(:new).with(consumer, 'rtoken', 'rsecret').returns(request_token)
|
38
|
+
|
39
|
+
twitter.authorize_from_request('rtoken', 'rsecret')
|
40
|
+
twitter.access_token.class.should be(OAuth::AccessToken)
|
41
|
+
twitter.access_token.token.should == 'atoken'
|
42
|
+
twitter.access_token.secret.should == 'asecret'
|
43
|
+
end
|
44
|
+
|
45
|
+
should "be able to create access token from access token and secret" do
|
46
|
+
twitter = Twitter::OAuth.new('token', 'secret')
|
47
|
+
consumer = OAuth::Consumer.new('token', 'secret', {:site => 'http://twitter.com'})
|
48
|
+
twitter.stubs(:consumer).returns(consumer)
|
49
|
+
|
50
|
+
twitter.authorize_from_access('atoken', 'asecret')
|
51
|
+
twitter.access_token.class.should be(OAuth::AccessToken)
|
52
|
+
twitter.access_token.token.should == 'atoken'
|
53
|
+
twitter.access_token.secret.should == 'asecret'
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RequestTest < Test::Unit::TestCase
|
4
|
+
context "new get request" do
|
5
|
+
setup do
|
6
|
+
@base = mock('twitter base')
|
7
|
+
@request = Twitter::Request.new(@base, :get, '/statuses/user_timeline.json', {:query => {:since_id => 1234}})
|
8
|
+
end
|
9
|
+
|
10
|
+
should "have base" do
|
11
|
+
@request.base.should == @base
|
12
|
+
end
|
13
|
+
|
14
|
+
should "have method" do
|
15
|
+
@request.method.should == :get
|
16
|
+
end
|
17
|
+
|
18
|
+
should "have path" do
|
19
|
+
@request.path.should == '/statuses/user_timeline.json'
|
20
|
+
end
|
21
|
+
|
22
|
+
should "have options" do
|
23
|
+
@request.options.should == {:query => {:since_id => 1234}}
|
24
|
+
end
|
25
|
+
|
26
|
+
should "have uri" do
|
27
|
+
@request.uri.should == '/statuses/user_timeline.json?since_id=1234'
|
28
|
+
end
|
29
|
+
|
30
|
+
context "performing request for collection" do
|
31
|
+
setup do
|
32
|
+
response = mock('response') do
|
33
|
+
stubs(:body).returns(fixture_file('user_timeline.json'))
|
34
|
+
stubs(:code).returns('200')
|
35
|
+
end
|
36
|
+
|
37
|
+
@base.expects(:get).returns(response)
|
38
|
+
@object = @request.perform
|
39
|
+
end
|
40
|
+
|
41
|
+
should "return array of mashes" do
|
42
|
+
@object.size.should == 20
|
43
|
+
@object.each { |obj| obj.class.should be(Mash) }
|
44
|
+
@object.first.text.should == 'Colder out today than expected. Headed to the Beanery for some morning wakeup drink. Latte or coffee...hmmm...'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "performing a request for a single object" do
|
49
|
+
setup do
|
50
|
+
response = mock('response') do
|
51
|
+
stubs(:body).returns(fixture_file('status.json'))
|
52
|
+
stubs(:code).returns('200')
|
53
|
+
end
|
54
|
+
|
55
|
+
@base.expects(:get).returns(response)
|
56
|
+
@object = @request.perform
|
57
|
+
end
|
58
|
+
|
59
|
+
should "return a single mash" do
|
60
|
+
@object.class.should be(Mash)
|
61
|
+
@object.text.should == 'Rob Dyrdek is the funniest man alive. That is all.'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with no query string" do
|
66
|
+
should "not have any query string" do
|
67
|
+
request = Twitter::Request.new(@base, :get, '/statuses/user_timeline.json')
|
68
|
+
request.uri.should == '/statuses/user_timeline.json'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with blank query string" do
|
73
|
+
should "not have any query string" do
|
74
|
+
request = Twitter::Request.new(@base, :get, '/statuses/user_timeline.json', :query => {})
|
75
|
+
request.uri.should == '/statuses/user_timeline.json'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
should "have get shortcut to initialize and perform all in one" do
|
80
|
+
Twitter::Request.any_instance.expects(:perform).returns(nil)
|
81
|
+
Twitter::Request.get(@base, '/foo')
|
82
|
+
end
|
83
|
+
|
84
|
+
should "allow setting query string and headers" do
|
85
|
+
response = mock('response') do
|
86
|
+
stubs(:body).returns('')
|
87
|
+
stubs(:code).returns('200')
|
88
|
+
end
|
89
|
+
|
90
|
+
@base.expects(:get).with('/statuses/friends_timeline.json?since_id=1234', {'Foo' => 'Bar'}).returns(response)
|
91
|
+
Twitter::Request.get(@base, '/statuses/friends_timeline.json?since_id=1234', :headers => {'Foo' => 'Bar'})
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "new post request" do
|
96
|
+
setup do
|
97
|
+
@base = mock('twitter base')
|
98
|
+
@request = Twitter::Request.new(@base, :post, '/statuses/update.json', {:body => {:status => 'Woohoo!'}})
|
99
|
+
end
|
100
|
+
|
101
|
+
should "allow setting body and headers" do
|
102
|
+
response = mock('response') do
|
103
|
+
stubs(:body).returns('')
|
104
|
+
stubs(:code).returns('200')
|
105
|
+
end
|
106
|
+
|
107
|
+
@base.expects(:post).with('/statuses/update.json', {:status => 'Woohoo!'}, {'Foo' => 'Bar'}).returns(response)
|
108
|
+
Twitter::Request.post(@base, '/statuses/update.json', :body => {:status => 'Woohoo!'}, :headers => {'Foo' => 'Bar'})
|
109
|
+
end
|
110
|
+
|
111
|
+
context "performing request" do
|
112
|
+
setup do
|
113
|
+
response = mock('response') do
|
114
|
+
stubs(:body).returns(fixture_file('status.json'))
|
115
|
+
stubs(:code).returns('200')
|
116
|
+
end
|
117
|
+
|
118
|
+
@base.expects(:post).returns(response)
|
119
|
+
@object = @request.perform
|
120
|
+
end
|
121
|
+
|
122
|
+
should "return a mash of the object" do
|
123
|
+
@object.text.should == 'Rob Dyrdek is the funniest man alive. That is all.'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
should "have post shortcut to initialize and perform all in one" do
|
128
|
+
Twitter::Request.any_instance.expects(:perform).returns(nil)
|
129
|
+
Twitter::Request.post(@base, '/foo')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "error raising" do
|
134
|
+
setup do
|
135
|
+
oauth = Twitter::OAuth.new('token', 'secret')
|
136
|
+
oauth.authorize_from_access('atoken', 'asecret')
|
137
|
+
@base = Twitter::Base.new(oauth)
|
138
|
+
end
|
139
|
+
|
140
|
+
should "not raise error for 200" do
|
141
|
+
stub_get('http://twitter.com:80/foo', '', ['200'])
|
142
|
+
lambda {
|
143
|
+
Twitter::Request.get(@base, '/foo')
|
144
|
+
}.should_not raise_error
|
145
|
+
end
|
146
|
+
|
147
|
+
should "not raise error for 304" do
|
148
|
+
stub_get('http://twitter.com:80/foo', '', ['304'])
|
149
|
+
lambda {
|
150
|
+
Twitter::Request.get(@base, '/foo')
|
151
|
+
}.should_not raise_error
|
152
|
+
end
|
153
|
+
|
154
|
+
should "raise RateLimitExceeded for 400" do
|
155
|
+
stub_get('http://twitter.com:80/foo', 'rate_limit_exceeded.json', ['400'])
|
156
|
+
lambda {
|
157
|
+
Twitter::Request.get(@base, '/foo')
|
158
|
+
}.should raise_error(Twitter::RateLimitExceeded)
|
159
|
+
end
|
160
|
+
|
161
|
+
should "raise Unauthorized for 401" do
|
162
|
+
stub_get('http://twitter.com:80/foo', '', ['401'])
|
163
|
+
lambda {
|
164
|
+
Twitter::Request.get(@base, '/foo')
|
165
|
+
}.should raise_error(Twitter::Unauthorized)
|
166
|
+
end
|
167
|
+
|
168
|
+
should "raise General for 403" do
|
169
|
+
stub_get('http://twitter.com:80/foo', '', ['403'])
|
170
|
+
lambda {
|
171
|
+
Twitter::Request.get(@base, '/foo')
|
172
|
+
}.should raise_error(Twitter::General)
|
173
|
+
end
|
174
|
+
|
175
|
+
should "raise NotFound for 404" do
|
176
|
+
stub_get('http://twitter.com:80/foo', '', ['404'])
|
177
|
+
lambda {
|
178
|
+
Twitter::Request.get(@base, '/foo')
|
179
|
+
}.should raise_error(Twitter::NotFound)
|
180
|
+
end
|
181
|
+
|
182
|
+
should "raise InformTwitter for 500" do
|
183
|
+
stub_get('http://twitter.com:80/foo', '', ['500'])
|
184
|
+
lambda {
|
185
|
+
Twitter::Request.get(@base, '/foo')
|
186
|
+
}.should raise_error(Twitter::InformTwitter)
|
187
|
+
end
|
188
|
+
|
189
|
+
should "raise Unavailable for 502" do
|
190
|
+
stub_get('http://twitter.com:80/foo', '', ['502'])
|
191
|
+
lambda {
|
192
|
+
Twitter::Request.get(@base, '/foo')
|
193
|
+
}.should raise_error(Twitter::Unavailable)
|
194
|
+
end
|
195
|
+
|
196
|
+
should "raise Unavailable for 503" do
|
197
|
+
stub_get('http://twitter.com:80/foo', '', ['503'])
|
198
|
+
lambda {
|
199
|
+
Twitter::Request.get(@base, '/foo')
|
200
|
+
}.should raise_error(Twitter::Unavailable)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class SearchTest < Test::Unit::TestCase
|
4
|
+
context "searching" do
|
5
|
+
setup do
|
6
|
+
@search = Twitter::Search.new
|
7
|
+
end
|
8
|
+
|
9
|
+
should "should be able to initialize with a search term" do
|
10
|
+
Twitter::Search.new('httparty').query[:q].should include('httparty')
|
11
|
+
end
|
12
|
+
|
13
|
+
should "should be able to specify from" do
|
14
|
+
@search.from('jnunemaker').query[:q].should include('from:jnunemaker')
|
15
|
+
end
|
16
|
+
|
17
|
+
should "should be able to specify to" do
|
18
|
+
@search.to('jnunemaker').query[:q].should include('to:jnunemaker')
|
19
|
+
end
|
20
|
+
|
21
|
+
should "should be able to specify referencing" do
|
22
|
+
@search.referencing('jnunemaker').query[:q].should include('@jnunemaker')
|
23
|
+
end
|
24
|
+
|
25
|
+
should "should alias references to referencing" do
|
26
|
+
@search.references('jnunemaker').query[:q].should include('@jnunemaker')
|
27
|
+
end
|
28
|
+
|
29
|
+
should "should alias ref to referencing" do
|
30
|
+
@search.ref('jnunemaker').query[:q].should include('@jnunemaker')
|
31
|
+
end
|
32
|
+
|
33
|
+
should "should be able to specify containing" do
|
34
|
+
@search.containing('milk').query[:q].should include('milk')
|
35
|
+
end
|
36
|
+
|
37
|
+
should "should alias contains to containing" do
|
38
|
+
@search.contains('milk').query[:q].should include('milk')
|
39
|
+
end
|
40
|
+
|
41
|
+
should "should be able to specify hashed" do
|
42
|
+
@search.hashed('twitter').query[:q].should include('#twitter')
|
43
|
+
end
|
44
|
+
|
45
|
+
should "should be able to specify the language" do
|
46
|
+
@search.lang('en')
|
47
|
+
@search.class.expects(:get).with('http://search.twitter.com/search.json', :query => {:lang => 'en', :q => ''}, :format => :json).returns({'foo' => 'bar'})
|
48
|
+
@search.fetch()
|
49
|
+
end
|
50
|
+
|
51
|
+
should "should be able to specify the number of results per page" do
|
52
|
+
@search.per_page(25)
|
53
|
+
@search.class.expects(:get).with('http://search.twitter.com/search.json', :query => {:rpp => 25, :q => ''}, :format => :json).returns({'foo' => 'bar'})
|
54
|
+
@search.fetch()
|
55
|
+
end
|
56
|
+
|
57
|
+
should "should be able to specify the page number" do
|
58
|
+
@search.page(20)
|
59
|
+
@search.class.expects(:get).with('http://search.twitter.com/search.json', :query => {:page => 20, :q => ''}, :format => :json).returns({'foo' => 'bar'})
|
60
|
+
@search.fetch()
|
61
|
+
end
|
62
|
+
|
63
|
+
should "should be able to specify only returning results greater than an id" do
|
64
|
+
@search.since(1234)
|
65
|
+
@search.class.expects(:get).with('http://search.twitter.com/search.json', :query => {:since_id => 1234, :q => ''}, :format => :json).returns({'foo' => 'bar'})
|
66
|
+
@search.fetch()
|
67
|
+
end
|
68
|
+
|
69
|
+
should "should be able to specify geo coordinates" do
|
70
|
+
@search.geocode('40.757929', '-73.985506', '25mi')
|
71
|
+
@search.class.expects(:get).with('http://search.twitter.com/search.json', :query => {:geocode => '40.757929,-73.985506,25mi', :q => ''}, :format => :json).returns({'foo' => 'bar'})
|
72
|
+
@search.fetch()
|
73
|
+
end
|
74
|
+
|
75
|
+
should "should be able to clear the filters set" do
|
76
|
+
@search.from('jnunemaker').to('oaknd1')
|
77
|
+
@search.clear.query.should == {:q => []}
|
78
|
+
end
|
79
|
+
|
80
|
+
should "should be able to chain methods together" do
|
81
|
+
@search.from('jnunemaker').to('oaknd1').referencing('orderedlist').containing('milk').hashed('twitter').lang('en').per_page(20).since(1234).geocode('40.757929', '-73.985506', '25mi')
|
82
|
+
@search.query[:q].should == ['from:jnunemaker', 'to:oaknd1', '@orderedlist', 'milk', '#twitter']
|
83
|
+
@search.query[:lang].should == 'en'
|
84
|
+
@search.query[:rpp].should == 20
|
85
|
+
@search.query[:since_id].should == 1234
|
86
|
+
@search.query[:geocode].should == '40.757929,-73.985506,25mi'
|
87
|
+
end
|
88
|
+
|
89
|
+
context "fetching" do
|
90
|
+
setup do
|
91
|
+
stub_get('http://search.twitter.com:80/search.json?q=%40jnunemaker', 'search.json')
|
92
|
+
@search = Twitter::Search.new('@jnunemaker')
|
93
|
+
@response = @search.fetch
|
94
|
+
end
|
95
|
+
|
96
|
+
should "should return results" do
|
97
|
+
@response.results.size.should == 15
|
98
|
+
end
|
99
|
+
|
100
|
+
should "should support dot notation" do
|
101
|
+
first = @response.results.first
|
102
|
+
first.text.should == %q(Someone asked about a tweet reader. Easy to do in ruby with @jnunemaker's twitter gem and the win32-sapi gem, if you are on windows.)
|
103
|
+
first.from_user.should == 'PatParslow'
|
104
|
+
end
|
105
|
+
|
106
|
+
should "cache fetched results so multiple fetches don't keep hitting api" do
|
107
|
+
Twitter::Search.expects(:get).never
|
108
|
+
@search.fetch
|
109
|
+
end
|
110
|
+
|
111
|
+
should "rehit api if fetch is called with true" do
|
112
|
+
Twitter::Search.expects(:get).once
|
113
|
+
@search.fetch(true)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "iterating over results" do
|
118
|
+
setup do
|
119
|
+
stub_get('http://search.twitter.com:80/search.json?q=from%3Ajnunemaker', 'search_from_jnunemaker.json')
|
120
|
+
@search.from('jnunemaker')
|
121
|
+
end
|
122
|
+
|
123
|
+
should "work" do
|
124
|
+
@search.each { |result| result.should_not be(nil) }
|
125
|
+
end
|
126
|
+
|
127
|
+
should "work multiple times in a row" do
|
128
|
+
@search.each { |result| result.should_not be(nil) }
|
129
|
+
@search.each { |result| result.should_not be(nil) }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
should "should be able to iterate over results" do
|
134
|
+
@search.respond_to?(:each).should be(true)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TwitterTest < Test::Unit::TestCase
|
4
|
+
should "have firehose method for public timeline" do
|
5
|
+
stub_get('http://twitter.com:80/statuses/public_timeline.json', 'firehose.json')
|
6
|
+
hose = Twitter.firehose
|
7
|
+
hose.size.should == 20
|
8
|
+
first = hose.first
|
9
|
+
first.text.should == '#torrents Ultimativer Flirt Guide - In 10 Minuten jede Frau erobern: Ultimativer Flirt Guide - In 10 Mi.. http://tinyurl.com/d3okh4'
|
10
|
+
first.user.name.should == 'P2P Torrents'
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rcarver-twitter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Nunemaker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-10 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: oauth
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: extlib
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: httparty
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.4.2
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: thoughtbot-shoulda
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jeremymcanally-matchy
|
57
|
+
type: :development
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: mocha
|
67
|
+
type: :development
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: fakeweb
|
77
|
+
type: :development
|
78
|
+
version_requirement:
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "0"
|
84
|
+
version:
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: extlib
|
87
|
+
type: :development
|
88
|
+
version_requirement:
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "0"
|
94
|
+
version:
|
95
|
+
description:
|
96
|
+
email: nunemaker@gmail.com
|
97
|
+
executables: []
|
98
|
+
|
99
|
+
extensions: []
|
100
|
+
|
101
|
+
extra_rdoc_files:
|
102
|
+
- README.rdoc
|
103
|
+
files:
|
104
|
+
- History
|
105
|
+
- License
|
106
|
+
- Notes
|
107
|
+
- README.rdoc
|
108
|
+
- Rakefile
|
109
|
+
- VERSION.yml
|
110
|
+
- examples/connect.rb
|
111
|
+
- examples/friendship_existance.rb
|
112
|
+
- examples/helpers/config_store.rb
|
113
|
+
- examples/search.rb
|
114
|
+
- examples/timeline.rb
|
115
|
+
- examples/update.rb
|
116
|
+
- lib/twitter.rb
|
117
|
+
- lib/twitter/base.rb
|
118
|
+
- lib/twitter/oauth.rb
|
119
|
+
- lib/twitter/request.rb
|
120
|
+
- lib/twitter/search.rb
|
121
|
+
- test/fixtures/firehose.json
|
122
|
+
- test/fixtures/friends_timeline.json
|
123
|
+
- test/fixtures/rate_limit_exceeded.json
|
124
|
+
- test/fixtures/replies.json
|
125
|
+
- test/fixtures/search.json
|
126
|
+
- test/fixtures/search_from_jnunemaker.json
|
127
|
+
- test/fixtures/status.json
|
128
|
+
- test/fixtures/user_timeline.json
|
129
|
+
- test/test_helper.rb
|
130
|
+
- test/twitter/base_test.rb
|
131
|
+
- test/twitter/oauth_test.rb
|
132
|
+
- test/twitter/request_test.rb
|
133
|
+
- test/twitter/search_test.rb
|
134
|
+
- test/twitter_test.rb
|
135
|
+
has_rdoc: true
|
136
|
+
homepage: http://github.com/jnunemaker/twitter
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options:
|
139
|
+
- --charset=UTF-8
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: "0"
|
147
|
+
version:
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: "0"
|
153
|
+
version:
|
154
|
+
requirements: []
|
155
|
+
|
156
|
+
rubyforge_project: twitter
|
157
|
+
rubygems_version: 1.2.0
|
158
|
+
signing_key:
|
159
|
+
specification_version: 2
|
160
|
+
summary: wrapper for the twitter api (oauth only)
|
161
|
+
test_files:
|
162
|
+
- test/test_helper.rb
|
163
|
+
- test/twitter/base_test.rb
|
164
|
+
- test/twitter/oauth_test.rb
|
165
|
+
- test/twitter/request_test.rb
|
166
|
+
- test/twitter/search_test.rb
|
167
|
+
- test/twitter_test.rb
|
168
|
+
- examples/connect.rb
|
169
|
+
- examples/friendship_existance.rb
|
170
|
+
- examples/helpers/config_store.rb
|
171
|
+
- examples/search.rb
|
172
|
+
- examples/timeline.rb
|
173
|
+
- examples/update.rb
|