Permalink
Browse files

Respond with NullObject if Tweet has no User

Closes #415.
  • Loading branch information...
1 parent 810129b commit 17880f491726cee77c1cbcf914887e95d5e6ae7e @sferik committed Jun 30, 2013
View
@@ -32,7 +32,11 @@ module Users
# Twitter.settings
def settings(options={})
request_method = options.size.zero? ? :get : :post
- object_from_response(Twitter::Settings, request_method, "/1.1/account/settings.json", options)
+ settings = object_from_response(Twitter::Settings, request_method, "/1.1/account/settings.json", options)
+ # https://dev.twitter.com/issues/59
+ trend_location = Array(settings.attrs[:trend_location]).first
+ settings.update(trend_location: trend_location)
+ settings
end
# Returns the requesting user if authentication was successful, otherwise raises {Twitter::Error::Unauthorized}
View
@@ -1,4 +1,5 @@
require 'forwardable'
+require 'twitter/null_object'
module Twitter
class Base
@@ -62,6 +63,20 @@ def new_without_self(klass, key1, key2)
attrs = @attrs.dup
value = attrs.delete(key1)
klass.new(value.update(key2 => attrs))
+ else
+ NullObject.new
+ end
+ end
+
+ # Create a new object (or NullObject) from attributes
+ #
+ # @param klass [Class]
+ # @param key [Symbol]
+ def new_or_null_object(klass, key)
+ if @attrs[key]
+ klass.new(@attrs[key])
+ else
+ NullObject.new
end
end
@@ -9,12 +9,12 @@ class DirectMessage < Twitter::Identity
# @return [Twitter::User]
def recipient
- @recipient ||= Twitter::User.new(@attrs[:recipient]) unless @attrs[:recipient].nil?
+ @recipient ||= new_or_null_object(Twitter::User, :recipient)
end
# @return [Twitter::User]
def sender
- @sender ||= Twitter::User.new(@attrs[:sender]) unless @attrs[:sender].nil?
+ @sender ||= new_or_null_object(Twitter::User, :sender)
end
end
View
@@ -9,7 +9,7 @@ class List < Twitter::Identity
# @return [Twitter::User]
def user
- @user ||= Twitter::User.new(@attrs[:user]) unless @attrs[:user].nil?
+ @user ||= new_or_null_object(Twitter::User, :user)
end
end
View
@@ -0,0 +1,16 @@
+class NullObject
+
+ def method_missing(*args, &block)
+ nil
+ end
+
+ def null?
+ true
+ end
+ alias nil? null?
+
+ def !
+ true
+ end
+
+end
View
@@ -7,7 +7,7 @@ class Place < Twitter::Identity
# @return [Twitter::Geo]
def bounding_box
- @bounding_box ||= Twitter::GeoFactory.new(@attrs[:bounding_box]) unless @attrs[:bounding_box].nil?
+ @bounding_box ||= new_or_null_object(Twitter::GeoFactory, :bounding_box)
end
# @return [String]
@@ -13,12 +13,12 @@ def initialize(attrs={})
# @return [Twitter::SourceUser]
def source
- @source ||= Twitter::SourceUser.new(@attrs[:source]) unless @attrs[:source].nil?
+ @source ||= new_or_null_object(Twitter::SourceUser, :source)
end
# @return [Twitter::TargetUser]
def target
- @target ||= Twitter::TargetUser.new(@attrs[:target]) unless @attrs[:target].nil?
+ @target ||= new_or_null_object(Twitter::TargetUser, :target)
end
# Update the attributes of a Relationship
View
@@ -8,7 +8,7 @@ class Settings < Twitter::Base
# @return [Twitter::Place]
def trend_location
- @trend_location ||= Twitter::Place.new(Array(@attrs[:trend_location]).first) unless @attrs[:trend_location].nil?
+ @trend_location ||= new_or_null_object(Twitter::Place, :trend_location)
end
end
View
@@ -10,14 +10,14 @@ class Tweet < Twitter::Identity
:in_reply_to_screen_name, :in_reply_to_attrs_id, :in_reply_to_status_id,
:in_reply_to_user_id, :lang, :retweet_count, :retweeted, :source, :text,
:to_user, :to_user_id, :to_user_name, :truncated
- alias in_reply_to_tweet_id in_reply_to_status_id
alias favorites_count favorite_count
alias favourite_count favorite_count
alias favourites_count favorite_count
alias favoriters_count favorite_count
alias favouriters_count favorite_count
alias favourited favorited
alias favourited? favorited?
+ alias in_reply_to_tweet_id in_reply_to_status_id
alias retweeters_count retweet_count
def_delegators :user, :profile_image_url, :profile_image_url_https
@@ -38,7 +38,7 @@ def filter_level
# @return [String]
# @note May be > 140 characters.
def full_text
- if retweeted_status
+ if retweeted_status?
prefix = text[/\A(RT @[a-z0-9_]{1,20}: )/i, 1]
[prefix, retweeted_status.text].compact.join
else
@@ -48,7 +48,7 @@ def full_text
# @return [Twitter::Geo]
def geo
- @geo ||= Twitter::GeoFactory.new(@attrs[:geo]) unless @attrs[:geo].nil?
+ @geo ||= new_or_null_object(Twitter::GeoFactory, :geo)
end
# @note Must include entities in your request for this method to work
@@ -65,12 +65,12 @@ def media
# @return [Twitter::Metadata]
def metadata
- @metadata ||= Twitter::Metadata.new(@attrs[:metadata]) unless @attrs[:metadata].nil?
+ @metadata ||= new_or_null_object(Twitter::Metadata, :metadata)
end
# @return [Twitter::Place]
def place
- @place ||= Twitter::Place.new(@attrs[:place]) unless @attrs[:place].nil?
+ @place ||= new_or_null_object(Twitter::Place, :place)
end
# @return [Boolean]
@@ -79,18 +79,21 @@ def reply?
end
# @return [Boolean]
- def retweet?
+ def retweeted_status?
!!retweeted_status
end
+ alias retweet? retweeted_status?
+ alias retweeted? retweeted_status?
+ alias retweeted_tweet? retweeted_status?
# If this Tweet is a retweet, the original Tweet is available here.
#
# @return [Twitter::Tweet]
def retweeted_status
- @retweeted_status ||= self.class.new(@attrs[:retweeted_status]) unless @attrs[:retweeted_status].nil?
+ @retweeted_status ||= new_or_null_object(self.class, :retweeted_status)
end
- alias retweeted_tweet retweeted_status
alias retweet retweeted_status
+ alias retweeted_tweet retweeted_status
# @note Must include entities in your request for this method to work
# @return [Array<Twitter::Entity::Symbol>]
View
@@ -89,10 +89,13 @@ def profile_image_url?
def status
@status ||= new_without_self(Twitter::Tweet, :status, :user)
end
+ alias tweet status
def status?
!@attrs[:status].nil?
end
+ alias tweet? status?
+ alias tweeted? status?
private
@@ -4,7 +4,7 @@
describe "#trend_location" do
it "returns a Twitter::Place when set" do
- place = Twitter::Settings.new(trend_location: [{countryCode: 'US', name: 'San Francisco', country: 'United States', placeType: {name: 'Town', code: 7}, woeid: 2487956, parentid: 23424977, url: 'http://where.yahooapis.com/v1/place/2487956'}])
+ place = Twitter::Settings.new(trend_location: {countryCode: 'US', name: 'San Francisco', country: 'United States', placeType: {name: 'Town', code: 7}, woeid: 2487956, parentid: 23424977, url: 'http://where.yahooapis.com/v1/place/2487956'})
expect(place.trend_location).to be_a Twitter::Place
end
it "returns nil when not set" do

0 comments on commit 17880f4

Please sign in to comment.