diff --git a/README.rdoc b/README.rdoc
index c68c371..5841f46 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -3,12 +3,12 @@
TweetStream provides simple Ruby access to Twitter's Streaming API
(http://apiwiki.twitter.com/Streaming-API-Documentation).
-This fork has been modified to support the site_streams API currently in Beta.
+This fork has been modified to support the site_streams API currently in Beta.
-We have also added support for location-based queries to the streaming API.
+We have also added support for location-based queries to the streaming API.
== Installation
-
+
To install from Gemcutter:
gem install tweetstream
@@ -19,15 +19,15 @@ Using TweetStream is quite simple:
require 'rubygems'
require 'tweetstream'
-
+
# This will pull a sample of all tweets based on
# your Twitter account's Streaming API role.
TweetStream::Client.new('username','password').sample do |status|
- # The status object is a special Hash with
+ # The status object is a special Hash with
# method access to its keys.
puts "#{status.text}"
end
-
+
You can also use it to track keywords or follow a given set of
user ids:
@@ -35,12 +35,12 @@ user ids:
TweetStream::Client.new('username','password').track('term1', 'term2') do |status|
puts "#{status.text}"
end
-
+
# Use 'follow' to follow a group of user ids (integers, not screen names)
TweetStream::Client.new('username','password').follow(14252, 53235) do |status|
puts "#{status.text}"
end
-
+
The methods available to TweetStream::Client will be kept in parity
with the methods available on the Streaming API wiki page.
@@ -52,7 +52,7 @@ client or daemon by passing it in as the last argument:
# Parse tweets using Yajl-Ruby
TweetStream::Client.new('abc','def',:yajl) # ...
-
+
Available options are :yajl, :json_gem (default),
:json_pure, and :active_support.
@@ -64,17 +64,17 @@ have caused some tweets not to appear in the stream. To handle these,
you can use the on_delete and on_limit methods. Example:
@client = TweetStream::Client.new('user','pass')
-
+
@client.on_delete do |status_id, user_id|
Tweet.delete(status_id)
end
-
+
@client.on_limit do |skip_count|
# do something
- end
-
+ end
+
@client.track('intridea')
-
+
The on_delete and on_limit methods can also be chained, like so:
TweetStream::Client.new('user','pass').on_delete{ |status_id, user_id|
@@ -84,8 +84,8 @@ The on_delete and on_limit methods can also be chained, like so:
}.track('intridea') do |status|
# do something with the status like normal
end
-
-You can also provide :delete and/or :limit
+
+You can also provide :delete and/or :limit
options when you make your method call:
TweetStream::Client.new('user','pass').track('intridea',
@@ -94,7 +94,7 @@ options when you make your method call:
) do |status|
# do something with the status like normal
end
-
+
Twitter recommends honoring deletions as quickly as possible, and
you would likely be wise to integrate this functionality into your
application.
@@ -115,7 +115,7 @@ down. It could be for routine maintenance, etc.
end
However, if the maximum number of reconnect attempts has been reached,
-TweetStream will raise a TweetStream::ReconnectError with
+TweetStream will raise a TweetStream::ReconnectError with
information about the timeout and number of retries attempted.
== Terminating a TweetStream
@@ -131,7 +131,7 @@ the client itself:
@statuses << status
client.stop if @statuses.size >= 10
end
-
+
When stop is called, TweetStream will return from the block
the last successfully yielded status, allowing you to make note of
it in your application as necessary.
@@ -145,12 +145,12 @@ using the TweetStream library:
TweetStream::Daemon.new('username','password', 'tracker').track('term1', 'term2') do |status|
# do something in the background
end
-
+
If you put the above into a script and run the script with ruby scriptname.rb, you will see a list of daemonization commands such
as start, stop, and run.
== Note on Patches/Pull Requests
-
+
* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a future version unintentionally.
diff --git a/examples/growl_daemon.rb b/examples/growl_daemon.rb
index e760786..42cec32 100644
--- a/examples/growl_daemon.rb
+++ b/examples/growl_daemon.rb
@@ -4,7 +4,7 @@
if args_start = ARGV.index('--')
username, password = ARGV[args_start + 1].split(':')
- tracks = ARGV[args_start + 2 .. -1]
+ tracks = ARGV[args_start + 2 .. -1]
puts "Starting a GrowlTweet to track: #{tracks.inspect}"
end
diff --git a/lib/tweetstream/client.rb b/lib/tweetstream/client.rb
index e87b95f..a9ac29d 100644
--- a/lib/tweetstream/client.rb
+++ b/lib/tweetstream/client.rb
@@ -35,7 +35,7 @@ class Client
def parser=(parser)
@parser = parser_from(parser)
end
-
+
# Create a new client with the Twitter credentials
# of the account you want to be using its API quota.
# You may also set the JSON parsing library as specified
@@ -47,16 +47,16 @@ def initialize(consumer_key, consumer_secret, access_key, access_secret, parser
self.access_secret = access_secret
self.parser = parser
end
-
+
# Returns all public statuses. The Firehose is not a generally
- # available resource. Few applications require this level of access.
- # Creative use of a combination of other resources and various access
- # levels can satisfy nearly every application use case.
+ # available resource. Few applications require this level of access.
+ # Creative use of a combination of other resources and various access
+ # levels can satisfy nearly every application use case.
def firehose(query_parameters = {}, &block)
start('statuses/firehose', query_parameters, &block)
end
-
- # Returns all retweets. The retweet stream is not a generally available
+
+ # Returns all retweets. The retweet stream is not a generally available
# resource. Few applications require this level of access. Creative
# use of a combination of other resources and various access levels
# can satisfy nearly every application use case. As of 9/11/2009,
@@ -65,8 +65,8 @@ def firehose(query_parameters = {}, &block)
def retweet(query_parameters = {}, &block)
start('statuses/retweet', query_parameters, &block)
end
-
- # Returns a random sample of all public statuses. The default access level
+
+ # Returns a random sample of all public statuses. The default access level
# provides a small proportion of the Firehose. The "Gardenhose" access
# level provides a proportion more suitable for data mining and
# research applications that desire a larger proportion to be statistically
@@ -75,11 +75,11 @@ def sample(query_parameters = {}, &block)
start('statuses/sample', query_parameters, &block)
end
- # Specify keywords to track. Queries are subject to Track Limitations,
- # described in Track Limiting and subject to access roles, described in
- # the statuses/filter method. Track keywords are case-insensitive logical
+ # Specify keywords to track. Queries are subject to Track Limitations,
+ # described in Track Limiting and subject to access roles, described in
+ # the statuses/filter method. Track keywords are case-insensitive logical
# ORs. Terms are exact-matched, and also exact-matched ignoring
- # punctuation. Phrases, keywords with spaces, are not supported.
+ # punctuation. Phrases, keywords with spaces, are not supported.
# Keywords containing punctuation will only exact match tokens.
# Query parameters may be passed as the last argument.
def track(*keywords, &block)
@@ -88,8 +88,8 @@ def track(*keywords, &block)
filter(query_params.merge(:track => keywords), &block)
end
- # Returns public statuses from or in reply to a set of users. Mentions
- # ("Hello @user!") and implicit replies ("@user Hello!" created without
+ # Returns public statuses from or in reply to a set of users. Mentions
+ # ("Hello @user!") and implicit replies ("@user Hello!" created without
# pressing the reply "swoosh") are not matched. Requires integer user
# IDs, not screen names. Query parameters may be passed as the last argument.
def follow(*user_ids, &block)
@@ -101,7 +101,7 @@ def follow(*user_ids, &block)
def locations(coords, &block)
filter(query_params.merge(:locations => coords), &block)
end
-
+
# Make a call to the statuses/filter method of the Streaming API,
# you may provide :follow, :track or both as options
# to follow the tweets of specified users or track keywords. This
@@ -117,10 +117,10 @@ def filter(query_params = {}, &block)
end
start('statuses/filter', query_params.merge(:method => :post), &block)
end
-
+
def site_follow(*user_ids, &block)
query_params ||= {:follow => user_ids}
-
+
if query_params[:follow].is_a?(Array)
query_params[:follow] = query_params[:follow].collect{|q| q.to_s}.join(',')
elsif query_params[:follow]
@@ -128,10 +128,10 @@ def site_follow(*user_ids, &block)
end
query_params[:site_streams] = query_params[:follow]
query_params[:track] = ["foo"]
-
+
start('site', query_params.merge(:method => :post, :host => 'betastream.twitter.com', :version => '2b'), &block)
end
-
+
# Set a Proc to be run when a deletion notice is received
# from the Twitter stream. For example:
#
@@ -141,7 +141,7 @@ def site_follow(*user_ids, &block)
# end
#
# Block must take two arguments: the status id and the user id.
- # If no block is given, it will return the currently set
+ # If no block is given, it will return the currently set
# deletion proc. When a block is given, the TweetStream::Client
# object is returned to allow for chaining.
def on_delete(&block)
@@ -152,7 +152,7 @@ def on_delete(&block)
@on_delete
end
end
-
+
# Set a Proc to be run when a rate limit notice is received
# from the Twitter stream. For example:
#
@@ -162,7 +162,7 @@ def on_delete(&block)
# end
#
# Block must take one argument: the number of discarded tweets.
- # If no block is given, it will return the currently set
+ # If no block is given, it will return the currently set
# limit proc. When a block is given, the TweetStream::Client
# object is returned to allow for chaining.
def on_limit(&block)
@@ -173,7 +173,7 @@ def on_limit(&block)
@on_limit
end
end
-
+
# Set a Proc to be run when an HTTP error is encountered in the
# processing of the stream. Note that TweetStream will automatically
# try to reconnect, this is for reference only. Don't panic!
@@ -184,7 +184,7 @@ def on_limit(&block)
# end
#
# Block must take one argument: the error message.
- # If no block is given, it will return the currently set
+ # If no block is given, it will return the currently set
# error proc. When a block is given, the TweetStream::Client
# object is returned to allow for chaining.
def on_error(&block)
@@ -195,7 +195,7 @@ def on_error(&block)
@on_error
end
end
-
+
def start(path, query_parameters = {}, &block) #:nodoc:
host = query_parameters.delete(:host) || 'stream.twitter.com'
@@ -205,16 +205,16 @@ def start(path, query_parameters = {}, &block) #:nodoc:
delete_proc = query_parameters.delete(:delete) || self.on_delete
limit_proc = query_parameters.delete(:limit) || self.on_limit
error_proc = query_parameters.delete(:error) || self.on_error
-
+
uri = method == :get ? build_uri(path, version, query_parameters) : build_uri(path, version)
-
+
oauth = {
:consumer_key => self.consumer_key,
:consumer_secret => self.consumer_secret,
:access_key => self.access_key,
:access_secret => self.access_secret
}
-
+
EventMachine::run {
@stream = Twitter::JSONStream.connect(
:path => uri,
@@ -228,24 +228,24 @@ def start(path, query_parameters = {}, &block) #:nodoc:
:content => (method == :post ? build_post_body(query_parameters) : ''),
:user_agent => 'TweetStream'
)
-
+
@stream.each_item do |item|
raw_hash = @parser.decode(item)
-
+
unless raw_hash.is_a?(::Hash)
error_proc.call("Unexpected JSON object in stream: #{item}")
next
end
-
+
hash = TweetStream::Hash.new(raw_hash) # @parser.parse(item)
-
+
if hash[:delete] && hash[:delete][:status]
delete_proc.call(hash[:delete][:status][:id], hash[:delete][:status][:user_id]) if delete_proc.is_a?(Proc)
elsif hash[:limit] && hash[:limit][:track]
limit_proc.call(hash[:limit][:track]) if limit_proc.is_a?(Proc)
elsif hash[:text] && hash[:user]
@last_status = TweetStream::Status.new(hash)
-
+
# Give the block the option to receive either one
# or two arguments, depending on its arity.
case block.arity
@@ -255,9 +255,9 @@ def start(path, query_parameters = {}, &block) #:nodoc:
yield @last_status, self
end
elsif hash[:for_user]
-
+
@last_status = TweetStream::Status.new(hash[:messages] || hash[:message])
-
+
# Give the block the option to receive either one
# or two arguments, depending on its arity.
case block.arity
@@ -268,23 +268,23 @@ def start(path, query_parameters = {}, &block) #:nodoc:
end
end
end
-
+
@stream.on_error do |message|
error_proc.call(message) if error_proc.is_a?(Proc)
end
-
+
@stream.on_max_reconnects do |timeout, retries|
raise TweetStream::ReconnectError.new(timeout, retries)
end
}
end
-
+
# Terminate the currently running TweetStream.
def stop
EventMachine.stop_event_loop
@last_status
end
-
+
protected
def parser_from(parser)
@@ -296,7 +296,7 @@ def parser_from(parser)
eval("TweetStream::Parsers::#{parser.to_s.split('_').map{|s| s.capitalize}.join('')}")
end
end
-
+
def build_uri(path, version = '1', query_parameters = {}) #:nodoc:
URI.parse("/#{version}/#{path}.json#{build_query_parameters(query_parameters)}")
end
@@ -304,11 +304,11 @@ def build_uri(path, version = '1', query_parameters = {}) #:nodoc:
def build_query_parameters(query)
query.size > 0 ? "?#{build_post_body(query)}" : ''
end
-
+
def build_post_body(query) #:nodoc:
return '' unless query && query.is_a?(::Hash) && query.size > 0
pairs = []
-
+
query.each_pair do |k,v|
pairs << "#{k.to_s}=#{CGI.escape(v.to_s)}"
end
diff --git a/lib/tweetstream/daemon.rb b/lib/tweetstream/daemon.rb
index 5570d7c..87c22ce 100644
--- a/lib/tweetstream/daemon.rb
+++ b/lib/tweetstream/daemon.rb
@@ -30,7 +30,7 @@ def initialize(consumer_key, consumer_secret, access_key, access_secret, app_nam
@app_name = app_name
super(consumer_key, consumer_secret, access_key, access_secret, parser)
end
-
+
def start(path, query_parameters = {}, &block) #:nodoc:
Daemons.run_proc(@app_name || 'tweetstream', :multiple => true) do
super(path, query_parameters, &block)
diff --git a/lib/tweetstream/hash.rb b/lib/tweetstream/hash.rb
index e378b02..8a734c0 100644
--- a/lib/tweetstream/hash.rb
+++ b/lib/tweetstream/hash.rb
@@ -6,7 +6,7 @@ def initialize(other_hash = {})
self[key.to_sym] = value
end
end
-
+
def method_missing(method_name, *args)
if key?(method_name.to_sym)
self[method_name.to_sym]
diff --git a/lib/tweetstream/status.rb b/lib/tweetstream/status.rb
index e44b137..2940e88 100644
--- a/lib/tweetstream/status.rb
+++ b/lib/tweetstream/status.rb
@@ -5,7 +5,7 @@ def initialize(hash)
super
self[:user] = TweetStream::User.new(self[:user]) if self[:user]
end
-
+
def id
self[:id] || super
end
diff --git a/spec/data/statuses.json b/spec/data/statuses.json
index 7c26336..7e56cc5 100644
--- a/spec/data/statuses.json
+++ b/spec/data/statuses.json
@@ -1 +1 @@
-{"favorited":false,"text":"listening to Where U Headed by Universal Playaz. http://iLike.com/s/9zpOZ #musicmonday something for the ladies","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"iLike","truncated":false,"created_at":"Tue Sep 22 01:29:13 +0000 2009","user":{"statuses_count":378,"favourites_count":1,"profile_text_color":"666666","location":"Atlanta, Ga","profile_background_image_url":"http://a3.twimg.com/profile_background_images/36516125/Universal_Playaz.jpg","profile_link_color":"2FC2EF","description":"Paper Chaser","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"252429","profile_image_url":"http://a1.twimg.com/profile_images/413331530/DIESELSTATScopy_normal.jpg","url":"http://www.myspace.com/DieselDtheg","profile_sidebar_border_color":"181A1E","screen_name":"DieselD2143","profile_background_tile":true,"followers_count":75,"protected":false,"time_zone":"Eastern Time (US & Canada)","created_at":"Thu Jun 18 15:56:32 +0000 2009","name":"Diesel D","friends_count":119,"profile_background_color":"1A1B1F","id":48392351,"utc_offset":-18000},"in_reply_to_status_id":null,"id":4161231023} {"favorited":false,"text":"David Bowie and Nine Inch Nails perform \"Hurt\" http://bit.ly/AOaWG #musicmonday #nineinchnails #nin","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"web","truncated":false,"created_at":"Tue Sep 22 01:29:16 +0000 2009","user":{"statuses_count":668,"favourites_count":25,"profile_text_color":"445d85","location":"S\u00e3o Paulo, Brazil","profile_background_image_url":"http://a3.twimg.com/profile_background_images/38174991/GeorgeRomero-oil-400.jpg","profile_link_color":"555757","description":"You think I ain't worth a dollar, but I feel like a millionaire","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"a3a7ad","profile_image_url":"http://a1.twimg.com/profile_images/96034368/n1076431955_30001395_7912_normal.jpg","url":null,"profile_sidebar_border_color":"c7d1ed","screen_name":"RenatonMiranda","profile_background_tile":true,"followers_count":111,"protected":false,"time_zone":"Santiago","created_at":"Sat Mar 14 15:03:59 +0000 2009","name":"Renato Miranda","friends_count":143,"profile_background_color":"287356","id":24379310,"utc_offset":-14400},"in_reply_to_status_id":null,"id":4161232008} {"favorited":false,"text":"#musicmonday ,time to download some songs today!! :)","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"web","truncated":false,"created_at":"Tue Sep 22 01:29:19 +0000 2009","user":{"statuses_count":188,"favourites_count":0,"profile_text_color":"3D1957","location":"under the water","profile_background_image_url":"http://s.twimg.com/a/1253562286/images/themes/theme10/bg.gif","profile_link_color":"FF0000","description":"ask me ","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"7AC3EE","profile_image_url":"http://a1.twimg.com/profile_images/421281292/twit_pic_normal.jpg","url":"http://www.exploretalent.com/contest_video.php?talentnum=2053105&cm_id=3398","profile_sidebar_border_color":"65B0DA","screen_name":"julieanne11343","profile_background_tile":true,"followers_count":9,"protected":false,"time_zone":"Pacific Time (US & Canada)","created_at":"Mon Jul 20 21:08:22 +0000 2009","name":"Julieanne","friends_count":17,"profile_background_color":"642D8B","id":58591151,"utc_offset":-28800},"in_reply_to_status_id":null,"id":4161233120} {"text":"#Musicmonday \"Dont be tardy f0r the party\"","truncated":false,"source":"mobile web","in_reply_to_status_id":null,"favorited":false,"created_at":"Tue Sep 22 01:29:19 +0000 2009","user":{"verified":false,"notifications":null,"profile_sidebar_fill_color":"e0ff92","location":"Dope Girl Island","profile_sidebar_border_color":"87bc44","description":"","following":null,"profile_background_tile":false,"followers_count":29,"profile_image_url":"http://a3.twimg.com/profile_images/217487577/badbad_normal.jpg","time_zone":"Eastern Time (US & Canada)","url":null,"friends_count":65,"profile_background_color":"9ae4e8","screen_name":"SwagGirlOnDeck","protected":false,"statuses_count":847,"favourites_count":0,"created_at":"Fri May 01 16:59:15 +0000 2009","profile_text_color":"000000","name":"Mariah Reta","id":36987168,"profile_background_image_url":"http://s.twimg.com/a/1253301564/images/themes/theme1/bg.png","utc_offset":-18000,"profile_link_color":"0000ff"},"in_reply_to_user_id":null,"id":4161233317,"in_reply_to_screen_name":null}
\ No newline at end of file
+{"favorited":false,"text":"listening to Where U Headed by Universal Playaz. http://iLike.com/s/9zpOZ #musicmonday something for the ladies","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"iLike","truncated":false,"created_at":"Tue Sep 22 01:29:13 +0000 2009","user":{"statuses_count":378,"favourites_count":1,"profile_text_color":"666666","location":"Atlanta, Ga","profile_background_image_url":"http://a3.twimg.com/profile_background_images/36516125/Universal_Playaz.jpg","profile_link_color":"2FC2EF","description":"Paper Chaser","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"252429","profile_image_url":"http://a1.twimg.com/profile_images/413331530/DIESELSTATScopy_normal.jpg","url":"http://www.myspace.com/DieselDtheg","profile_sidebar_border_color":"181A1E","screen_name":"DieselD2143","profile_background_tile":true,"followers_count":75,"protected":false,"time_zone":"Eastern Time (US & Canada)","created_at":"Thu Jun 18 15:56:32 +0000 2009","name":"Diesel D","friends_count":119,"profile_background_color":"1A1B1F","id":48392351,"utc_offset":-18000},"in_reply_to_status_id":null,"id":4161231023} {"favorited":false,"text":"David Bowie and Nine Inch Nails perform \"Hurt\" http://bit.ly/AOaWG #musicmonday #nineinchnails #nin","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"web","truncated":false,"created_at":"Tue Sep 22 01:29:16 +0000 2009","user":{"statuses_count":668,"favourites_count":25,"profile_text_color":"445d85","location":"S\u00e3o Paulo, Brazil","profile_background_image_url":"http://a3.twimg.com/profile_background_images/38174991/GeorgeRomero-oil-400.jpg","profile_link_color":"555757","description":"You think I ain't worth a dollar, but I feel like a millionaire","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"a3a7ad","profile_image_url":"http://a1.twimg.com/profile_images/96034368/n1076431955_30001395_7912_normal.jpg","url":null,"profile_sidebar_border_color":"c7d1ed","screen_name":"RenatonMiranda","profile_background_tile":true,"followers_count":111,"protected":false,"time_zone":"Santiago","created_at":"Sat Mar 14 15:03:59 +0000 2009","name":"Renato Miranda","friends_count":143,"profile_background_color":"287356","id":24379310,"utc_offset":-14400},"in_reply_to_status_id":null,"id":4161232008} {"favorited":false,"text":"#musicmonday ,time to download some songs today!! :)","in_reply_to_user_id":null,"in_reply_to_screen_name":null,"source":"web","truncated":false,"created_at":"Tue Sep 22 01:29:19 +0000 2009","user":{"statuses_count":188,"favourites_count":0,"profile_text_color":"3D1957","location":"under the water","profile_background_image_url":"http://s.twimg.com/a/1253562286/images/themes/theme10/bg.gif","profile_link_color":"FF0000","description":"ask me ","following":null,"verified":false,"notifications":null,"profile_sidebar_fill_color":"7AC3EE","profile_image_url":"http://a1.twimg.com/profile_images/421281292/twit_pic_normal.jpg","url":"http://www.exploretalent.com/contest_video.php?talentnum=2053105&cm_id=3398","profile_sidebar_border_color":"65B0DA","screen_name":"julieanne11343","profile_background_tile":true,"followers_count":9,"protected":false,"time_zone":"Pacific Time (US & Canada)","created_at":"Mon Jul 20 21:08:22 +0000 2009","name":"Julieanne","friends_count":17,"profile_background_color":"642D8B","id":58591151,"utc_offset":-28800},"in_reply_to_status_id":null,"id":4161233120} {"text":"#Musicmonday \"Dont be tardy f0r the party\"","truncated":false,"source":"mobile web","in_reply_to_status_id":null,"favorited":false,"created_at":"Tue Sep 22 01:29:19 +0000 2009","user":{"verified":false,"notifications":null,"profile_sidebar_fill_color":"e0ff92","location":"Dope Girl Island","profile_sidebar_border_color":"87bc44","description":"","following":null,"profile_background_tile":false,"followers_count":29,"profile_image_url":"http://a3.twimg.com/profile_images/217487577/badbad_normal.jpg","time_zone":"Eastern Time (US & Canada)","url":null,"friends_count":65,"profile_background_color":"9ae4e8","screen_name":"SwagGirlOnDeck","protected":false,"statuses_count":847,"favourites_count":0,"created_at":"Fri May 01 16:59:15 +0000 2009","profile_text_color":"000000","name":"Mariah Reta","id":36987168,"profile_background_image_url":"http://s.twimg.com/a/1253301564/images/themes/theme1/bg.png","utc_offset":-18000,"profile_link_color":"0000ff"},"in_reply_to_user_id":null,"id":4161233317,"in_reply_to_screen_name":null}
\ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index ec0debe..419d07c 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -21,5 +21,5 @@ def sample_tweets
end
Spec::Runner.configure do |config|
-
+
end
diff --git a/spec/tweetstream/client_spec.rb b/spec/tweetstream/client_spec.rb
index d99efe6..26a724b 100644
--- a/spec/tweetstream/client_spec.rb
+++ b/spec/tweetstream/client_spec.rb
@@ -29,7 +29,7 @@
before do
@client = TweetStream::Client.new('abc','def')
end
-
+
it 'should return a blank string if passed a nil value' do
@client.send(:build_post_body, nil).should == ''
end
@@ -53,10 +53,10 @@
describe '#start' do
before do
- @stream = stub("Twitter::JSONStream",
+ @stream = stub("Twitter::JSONStream",
:connect => true,
- :unbind => true,
- :each_item => true,
+ :unbind => true,
+ :each_item => true,
:on_error => true,
:on_max_reconnects => true,
:connection_completed => true
@@ -65,7 +65,7 @@
Twitter::JSONStream.stub!(:connect).and_return(@stream)
@client = TweetStream::Client.new('abc','def')
end
-
+
it 'should try to connect via a JSON stream' do
Twitter::JSONStream.should_receive(:connect).with(
:auth => 'abc:def',
@@ -74,10 +74,10 @@
:method => 'POST',
:user_agent => 'TweetStream'
).and_return(@stream)
-
+
@client.track('monday')
end
-
+
describe '#each_item' do
it 'should call the appropriate parser' do
@client = TweetStream::Client.new('abc','def',:active_support)
@@ -85,39 +85,39 @@
@stream.should_receive(:each_item).and_yield(sample_tweets[0].to_json)
@client.track('abc','def')
end
-
+
it 'should yield a TweetStream::Status' do
@stream.should_receive(:each_item).and_yield(sample_tweets[0].to_json)
@client.track('abc'){|s| s.should be_kind_of(TweetStream::Status)}
end
-
+
it 'should also yield the client if a block with arity 2 is given' do
@stream.should_receive(:each_item).and_yield(sample_tweets[0].to_json)
@client.track('abc'){|s,c| c.should == @client}
end
-
+
it 'should include the proper values' do
tweet = sample_tweets[0]
tweet[:id] = 123
tweet[:user][:screen_name] = 'monkey'
tweet[:text] = "Oo oo aa aa"
@stream.should_receive(:each_item).and_yield(tweet.to_json)
- @client.track('abc') do |s|
+ @client.track('abc') do |s|
s[:id].should == 123
s.user.screen_name.should == 'monkey'
s.text.should == 'Oo oo aa aa'
end
end
-
+
it 'should call the on_delete if specified' do
delete = '{ "delete": { "status": { "id": 1234, "user_id": 3 } } }'
@stream.should_receive(:each_item).and_yield(delete)
- @client.on_delete do |id, user_id|
+ @client.on_delete do |id, user_id|
id.should == 1234
user_id.should == 3
end.track('abc')
end
-
+
it 'should call the on_limit if specified' do
limit = '{ "limit": { "track": 1234 } }'
@stream.should_receive(:each_item).and_yield(limit)
@@ -125,7 +125,7 @@
track.should == 1234
end.track('abc')
end
-
+
it 'should call on_error if a non-hash response is received' do
@stream.should_receive(:each_item).and_yield('["favorited"]')
@client.on_error do |message|
@@ -133,7 +133,7 @@
end.track('abc')
end
end
-
+
describe '#on_error' do
it 'should pass the message on to the error block' do
@stream.should_receive(:on_error).and_yield('Uh oh')
@@ -142,7 +142,7 @@
end.track('abc')
end
end
-
+
describe '#on_max_reconnects' do
it 'should raise a ReconnectError' do
@stream.should_receive(:on_max_reconnects).and_yield(30, 20)
@@ -153,51 +153,51 @@
end
end
end
-
+
describe ' API methods' do
before do
@client = TweetStream::Client.new('abc','def')
end
-
+
%w(firehose retweet sample).each do |method|
it "##{method} should make a call to start with \"statuses/#{method}\"" do
@client.should_receive(:start).once.with('statuses/' + method, {})
@client.send(method)
end
end
-
+
it '#track should make a call to start with "statuses/filter" and a track query parameter' do
@client.should_receive(:start).once.with('statuses/filter', :track => 'test', :method => :post)
@client.track('test')
end
-
+
it '#track should comma-join multiple arguments' do
@client.should_receive(:start).once.with('statuses/filter', :track => 'foo,bar,baz', :method => :post)
@client.track('foo', 'bar', 'baz')
end
-
+
it '#follow should make a call to start with "statuses/filter" and a follow query parameter' do
@client.should_receive(:start).once.with('statuses/filter', :follow => '123', :method => :post)
@client.follow(123)
end
-
+
it '#follow should comma-join multiple arguments' do
@client.should_receive(:start).once.with('statuses/filter', :follow => '123,456', :method => :post)
@client.follow(123, 456)
end
-
+
it '#filter should make a call to "statuses/filter" with the query params provided' do
@client.should_receive(:start).once.with('statuses/filter', :follow => '123', :method => :post)
@client.filter(:follow => 123)
end
end
-
+
%w(on_delete on_limit).each do |proc_setter|
describe "##{proc_setter}" do
before do
@client = TweetStream::Client.new('abc','def')
end
-
+
it 'should set when a block is given' do
proc = Proc.new{|a,b| puts a }
@client.send(proc_setter, &proc)
@@ -222,7 +222,7 @@
EventMachine.should_receive :stop_event_loop
TweetStream::Client.new('test','fake').stop.should be_nil
end
-
+
it 'should return the last status yielded' do
EventMachine.should_receive :stop_event_loop
client = TweetStream::Client.new('test','fake')
diff --git a/spec/tweetstream/hash_spec.rb b/spec/tweetstream/hash_spec.rb
index 6a9737f..10e4319 100644
--- a/spec/tweetstream/hash_spec.rb
+++ b/spec/tweetstream/hash_spec.rb
@@ -4,15 +4,15 @@
it 'should be initialized by passing in an existing hash' do
TweetStream::Hash.new(:abc => 123)[:abc].should == 123
end
-
+
it 'should symbolize incoming keys' do
TweetStream::Hash.new('abc' => 123)[:abc].should == 123
end
-
+
it 'should allow access via method calls' do
TweetStream::Hash.new(:abc => 123).abc.should == 123
end
-
+
it 'should still throw NoMethod for non-existent keys' do
lambda{TweetStream::Hash.new({}).akabi}.should raise_error(NoMethodError)
end
diff --git a/spec/tweetstream/parser_spec.rb b/spec/tweetstream/parser_spec.rb
index 24292f3..941e2c5 100644
--- a/spec/tweetstream/parser_spec.rb
+++ b/spec/tweetstream/parser_spec.rb
@@ -4,18 +4,18 @@
it 'should default to the JSON Gem' do
TweetStream::Client.new('test','fake').parser.should == TweetStream::Parsers::JsonGem
end
-
+
[:json_gem, :yajl, :active_support, :json_pure].each do |engine|
describe "#{engine} parsing" do
before do
@client = TweetStream::Client.new('test','fake',engine)
@class_name = "TweetStream::Parsers::#{engine.to_s.split('_').map{|s| s.capitalize}.join('')}"
end
-
+
it 'should set the parser to the appropriate class' do
@client.parser.to_s == @class_name
end
-
+
it 'should be settable via client.parser=' do
@client.parser = nil
@client.parser.should be_nil
@@ -24,13 +24,13 @@
end
end
end
-
+
class FakeParser
def self.decode(text)
{}
end
end
-
+
it 'should be settable to a class' do
@client = TweetStream::Client.new('abc','def')
@client.parser = FakeParser
diff --git a/spec/tweetstream/status_spec.rb b/spec/tweetstream/status_spec.rb
index 7ce1817..b48ce16 100644
--- a/spec/tweetstream/status_spec.rb
+++ b/spec/tweetstream/status_spec.rb
@@ -6,7 +6,7 @@
@status.user.is_a?(TweetStream::User).should be_true
@status.user.screen_name.should == 'bob'
end
-
+
it 'should override the #id method for itself and the user' do
@status = TweetStream::Status.new(:id => 123, :user => {:id => 345})
@status.id.should == 123