Skip to content

Commit

Permalink
Merge commit 'rails/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
miloops committed Oct 3, 2009
2 parents 29457a2 + 89630a7 commit 61c959a
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 25 deletions.
42 changes: 36 additions & 6 deletions activeresource/lib/active_resource/base.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'active_support' require 'active_support'
require 'active_support/core_ext/class/attribute_accessors' require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/class/inheritable_attributes' require 'active_support/core_ext/class/inheritable_attributes'
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/kernel/reporting' require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/module/attr_accessor_with_default' require 'active_support/core_ext/module/attr_accessor_with_default'
require 'active_support/core_ext/module/delegation' require 'active_support/core_ext/module/delegation'
Expand Down Expand Up @@ -155,7 +156,7 @@ module ActiveResource
# #
# <tt>404</tt> is just one of the HTTP error response codes that Active Resource will handle with its own exception. The # <tt>404</tt> is just one of the HTTP error response codes that Active Resource will handle with its own exception. The
# following HTTP response codes will also result in these exceptions: # following HTTP response codes will also result in these exceptions:
# #
# * 200..399 - Valid response, no exception (other than 301, 302) # * 200..399 - Valid response, no exception (other than 301, 302)
# * 301, 302 - ActiveResource::Redirection # * 301, 302 - ActiveResource::Redirection
# * 400 - ActiveResource::BadRequest # * 400 - ActiveResource::BadRequest
Expand Down Expand Up @@ -414,7 +415,7 @@ def headers


attr_accessor_with_default(:collection_name) { ActiveSupport::Inflector.pluralize(element_name) } #:nodoc: attr_accessor_with_default(:collection_name) { ActiveSupport::Inflector.pluralize(element_name) } #:nodoc:
attr_accessor_with_default(:primary_key, 'id') #:nodoc: attr_accessor_with_default(:primary_key, 'id') #:nodoc:

# Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.xml</tt>) # Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.xml</tt>)
# This method is regenerated at runtime based on what the \prefix is set to. # This method is regenerated at runtime based on what the \prefix is set to.
def prefix(options={}) def prefix(options={})
Expand Down Expand Up @@ -770,7 +771,7 @@ def split_options(options = {})
# my_other_course = Course.new(:name => "Philosophy: Reason and Being", :lecturer => "Ralph Cling") # my_other_course = Course.new(:name => "Philosophy: Reason and Being", :lecturer => "Ralph Cling")
# my_other_course.save # my_other_course.save
def initialize(attributes = {}) def initialize(attributes = {})
@attributes = {} @attributes = {}.with_indifferent_access
@prefix_options = {} @prefix_options = {}
load(attributes) load(attributes)
end end
Expand Down Expand Up @@ -915,7 +916,7 @@ def dup
def save def save
new? ? create : update new? ? create : update
end end

# Saves the resource. # Saves the resource.
# #
# If the resource is new, it is created via +POST+, otherwise the # If the resource is new, it is created via +POST+, otherwise the
Expand All @@ -924,7 +925,7 @@ def save
# With <tt>save!</tt> validations always run. If any of them fail # With <tt>save!</tt> validations always run. If any of them fail
# ActiveResource::ResourceInvalid gets raised, and nothing is POSTed to # ActiveResource::ResourceInvalid gets raised, and nothing is POSTed to
# the remote system. # the remote system.
# See ActiveResource::Validations for more information. # See ActiveResource::Validations for more information.
# #
# There's a series of callbacks associated with <tt>save!</tt>. If any # There's a series of callbacks associated with <tt>save!</tt>. If any
# of the <tt>before_*</tt> callbacks return +false+ the action is # of the <tt>before_*</tt> callbacks return +false+ the action is
Expand Down Expand Up @@ -1099,6 +1100,36 @@ def load(attributes)
self self
end end


# Updates a single attribute and then saves the object.
#
# Note: Unlike ActiveRecord::Base.update_attribute, this method <b>is</b>
# subject to normal validation routines as an update sends the whole body
# of the resource in the request. (See Validations).
#
# As such, this method is equivalent to calling update_attributes with a single attribute/value pair.
#
# If the saving fails because of a connection or remote service error, an
# exception will be raised. If saving fails because the resource is
# invalid then <tt>false</tt> will be returned.
def update_attribute(name, value)
self.send("#{name}=".to_sym, value)
self.save
end

# Updates this resource with all the attributes from the passed-in Hash
# and requests that the record be saved.
#
# If the saving fails because of a connection or remote service error, an
# exception will be raised. If saving fails because the resource is
# invalid then <tt>false</tt> will be returned.
#
# Note: Though this request can be made with a partial set of the
# resource's attributes, the full body of the request will still be sent
# in the save request to the remote service.
def update_attributes(attributes)
load(attributes) && save
end

# For checking <tt>respond_to?</tt> without searching the attributes (which is faster). # For checking <tt>respond_to?</tt> without searching the attributes (which is faster).
alias_method :respond_to_without_attributes?, :respond_to? alias_method :respond_to_without_attributes?, :respond_to?


Expand All @@ -1119,7 +1150,6 @@ def respond_to?(method, include_priv = false)
super super
end end



protected protected
def connection(refresh = false) def connection(refresh = false)
self.class.connection(refresh) self.class.connection(refresh)
Expand Down
38 changes: 22 additions & 16 deletions activeresource/test/cases/base/load_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -15,26 +15,21 @@ class Comment < ActiveResource::Base


module Deeply module Deeply
module Nested module Nested

class Note < ActiveResource::Base class Note < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000" self.site = "http://37s.sunrise.i:3000"
end end


class Comment < ActiveResource::Base class Comment < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000" self.site = "http://37s.sunrise.i:3000"
end end

module TestDifferentLevels

class Note < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000"
end

end


module TestDifferentLevels
class Note < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000"
end
end
end end
end end

end end




Expand Down Expand Up @@ -68,6 +63,19 @@ def test_load_simple_hash
assert_equal @matz.stringify_keys, @person.load(@matz).attributes assert_equal @matz.stringify_keys, @person.load(@matz).attributes
end end


def test_after_load_attributes_are_accessible
assert_equal Hash.new, @person.attributes
assert_equal @matz.stringify_keys, @person.load(@matz).attributes
assert_equal @matz[:name], @person.attributes['name']
end

def test_after_load_attributes_are_accessible_via_indifferent_access
assert_equal Hash.new, @person.attributes
assert_equal @matz.stringify_keys, @person.load(@matz).attributes
assert_equal @matz[:name], @person.attributes['name']
assert_equal @matz[:name], @person.attributes[:name]
end

def test_load_one_with_existing_resource def test_load_one_with_existing_resource
address = @person.load(:street_address => @first_address).street_address address = @person.load(:street_address => @first_address).street_address
assert_kind_of StreetAddress, address assert_kind_of StreetAddress, address
Expand Down Expand Up @@ -143,7 +151,7 @@ def test_recursively_loaded_collections
assert_kind_of String, places.first assert_kind_of String, places.first
assert_equal @deep[:street][:state][:places].first, places.first assert_equal @deep[:street][:state][:places].first, places.first
end end

def test_nested_collections_within_the_same_namespace def test_nested_collections_within_the_same_namespace
n = Highrise::Note.new(:comments => [{ :name => "1" }]) n = Highrise::Note.new(:comments => [{ :name => "1" }])
assert_kind_of Highrise::Comment, n.comments.first assert_kind_of Highrise::Comment, n.comments.first
Expand All @@ -158,6 +166,4 @@ def test_nested_collections_in_different_levels_of_namespaces
n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }]) n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
end end


end end
70 changes: 67 additions & 3 deletions activeresource/test/cases/base_test.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ def setup
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person') @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
@david = { :id => 2, :name => 'David' }.to_xml(:root => 'person') @david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
@greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person') @greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
@addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address') @addy = { :id => 1, :street => '12345 Street', :country => 'Australia' }.to_xml(:root => 'address')
@default_request_headers = { 'Content-Type' => 'application/xml' } @default_request_headers = { 'Content-Type' => 'application/xml' }
@rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person") @rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
@people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people') @people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
@people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people') @people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
@addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses') @addresses = [{ :id => 1, :street => '12345 Street', :country => 'Australia' }].to_xml(:root => 'addresses')


# - deep nested resource - # - deep nested resource -
# - Luis (Customer) # - Luis (Customer)
Expand Down Expand Up @@ -102,6 +102,9 @@ def setup
Person.password = nil Person.password = nil
end end


########################################################################
# Tests relating to setting up the API-connection configuration
########################################################################


def test_site_accessor_accepts_uri_or_string_argument def test_site_accessor_accepts_uri_or_string_argument
site = URI.parse('http://localhost') site = URI.parse('http://localhost')
Expand Down Expand Up @@ -509,6 +512,11 @@ def test_updating_baseclass_timeout_wipes_descendent_cached_connection_objects
assert_not_equal(first_connection, second_connection, 'Connection should be re-created') assert_not_equal(first_connection, second_connection, 'Connection should be re-created')
end end



########################################################################
# Tests for setting up remote URLs for a given model (including adding
# parameters appropriately)
########################################################################
def test_collection_name def test_collection_name
assert_equal "people", Person.collection_name assert_equal "people", Person.collection_name
end end
Expand Down Expand Up @@ -637,6 +645,10 @@ def test_custom_prefix
assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters) assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters)
end end



########################################################################
# Tests basic CRUD functions (find/save/create etc)
########################################################################
def test_respond_to def test_respond_to
matz = Person.find(1) matz = Person.find(1)
assert matz.respond_to?(:name) assert matz.respond_to?(:name)
Expand Down Expand Up @@ -813,6 +825,55 @@ def test_update_conflict
assert_raise(ActiveResource::ResourceConflict) { Person.find(2).save } assert_raise(ActiveResource::ResourceConflict) { Person.find(2).save }
end end



######
# update_attribute(s)(!)

def test_update_attribute_as_symbol
matz = Person.first
matz.expects(:save).returns(true)

assert_equal "Matz", matz.name
assert matz.update_attribute(:name, "David")
assert_equal "David", matz.name
end

def test_update_attribute_as_string
matz = Person.first
matz.expects(:save).returns(true)

assert_equal "Matz", matz.name
assert matz.update_attribute('name', "David")
assert_equal "David", matz.name
end


def test_update_attributes_as_symbols
addy = StreetAddress.first(:params => {:person_id => 1})
addy.expects(:save).returns(true)

assert_equal "12345 Street", addy.street
assert_equal "Australia", addy.country
assert addy.update_attributes(:street => '54321 Street', :country => 'USA')
assert_equal "54321 Street", addy.street
assert_equal "USA", addy.country
end

def test_update_attributes_as_strings
addy = StreetAddress.first(:params => {:person_id => 1})
addy.expects(:save).returns(true)

assert_equal "12345 Street", addy.street
assert_equal "Australia", addy.country
assert addy.update_attributes('street' => '54321 Street', 'country' => 'USA')
assert_equal "54321 Street", addy.street
assert_equal "USA", addy.country
end


#####
# Mayhem and destruction

def test_destroy def test_destroy
assert Person.find(1).destroy assert Person.find(1).destroy
ActiveResource::HttpMock.respond_to do |mock| ActiveResource::HttpMock.respond_to do |mock|
Expand Down Expand Up @@ -852,7 +913,7 @@ def test_delete_with_custom_prefix
end end
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) } assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
end end

def test_delete_with_410_gone def test_delete_with_410_gone
assert Person.delete(1) assert Person.delete(1)
ActiveResource::HttpMock.respond_to do |mock| ActiveResource::HttpMock.respond_to do |mock|
Expand All @@ -861,6 +922,9 @@ def test_delete_with_410_gone
assert_raise(ActiveResource::ResourceGone) { Person.find(1) } assert_raise(ActiveResource::ResourceGone) { Person.find(1) }
end end


########################################################################
# Tests the more miscelaneous helper methods
########################################################################
def test_exists def test_exists
# Class method. # Class method.
assert !Person.exists?(nil) assert !Person.exists?(nil)
Expand Down

0 comments on commit 61c959a

Please sign in to comment.