Skip to content
This repository was archived by the owner on Aug 21, 2023. It is now read-only.

Commit 05c03b4

Browse files
Jason Foxdatanoise
authored andcommitted
Updating the cast_to_structured_type method to prevent 'casting' subclasses of the parameter type in the API signature. Allows keeping a Cat < Animal a Cat when passed into a service method that expects an Animal.
Signed-off-by: datanoise <[email protected]>
1 parent da6bd84 commit 05c03b4

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

lib/action_web_service/casting.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,13 @@ def cast_base_type(value, signature_type) # :nodoc:
117117

118118
def cast_to_structured_type(value, signature_type) # :nodoc:
119119
obj = nil
120-
obj = value if canonical_type(value.class) == canonical_type(signature_type.type)
121-
obj ||= signature_type.type_class.new
120+
# if the canonical classes are the same or if the given value is of
121+
# a type that is derived from the signature_type do not attempt to
122+
# "cast" the value into the signature_type as it's already good to go
123+
obj = (
124+
canonical_type(value.class) == canonical_type(signature_type.type) or
125+
derived_from?(signature_type.type, value.class)
126+
) ? value : signature_type.type_class.new
122127
if value.respond_to?(:each_pair)
123128
klass = signature_type.type_class
124129
value.each_pair do |name, val|

test/casting_test.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
require File.dirname(__FILE__) + '/abstract_unit'
22

33
module CastingTest
4+
class A < ActionWebService::Struct; end
5+
class B < A; end
46
class API < ActionWebService::API::Base
57
api_method :int, :expects => [:int]
68
api_method :str, :expects => [:string]
@@ -14,6 +16,8 @@ class API < ActionWebService::API::Base
1416
api_method :int_array, :expects => [[:int]]
1517
api_method :str_array, :expects => [[:string]]
1618
api_method :bool_array, :expects => [[:bool]]
19+
20+
api_method :a, :expects => [A]
1721
end
1822
end
1923

@@ -78,6 +82,10 @@ def test_array_type_casting_failure
7882
cast_expects(:int_array, ['1', '2.021', '4'])
7983
end
8084
end
85+
86+
def test_structured_type_casting_with_polymorphism
87+
assert cast_expects(:a, B.new)[0].is_a?(B)
88+
end
8189

8290
private
8391
def cast_expects(method_name, *args)

0 commit comments

Comments
 (0)