smacks-savon 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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