From d5ce8537164912e79dffc5a054ecd9ae6ecb8075 Mon Sep 17 00:00:00 2001 From: Erik Michaels-Ober Date: Fri, 26 Jul 2013 11:39:24 +0200 Subject: [PATCH] Make Twitter::SearchResults enumerable --- README.md | 13 +++++++--- lib/twitter/base.rb | 2 +- lib/twitter/cursor.rb | 2 +- lib/twitter/search_results.rb | 38 +++++++++++++++++++++++------ spec/twitter/api/search_spec.rb | 9 +++---- spec/twitter/search_results_spec.rb | 24 +++++++++++------- 6 files changed, 61 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 1f0a86e5e..691547524 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,13 @@ Here is a list of the interface changes to `Twitter::Cursor`: * `#all` has been replaced by `#to_a`. * `#collection` and its aliases have been removed. +### Search Results +The `Twitter::SearchResults` class has also been redesigned to have an +[`Enumerable`][enumerable] interface. The `#statuses` method and its aliases +(`#collection` and `#results`) have been replaced by `#to_a`. Additionally, +this class no longer inherits from `Twitter::Base`. As a result, the `#[]` +method has been removed without replacement. + ## Configuration Twitter API v1.1 requires you to authenticate via OAuth, so you'll need to [register your application with Twitter][register]. Once you've registered an @@ -412,14 +419,14 @@ Twitter.status(27558893223) **Collect the 3 most recent marriage proposals to @justinbieber** ```ruby -Twitter.search("to:justinbieber marry me", :count => 3, :result_type => "recent").results.collect do |status| - "#{status.from_user}: #{status.text}" +Twitter.search("to:justinbieber marry me", :count => 3, :result_type => "recent").collect do |tweet| + "#{tweet.from_user}: #{tweet.text}" end ``` **Find a Japanese-language Tweet tagged #ruby (excluding retweets)** ```ruby -Twitter.search("#ruby -rt", :lang => "ja", :count => 1).results.first.text +Twitter.search("#ruby -rt", :lang => "ja").first.text ``` For more usage examples, please see the full [documentation][]. diff --git a/lib/twitter/base.rb b/lib/twitter/base.rb index a002a0fb0..8b3d081d4 100644 --- a/lib/twitter/base.rb +++ b/lib/twitter/base.rb @@ -28,7 +28,7 @@ def self.attr_reader(*attrs) include mod end - # Construct an object from the response hash + # Construct an object from a response hash # # @param response [Hash] # @return [Twitter::Base] diff --git a/lib/twitter/cursor.rb b/lib/twitter/cursor.rb index 0b80447b1..6840d7a24 100644 --- a/lib/twitter/cursor.rb +++ b/lib/twitter/cursor.rb @@ -6,7 +6,7 @@ class Cursor alias to_hash attrs alias to_hsh attrs - # Initializes a new Cursor object + # Construct a new Cursor object from a response hash # # @param response [Hash] # @param key [String, Symbol] The key to fetch the data from the response diff --git a/lib/twitter/search_results.rb b/lib/twitter/search_results.rb index c25e62880..79aa279ff 100644 --- a/lib/twitter/search_results.rb +++ b/lib/twitter/search_results.rb @@ -1,16 +1,38 @@ -require 'twitter/base' - module Twitter - class SearchResults < Twitter::Base + class SearchResults + include Enumerable + attr_reader :attrs + alias to_h attrs + alias to_hash attrs + alias to_hsh attrs + + # Construct a new SearchResults object from a response hash + # + # @param response [Hash] + # @return [Twitter::Base] + def self.from_response(response={}) + new(response[:body]) + end - # @return [Array] - def statuses - @results ||= Array(@attrs[:statuses]).map do |tweet| + # Initializes a new SearchResults object + # + # @param attrs [Hash] + # @return [Twitter::Base] + def initialize(attrs={}) + @attrs = attrs + @collection = Array(@attrs[:statuses]).map do |tweet| Twitter::Tweet.new(tweet) end end - alias collection statuses - alias results statuses + + # @return [Enumerator] + def each(start = 0, &block) + return to_enum(:each) unless block_given? + Array(@collection[start..-1]).each do |element| + yield element + end + self + end # @return [Float] def completed_in diff --git a/spec/twitter/api/search_spec.rb b/spec/twitter/api/search_spec.rb index 2fa6e21b6..38dabb2a5 100644 --- a/spec/twitter/api/search_spec.rb +++ b/spec/twitter/api/search_spec.rb @@ -17,9 +17,8 @@ it "returns recent Tweets related to a query with images and videos embedded" do search = @client.search("twitter") expect(search).to be_a Twitter::SearchResults - expect(search.results).to be_an Array - expect(search.results.first).to be_a Twitter::Tweet - expect(search.results.first.text).to eq "Bubble Mailer #freebandnames" + expect(search.first).to be_a Twitter::Tweet + expect(search.first.text).to eq "Bubble Mailer #freebandnames" end it "returns the max_id value for a search result" do search = @client.search("twitter") @@ -33,8 +32,8 @@ it "returns an empty array" do search = @client.search("twitter") - expect(search.results).to be_an Array - expect(search.results).to be_empty + expect(search.to_a).to be_an Array + expect(search.to_a).to be_empty end end end diff --git a/spec/twitter/search_results_spec.rb b/spec/twitter/search_results_spec.rb index e94e8ed52..e7fba2446 100644 --- a/spec/twitter/search_results_spec.rb +++ b/spec/twitter/search_results_spec.rb @@ -2,15 +2,21 @@ describe Twitter::SearchResults do - describe "#statuses" do - it "returns an array of Tweets" do - statuses = Twitter::SearchResults.new(:statuses => [{:id => 25938088801, :text => "tweet!"}]).statuses - expect(statuses).to be_an Array - expect(statuses.first).to be_a Twitter::Tweet - end - it "is empty when not set" do - statuses = Twitter::SearchResults.new.statuses - expect(statuses).to be_empty + describe "#each" do + before do + @search_results = Twitter::SearchResults.new(:statuses => [{:id => 1}, {:id => 2}, {:id => 3}, {:id => 4}, {:id => 5}, {:id => 6}]) + end + it "iterates" do + count = 0 + @search_results.each{count += 1} + expect(count).to eq 6 + end + context "with start" do + it "iterates" do + count = 0 + @search_results.each(5){count += 1} + expect(count).to eq 1 + end end end