* Fix casting of nested members in structured types if we have a signature

type available for it even if they are already of the desired type as
   SOAP/XML-RPC unmarshaling may have gotten it wrong: SOAP likes to always
   use DateTime no matter what, for example, whereas we allow a distinction
   between Date, DateTime and Time in the signature for convenience casting
 * Fix raising of exceptions by test_invoke so functional tests fail properly on exception
   instead of returning the exception object
 * Fix Struct#each_pair to yield the value and not the member type


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1089 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Leon Breedt 2005-04-04 22:58:02 +00:00
parent a87c1d4dd8
commit d7a7d85dbd
5 changed files with 22 additions and 16 deletions

View File

@ -10,6 +10,9 @@
* Include backtraces in 500 error responses for failed request parsing, and remove "rescue nil" statements obscuring real errors for XML-RPC
* Perform casting of struct members even if the structure is already of the correct type, so that the type we specify for
the struct member is always the type of the value seen by the API implementation
*0.6.2* (27th March, 2005)

View File

@ -40,7 +40,7 @@ module ActionWebService # :nodoc:
def cast(value, signature_type) # :nodoc:
return value if signature_type.nil? # signature.length != params.length
unless signature_type.array?
unless signature_type.array? || signature_type.structured?
return value if canonical_type(value.class) == signature_type.type
end
if signature_type.array?
@ -86,13 +86,20 @@ module ActionWebService # :nodoc:
end
def cast_to_structured_type(value, signature_type) # :nodoc:
obj = signature_type.type_class.new
obj = nil
obj = value if canonical_type(value.class) == canonical_type(signature_type.type)
obj ||= signature_type.type_class.new
if value.respond_to?(:each_pair)
klass = signature_type.type_class
value.each_pair do |name, val|
type = klass.respond_to?(:member_type) ? klass.member_type(name) : nil
val = cast(val, type) if type
obj.send("#{name}=", val)
obj.__send__("#{name}=", val)
end
elsif value.respond_to?(:attributes)
signature_type.each_member do |name, type|
val = value.__send__(name)
obj.__send__("#{name}=", cast(val, type))
end
else
raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}"

View File

@ -24,7 +24,7 @@ module ActionWebService
# it can contain initial values for the structure member.
def initialize(values={})
if values.is_a?(Hash)
values.map{|k,v| send('%s=' % k.to_s, v)}
values.map{|k,v| __send__('%s=' % k.to_s, v)}
end
end
@ -36,7 +36,7 @@ module ActionWebService
# Iterates through each member
def each_pair(&block)
self.class.members.each do |name, type|
yield name, type
yield name, self.__send__(name)
end
end

View File

@ -59,10 +59,8 @@ module Test # :nodoc:
def decode_rpc_response
public_method_name, return_value = protocol.decode_response(@response.body)
unless @return_exceptions
exception = is_exception?(return_value)
raise exception if exception
end
exception = is_exception?(return_value)
raise exception if exception
return_value
end
@ -90,10 +88,10 @@ module Test # :nodoc:
def is_exception?(obj)
case protocol
when :soap
when :soap, ActionWebService::Protocol::Soap::SoapProtocol
(obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \
obj.detail.cause.is_a?(Exception)) ? obj.detail.cause : nil
when :xmlrpc
when :xmlrpc, ActionWebService::Protocol::XmlRpc::XmlRpcProtocol
obj.is_a?(XMLRPC::FaultException) ? obj : nil
end
end

View File

@ -44,11 +44,9 @@ class TC_Struct < Test::Unit::TestCase
end
def test_each_pair
members = {}
@struct.each_pair do |name, type|
members[name] = type
assert ActionWebService::BaseType === type
@struct.each_pair do |name, value|
assert_equal @struct.__send__(name), value
assert_equal @struct[name], value
end
assert_equal members, Struct.members
end
end