smacks-savon 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,77 +4,135 @@ require "apricoteatsgorilla"
4
4
 
5
5
  module Savon
6
6
 
7
- # Savon::Response represents the HTTP response.
7
+ # Savon::Response validates and represents the HTTP/SOAP response.
8
8
  class Response
9
9
 
10
- # The HTTP error or SOAP fault message.
11
- attr_reader :error_message
10
+ # The core (inherited) methods to shadow.
11
+ @@core_methods_to_shadow = [:id]
12
+
13
+ # Returns the core methods to shadow.
14
+ def self.core_methods_to_shadow
15
+ @@core_methods_to_shadow
16
+ end
12
17
 
13
- # The HTTP error or SOAP fault code.
18
+ # Sets the core +methods+ to shadow.
19
+ def self.core_methods_to_shadow=(methods)
20
+ @@core_methods_to_shadow = methods if methods.kind_of? Array
21
+ end
22
+
23
+ # Returns the error code.
14
24
  attr_reader :error_code
15
25
 
16
- # Initializer expects the HTTP response and checks for HTTP or SOAP faults.
17
- #
18
- # === Parameters
19
- #
20
- # * +response+ - The Net::HTTP response.
21
- def initialize(response)
22
- @response = response
23
- validate
26
+ # Returns the error message.
27
+ attr_reader :error_message
28
+
29
+ # Initializer expects the +source+ to initialize from. Sets up the instance
30
+ # from a given Net::HTTPResponse or a Hash depending on the given +source+.
31
+ # May be called with a custom +root_node+ to start parsing the response at
32
+ # in case the given +source+ is a Net::HTTPResponse.
33
+ def initialize(source, root_node = nil)
34
+ if source.kind_of? Hash
35
+ initialize_from_hash source
36
+ elsif source.respond_to? :body
37
+ initialize_from_response source, root_node
38
+ end
39
+ end
40
+
41
+ # Returns the value from a given +key+ from the response Hash.
42
+ def [](key)
43
+ value_from_hash(key)
24
44
  end
25
45
 
26
- # Returns true if the request was successful, false otherwise.
46
+ # Returns +true+ in case the request was successful, +false+ otherwise
47
+ # or +nil+ in case there's no request at all.
27
48
  def success?
49
+ return nil unless @response
28
50
  @error_code.nil?
29
51
  end
30
52
 
31
- # Returns true if there was a HTTP or SOAP fault, false otherwise.
53
+ # Returns +false+ in case the request was not successful, +false+ otherwise
54
+ # or +nil+ in case there's no request at all.
32
55
  def error?
56
+ return nil unless @response
33
57
  !@error_code.nil?
34
58
  end
35
59
 
36
- # Returns the SOAP response message as a Hash. Call with XPath expession
37
- # (Hpricot search) to define a custom +root_node+ to start parsing at.
38
- # Defaults to "//return". The root node will not be included in the Hash.
39
- #
40
- # === Parameters
41
- #
42
- # * +root_node+ - Optional. Custom root node to start parsing at.
43
- def to_hash(root_node = "//return")
44
- return nil if error?
45
- ApricotEatsGorilla[@response.body, root_node]
60
+ # Returns the response Hash.
61
+ def to_hash
62
+ @hash
46
63
  end
47
64
 
48
- # Returns the SOAP response message as a Savon::Mash object. Call with
49
- # XPath expession to define a custom +root_node+. Defaults to "//return".
50
- # The root node will not be included in the Mash object.
51
- #
52
- # === Parameters
53
- #
54
- # * +root_node+ - Optional. Custom root node to start parsing at.
55
- def to_mash(root_node = "//return")
56
- return nil if error?
57
- hash = to_hash(root_node)
58
- Savon::Mash.new(hash)
59
- end
60
-
61
- # Returns the SOAP response XML.
65
+ # Returns the response body in case there is any, +nil+ otherwise.
62
66
  def to_s
67
+ return nil unless @response
63
68
  @response.body
64
69
  end
65
70
 
71
+ # Intercepts calls to missing methods and returns values from the response
72
+ # Hash in case the name of the missing +method+ matches one of its key.
73
+ # Returns a new Savon::Response instance containing the value or returns
74
+ # the actual value in case it is not a Hash.
75
+ def method_missing(method, *args)
76
+ value = value_from_hash method
77
+ return value unless value.kind_of? Hash
78
+ Savon::Response.new value
79
+ end
80
+
66
81
  private
67
82
 
68
- # Checks for HTTP errors and SOAP faults.
69
- def validate
83
+ # Initializes the instance from a Net::HTTPResponse. Validates the +response+
84
+ # against HTTP errors and SOAP faults. Continues to translate the response
85
+ # body into a Hash and delegates to initializing the instance from this Hash
86
+ # in case the request was successful. An optional +root_node+ to start parsing
87
+ # the response at might be supplied.
88
+ def initialize_from_response(response, root_node = nil)
89
+ @response = response
90
+ validate_response
91
+
92
+ if success?
93
+ root_node ||= "//return"
94
+ hash = ApricotEatsGorilla[@response.body, root_node]
95
+ initialize_from_hash hash
96
+ end
97
+ end
98
+
99
+ # Initializes the instance from a given +hash+.
100
+ def initialize_from_hash(hash)
101
+ @hash = hash
102
+ shadow_core_methods
103
+ end
104
+
105
+ # Validates the response against HTTP errors and SOAP faults and sets the
106
+ # +error_code+ and +error_message+ in case the request was not successful.
107
+ def validate_response
70
108
  if @response.code.to_i >= 300
71
- @error_message, @error_code = @response.message, @response.code
109
+ @error_message = @response.message
110
+ @error_code = @response.code
72
111
  else
73
- soap_fault = to_hash("//soap:Fault")
74
- @error_message = soap_fault[:faultstring] unless soap_fault.nil?
75
- @error_code = soap_fault[:faultcode] unless soap_fault.nil?
112
+ soap_fault = ApricotEatsGorilla[@response.body, "//soap:Fault"]
113
+ unless soap_fault.nil?
114
+ @error_message = soap_fault[:faultstring]
115
+ @error_code = soap_fault[:faultcode]
116
+ end
117
+ end
118
+ end
119
+
120
+ # Dynamically defines methods from the Array of +@@core_methods_to_shadow+
121
+ # to "shadow" inherited methods. Returns a value from the response Hash in
122
+ # case a matching public method and a key from the Hash could be found.
123
+ def shadow_core_methods
124
+ @@core_methods_to_shadow.each do |method|
125
+ if self.public_methods.include?(method.to_s) && value_from_hash(method)
126
+ self.class.send(:define_method, method) { value_from_hash(method) }
127
+ end
76
128
  end
77
129
  end
78
130
 
131
+ # Returns a value from the response Hash. Tries to convert the given +key+
132
+ # into a Symbol or a String to find the value to return.
133
+ def value_from_hash(key)
134
+ @hash[key.to_sym] || @hash[key.to_s]
135
+ end
136
+
79
137
  end
80
138
  end
data/lib/savon/service.rb CHANGED
@@ -14,24 +14,23 @@ module Savon
14
14
  # of options for the service method to receive.
15
15
  class Service
16
16
 
17
- # The logger to use.
17
+ # The logger instance to use.
18
18
  @@logger = nil
19
19
 
20
- # Initializer expects the WSDL +endpoint+ URI to use and sets up
21
- # Apricot eats Gorilla.
22
- #
23
- # ==== Parameters
24
- #
25
- # * +endpoint+ - WSDL endpoint URI to use.
20
+ # The log level to use.
21
+ @@log_level = :debug
22
+
23
+ # Initializer expects the WSDL +endpoint+ URI and defines nodes to
24
+ # namespace for Apricot eats Gorilla.
26
25
  def initialize(endpoint)
27
26
  @uri = URI(endpoint)
28
27
  ApricotEatsGorilla.nodes_to_namespace = wsdl.choice_elements
29
28
  ApricotEatsGorilla.node_namespace = "wsdl"
30
29
  end
31
30
 
32
- # Returns an instance of the WSDL.
31
+ # Returns an instance of the Savon::Wsdl.
33
32
  def wsdl
34
- @wsdl = Savon::Wsdl.new(@uri, http) if @wsdl.nil?
33
+ @wsdl = Savon::Wsdl.new(@uri, http) unless @wsdl
35
34
  @wsdl
36
35
  end
37
36
 
@@ -40,73 +39,77 @@ module Savon
40
39
  @http = http
41
40
  end
42
41
 
43
- # Sets the logger to use.
42
+ # Sets the logger instance to use.
44
43
  def self.logger=(logger)
45
44
  @@logger = logger
46
45
  end
47
46
 
47
+ # Sets the log level to use.
48
+ def self.log_level=(log_level)
49
+ @@log_level = log_level
50
+ end
51
+
48
52
  private
49
53
 
50
- # Sets up and dispatches the SOAP request. Returns a Savon::Response object.
51
- def call_service
52
- headers = { "Content-Type" => "text/xml; charset=utf-8", "SOAPAction" => @action }
54
+ # Constructs and dispatches the SOAP request. Returns a Savon::Response.
55
+ def dispatch(root_node = nil)
56
+ headers = { "Content-Type" => "text/xml; charset=utf-8", "SOAPAction" => @soap_action }
53
57
 
54
58
  body = ApricotEatsGorilla.soap_envelope("wsdl" => wsdl.namespace_uri) do
55
- ApricotEatsGorilla["wsdl:#{@action}" => @options]
59
+ ApricotEatsGorilla["wsdl:#{@soap_action}" => @options]
56
60
  end
57
61
 
58
62
  debug do |logger|
59
- logger.info "Requesting #{@uri}"
60
- logger.info headers.map { |key, value| "#{key}: #{value}" }.join("\n")
61
- logger.info body
63
+ logger.send @@log_level, "Requesting #{@uri}"
64
+ logger.send @@log_level, headers.map { |key, value| "#{key}: #{value}" }.join("\n")
65
+ logger.send @@log_level, body
62
66
  end
63
- response = @http.request_post(@uri.path, body, headers)
67
+ response = http.request_post(@uri.path, body, headers)
64
68
  debug do |logger|
65
- logger.info "Response (Status #{response.code}):"
66
- logger.info response.body
69
+ logger.send @@log_level, "Response (Status #{response.code}):"
70
+ logger.send @@log_level, response.body
67
71
  end
68
- Savon::Response.new(response)
72
+ Savon::Response.new response, root_node
69
73
  end
70
74
 
71
75
  # Returns the Net::HTTP instance to use.
72
76
  def http
73
77
  if @http.nil?
74
- raise ArgumentError, "Invalid endpoint URI" unless @uri.scheme
78
+ raise ArgumentError, "Invalid endpoint URI: #{@uri}" unless @uri.scheme
75
79
  @http = Net::HTTP.new(@uri.host, @uri.port)
76
80
  end
77
81
  @http
78
82
  end
79
83
 
80
- # Checks if the requested SOAP service method is available.
81
- # Raises an ArgumentError in case it is not.
82
- def validate_action
83
- unless wsdl.service_methods.include? @action
84
- raise ArgumentError, "Invalid service method '#{@action}'"
84
+ # Checks if the requested SOAP action was found on the WSDL.
85
+ # Raises an ArgumentError in case it was not found.
86
+ def validate_soap_action
87
+ unless wsdl.service_methods.include? @soap_action
88
+ raise ArgumentError, "Invalid service method: #{@soap_action}"
85
89
  end
86
90
  end
87
91
 
88
- # Logs a given +message+ using the @@logger instance or yields the logger
89
- # to a given +block+ for logging multiple things at once.
92
+ # Logs a given +message+ using the +@@logger+ instance or yields the logger
93
+ # to a given +block+ for logging multiple messages at once.
90
94
  def debug(message = nil)
91
95
  if @@logger
92
- @@logger.info(message) if message
96
+ @@logger.send(@@log_level, message) if message
93
97
  yield @@logger if block_given?
94
98
  end
95
99
  end
96
100
 
97
- # Method missing catches SOAP service methods called on this object. This
98
- # is the default way of calling a SOAP service. The given +method+ will be
99
- # validated against the WSDL and dispatched if available. Values supplied
100
- # through the optional Hash of +options+ will be send to the service method.
101
- #
102
- # === Parameters
103
- #
104
- # * +method+ - The SOAP service method to call.
105
- # * +options+ - Hash of options for the service method to receive.
106
- def method_missing(method, options = {})
107
- @action, @options = method.to_s, options
108
- validate_action
109
- call_service
101
+ # Catches SOAP actions called on the Savon::Service instance.
102
+ # This is the default way of calling a SOAP action.
103
+ #
104
+ # The given +method+ will be validated against available SOAP actions found
105
+ # on the WSDL and dispatched if available. Options for the SOAP action to
106
+ # receive can be given through the optional Hash of +options+. A custom
107
+ # +root_node+ to start parsing the SOAP response at might be supplied as well.
108
+ def method_missing(method, options = {}, root_node = nil)
109
+ @soap_action = ApricotEatsGorilla.to_lower_camel_case(method)
110
+ @options = options
111
+ validate_soap_action
112
+ dispatch(root_node)
110
113
  end
111
114
 
112
115
  end
data/lib/savon/wsdl.rb CHANGED
@@ -18,11 +18,6 @@ module Savon
18
18
 
19
19
  # Initializer expects an endpoint +uri+ and an +http+ connection instance,
20
20
  # then gets and parses the WSDL at the given URI.
21
- #
22
- # === Parameters
23
- #
24
- # * +uri+ - The URI of the WSDL.
25
- # * +http+ - The Net::HTTP connection instance to use.
26
21
  def initialize(uri, http)
27
22
  @uri, @http = uri, http
28
23
  get_wsdl
data/lib/savon.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), "savon"))
2
2
  require "service"
3
- require "response"
4
3
  require "wsdl"
5
- require "mash"
4
+ require "response"
@@ -0,0 +1,75 @@
1
+ module SoapResponseFixture
2
+
3
+ def some_response_hash
4
+ {
5
+ :authentication => {
6
+ :user => "example",
7
+ :password => "secret"
8
+ },
9
+ :success => true,
10
+ :tokens => ["abc", "xyz", "123"]
11
+ }
12
+ end
13
+
14
+ def response_hash_with_id
15
+ some_response_hash.dup.update :id => "shadow_id"
16
+ end
17
+
18
+ def response_hash_with_inspect
19
+ some_response_hash.dup.update :inspect => "shadow_inspect"
20
+ end
21
+
22
+ def some_soap_response
23
+ build_soap_response
24
+ end
25
+
26
+ def soap_response_with_id
27
+ build_soap_response '<id>shadow_id</id>'
28
+ end
29
+
30
+ def soap_response_with_inspect
31
+ build_soap_response '<inspect>shadow_inspect</inspect>'
32
+ end
33
+
34
+ def soap_fault_response
35
+ '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
36
+ '<soap:Body>' <<
37
+ '<soap:Fault>' <<
38
+ '<faultcode>' << soap_fault_code << '</faultcode>' <<
39
+ '<faultstring>' << soap_fault << '</faultstring>' <<
40
+ '</soap:Fault>' <<
41
+ '</soap:Body>' <<
42
+ '</soap:Envelope>'
43
+ end
44
+
45
+ def soap_fault
46
+ "Failed to authenticate client."
47
+ end
48
+
49
+ def soap_fault_code
50
+ "soap:Server"
51
+ end
52
+
53
+ private
54
+
55
+ def build_soap_response(mixin = "")
56
+ '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
57
+ '<soap:Body>' <<
58
+ '<ns2:result xmlns:ns2="http://example.com/">' <<
59
+ '<return>' <<
60
+ '<authentication>' <<
61
+ '<user>example</user>' <<
62
+ '<password>secret</password>' <<
63
+ '</authentication>' <<
64
+ mixin <<
65
+ '<success>true</success>' <<
66
+ '<tokens>abc</tokens>' <<
67
+ '<tokens>xyz</tokens>' <<
68
+ '<tokens>123</tokens>' <<
69
+ '</return>' <<
70
+ '</ns2:result>' <<
71
+ '</soap:Body>' <<
72
+ '</soap:Envelope>'
73
+ end
74
+
75
+ end
data/test/helper.rb CHANGED
@@ -6,7 +6,7 @@ require "apricoteatsgorilla"
6
6
 
7
7
  require File.join(File.dirname(__FILE__), "..", "lib", "savon")
8
8
  require File.join(File.dirname(__FILE__), "factories", "wsdl")
9
- require File.join(File.dirname(__FILE__), "fixtures", "soap_response")
9
+ require File.join(File.dirname(__FILE__), "fixtures", "soap_response_fixture")
10
10
 
11
11
  module TestHelper
12
12
 
@@ -5,116 +5,129 @@ class SavonResponseTest < Test::Unit::TestCase
5
5
  include TestHelper
6
6
  include SoapResponseFixture
7
7
 
8
- context "Savon::Response with some SOAP response" do
9
- setup do
10
- ApricotEatsGorilla.sort_keys = true
11
- @response = Savon::Response.new(response_mock(some_soap_response))
12
- end
13
-
14
- should "return a Hash on to_hash" do
15
- assert_kind_of Hash, @response.to_hash
16
- end
17
-
18
- should "return a Hash equal to the response on to_hash" do
19
- assert_equal ApricotEatsGorilla[some_soap_response, "//return"], @response.to_hash
20
- end
21
-
22
- should "return a Mash object on to_mash" do
23
- assert_kind_of Savon::Mash, @response.to_mash
24
- end
25
-
26
- should "return a Mash object equal to the response on to_mash" do
27
- assert_equal "secret", @response.to_mash.token
28
- end
29
-
30
- should "return the raw XML response on to_s" do
31
- assert_equal some_soap_response, @response.to_s
32
- end
33
-
34
- should "return 'true' on success?" do
35
- assert_equal true, @response.success?
36
- end
37
-
38
- should "return 'false' on error?" do
39
- assert_equal false, @response.error?
40
- end
41
-
42
- should "return 'nil' for error_message" do
43
- assert_equal nil, @response.error_message
44
- end
45
-
46
- should "return 'nil' for error_code" do
47
- assert_equal nil, @response.error_code
48
- end
49
- end
50
-
51
- context "Savon::Response with SOAP::Fault response" do
52
- setup do
53
- ApricotEatsGorilla.sort_keys = true
54
- @response = Savon::Response.new(response_mock(soap_fault_response))
55
- end
56
-
57
- should "return 'nil' on to_hash" do
58
- assert_equal nil, @response.to_hash
59
- end
60
-
61
- should "return 'nil' on to_mash" do
62
- assert_equal nil, @response.to_mash
63
- end
64
-
65
- should "return the raw XML response on to_s" do
66
- assert_equal soap_fault_response, @response.to_s
67
- end
68
-
69
- should "return 'false' on success?" do
70
- assert_equal false, @response.success?
71
- end
72
-
73
- should "return 'true' on error?" do
74
- assert_equal true, @response.error?
75
- end
76
-
77
- should "return the error message on error_message" do
78
- assert_equal soap_fault, @response.error_message
79
- end
80
-
81
- should "return the error code on error_code" do
82
- assert_equal soap_fault_code, @response.error_code
83
- end
84
- end
85
-
86
- context "Savon::Response with 404 error" do
87
- setup do
88
- ApricotEatsGorilla.sort_keys = true
89
- @response = Savon::Response.new(response_fault_mock)
90
- end
91
-
92
- should "return 'nil' on to_hash" do
93
- assert_equal nil, @response.to_hash
94
- end
95
-
96
- should "return 'nil' on to_mash" do
97
- assert_equal nil, @response.to_mash
98
- end
99
-
100
- should "return nil on to_s" do
101
- assert_equal nil, @response.to_s
102
- end
103
-
104
- should "return 'false' on success?" do
105
- assert_equal false, @response.success?
106
- end
107
-
108
- should "return 'true' on error?" do
109
- assert_equal true, @response.error?
110
- end
111
-
112
- should "return the error message on error_message" do
113
- assert_equal "NotFound", @response.error_message
114
- end
115
-
116
- should "return the error code on error_code" do
117
- assert_equal "404", @response.error_code
8
+ context "A Savon::Response instance" do
9
+
10
+ context "initialized with a Net::HTTPResponse containing a successful SOAP response" do
11
+ setup do
12
+ ApricotEatsGorilla.sort_keys = true
13
+ Savon::Response.core_methods_to_shadow = [:id] # set to default
14
+ @response = Savon::Response.new response_mock(some_soap_response)
15
+ end
16
+
17
+ should "return that the request was successful" do
18
+ assert_equal true, @response.success?
19
+ assert_equal false, @response.error?
20
+ end
21
+
22
+ should "return nil for error_code and error_message" do
23
+ assert_nil @response.error_code
24
+ assert_nil @response.error_message
25
+ end
26
+
27
+ should "return the SOAP response XML when calling to_s" do
28
+ assert_equal some_soap_response, @response.to_s
29
+ end
30
+
31
+ should "return the Hash translated from the SOAP response XML when calling to_hash" do
32
+ assert_kind_of Hash, @response.to_hash
33
+ assert_equal some_response_hash, @response.to_hash
34
+ end
35
+
36
+ should "return a Hash for Hash values accessed through []" do
37
+ assert_kind_of Hash, @response[:authentication]
38
+ assert_equal some_response_hash[:authentication], @response[:authentication]
39
+ end
40
+
41
+ should "return the actual value for values other than Hashes through []" do
42
+ assert_kind_of TrueClass, @response[:success]
43
+ assert_kind_of Array, @response[:tokens]
44
+ assert_equal some_response_hash[:success], @response[:success]
45
+ assert_equal some_response_hash[:tokens], @response[:tokens]
46
+ end
47
+
48
+ should "return nil when trying to access a not-existing key from the Hash" do
49
+ assert_nil @response.some_undefined_key
50
+ end
51
+
52
+ should "return a Savon::Response for Hash values accessed through method_missing" do
53
+ assert_kind_of Savon::Response, @response.authentication
54
+ end
55
+
56
+ should "return the actual value for values other than Hashes through method_missing" do
57
+ assert_kind_of TrueClass, @response.success
58
+ assert_kind_of Array, @response.tokens
59
+ assert_equal some_response_hash[:success], @response.success
60
+ assert_equal some_response_hash[:tokens], @response.tokens
61
+ end
62
+
63
+ should "by default shadow the :id method if it was found in the Hash" do
64
+ response_with_id = Savon::Response.new response_mock(soap_response_with_id)
65
+ assert_equal response_hash_with_id[:id], response_with_id.id
66
+ end
67
+
68
+ should "shadow user-specified core methods in case they were found in the Hash" do
69
+ Savon::Response.core_methods_to_shadow = [:inspect]
70
+ response_with_inspect = Savon::Response.new response_mock(soap_response_with_inspect)
71
+
72
+ assert_equal response_hash_with_inspect[:inspect], response_with_inspect.inspect
73
+ end
74
+ end
75
+
76
+ context "initialized with a Hash" do
77
+ setup do
78
+ ApricotEatsGorilla.sort_keys = true
79
+ Savon::Response.core_methods_to_shadow = [:id] # set to default
80
+ @response = Savon::Response.new some_response_hash
81
+ end
82
+
83
+ should "return nil for HTTP::Response-specific methods" do
84
+ assert_nil @response.success?
85
+ assert_nil @response.error?
86
+ assert_nil @response.error_code
87
+ assert_nil @response.error_message
88
+ assert_nil @response.to_s
89
+ end
90
+
91
+ should "return the given Hash when calling to_hash" do
92
+ assert_kind_of Hash, @response.to_hash
93
+ assert_equal some_response_hash, @response.to_hash
94
+ end
95
+
96
+ should "return a Hash for Hash values accessed through []" do
97
+ assert_kind_of Hash, @response[:authentication]
98
+ assert_equal some_response_hash[:authentication], @response[:authentication]
99
+ end
100
+
101
+ should "return the actual value for values other than Hashes through []" do
102
+ assert_kind_of TrueClass, @response[:success]
103
+ assert_kind_of Array, @response[:tokens]
104
+ assert_equal some_response_hash[:success], @response[:success]
105
+ assert_equal some_response_hash[:tokens], @response[:tokens]
106
+ end
107
+
108
+ should "return a Savon::Response for Hash values accessed through method_missing" do
109
+ assert_kind_of Savon::Response, @response.authentication
110
+ end
111
+
112
+ should "return the actual value for values other than Hashes through method_missing" do
113
+ assert_kind_of TrueClass, @response.success
114
+ assert_kind_of Array, @response.tokens
115
+ assert_equal some_response_hash[:success], @response.success
116
+ assert_equal some_response_hash[:tokens], @response.tokens
117
+ end
118
+
119
+ should "by default shadow the :id method if it was found in the Hash" do
120
+ hash_with_id = response_hash_with_id
121
+ @response = Savon::Response.new hash_with_id
122
+ assert_equal hash_with_id[:id], @response.id
123
+ end
124
+
125
+ should "shadow user-specified core methods in case they were found in the Hash" do
126
+ Savon::Response.core_methods_to_shadow = [:inspect]
127
+ response_with_inspect = Savon::Response.new response_hash_with_inspect
128
+
129
+ assert_equal response_hash_with_inspect[:inspect], response_with_inspect.inspect
130
+ end
118
131
  end
119
132
 
120
133
  end
data/test/savon_test.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), "savon"))
2
2
  require "service_test"
3
- require "response_test"
4
- require "mash_test"
5
3
  require "wsdl_test"
4
+ require "response_test"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smacks-savon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.4.1
33
+ version: 0.4.3
34
34
  version:
35
35
  description: Ruby SOAP client library to enjoy.
36
36
  email:
@@ -46,7 +46,6 @@ files:
46
46
  - lib/savon/service.rb
47
47
  - lib/savon/wsdl.rb
48
48
  - lib/savon/response.rb
49
- - lib/savon/mash.rb
50
49
  has_rdoc: true
51
50
  homepage: http://github.com/smacks/savon
52
51
  post_install_message:
@@ -78,8 +77,7 @@ test_files:
78
77
  - test/savon_test.rb
79
78
  - test/helper.rb
80
79
  - test/factories/wsdl.rb
81
- - test/fixtures/soap_response.rb
80
+ - test/fixtures/soap_response_fixture.rb
82
81
  - test/savon/service_test.rb
83
82
  - test/savon/response_test.rb
84
83
  - test/savon/wsdl_test.rb
85
- - test/savon/mash_test.rb
data/lib/savon/mash.rb DELETED
@@ -1,61 +0,0 @@
1
- module Savon
2
-
3
- # Savon::Mash converts a given Hash into an Object.
4
- class Mash
5
-
6
- # Iterates through a given +hash+, stores each value in an instance
7
- # variable and creates getter and setter methods.
8
- #
9
- # === Parameters
10
- #
11
- # * +hash+ - The Hash to convert.
12
- def initialize(hash)
13
- hash.each do |key,value|
14
- value = Savon::Mash.new(value) if value.is_a? Hash
15
-
16
- if value.is_a? Array
17
- value = value.map do |item|
18
- if item.is_a?(Hash) then Savon::Mash.new(item) else item end
19
- end
20
- end
21
-
22
- set_instance_variable(key, value)
23
- define_reader(key)
24
- define_writer(key)
25
- end
26
- end
27
-
28
- private
29
-
30
- # Sets and instance variable with a given +name+ and +value+.
31
- #
32
- # === Parameters
33
- #
34
- # * +name+ - Name of the instance variable.
35
- # * +value+ - Value of the instance variable.
36
- def set_instance_variable(name, value)
37
- self.instance_variable_set("@#{name}", value)
38
- end
39
-
40
- # Defines a reader method for a given instance +variable+.
41
- #
42
- # === Parameters
43
- #
44
- # * +variable+ - Name of the instance variable.
45
- def define_reader(variable)
46
- method = proc { self.instance_variable_get("@#{variable}") }
47
- self.class.send(:define_method, variable, method)
48
- end
49
-
50
- # Defines a writer method for a given instance +variable+.
51
- #
52
- # === Parameters
53
- #
54
- # * +variable+ - Name of the instance variable.
55
- def define_writer(variable)
56
- method = proc { |value| self.instance_variable_set("@#{variable}", value) }
57
- self.class.send(:define_method, "#{variable}=", method)
58
- end
59
-
60
- end
61
- end
@@ -1,34 +0,0 @@
1
- module SoapResponseFixture
2
-
3
- def some_soap_response
4
- '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
5
- '<soap:Body>' <<
6
- '<ns2:result xmlns:ns2="http://example.com/">' <<
7
- '<return>' <<
8
- '<token>secret</token>' <<
9
- '</return>' <<
10
- '</ns2:result>' <<
11
- '</soap:Body>' <<
12
- '</soap:Envelope>'
13
- end
14
-
15
- def soap_fault_response
16
- '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' <<
17
- '<soap:Body>' <<
18
- '<soap:Fault>' <<
19
- '<faultcode>' << soap_fault_code << '</faultcode>' <<
20
- '<faultstring>' << soap_fault << '</faultstring>' <<
21
- '</soap:Fault>' <<
22
- '</soap:Body>' <<
23
- '</soap:Envelope>'
24
- end
25
-
26
- def soap_fault
27
- "Failed to authenticate client."
28
- end
29
-
30
- def soap_fault_code
31
- "soap:Server"
32
- end
33
-
34
- end
@@ -1,18 +0,0 @@
1
- require File.join(File.dirname(__FILE__), "..", "helper")
2
-
3
- class SavonMashTest < Test::Unit::TestCase
4
-
5
- context "Creating a new Savon::Mash" do
6
- context "with a simple Hash" do
7
- should "return a Mash object matching the given Hash" do
8
- hash = { :some => { :simple => "test" } }
9
- mash = Savon::Mash.new(hash)
10
-
11
- assert_respond_to(mash, :some)
12
- assert_respond_to(mash, :simple)
13
- assert_equal "test", mash.some.simple
14
- end
15
- end
16
- end
17
-
18
- end