jls-tweetstream 2.5.0
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/.yardopts +6 -0
- data/CHANGELOG.md +76 -0
- data/CONTRIBUTING.md +9 -0
- data/LICENSE.md +20 -0
- data/README.md +392 -0
- data/Rakefile +11 -0
- data/lib/tweetstream.rb +36 -0
- data/lib/tweetstream/client.rb +582 -0
- data/lib/tweetstream/configuration.rb +92 -0
- data/lib/tweetstream/daemon.rb +52 -0
- data/lib/tweetstream/site_stream_client.rb +122 -0
- data/lib/tweetstream/version.rb +3 -0
- data/spec/fixtures/delete.json +8 -0
- data/spec/fixtures/direct_messages.json +1 -0
- data/spec/fixtures/favorite.json +150 -0
- data/spec/fixtures/ids.json +30 -0
- data/spec/fixtures/info.json +18 -0
- data/spec/fixtures/limit.json +5 -0
- data/spec/fixtures/scrub_geo.json +8 -0
- data/spec/fixtures/stall_warning.json +7 -0
- data/spec/fixtures/status_withheld.json +7 -0
- data/spec/fixtures/statuses.json +1 -0
- data/spec/fixtures/user_withheld.json +6 -0
- data/spec/helper.rb +58 -0
- data/spec/tweetstream/client_authentication_spec.rb +83 -0
- data/spec/tweetstream/client_site_stream_spec.rb +145 -0
- data/spec/tweetstream/client_spec.rb +391 -0
- data/spec/tweetstream/client_userstream_spec.rb +74 -0
- data/spec/tweetstream/daemon_spec.rb +29 -0
- data/spec/tweetstream/site_stream_client_spec.rb +233 -0
- data/spec/tweetstream_spec.rb +129 -0
- data/tweetstream.gemspec +29 -0
- metadata +179 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe TweetStream::Client do
|
4
|
+
before(:each) do
|
5
|
+
TweetStream.configure do |config|
|
6
|
+
config.consumer_key = 'abc'
|
7
|
+
config.consumer_secret = 'def'
|
8
|
+
config.oauth_token = '123'
|
9
|
+
config.oauth_token_secret = '456'
|
10
|
+
end
|
11
|
+
@client = TweetStream::Client.new
|
12
|
+
|
13
|
+
@stream = stub("EM::Twitter::Client",
|
14
|
+
:connect => true,
|
15
|
+
:unbind => true,
|
16
|
+
:each => true,
|
17
|
+
:on_error => true,
|
18
|
+
:on_max_reconnects => true,
|
19
|
+
:on_reconnect => true,
|
20
|
+
:connection_completed => true,
|
21
|
+
:on_no_data_received => true,
|
22
|
+
:on_unauthorized => true,
|
23
|
+
:on_enhance_your_calm => true
|
24
|
+
)
|
25
|
+
EM.stub!(:run).and_yield
|
26
|
+
EM::Twitter::Client.stub!(:connect).and_return(@stream)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "User Stream support" do
|
30
|
+
context "when calling #userstream" do
|
31
|
+
it "sends the userstream host" do
|
32
|
+
EM::Twitter::Client.should_receive(:connect).with(hash_including(:host => "userstream.twitter.com")).and_return(@stream)
|
33
|
+
@client.userstream
|
34
|
+
end
|
35
|
+
|
36
|
+
it "uses the userstream uri" do
|
37
|
+
@client.should_receive(:start).once.with("/1.1/user.json", an_instance_of(Hash)).and_return(@stream)
|
38
|
+
@client.userstream
|
39
|
+
end
|
40
|
+
|
41
|
+
it "supports :replies => 'all'" do
|
42
|
+
@client.should_receive(:start).once.with("/1.1/user.json", hash_including(:replies => 'all')).and_return(@stream)
|
43
|
+
@client.userstream(:replies => 'all')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "supports :stall_warnings => 'true'" do
|
47
|
+
@client.should_receive(:start).once.with("/1.1/user.json", hash_including(:stall_warnings => 'true')).and_return(@stream)
|
48
|
+
@client.userstream(:stall_warnings => 'true')
|
49
|
+
end
|
50
|
+
|
51
|
+
it "supports :with => 'followings'" do
|
52
|
+
@client.should_receive(:start).once.with("/1.1/user.json", hash_including(:with => 'followings')).and_return(@stream)
|
53
|
+
@client.userstream(:with => 'followings')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "supports :with => 'user'" do
|
57
|
+
@client.should_receive(:start).once.with("/1.1/user.json", hash_including(:with => 'user')).and_return(@stream)
|
58
|
+
@client.userstream(:with => 'user')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "supports event callbacks" do
|
62
|
+
event = nil
|
63
|
+
@stream.should_receive(:each).and_yield(fixture('favorite.json'))
|
64
|
+
@client.on_event(:favorite) do |e|
|
65
|
+
event = e
|
66
|
+
end.userstream
|
67
|
+
|
68
|
+
expect(event[:source]).not_to be_nil
|
69
|
+
expect(event[:target]).not_to be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe TweetStream::Daemon do
|
4
|
+
describe ".new" do
|
5
|
+
it "initializes with no arguments" do
|
6
|
+
client = TweetStream::Daemon.new
|
7
|
+
expect(client).to be_kind_of(TweetStream::Client)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "initializes with defaults" do
|
11
|
+
client = TweetStream::Daemon.new
|
12
|
+
expect(client.app_name).to eq(TweetStream::Daemon::DEFAULT_NAME)
|
13
|
+
expect(client.daemon_options).to eq(TweetStream::Daemon::DEFAULT_OPTIONS)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "initializes with an app_name" do
|
17
|
+
client = TweetStream::Daemon.new('tweet_tracker')
|
18
|
+
expect(client.app_name).to eq('tweet_tracker')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#start" do
|
23
|
+
it "starts the daemon" do
|
24
|
+
client = TweetStream::Daemon.new
|
25
|
+
Daemons.should_receive(:run_proc).once
|
26
|
+
client.track('intridea')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe TweetStream::SiteStreamClient do
|
4
|
+
before do
|
5
|
+
@keys = TweetStream::Configuration::OAUTH_OPTIONS_KEYS
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "initialization" do
|
9
|
+
context "with module configuration" do
|
10
|
+
|
11
|
+
before do
|
12
|
+
TweetStream.configure do |config|
|
13
|
+
@keys.each do |key|
|
14
|
+
config.send("#{key}=", key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
TweetStream.reset
|
21
|
+
end
|
22
|
+
|
23
|
+
it "inherits module configuration" do
|
24
|
+
api = TweetStream::SiteStreamClient.new('/config_uri')
|
25
|
+
@keys.each do |key|
|
26
|
+
expect(api.send(key)).to eq(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with class configuration" do
|
32
|
+
before do
|
33
|
+
@configuration = {
|
34
|
+
:consumer_key => 'CK',
|
35
|
+
:consumer_secret => 'CS',
|
36
|
+
:oauth_token => 'AT',
|
37
|
+
:oauth_token_secret => 'AS'
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
context "during initialization" do
|
42
|
+
it "overrides module configuration" do
|
43
|
+
api = TweetStream::SiteStreamClient.new('/config_uri', @configuration)
|
44
|
+
@keys.each do |key|
|
45
|
+
expect(api.send(key)).to eq(@configuration[key])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "after initilization" do
|
51
|
+
it "overrides module configuration after initialization" do
|
52
|
+
api = TweetStream::SiteStreamClient.new('/config_uri')
|
53
|
+
@configuration.each do |key, value|
|
54
|
+
api.send("#{key}=", value)
|
55
|
+
end
|
56
|
+
@keys.each do |key|
|
57
|
+
expect(api.send(key)).to eq(@configuration[key])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#on_error" do
|
65
|
+
it "stores the on_error proc" do
|
66
|
+
@client = TweetStream::SiteStreamClient.new('/config_uri')
|
67
|
+
@client.on_error { puts 'hi' }
|
68
|
+
expect(@client.on_error).to be_kind_of(Proc)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#info" do
|
73
|
+
context "success" do
|
74
|
+
it "returns the information hash" do
|
75
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5f'
|
76
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
77
|
+
|
78
|
+
stub_request(:get, "https://sitestream.twitter.com#{@config_uri}/info.json").
|
79
|
+
to_return(:status => 200, :body => fixture('info.json'), :headers => {})
|
80
|
+
stream_info = nil
|
81
|
+
|
82
|
+
EM.run_block do
|
83
|
+
@client.info { |info| stream_info = info}
|
84
|
+
end
|
85
|
+
expect(stream_info).to be_kind_of(Hash)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "failure" do
|
90
|
+
it "invokes the on_error callback" do
|
91
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5g'
|
92
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
93
|
+
|
94
|
+
stub_request(:get, "https://sitestream.twitter.com#{@config_uri}/info.json").
|
95
|
+
to_return(:status => 401, :body => '', :headers => {})
|
96
|
+
called = false
|
97
|
+
|
98
|
+
EM.run_block do
|
99
|
+
@client.on_error { called = true }
|
100
|
+
@client.info { |info| info }
|
101
|
+
end
|
102
|
+
expect(called).to be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#add_user" do
|
109
|
+
context "success" do
|
110
|
+
it "calls a block (if passed one)" do
|
111
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5f'
|
112
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
113
|
+
|
114
|
+
stub_request(:post, "https://sitestream.twitter.com#{@config_uri}/add_user.json").
|
115
|
+
to_return(:status => 200, :body => '', :headers => {})
|
116
|
+
called = false
|
117
|
+
|
118
|
+
EM.run_block do
|
119
|
+
@client.add_user(12345) { called = true }
|
120
|
+
end
|
121
|
+
expect(called).to be_true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "failure" do
|
126
|
+
it "invokes the on_error callback" do
|
127
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5g'
|
128
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
129
|
+
|
130
|
+
stub_request(:post, "https://sitestream.twitter.com#{@config_uri}/add_user.json").
|
131
|
+
to_return(:status => 401, :body => '', :headers => {})
|
132
|
+
called = false
|
133
|
+
|
134
|
+
EM.run_block do
|
135
|
+
@client.on_error { called = true }
|
136
|
+
@client.add_user(12345) { |info| info }
|
137
|
+
end
|
138
|
+
expect(called).to be_true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
it "accepts an array of user_ids" do
|
143
|
+
@client = TweetStream::SiteStreamClient.new('/config_uri')
|
144
|
+
conn = stub('Connection')
|
145
|
+
conn.should_receive(:post).
|
146
|
+
with(:path => '/config_uri/add_user.json', :body => { 'user_id' => '1234,5678' }).
|
147
|
+
and_return(FakeHttp.new)
|
148
|
+
@client.stub(:connection) { conn }
|
149
|
+
@client.add_user(['1234','5678'])
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "#remove_user" do
|
154
|
+
context "success" do
|
155
|
+
it "calls a block (if passed one)" do
|
156
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5f'
|
157
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
158
|
+
|
159
|
+
stub_request(:post, "https://sitestream.twitter.com#{@config_uri}/remove_user.json").
|
160
|
+
to_return(:status => 200, :body => '', :headers => {})
|
161
|
+
called = false
|
162
|
+
|
163
|
+
EM.run_block do
|
164
|
+
@client.remove_user(12345) { called = true }
|
165
|
+
end
|
166
|
+
expect(called).to be_true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context "failure" do
|
171
|
+
it "invokes the on_error callback" do
|
172
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5g'
|
173
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
174
|
+
|
175
|
+
stub_request(:post, "https://sitestream.twitter.com#{@config_uri}/remove_user.json").
|
176
|
+
to_return(:status => 401, :body => '', :headers => {})
|
177
|
+
called = false
|
178
|
+
|
179
|
+
EM.run_block do
|
180
|
+
@client.on_error { called = true }
|
181
|
+
@client.remove_user(12345) { |info| info }
|
182
|
+
end
|
183
|
+
expect(called).to be_true
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
it "accepts an array of user_ids" do
|
188
|
+
@client = TweetStream::SiteStreamClient.new('/config_uri')
|
189
|
+
conn = stub('Connection')
|
190
|
+
conn.should_receive(:post).
|
191
|
+
with(:path => '/config_uri/remove_user.json', :body => { 'user_id' => '1234,5678' }).
|
192
|
+
and_return(FakeHttp.new)
|
193
|
+
@client.stub(:connection) { conn }
|
194
|
+
@client.remove_user(['1234','5678'])
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "#friends_ids" do
|
199
|
+
context "success" do
|
200
|
+
it "returns the information hash" do
|
201
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5f'
|
202
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
203
|
+
|
204
|
+
stub_request(:post, "https://sitestream.twitter.com#{@config_uri}/friends/ids.json").
|
205
|
+
to_return(:status => 200, :body => fixture('ids.json'), :headers => {})
|
206
|
+
stream_info = nil
|
207
|
+
|
208
|
+
EM.run_block do
|
209
|
+
@client.friends_ids(12345) { |info| stream_info = info }
|
210
|
+
end
|
211
|
+
expect(stream_info).to be_kind_of(Hash)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context "failure" do
|
216
|
+
it "invokes the on_error callback" do
|
217
|
+
@config_uri = '/2b/site/c/1_1_54e345d655ee3e8df359ac033648530bfbe26c5g'
|
218
|
+
@client = TweetStream::SiteStreamClient.new(@config_uri)
|
219
|
+
|
220
|
+
stub_request(:post, "https://sitestream.twitter.com#{@config_uri}/friends/ids.json").
|
221
|
+
to_return(:status => 401, :body => '', :headers => {})
|
222
|
+
called = false
|
223
|
+
|
224
|
+
EM.run_block do
|
225
|
+
@client.on_error { called = true }
|
226
|
+
@client.friends_ids(12345) { |info| info }
|
227
|
+
end
|
228
|
+
expect(called).to be_true
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe TweetStream do
|
4
|
+
|
5
|
+
context "when delegating to a client" do
|
6
|
+
before do
|
7
|
+
@stream = stub("EM::Twitter::Client",
|
8
|
+
:connect => true,
|
9
|
+
:unbind => true,
|
10
|
+
:each_item => true,
|
11
|
+
:on_error => true,
|
12
|
+
:on_max_reconnects => true,
|
13
|
+
:on_reconnect => true,
|
14
|
+
:connection_completed => true,
|
15
|
+
:on_no_data_received => true,
|
16
|
+
:on_unauthorized => true,
|
17
|
+
:on_enhance_your_calm => true
|
18
|
+
)
|
19
|
+
EM.stub!(:run).and_yield
|
20
|
+
EM::Twitter::Client.stub!(:connect).and_return(@stream)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns the same results as a client" do
|
24
|
+
Yajl::Parser.should_receive(:parse).twice.and_return({})
|
25
|
+
@stream.should_receive(:each).and_yield(sample_tweets[0].to_json)
|
26
|
+
TweetStream.track('abc','def')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe ".new" do
|
31
|
+
it "is a TweetStream::Client" do
|
32
|
+
expect(TweetStream.new).to be_a TweetStream::Client
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".respond_to?" do
|
37
|
+
it "takes an optional argument" do
|
38
|
+
expect(TweetStream.respond_to?(:new, true)).to be_true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ".username" do
|
43
|
+
it "returns the default username" do
|
44
|
+
expect(TweetStream.username).to eq(TweetStream::Configuration::DEFAULT_USERNAME)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".username=" do
|
49
|
+
it "sets the username" do
|
50
|
+
TweetStream.username = 'jack'
|
51
|
+
expect(TweetStream.username).to eq('jack')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe ".password" do
|
56
|
+
it "returns the default password" do
|
57
|
+
expect(TweetStream.password).to eq(TweetStream::Configuration::DEFAULT_PASSWORD)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe ".password=" do
|
62
|
+
it "sets the password" do
|
63
|
+
TweetStream.password = 'passw0rd'
|
64
|
+
expect(TweetStream.password).to eq('passw0rd')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe ".auth_method" do
|
69
|
+
it "shold return the default auth method" do
|
70
|
+
expect(TweetStream.auth_method).to eq(TweetStream::Configuration::DEFAULT_AUTH_METHOD)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe ".auth_method=" do
|
75
|
+
it "sets the auth method" do
|
76
|
+
TweetStream.auth_method = :basic
|
77
|
+
expect(TweetStream.auth_method).to eq(:basic)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe ".user_agent" do
|
82
|
+
it "returns the default user agent" do
|
83
|
+
expect(TweetStream.user_agent).to eq(TweetStream::Configuration::DEFAULT_USER_AGENT)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe ".user_agent=" do
|
88
|
+
it "sets the user_agent" do
|
89
|
+
TweetStream.user_agent = 'Custom User Agent'
|
90
|
+
expect(TweetStream.user_agent).to eq('Custom User Agent')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe ".configure" do
|
95
|
+
TweetStream::Configuration::VALID_OPTIONS_KEYS.each do |key|
|
96
|
+
it "sets the #{key}" do
|
97
|
+
TweetStream.configure do |config|
|
98
|
+
config.send("#{key}=", key)
|
99
|
+
expect(TweetStream.send(key)).to eq(key)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe ".options" do
|
106
|
+
it "returns the configuration as a hash" do
|
107
|
+
expect(TweetStream.options).to be_kind_of(Hash)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe ".oauth_options" do
|
112
|
+
it "returns the oauth configuration as a hash" do
|
113
|
+
expect(TweetStream.oauth_options).to be_kind_of(Hash)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '.proxy' do
|
118
|
+
it 'returns the default proxy' do
|
119
|
+
expect(TweetStream.proxy).to eq(TweetStream::Configuration::DEFAULT_PROXY)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe '.proxy=' do
|
124
|
+
it 'sets the proxy' do
|
125
|
+
TweetStream.proxy = { :uri => 'http://someproxy:8081' }
|
126
|
+
expect(TweetStream.proxy).to be_kind_of(Hash)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|