Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

just add spec and little style refactoring

Need to add more spec and refactor this part of code. Except if nobody
use it...
  • Loading branch information...
commit eb530275149b0c14b050f752eb4ee742480c9373 1 parent 9970988
@yaf yaf authored
View
210 lib/action_web_service/casting.rb
@@ -5,6 +5,7 @@
module ActionWebService # :nodoc:
module Casting # :nodoc:
class CastingError < ActionWebServiceError # :nodoc:
+
end
# Performs casting of arbitrary values into the correct types for the signature
@@ -19,128 +20,133 @@ def cast_expects(params)
self.class.cast_expects(@api_method, params)
end
+ def self.cast_expects(api_method, params) # :nodoc:
+ return [] if api_method.expects.nil?
+ api_method.expects.zip(params).map{ |type, param| cast(param, type) }
+ end
+
# Coerces the given +return_value+ into the type returned by this
# method
def cast_returns(return_value)
self.class.cast_returns(@api_method, return_value)
end
- class << self
- include ActionWebService::SignatureTypes
+ def self.cast_returns(api_method, return_value) # :nodoc:
+ return nil if api_method.returns.nil?
+ cast(return_value, api_method.returns[0])
+ end
- def cast_expects(api_method, params) # :nodoc:
- return [] if api_method.expects.nil?
- api_method.expects.zip(params).map{ |type, param| cast(param, type) }
+ def self.cast(value, signature_type) # :nodoc:
+ return value if signature_type.nil? # signature.length != params.length
+ return nil if value.nil?
+ # XMLRPC protocol doesn't support nil values. It uses false instead.
+ if signature_type.structured? && value.equal?(false)
+ return nil
end
- def cast_returns(api_method, return_value) # :nodoc:
- return nil if api_method.returns.nil?
- cast(return_value, api_method.returns[0])
+ unless signature_type.array? || signature_type.structured?
+ return value if canonical_type(value.class) == signature_type.type
end
- def cast(value, signature_type) # :nodoc:
- return value if signature_type.nil? # signature.length != params.length
- return nil if value.nil?
- # XMLRPC protocol doesn't support nil values. It uses false instead.
- if signature_type.structured? && value.equal?(false)
- return nil
+ if signature_type.array?
+ unless value.respond_to?(:entries)
+ raise CastingError, "Don't know how to cast #{value.class} into #{signature_type.type.inspect}"
end
- unless signature_type.array? || signature_type.structured?
- return value if canonical_type(value.class) == signature_type.type
- end
- if signature_type.array?
- unless value.respond_to?(:entries) && !value.is_a?(String)
- raise CastingError, "Don't know how to cast #{value.class} into #{signature_type.type.inspect}"
- end
- value.entries.map do |entry|
- cast(entry, signature_type.element_type)
- end
- elsif signature_type.structured?
- cast_to_structured_type(value, signature_type)
- elsif !signature_type.custom?
- cast_base_type(value, signature_type)
+ value.entries.map do |entry|
+ cast(entry, signature_type.element_type)
end
+ elsif signature_type.structured?
+ cast_to_structured_type(value, signature_type)
+ elsif !signature_type.custom?
+ cast_base_type(value, signature_type)
end
+ end
- def cast_base_type(value, signature_type) # :nodoc:
- # This is a work-around for the fact that XML-RPC special-cases DateTime values into its own DateTime type
- # in order to support iso8601 dates. This doesn't work too well for us, so we'll convert it into a Time,
- # with the caveat that we won't be able to handle pre-1970 dates that are sent to us.
- #
- # See http://dev.rubyonrails.com/ticket/2516
- value = value.to_time if value.is_a?(XMLRPC::DateTime)
-
- case signature_type.type
- when :int
- Integer(value)
- when :string
- value.to_s
- when :base64
- if value.is_a?(ActionWebService::Base64)
- value
- else
- ActionWebService::Base64.new(value.to_s)
- end
- when :bool
- return false if value.nil?
- return value if value == true || value == false
- case value.to_s.downcase
- when '1', 'true', 'y', 'yes'
- true
- when '0', 'false', 'n', 'no'
- false
- else
- raise CastingError, "Don't know how to cast #{value.class} into Boolean"
- end
- when :float
- Float(value)
- when :decimal
- BigDecimal(value.to_s)
- when :time
- value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash)
- if value.kind_of?(Time)
- value
- elsif value.kind_of?(DateTime)
- value.to_time
- else
- Time.parse(value.to_s)
- end
- when :date
- value = "%s/%s/%s" % value.values_at(*%w[2 3 1]) if value.kind_of?(Hash)
- value.kind_of?(Date) ? value : Date.parse(value.to_s)
- when :datetime
- value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash)
- value.kind_of?(DateTime) ? value : DateTime.parse(value.to_s)
+ class << self
+ include ActionWebService::SignatureTypes
+ end
+
+ private
+
+ def self.cast_to_structured_type(value, signature_type) # :nodoc:
+ obj = nil
+ # if the canonical classes are the same or if the given value is of
+ # a type that is derived from the signature_type do not attempt to
+ # "cast" the value into the signature_type as it's already good to go
+ obj = (
+ canonical_type(value.class) == canonical_type(signature_type.type) or
+ derived_from?(signature_type.type, value.class)
+ ) ? value : 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
+ # See http://dev.rubyonrails.com/ticket/3567
+ val = val.to_time if val.is_a?(XMLRPC::DateTime)
+ obj.__send__("#{name}=", val) if obj.respond_to?(name)
+ end
+ elsif value.respond_to?(:attributes)
+ signature_type.each_member do |name, type|
+ val = value.__send__(name)
+ obj.__send__("#{name}=", cast(val, type)) if obj.respond_to?(name)
end
+ else
+ raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}"
end
+ obj
+ end
+
- def cast_to_structured_type(value, signature_type) # :nodoc:
- obj = nil
- # if the canonical classes are the same or if the given value is of
- # a type that is derived from the signature_type do not attempt to
- # "cast" the value into the signature_type as it's already good to go
- obj = (
- canonical_type(value.class) == canonical_type(signature_type.type) or
- derived_from?(signature_type.type, value.class)
- ) ? value : 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
- # See http://dev.rubyonrails.com/ticket/3567
- val = val.to_time if val.is_a?(XMLRPC::DateTime)
- obj.__send__("#{name}=", val) if obj.respond_to?(name)
- end
- elsif value.respond_to?(:attributes)
- signature_type.each_member do |name, type|
- val = value.__send__(name)
- obj.__send__("#{name}=", cast(val, type)) if obj.respond_to?(name)
- end
+ def self.cast_base_type(value, signature_type) # :nodoc:
+ # This is a work-around for the fact that XML-RPC special-cases DateTime values into its own DateTime type
+ # in order to support iso8601 dates. This doesn't work too well for us, so we'll convert it into a Time,
+ # with the caveat that we won't be able to handle pre-1970 dates that are sent to us.
+ #
+ # See http://dev.rubyonrails.com/ticket/2516
+ value = value.to_time if value.is_a?(XMLRPC::DateTime)
+
+ case signature_type.type
+ when :int
+ Integer(value)
+ when :string
+ value.to_s
+ when :base64
+ if value.is_a?(ActionWebService::Base64)
+ value
+ else
+ ActionWebService::Base64.new(value.to_s)
+ end
+ when :bool
+ return false if value.nil?
+ return value if value == true || value == false
+ case value.to_s.downcase
+ when '1', 'true', 'y', 'yes'
+ true
+ when '0', 'false', 'n', 'no'
+ false
+ else
+ raise CastingError, "Don't know how to cast #{value.class} into Boolean"
+ end
+ when :float
+ Float(value)
+ when :decimal
+ BigDecimal(value.to_s)
+ when :time
+ value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash)
+ if value.kind_of?(Time)
+ value
+ elsif value.kind_of?(DateTime)
+ value.to_time
else
- raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}"
+ Time.parse(value.to_s)
end
- obj
+ when :date
+ value = "%s/%s/%s" % value.values_at(*%w[2 3 1]) if value.kind_of?(Hash)
+ value.kind_of?(Date) ? value : Date.parse(value.to_s)
+ when :datetime
+ value = "%s/%s/%s %s:%s:%s" % value.values_at(*%w[2 3 1 4 5 6]) if value.kind_of?(Hash)
+ value.kind_of?(DateTime) ? value : DateTime.parse(value.to_s)
end
end
end
View
63 spec/lib/action_web_service_base_caster_spec.rb
@@ -0,0 +1,63 @@
+require 'spec_helper'
+
+include ActionWebService::Casting
+
+describe ActionWebService::Casting::BaseCaster do
+
+ describe "#cast" do
+
+ it "returns value when signature_type is nil" do
+ BaseCaster.cast("some", nil).should eq "some"
+ end
+
+ it "returns nil when value is nil" do
+ BaseCaster.cast(nil, 0).should be_nil
+ end
+
+ it "returns nil when signature is structured? and value is false" do
+ structured_signature = OpenStruct.new(structured?: true)
+ BaseCaster.cast(false, structured_signature).should be_nil
+ end
+
+ context "when value is not false" do
+ it "returns value when signature is not structued?" do
+ matching_canonical_type = "matching_canonical_type"
+ other = "Other"
+ structured_signature = OpenStruct.new(structured?: false, type: matching_canonical_type)
+ BaseCaster.should_receive(:canonical_type).with(other.class).and_return(matching_canonical_type)
+ BaseCaster.cast(other, structured_signature).should eq other
+ end
+
+ it "returns value when signature is not array?" do
+ matching_canonical_type = "matching_canonical_type"
+ other = "Other"
+ structured_signature = OpenStruct.new(array?: false, type: matching_canonical_type)
+ BaseCaster.should_receive(:canonical_type).with(other.class).and_return(matching_canonical_type)
+ BaseCaster.cast(other, structured_signature).should eq other
+ end
+ end
+
+
+ context "when signature is array?" do
+ it "raise CastingError where value not respond_to entries and value is a String" do
+ other = "a string"
+ structured_signature = OpenStruct.new(array?: true, type: "to_inspect")
+ expect {
+ BaseCaster.cast(other, structured_signature)
+ }.to raise_error(ActionWebService::Casting::CastingError)
+ end
+ end
+
+ context "when signature is structured?" do
+ it "returns " do
+ structured_signature = OpenStruct.new(array?: false, structured?: true)
+ end
+ end
+
+ context "when signature is custom?" do
+ it "returns " do
+ structured_signature = OpenStruct.new(array?: false, structured?: false, custom?: true)
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.