smacks-savon 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +11 -0
- data/lib/savon.rb +5 -0
- data/lib/savon/response.rb +29 -0
- data/lib/savon/service.rb +109 -0
- data/lib/savon/wsdl.rb +60 -0
- data/tests/factories/wsdl.rb +127 -0
- data/tests/fixtures/soap_response.rb +15 -0
- data/tests/helper.rb +46 -0
- data/tests/savon/response_test.rb +28 -0
- data/tests/savon/service_test.rb +32 -0
- data/tests/savon/wsdl_test.rb +45 -0
- data/tests/savon_test.rb +5 -0
- metadata +85 -0
data/README.rdoc
ADDED
data/lib/savon.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'apricoteatsgorilla'
|
4
|
+
|
5
|
+
module Savon
|
6
|
+
|
7
|
+
# Savon::Response represents the SOAP response and offers different methods
|
8
|
+
# to handle the response.
|
9
|
+
class Response
|
10
|
+
|
11
|
+
# Initializer to set the SOAP response.
|
12
|
+
def initialize(response)
|
13
|
+
@response = response
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the SOAP response message as a Hash. Call with XPath expession
|
17
|
+
# (Hpricot search) as parameter to define a custom root node. The root node
|
18
|
+
# itself will not be included in the Hash.
|
19
|
+
def to_hash(root_node = "//return")
|
20
|
+
ApricotEatsGorilla(@response.body, root_node)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the raw XML response.
|
24
|
+
def to_s
|
25
|
+
@response.body
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
require 'apricoteatsgorilla'
|
6
|
+
|
7
|
+
module Savon
|
8
|
+
|
9
|
+
# Savon::Service is the actual SOAP client implementation to use.
|
10
|
+
#
|
11
|
+
# Instantiate Savon::Service and pass in the WSDL of the service you would
|
12
|
+
# like to work with. Then simply call the SOAP service method on your
|
13
|
+
# instance (which will be catched via method_missing) and pass in a Hash
|
14
|
+
# of options you would like to send.
|
15
|
+
#
|
16
|
+
# Example:
|
17
|
+
# proxy = Savon::Service.new "http://example.com/ExampleService?wsdl"
|
18
|
+
# response = proxy.findExampleById(:id => "123")
|
19
|
+
#
|
20
|
+
# Get the raw response XML:
|
21
|
+
# response.to_s
|
22
|
+
#
|
23
|
+
# Get it as a Hash (offers optional XPath expression to set a custom root node):
|
24
|
+
# response.to_hash
|
25
|
+
# response.to_hash("//return")
|
26
|
+
#
|
27
|
+
# Or as a Mash object (also offers specifying a custom root node):
|
28
|
+
# response.to_mash
|
29
|
+
# response.to_mash("//user/email")
|
30
|
+
class Service
|
31
|
+
|
32
|
+
# Sets the HTTP connection instance.
|
33
|
+
attr_writer :http
|
34
|
+
|
35
|
+
# Initializer sets the endpoint URI.
|
36
|
+
def initialize(endpoint)
|
37
|
+
@uri = URI(endpoint)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns an Wsdl instance.
|
41
|
+
def wsdl
|
42
|
+
@wsdl = Savon::Wsdl.new(@uri, http) if @wsdl.nil?
|
43
|
+
@wsdl
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Sets up the request headers and body, makes the request and returns a
|
49
|
+
# Savon::Response object.
|
50
|
+
def call_service
|
51
|
+
headers = { 'Content-Type' => 'text/xml; charset=utf-8', 'SOAPAction' => @action }
|
52
|
+
body = ApricotEatsGorilla.soap_envelope("wsdl" => wsdl.namespace_uri) do
|
53
|
+
ApricotEatsGorilla("wsdl:#{@action}" => namespaced_options)
|
54
|
+
end
|
55
|
+
response = @http.request_post(@uri.path, body, headers)
|
56
|
+
Savon::Response.new(response)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns an HTTP connection instance.
|
60
|
+
def http
|
61
|
+
if @http.nil?
|
62
|
+
raise ArgumentError, "Invalid endpoint URI" unless @uri.scheme
|
63
|
+
@http = Net::HTTP.new(@uri.host, @uri.port)
|
64
|
+
#@http.set_debug_output(STDOUT)
|
65
|
+
#@http.read_timeout = 5
|
66
|
+
end
|
67
|
+
@http
|
68
|
+
end
|
69
|
+
|
70
|
+
# Checks if the requestion SOAP action is available.
|
71
|
+
# Raises an ArgumentError in case it isn't.
|
72
|
+
def validate_action
|
73
|
+
unless wsdl.service_methods.include? @action
|
74
|
+
raise ArgumentError, "Invalid service method '#{@action}'"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Checks if there were any choice elements found in the wsdl and namespaces
|
79
|
+
# the corresponding keys from the passed in Hash of options.
|
80
|
+
def namespaced_options
|
81
|
+
return @options if wsdl.choice_elements.empty?
|
82
|
+
|
83
|
+
options = {}
|
84
|
+
@options.each do |key, value|
|
85
|
+
key = "wsdl:#{key}" if wsdl.choice_elements.include? key.to_s
|
86
|
+
|
87
|
+
current = options[key]
|
88
|
+
case current
|
89
|
+
when Array
|
90
|
+
options[key] << value
|
91
|
+
when nil
|
92
|
+
options[key] = value
|
93
|
+
else
|
94
|
+
options[key] = [current.dup, value]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
options
|
98
|
+
end
|
99
|
+
|
100
|
+
# Catches calls to SOAP service methods.
|
101
|
+
def method_missing(method, options = {})
|
102
|
+
@action = method.to_s
|
103
|
+
@options = options
|
104
|
+
validate_action
|
105
|
+
call_service
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
data/lib/savon/wsdl.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'net/http'
|
4
|
+
require 'hpricot'
|
5
|
+
|
6
|
+
module Savon
|
7
|
+
|
8
|
+
# Savon::Wsdl gets, parses and represents the SOAP-WSDL.
|
9
|
+
class Wsdl
|
10
|
+
|
11
|
+
# The namespace URI.
|
12
|
+
attr_reader :namespace_uri
|
13
|
+
|
14
|
+
# Available service methods.
|
15
|
+
attr_reader :service_methods
|
16
|
+
|
17
|
+
# Choice elements.
|
18
|
+
attr_reader :choice_elements
|
19
|
+
|
20
|
+
# Initializer expects an endpoint URI and an HTTP connection instance.
|
21
|
+
# Gets and parses the WSDL at the given URI.
|
22
|
+
def initialize(uri, http)
|
23
|
+
@uri = uri
|
24
|
+
@http = http
|
25
|
+
get_wsdl
|
26
|
+
parse_wsdl
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the response body from the WSDL request.
|
30
|
+
def to_s
|
31
|
+
@response.body
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Gets the WSDL at the given URI.
|
37
|
+
def get_wsdl
|
38
|
+
@response = @http.get("#{@uri.path}?#{@uri.query}")
|
39
|
+
@doc = Hpricot.XML(@response.body)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Parses the WSDL for the namespace URI, available service methods
|
43
|
+
# and choice elements.
|
44
|
+
def parse_wsdl
|
45
|
+
@namespace_uri = @doc.at('//wsdl:definitions').get_attribute('targetNamespace')
|
46
|
+
|
47
|
+
@service_methods = []
|
48
|
+
@doc.search('//soap:operation').each do |operation|
|
49
|
+
service_methods << operation.parent.get_attribute('name')
|
50
|
+
end
|
51
|
+
|
52
|
+
@choice_elements = []
|
53
|
+
@doc.search('//xs:choice//xs:element').each do |choice|
|
54
|
+
name = choice.get_attribute('ref').sub(/(.+):/, '')
|
55
|
+
choice_elements << name unless @choice_elements.include? name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
class WsdlFactory
|
2
|
+
attr_accessor :namespace_uri, :service_methods, :choice_elements
|
3
|
+
|
4
|
+
def initialize(new_options = {})
|
5
|
+
options = {
|
6
|
+
:namespace_uri => "http://some.example.com",
|
7
|
+
:service_methods => {"findById" => ["id"]},
|
8
|
+
:choice_elements => {}
|
9
|
+
}.update(new_options)
|
10
|
+
|
11
|
+
@namespace_uri = options[:namespace_uri]
|
12
|
+
@service_methods = options[:service_methods]
|
13
|
+
@choice_elements = options[:choice_elements]
|
14
|
+
end
|
15
|
+
|
16
|
+
def build
|
17
|
+
wsdl = '<wsdl:definitions name="SomeService" targetNamespace="' << namespace_uri << '"
|
18
|
+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://example.com"
|
19
|
+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
20
|
+
<wsdl:types>
|
21
|
+
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified"
|
22
|
+
targetNamespace="http://example.com" xmlns:tns="http://example.com"
|
23
|
+
xmlns:xs="http://www.w3.org/2001/XMLSchema">'
|
24
|
+
wsdl << build_elements
|
25
|
+
wsdl << '<xs:element name="result" type="tns:result" />'
|
26
|
+
wsdl << build_complex_types
|
27
|
+
wsdl << '<xs:complexType name="result">
|
28
|
+
<xs:sequence><xs:element name="token" type="xs:token" /></xs:sequence>
|
29
|
+
</xs:complexType>
|
30
|
+
</xs:schema>
|
31
|
+
</wsdl:types>'
|
32
|
+
wsdl << build_messages
|
33
|
+
wsdl << '<wsdl:portType name="SomeWebService">'
|
34
|
+
wsdl << build_operation_input_output
|
35
|
+
wsdl << '</wsdl:portType>
|
36
|
+
<wsdl:binding name="SomeServiceSoapBinding" type="tns:SomeService">
|
37
|
+
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />'
|
38
|
+
wsdl << build_operation_input_output_body
|
39
|
+
wsdl << '</wsdl:binding>
|
40
|
+
<wsdl:service name="SomeService">
|
41
|
+
<wsdl:port binding="tns:SomeServiceSoapBinding" name="SomeServicePort">
|
42
|
+
<soap:address location="http://example.com/SomeService" />
|
43
|
+
</wsdl:port>
|
44
|
+
</wsdl:service>
|
45
|
+
</wsdl:definitions>'
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_elements
|
49
|
+
wsdl = service_methods.keys.map { |method|
|
50
|
+
'<xs:element name="' << method << '" type="tns:' << method << '" />
|
51
|
+
<xs:element name="' << method << 'Response" type="tns:' << method << 'Response" />'
|
52
|
+
}.to_s
|
53
|
+
wsdl << choice_elements.map { |c_method, c_elements|
|
54
|
+
c_elements.map { |c_element|
|
55
|
+
'<xs:element name="' << c_element << '" type="tns:' << c_element << 'Value" />'
|
56
|
+
}.to_s
|
57
|
+
}.to_s
|
58
|
+
wsdl
|
59
|
+
end
|
60
|
+
|
61
|
+
def build_complex_types
|
62
|
+
service_methods.map { |method, inputs|
|
63
|
+
wsdl = '<xs:complexType name="' << method << '"><xs:sequence>'
|
64
|
+
inputs.each do |input|
|
65
|
+
if choice_elements.keys.include? input
|
66
|
+
wsdl << '<xs:choice>'
|
67
|
+
wsdl << choice_elements[input].map { |element|
|
68
|
+
'<xs:element ref="tns:' << element << '"/>'
|
69
|
+
}.to_s
|
70
|
+
wsdl << '</xs:choice>'
|
71
|
+
else
|
72
|
+
wsdl << '<xs:element minOccurs="0" name="' << input << '" type="xs:string" />'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
wsdl << '</xs:sequence></xs:complexType>'
|
76
|
+
wsdl << build_complex_types_choice_elements
|
77
|
+
wsdl << '<xs:complexType name="' << method << 'Response"><xs:sequence>
|
78
|
+
<xs:element minOccurs="0" name="return" type="tns:result" />
|
79
|
+
</xs:sequence></xs:complexType>'
|
80
|
+
}.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_complex_types_choice_elements
|
84
|
+
choice_elements.map { |c_method, c_elements|
|
85
|
+
c_elements.map { |c_element|
|
86
|
+
'<xs:complexType name="' << c_element << 'Value"><xs:sequence>
|
87
|
+
<xs:element minOccurs="0" name="' << c_element << '" type="xs:string" />
|
88
|
+
</xs:sequence></xs:complexType>'
|
89
|
+
}.to_s
|
90
|
+
}.to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_messages
|
94
|
+
service_methods.keys.map { |method|
|
95
|
+
'<wsdl:message name="' << method << '">
|
96
|
+
<wsdl:part element="tns:' << method << '" name="parameters"> </wsdl:part>
|
97
|
+
</wsdl:message>
|
98
|
+
<wsdl:message name="' << method << 'Response">
|
99
|
+
<wsdl:part element="tns:' << method << 'Response" name="parameters"> </wsdl:part>
|
100
|
+
</wsdl:message>'
|
101
|
+
}.to_s
|
102
|
+
end
|
103
|
+
|
104
|
+
def build_operation_input_output
|
105
|
+
service_methods.keys.map { |method|
|
106
|
+
'<wsdl:operation name="' << method << '">
|
107
|
+
<wsdl:input message="tns:' << method << '" name="' << method << '"> </wsdl:input>
|
108
|
+
<wsdl:output message="tns:' << method << 'Response" name="' << method << 'Response"> </wsdl:output>
|
109
|
+
</wsdl:operation>'
|
110
|
+
}.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
def build_operation_input_output_body
|
114
|
+
service_methods.keys.map { |method|
|
115
|
+
'<wsdl:operation name="' << method << '">
|
116
|
+
<soap:operation soapAction="" style="document" />
|
117
|
+
<wsdl:input name="' << method << '">
|
118
|
+
<soap:body use="literal" />
|
119
|
+
</wsdl:input>
|
120
|
+
<wsdl:output name="' << method << 'Response">
|
121
|
+
<soap:body use="literal" />
|
122
|
+
</wsdl:output>
|
123
|
+
</wsdl:operation>'
|
124
|
+
}.to_s
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
end
|
data/tests/helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'mocha'
|
4
|
+
require 'shoulda'
|
5
|
+
require "apricoteatsgorilla"
|
6
|
+
|
7
|
+
["service", "wsdl", "response"].each do |file|
|
8
|
+
require File.join(File.dirname(__FILE__), "..", "lib", "savon", file)
|
9
|
+
end
|
10
|
+
|
11
|
+
require File.join(File.dirname(__FILE__), "factories", "wsdl")
|
12
|
+
require File.join(File.dirname(__FILE__), "fixtures", "soap_response")
|
13
|
+
|
14
|
+
module TestHelper
|
15
|
+
|
16
|
+
def some_url
|
17
|
+
"http://example.com"
|
18
|
+
end
|
19
|
+
|
20
|
+
def some_uri
|
21
|
+
URI(some_url)
|
22
|
+
end
|
23
|
+
|
24
|
+
def service_http_mock(response_body)
|
25
|
+
http_mock = mock()
|
26
|
+
http_mock.expects(:get).returns(response_mock(WsdlFactory.new.build))
|
27
|
+
http_mock.expects(:request_post).returns(response_mock(response_body))
|
28
|
+
http_mock
|
29
|
+
end
|
30
|
+
|
31
|
+
def http_mock(response_body)
|
32
|
+
http_mock = mock()
|
33
|
+
http_mock.expects(:get).returns(response_mock(response_body))
|
34
|
+
http_mock
|
35
|
+
end
|
36
|
+
|
37
|
+
def response_mock(response_body)
|
38
|
+
response_mock = mock('Net::HTTPResponse')
|
39
|
+
response_mock.stubs(
|
40
|
+
:code => '200', :message => "OK", :content_type => "text/html",
|
41
|
+
:body => response_body
|
42
|
+
)
|
43
|
+
response_mock
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "helper")
|
3
|
+
|
4
|
+
class SavonResponseTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include TestHelper
|
7
|
+
include SoapResponseFixture
|
8
|
+
|
9
|
+
context "Savon::Response with some SOAP response" do
|
10
|
+
setup do
|
11
|
+
ApricotEatsGorilla.sort_keys = true
|
12
|
+
@response = Savon::Response.new(response_mock(some_soap_response))
|
13
|
+
end
|
14
|
+
|
15
|
+
should "return a Hash on to_hash" do
|
16
|
+
assert_kind_of Hash, @response.to_hash
|
17
|
+
end
|
18
|
+
|
19
|
+
should "return a Hash equal to the response on to_hash" do
|
20
|
+
assert_equal ApricotEatsGorilla(some_soap_response, "//return"), @response.to_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
should "return the raw XML response on to_s" do
|
24
|
+
assert_equal some_soap_response, @response.to_s
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "helper")
|
3
|
+
|
4
|
+
class SavonServiceTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include TestHelper
|
7
|
+
include SoapResponseFixture
|
8
|
+
|
9
|
+
context "Savon::Service" do
|
10
|
+
setup do
|
11
|
+
@service = Savon::Service.new(some_url)
|
12
|
+
@service.http = service_http_mock(some_soap_response)
|
13
|
+
@result = @service.findById
|
14
|
+
end
|
15
|
+
|
16
|
+
should "return a Savon::Response object containing the given response" do
|
17
|
+
assert_kind_of Savon::Response, @result
|
18
|
+
assert_equal some_soap_response, @result.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
should "return an instance of Savon::Wsdl on wsdl" do
|
22
|
+
assert_kind_of Savon::Wsdl, @service.wsdl
|
23
|
+
end
|
24
|
+
|
25
|
+
should "raise an ArgumentError when called with an invalid action" do
|
26
|
+
assert_raise ArgumentError do
|
27
|
+
@service.somethingCrazy
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "helper")
|
3
|
+
|
4
|
+
class SavonWsdlTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
include TestHelper
|
7
|
+
|
8
|
+
context "Savon::Wsdl without choice elements" do
|
9
|
+
setup do
|
10
|
+
@some_factory = WsdlFactory.new
|
11
|
+
@some_wsdl = Savon::Wsdl.new(some_uri, http_mock(@some_factory.build))
|
12
|
+
end
|
13
|
+
|
14
|
+
should "return the namespace_uri" do
|
15
|
+
assert_equal @some_factory.namespace_uri, @some_wsdl.namespace_uri
|
16
|
+
end
|
17
|
+
|
18
|
+
should "return the available service_methods" do
|
19
|
+
assert_equal @some_factory.service_methods.keys, @some_wsdl.service_methods
|
20
|
+
end
|
21
|
+
|
22
|
+
should "not find any choice elements, so choice_elements returns []" do
|
23
|
+
assert_equal @some_factory.choice_elements.keys, @some_wsdl.choice_elements
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "Savon::Wsdl with choice elements" do
|
28
|
+
setup do
|
29
|
+
@choice_factory = WsdlFactory.new(
|
30
|
+
:service_methods => {"findUser" => ["credential"]},
|
31
|
+
:choice_elements => {"credential" => ["id", "email"]}
|
32
|
+
)
|
33
|
+
@choice_wsdl = Savon::Wsdl.new(some_uri, http_mock(@choice_factory.build))
|
34
|
+
end
|
35
|
+
|
36
|
+
should "return the available choice elements" do
|
37
|
+
assert_equal @choice_factory.choice_elements["credential"], @choice_wsdl.choice_elements
|
38
|
+
end
|
39
|
+
|
40
|
+
should "return the raw SOAP response on to_s" do
|
41
|
+
assert_equal @choice_factory.build, @choice_wsdl.to_s
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/tests/savon_test.rb
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smacks-savon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Harrington
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-16 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hpricot
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - "="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.6.164
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: smacks-apricoteatsgorilla
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.6
|
34
|
+
version:
|
35
|
+
description: Savon is a lightweight SOAP client.
|
36
|
+
email:
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- README.rdoc
|
45
|
+
- lib/savon.rb
|
46
|
+
- lib/savon/service.rb
|
47
|
+
- lib/savon/wsdl.rb
|
48
|
+
- lib/savon/response.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/smacks/savon
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --inline-source
|
54
|
+
- --charset=UTF-8
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements:
|
70
|
+
- mocha for testing
|
71
|
+
- shoulda for testing
|
72
|
+
- apricoteatsgorilla for testing
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 1.2.0
|
75
|
+
signing_key:
|
76
|
+
specification_version: 2
|
77
|
+
summary: Savon is a lightweight SOAP client.
|
78
|
+
test_files:
|
79
|
+
- tests/savon_test.rb
|
80
|
+
- tests/helper.rb
|
81
|
+
- tests/factories/wsdl.rb
|
82
|
+
- tests/fixtures/soap_response.rb
|
83
|
+
- tests/savon/service_test.rb
|
84
|
+
- tests/savon/wsdl_test.rb
|
85
|
+
- tests/savon/response_test.rb
|