lolsoap 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/VERSION +1 -1
- data/lib/lolsoap/envelope.rb +1 -1
- data/lib/lolsoap/wsdl/named_type_reference.rb +6 -5
- data/lib/lolsoap/wsdl/operation.rb +4 -2
- data/lib/lolsoap/wsdl/type.rb +1 -1
- data/lib/lolsoap/wsdl.rb +45 -38
- data/lib/lolsoap/wsdl_parser.rb +29 -45
- data/lolsoap.gemspec +3 -3
- data/test/fixtures/stock_quote.wsdl +4 -4
- data/test/integration/test_envelope.rb +6 -6
- data/test/integration/test_wsdl.rb +3 -3
- data/test/unit/test_envelope.rb +5 -5
- data/test/unit/test_wsdl.rb +43 -47
- data/test/unit/test_wsdl_parser.rb +92 -99
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d15ac33320b9b7a7f32e1fd15e111ba323683c75
|
4
|
+
data.tar.gz: d9fdcb8040c0e9e714b0512f73c69c15ca70d686
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4b2624bb3b81de8109863c618d1c9a11146f2394b908da4ffa1a3737ad9cd624e5a206f14262d23b454f9a1d9576ef1d1bfc3713101f49b020ee76f19f00428
|
7
|
+
data.tar.gz: 62efc9d01ee3e439b115aa9c7eb10c293036d353aa849a999fd9ecfd676c88ae0a483c976b320f1d974dea42923092655716212b4c6d185c24892a96d2019710
|
data/README.md
CHANGED
@@ -114,6 +114,12 @@ Development sponsored by [Loco2](http://loco2.com/).
|
|
114
114
|
|
115
115
|
## Changelog ##
|
116
116
|
|
117
|
+
### 0.5 ###
|
118
|
+
|
119
|
+
* Generate our own namespace prefixes rather than using ones from the
|
120
|
+
WSDL document. This fixes issues with WSDLs that use the same prefix
|
121
|
+
to denote different namespaces in different places.
|
122
|
+
|
117
123
|
### 0.4 ###
|
118
124
|
|
119
125
|
* Don't raise an exception on when a SOAP fault is detected. Whether or
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/lib/lolsoap/envelope.rb
CHANGED
@@ -87,7 +87,7 @@ module LolSoap
|
|
87
87
|
def initialize_doc
|
88
88
|
doc.root = root = doc.create_element('Envelope')
|
89
89
|
|
90
|
-
namespaces = Hash[wsdl.
|
90
|
+
namespaces = Hash[wsdl.namespaces.map { |prefix, uri| [prefix, root.add_namespace(prefix, uri)] }]
|
91
91
|
namespaces[soap_prefix] = root.add_namespace(soap_prefix, soap_namespace)
|
92
92
|
|
93
93
|
@header = doc.create_element 'Header'
|
@@ -1,14 +1,15 @@
|
|
1
1
|
class LolSoap::WSDL
|
2
2
|
class NamedTypeReference
|
3
|
-
attr_reader :name, :wsdl
|
3
|
+
attr_reader :namespace, :name, :wsdl
|
4
4
|
|
5
|
-
def initialize(name, wsdl)
|
6
|
-
@
|
7
|
-
@
|
5
|
+
def initialize(namespace, name, wsdl)
|
6
|
+
@namespace = namespace
|
7
|
+
@name = name
|
8
|
+
@wsdl = wsdl
|
8
9
|
end
|
9
10
|
|
10
11
|
def type
|
11
|
-
wsdl.type(name)
|
12
|
+
wsdl.type(namespace, name)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
class LolSoap::WSDL
|
2
2
|
class Operation
|
3
|
-
attr_reader :wsdl, :action, :input, :output
|
3
|
+
attr_reader :wsdl, :name, :action, :input, :output
|
4
4
|
|
5
|
-
def initialize(wsdl, action, input, output)
|
5
|
+
def initialize(wsdl, name, action, input, output)
|
6
6
|
@wsdl = wsdl
|
7
|
+
@name = name
|
7
8
|
@action = action
|
8
9
|
@input = input
|
9
10
|
@output = output
|
@@ -11,6 +12,7 @@ class LolSoap::WSDL
|
|
11
12
|
|
12
13
|
def inspect
|
13
14
|
"<#{self.class} " \
|
15
|
+
"name=#{name.inspect} " \
|
14
16
|
"action=#{action.inspect} " \
|
15
17
|
"input=#{input.inspect}>"
|
16
18
|
end
|
data/lib/lolsoap/wsdl/type.rb
CHANGED
data/lib/lolsoap/wsdl.rb
CHANGED
@@ -18,41 +18,37 @@ module LolSoap
|
|
18
18
|
# The SOAP endpoint URL
|
19
19
|
attr_reader :endpoint
|
20
20
|
|
21
|
-
# Hash of
|
22
|
-
attr_reader :namespaces
|
23
|
-
|
24
|
-
# Namespaces used by the types (a subset of #namespaces)
|
25
|
-
attr_reader :type_namespaces
|
26
|
-
|
27
|
-
# Hash of namespace prefixes used in the WSDL document (keys are namespace URIs)
|
21
|
+
# Hash of generated prefixes to namespaces
|
28
22
|
attr_reader :prefixes
|
29
23
|
|
24
|
+
# Hash of namespaces to generated prefixes
|
25
|
+
attr_reader :namespaces
|
26
|
+
|
30
27
|
# The version of SOAP detected.
|
31
28
|
attr_reader :soap_version
|
32
29
|
|
33
30
|
def initialize(parser)
|
34
|
-
@
|
35
|
-
@
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@soap_version = parser.soap_version
|
31
|
+
@prefixes = generate_prefixes(parser)
|
32
|
+
@namespaces = prefixes.invert
|
33
|
+
@types = load_types(parser)
|
34
|
+
@operations = load_operations(parser)
|
35
|
+
@endpoint = parser.endpoint
|
36
|
+
@soap_version = parser.soap_version
|
41
37
|
end
|
42
38
|
|
43
39
|
# Hash of types declared by the service
|
44
40
|
def types
|
45
|
-
@types.
|
41
|
+
Hash[@types.values.map { |t| [t.name, t] }]
|
46
42
|
end
|
47
43
|
|
48
44
|
# Get a single type, or a NullType if the type doesn't exist
|
49
|
-
def type(name)
|
50
|
-
@types.fetch(name) { NullType.new }
|
45
|
+
def type(namespace, name)
|
46
|
+
@types.fetch([namespace, name]) { NullType.new }
|
51
47
|
end
|
52
48
|
|
53
|
-
# Hash of operations that are
|
49
|
+
# Hash of operations that are supported by the SOAP service
|
54
50
|
def operations
|
55
|
-
@operations.
|
51
|
+
Hash[@operations.values.map { |o| [o.name, o] }]
|
56
52
|
end
|
57
53
|
|
58
54
|
# Get a single operation
|
@@ -60,11 +56,16 @@ module LolSoap
|
|
60
56
|
@operations.fetch(name)
|
61
57
|
end
|
62
58
|
|
59
|
+
# Get the prefix for a namespace
|
60
|
+
def prefix(namespace)
|
61
|
+
prefixes.fetch namespace
|
62
|
+
end
|
63
|
+
|
63
64
|
def inspect
|
64
65
|
"<#{self.class} " \
|
65
|
-
"namespaces=#{
|
66
|
-
"operations=#{
|
67
|
-
"types=#{
|
66
|
+
"namespaces=#{namespaces.inspect} " \
|
67
|
+
"operations=#{operations.inspect} " \
|
68
|
+
"types=#{types.inspect}>"
|
68
69
|
end
|
69
70
|
|
70
71
|
private
|
@@ -72,8 +73,8 @@ module LolSoap
|
|
72
73
|
# @private
|
73
74
|
def load_types(parser)
|
74
75
|
Hash[
|
75
|
-
parser.types.map do |
|
76
|
-
[
|
76
|
+
parser.types.map do |id, type|
|
77
|
+
[id, build_type(type)]
|
77
78
|
end
|
78
79
|
]
|
79
80
|
end
|
@@ -82,27 +83,33 @@ module LolSoap
|
|
82
83
|
def load_operations(parser)
|
83
84
|
Hash[
|
84
85
|
parser.operations.map do |k, op|
|
85
|
-
[k, Operation.new(self, op[:action], message_format(op[:input], parser), message_format(op[:output], parser))]
|
86
|
+
[k, Operation.new(self, k, op[:action], message_format(op[:input], parser), message_format(op[:output], parser))]
|
86
87
|
end
|
87
88
|
]
|
88
89
|
end
|
89
90
|
|
90
91
|
# @private
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
92
|
+
def generate_prefixes(parser)
|
93
|
+
prefixes = {}
|
94
|
+
index = 0
|
95
|
+
|
96
|
+
parser.types.merge(parser.elements).values.each do |el|
|
97
|
+
unless prefixes[el[:namespace]]
|
98
|
+
prefixes[el[:namespace]] = "ns#{index}"
|
99
|
+
index += 1
|
95
100
|
end
|
96
|
-
|
101
|
+
end
|
102
|
+
|
103
|
+
prefixes
|
97
104
|
end
|
98
105
|
|
99
106
|
# @private
|
100
107
|
def build_type(params)
|
101
108
|
Type.new(
|
102
109
|
params[:name],
|
103
|
-
params
|
104
|
-
build_elements(params
|
105
|
-
params
|
110
|
+
prefix(params.fetch(:namespace)),
|
111
|
+
build_elements(params.fetch(:elements)),
|
112
|
+
params.fetch(:attributes)
|
106
113
|
)
|
107
114
|
end
|
108
115
|
|
@@ -120,7 +127,7 @@ module LolSoap
|
|
120
127
|
Element.new(
|
121
128
|
self,
|
122
129
|
params[:name],
|
123
|
-
params[:
|
130
|
+
prefix(params[:namespace]),
|
124
131
|
type_reference(params[:type]),
|
125
132
|
params[:singular]
|
126
133
|
)
|
@@ -128,16 +135,16 @@ module LolSoap
|
|
128
135
|
|
129
136
|
# @private
|
130
137
|
def type_reference(type)
|
131
|
-
if type.
|
132
|
-
NamedTypeReference.new(type, self)
|
138
|
+
if type.is_a?(Array)
|
139
|
+
NamedTypeReference.new(*type, self)
|
133
140
|
else
|
134
|
-
ImmediateTypeReference.new(build_type(type))
|
141
|
+
ImmediateTypeReference.new(type ? build_type(type) : NullType.new)
|
135
142
|
end
|
136
143
|
end
|
137
144
|
|
138
145
|
# @private
|
139
146
|
def message_format(element, parser)
|
140
|
-
build_element(parser.elements
|
147
|
+
build_element(parser.elements.fetch(element))
|
141
148
|
end
|
142
149
|
end
|
143
150
|
end
|
data/lib/lolsoap/wsdl_parser.rb
CHANGED
@@ -5,21 +5,17 @@ module LolSoap
|
|
5
5
|
# @private
|
6
6
|
class WSDLParser
|
7
7
|
class Node
|
8
|
-
attr_reader :parser, :node, :target_namespace, :name, :
|
8
|
+
attr_reader :parser, :node, :target_namespace, :name, :namespace
|
9
9
|
|
10
10
|
def initialize(parser, node, target_namespace)
|
11
11
|
@parser = parser
|
12
12
|
@node = node
|
13
13
|
@target_namespace = target_namespace
|
14
|
-
@
|
14
|
+
@namespace, @name = parser.namespace_and_name(node, node.attr('name').to_s, target_namespace)
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def prefix_and_name(string)
|
22
|
-
parser.prefix_and_name(string, target_namespace)
|
17
|
+
def id
|
18
|
+
[namespace, name]
|
23
19
|
end
|
24
20
|
end
|
25
21
|
|
@@ -29,10 +25,11 @@ module LolSoap
|
|
29
25
|
type = Type.new(parser, complex_type, target_namespace)
|
30
26
|
{
|
31
27
|
:elements => type.elements,
|
28
|
+
:namespace => type.namespace,
|
32
29
|
:attributes => type.attributes
|
33
30
|
}
|
34
|
-
|
35
|
-
|
31
|
+
elsif type = node.attr('type')
|
32
|
+
parser.namespace_and_name(node, type, target_namespace)
|
36
33
|
end
|
37
34
|
end
|
38
35
|
|
@@ -72,10 +69,10 @@ module LolSoap
|
|
72
69
|
[
|
73
70
|
element.name,
|
74
71
|
{
|
75
|
-
:name
|
76
|
-
:
|
77
|
-
:type
|
78
|
-
:singular
|
72
|
+
:name => element.name,
|
73
|
+
:namespace => element.namespace,
|
74
|
+
:type => element.type,
|
75
|
+
:singular => element.singular
|
79
76
|
}
|
80
77
|
]
|
81
78
|
end
|
@@ -83,7 +80,9 @@ module LolSoap
|
|
83
80
|
end
|
84
81
|
|
85
82
|
def element_nodes
|
86
|
-
node.xpath('*/xs:element | */*/xs:element | xs:complexContent/xs:extension/*/xs:element | xs:complexContent/xs:extension/*/*/xs:element', parser.ns).map { |el|
|
83
|
+
node.xpath('*/xs:element | */*/xs:element | xs:complexContent/xs:extension/*/xs:element | xs:complexContent/xs:extension/*/*/xs:element', parser.ns).map { |el|
|
84
|
+
Element.new(parser, el, target_namespace)
|
85
|
+
}
|
87
86
|
end
|
88
87
|
|
89
88
|
def parent_elements
|
@@ -112,19 +111,6 @@ module LolSoap
|
|
112
111
|
@doc = doc
|
113
112
|
end
|
114
113
|
|
115
|
-
def namespaces
|
116
|
-
@namespaces ||= begin
|
117
|
-
namespaces = Hash[doc.collect_namespaces.map { |k, v| [k.sub(/^xmlns:/, ''), v] }]
|
118
|
-
namespaces.delete('xmlns')
|
119
|
-
namespaces
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# We invert the hash in a deterministic way so that the results are repeatable.
|
124
|
-
def prefixes
|
125
|
-
@prefixes ||= Hash[namespaces.sort_by { |k, v| k }.uniq { |k, v| v }].invert
|
126
|
-
end
|
127
|
-
|
128
114
|
def endpoint
|
129
115
|
@endpoint ||= CGI.unescape(doc.at_xpath('/d:definitions/d:service/d:port/s:address/@location', ns).to_s)
|
130
116
|
end
|
@@ -138,9 +124,9 @@ module LolSoap
|
|
138
124
|
types = {}
|
139
125
|
each_node('xs:complexType[not(@abstract="true")]') do |node, target_ns|
|
140
126
|
type = Type.new(self, node, target_ns)
|
141
|
-
types[type.
|
127
|
+
types[type.id] = {
|
142
128
|
:name => type.name,
|
143
|
-
:
|
129
|
+
:namespace => type.namespace,
|
144
130
|
:elements => type.elements,
|
145
131
|
:attributes => type.attributes
|
146
132
|
}
|
@@ -150,7 +136,7 @@ module LolSoap
|
|
150
136
|
end
|
151
137
|
|
152
138
|
def type(name)
|
153
|
-
name =
|
139
|
+
name = name.split(":").last
|
154
140
|
if node = doc.at_xpath("//xs:complexType[@name='#{name}']", ns)
|
155
141
|
target_namespace = node.at_xpath('parent::xs:schema/@targetNamespace', ns).to_s
|
156
142
|
Type.new(self, node, target_namespace)
|
@@ -162,10 +148,10 @@ module LolSoap
|
|
162
148
|
elements = {}
|
163
149
|
each_node('xs:element') do |node, target_ns|
|
164
150
|
element = Element.new(self, node, target_ns)
|
165
|
-
elements[element.
|
166
|
-
:name
|
167
|
-
:
|
168
|
-
:type
|
151
|
+
elements[element.id] = {
|
152
|
+
:name => element.name,
|
153
|
+
:namespace => element.namespace,
|
154
|
+
:type => element.type
|
169
155
|
}
|
170
156
|
end
|
171
157
|
elements
|
@@ -176,7 +162,7 @@ module LolSoap
|
|
176
162
|
@messages ||= Hash[
|
177
163
|
doc.xpath('/d:definitions/d:message', ns).map do |msg|
|
178
164
|
element = msg.at_xpath('./d:part/@element', ns).to_s
|
179
|
-
[msg.attribute('name').to_s,
|
165
|
+
[msg.attribute('name').to_s, namespace_and_name(msg, element)]
|
180
166
|
end
|
181
167
|
]
|
182
168
|
end
|
@@ -227,18 +213,16 @@ module LolSoap
|
|
227
213
|
}
|
228
214
|
end
|
229
215
|
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# Ensure we always use the same prefix for a given namespace
|
235
|
-
prefix = prefixes.fetch(namespaces.fetch(prefix))
|
216
|
+
def namespace_and_name(node, prefixed_name, default_namespace = nil)
|
217
|
+
if prefixed_name.include? ':'
|
218
|
+
prefix, name = prefixed_name.split(':')
|
219
|
+
namespace = node.namespaces.fetch("xmlns:#{prefix}")
|
236
220
|
else
|
237
|
-
name
|
238
|
-
|
221
|
+
name = prefixed_name
|
222
|
+
namespace = default_namespace
|
239
223
|
end
|
240
224
|
|
241
|
-
[
|
225
|
+
[namespace, name]
|
242
226
|
end
|
243
227
|
|
244
228
|
def each_node(xpath)
|
data/lolsoap.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: lolsoap 0.
|
5
|
+
# stub: lolsoap 0.5.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "lolsoap"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.5.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.authors = ["Jon Leighton"]
|
13
|
-
s.date = "2013-12-
|
13
|
+
s.date = "2013-12-10"
|
14
14
|
s.description = "A library for dealing with SOAP requests and responses. We tear our hair out so you don't have to."
|
15
15
|
s.email = "j@jonathanleighton.com"
|
16
16
|
s.extra_rdoc_files = [
|
@@ -23,11 +23,11 @@
|
|
23
23
|
<element name="TradePrice">
|
24
24
|
<complexType>
|
25
25
|
<all>
|
26
|
-
<element name="
|
26
|
+
<element name="Price" type="xsd3:price"/>
|
27
27
|
</all>
|
28
28
|
</complexType>
|
29
29
|
</element>
|
30
|
-
<element name="tradePriceRequest" type="TradePriceRequest" />
|
30
|
+
<element name="tradePriceRequest" type="xsd1:TradePriceRequest" />
|
31
31
|
<complexType name="xsd1:TradePriceRequest" abstract="false">
|
32
32
|
<complexContent>
|
33
33
|
<extension base="xsd1:BaseRequest">
|
@@ -47,7 +47,7 @@
|
|
47
47
|
</sequence>
|
48
48
|
</complexType>
|
49
49
|
</element>
|
50
|
-
<element name="historicalPriceRequest" type="HistoricalPriceRequest" />
|
50
|
+
<element name="historicalPriceRequest" type="xsd1:HistoricalPriceRequest" />
|
51
51
|
<complexType name="xsd1:HistoricalPriceRequest">
|
52
52
|
<complexContent>
|
53
53
|
<extension base="xsd1:BaseRequest">
|
@@ -87,7 +87,7 @@
|
|
87
87
|
</message>
|
88
88
|
|
89
89
|
<message name="GetLastTradePriceOutput">
|
90
|
-
<part name="body" element="
|
90
|
+
<part name="body" element="xsd1:TradePrice"/>
|
91
91
|
</message>
|
92
92
|
|
93
93
|
<message name="GetHistoricalPriceInput">
|
@@ -10,7 +10,7 @@ module LolSoap
|
|
10
10
|
let(:doc) { subject.doc }
|
11
11
|
|
12
12
|
it 'creates an empty envelope' do
|
13
|
-
body = doc.at_xpath('/soap:Envelope/soap:Body/
|
13
|
+
body = doc.at_xpath('/soap:Envelope/soap:Body/ns0:tradePriceRequest', doc.namespaces)
|
14
14
|
body.wont_equal nil
|
15
15
|
end
|
16
16
|
|
@@ -24,24 +24,24 @@ module LolSoap
|
|
24
24
|
b.id 42
|
25
25
|
end
|
26
26
|
|
27
|
-
el = doc.at_xpath('//
|
27
|
+
el = doc.at_xpath('//ns0:tradePriceRequest/ns0:tickerSymbol', doc.namespaces)
|
28
28
|
el.wont_equal nil
|
29
29
|
el.text.to_s.must_equal 'LOCO2'
|
30
30
|
|
31
|
-
el = doc.at_xpath('//
|
31
|
+
el = doc.at_xpath('//ns0:tradePriceRequest/ns0:specialTickerSymbol/ns1:name', doc.namespaces)
|
32
32
|
el.wont_equal nil
|
33
33
|
el.text.to_s.must_equal 'LOCOLOCOLOCO'
|
34
34
|
|
35
|
-
attr = doc.at_xpath('//
|
35
|
+
attr = doc.at_xpath('//ns0:tradePriceRequest/@id', doc.namespaces)
|
36
36
|
attr.to_s.must_equal "42"
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'creates some header' do
|
40
40
|
subject.header do |h|
|
41
|
-
h['
|
41
|
+
h['ns0'].verySpecialBoolean true
|
42
42
|
end
|
43
43
|
|
44
|
-
el = doc.at_xpath('/soap:Envelope/soap:Header/
|
44
|
+
el = doc.at_xpath('/soap:Envelope/soap:Header/ns0:verySpecialBoolean', doc.namespaces)
|
45
45
|
el.wont_equal nil
|
46
46
|
el.text.to_s.must_equal 'true'
|
47
47
|
end
|
@@ -7,14 +7,14 @@ module LolSoap
|
|
7
7
|
|
8
8
|
it 'should successfully parse a WSDL document' do
|
9
9
|
subject.operations.length.must_equal 2
|
10
|
-
subject.operations
|
10
|
+
subject.operations.fetch('GetLastTradePrice').tap do |o|
|
11
11
|
o.input.name.must_equal 'tradePriceRequest'
|
12
12
|
o.action.must_equal 'http://example.com/GetLastTradePrice'
|
13
13
|
end
|
14
14
|
|
15
15
|
subject.types.length.must_equal 4
|
16
|
-
subject.types
|
17
|
-
t.prefix.must_equal '
|
16
|
+
subject.types.fetch('TradePriceRequest').tap do |t|
|
17
|
+
t.prefix.must_equal 'ns0'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
data/test/unit/test_envelope.rb
CHANGED
@@ -5,25 +5,25 @@ module LolSoap
|
|
5
5
|
describe Envelope do
|
6
6
|
let(:wsdl) do
|
7
7
|
OpenStruct.new(
|
8
|
-
:
|
9
|
-
:soap_version
|
8
|
+
:namespaces => { 'ns0' => 'http://example.com/foo' },
|
9
|
+
:soap_version => '1.2'
|
10
10
|
)
|
11
11
|
end
|
12
12
|
|
13
13
|
let(:operation) do
|
14
|
-
OpenStruct.new(:input => OpenStruct.new(:prefix => '
|
14
|
+
OpenStruct.new(:input => OpenStruct.new(:prefix => 'ns0', :name => 'WashHandsRequest'))
|
15
15
|
end
|
16
16
|
|
17
17
|
subject { Envelope.new(wsdl, operation) }
|
18
18
|
|
19
19
|
let(:doc) { subject.doc }
|
20
20
|
let(:header) { doc.at_xpath('/soap:Envelope/soap:Header', doc.namespaces) }
|
21
|
-
let(:input) { doc.at_xpath('/soap:Envelope/soap:Body/
|
21
|
+
let(:input) { doc.at_xpath('/soap:Envelope/soap:Body/ns0:WashHandsRequest', doc.namespaces) }
|
22
22
|
|
23
23
|
it 'has a skeleton SOAP envelope structure when first created' do
|
24
24
|
doc.namespaces.must_equal(
|
25
25
|
'xmlns:soap' => Envelope::SOAP_1_2,
|
26
|
-
'xmlns:
|
26
|
+
'xmlns:ns0' => 'http://example.com/foo'
|
27
27
|
)
|
28
28
|
|
29
29
|
header.wont_equal nil
|
data/test/unit/test_wsdl.rb
CHANGED
@@ -5,6 +5,7 @@ module LolSoap
|
|
5
5
|
describe WSDL do
|
6
6
|
describe 'with a doc that can be parsed' do
|
7
7
|
let(:namespace) { 'http://lolsoap.api/bla' }
|
8
|
+
let(:xs) { "http://www.w3.org/2001/XMLSchema" }
|
8
9
|
|
9
10
|
let(:parser) do
|
10
11
|
OpenStruct.new(
|
@@ -12,70 +13,72 @@ module LolSoap
|
|
12
13
|
:operations => {
|
13
14
|
'washHands' => {
|
14
15
|
:action => 'urn:washHands',
|
15
|
-
:input => '
|
16
|
-
:output => '
|
16
|
+
:input => [namespace, 'brush'],
|
17
|
+
:output => [namespace, 'Color']
|
17
18
|
}
|
18
19
|
},
|
19
20
|
:types => {
|
20
|
-
'
|
21
|
+
[namespace, 'Brush'] => {
|
22
|
+
:name => 'Brush',
|
21
23
|
:elements => {
|
22
24
|
'handleColor' => {
|
23
|
-
:name
|
24
|
-
:
|
25
|
-
:type
|
25
|
+
:name => 'handleColor',
|
26
|
+
:namespace => namespace,
|
27
|
+
:type => {
|
26
28
|
:elements => {
|
27
29
|
'name' => {
|
28
|
-
:name
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:singular => true
|
30
|
+
:name => 'name',
|
31
|
+
:namespace => namespace,
|
32
|
+
:singular => true
|
32
33
|
},
|
33
34
|
'hex' => {
|
34
|
-
:name
|
35
|
-
:
|
36
|
-
:type
|
37
|
-
:singular
|
35
|
+
:name => 'hex',
|
36
|
+
:namespace => namespace,
|
37
|
+
:type => [xs, "string"],
|
38
|
+
:singular => true
|
38
39
|
}
|
39
40
|
},
|
41
|
+
:namespace => namespace,
|
40
42
|
:attributes => []
|
41
43
|
},
|
42
44
|
:singular => true
|
43
45
|
},
|
44
46
|
'age' => {
|
45
|
-
:name
|
46
|
-
:
|
47
|
-
:type
|
48
|
-
:singular
|
47
|
+
:name => 'age',
|
48
|
+
:namespace => namespace,
|
49
|
+
:type => [xs, "int"],
|
50
|
+
:singular => false
|
49
51
|
}
|
50
52
|
},
|
51
53
|
:attributes => ['id'],
|
52
|
-
:
|
54
|
+
:namespace => namespace
|
53
55
|
}
|
54
56
|
},
|
55
57
|
:elements => {
|
56
|
-
'
|
57
|
-
:name
|
58
|
-
:
|
59
|
-
:type
|
58
|
+
[namespace, 'brush'] => {
|
59
|
+
:name => 'brush',
|
60
|
+
:namespace => namespace,
|
61
|
+
:type => [namespace, 'Brush']
|
60
62
|
},
|
61
|
-
'
|
62
|
-
:name
|
63
|
-
:
|
64
|
-
:type
|
63
|
+
[namespace, 'Color'] => {
|
64
|
+
:name => 'Color',
|
65
|
+
:namespace => namespace,
|
66
|
+
:type => {
|
65
67
|
:elements => {
|
66
68
|
'name' => {
|
67
|
-
:name
|
68
|
-
:
|
69
|
-
:type
|
70
|
-
:singular
|
69
|
+
:name => 'name',
|
70
|
+
:namespace => namespace,
|
71
|
+
:type => [xs, "string"],
|
72
|
+
:singular => true
|
71
73
|
},
|
72
74
|
'hex' => {
|
73
|
-
:name
|
74
|
-
:
|
75
|
-
:type
|
76
|
-
:singular
|
75
|
+
:name => 'hex',
|
76
|
+
:namespace => namespace,
|
77
|
+
:type => [xs, "string"],
|
78
|
+
:singular => true
|
77
79
|
}
|
78
80
|
},
|
81
|
+
:namespace => namespace,
|
79
82
|
:attributes => []
|
80
83
|
}
|
81
84
|
}
|
@@ -115,7 +118,7 @@ module LolSoap
|
|
115
118
|
|
116
119
|
describe '#namespaces' do
|
117
120
|
it 'returns a namespaces hash' do
|
118
|
-
subject.namespaces.must_equal({ '
|
121
|
+
subject.namespaces.must_equal({ 'ns0' => namespace })
|
119
122
|
end
|
120
123
|
end
|
121
124
|
|
@@ -123,13 +126,13 @@ module LolSoap
|
|
123
126
|
it 'returns a hash of types' do
|
124
127
|
subject.types.length.must_equal 1
|
125
128
|
|
126
|
-
subject.types['
|
129
|
+
subject.types['Brush'].tap do |t|
|
127
130
|
t.elements.length.must_equal 2
|
128
131
|
t.element('handleColor').type.tap do |type|
|
129
132
|
type.is_a?(WSDL::Type).must_equal true
|
130
133
|
type.elements.keys.sort.must_equal %w(hex name)
|
131
134
|
end
|
132
|
-
t.element('handleColor').prefix.must_equal '
|
135
|
+
t.element('handleColor').prefix.must_equal 'ns0'
|
133
136
|
t.element('handleColor').singular?.must_equal true
|
134
137
|
t.element('age').type.must_equal WSDL::NullType.new
|
135
138
|
t.element('age').singular?.must_equal false
|
@@ -140,18 +143,11 @@ module LolSoap
|
|
140
143
|
|
141
144
|
describe '#type' do
|
142
145
|
it 'returns a single type' do
|
143
|
-
subject.type('
|
146
|
+
subject.type(namespace, 'Brush').must_equal subject.types.fetch('Brush')
|
144
147
|
end
|
145
148
|
|
146
149
|
it 'returns a null object if a type is missing' do
|
147
|
-
subject.type('FooBar').must_equal WSDL::NullType.new
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
describe '#type_namespaces' do
|
152
|
-
it 'returns only the namespaces that are used by types' do
|
153
|
-
parser.namespaces['foo'] = 'bar'
|
154
|
-
subject.type_namespaces.must_equal 'bla' => namespace
|
150
|
+
subject.type(namespace, 'FooBar').must_equal WSDL::NullType.new
|
155
151
|
end
|
156
152
|
end
|
157
153
|
end
|
@@ -7,23 +7,13 @@ module LolSoap
|
|
7
7
|
File.read(TEST_ROOT + '/fixtures/stock_quote.wsdl')
|
8
8
|
end
|
9
9
|
|
10
|
-
let(:doc)
|
10
|
+
let(:doc) { Nokogiri::XML(raw_doc) }
|
11
|
+
let(:namespace) { "http://example.com/stockquote.xsd" }
|
12
|
+
let(:namespace2) { "http://example.com/stockquote2.xsd" }
|
13
|
+
let(:xs) { "http://www.w3.org/2001/XMLSchema" }
|
11
14
|
|
12
15
|
subject { WSDLParser.new(doc) }
|
13
16
|
|
14
|
-
describe '#namespaces' do
|
15
|
-
it 'returns the namespaces used' do
|
16
|
-
subject.namespaces.must_equal({
|
17
|
-
'tns' => 'http://example.com/stockquote.wsdl',
|
18
|
-
'xsd1' => 'http://example.com/stockquote.xsd',
|
19
|
-
'xsd2' => 'http://example.com/stockquote2.xsd',
|
20
|
-
'xsd3' => 'http://example.com/stockquote.xsd',
|
21
|
-
'soap' => 'http://schemas.xmlsoap.org/wsdl/soap12/',
|
22
|
-
'xs' => 'http://www.w3.org/2001/XMLSchema'
|
23
|
-
})
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
17
|
describe '#endpoint' do
|
28
18
|
it 'returns the SOAP 1.2 service endpoint' do
|
29
19
|
subject.endpoint.must_equal 'http://example.com/stockquote'
|
@@ -33,63 +23,64 @@ module LolSoap
|
|
33
23
|
describe '#types' do
|
34
24
|
it 'returns the types, with attributes and namespace' do
|
35
25
|
subject.types.must_equal({
|
36
|
-
'
|
37
|
-
:prefix => 'xsd1',
|
26
|
+
[namespace, 'Price'] => {
|
38
27
|
:name => 'Price',
|
28
|
+
:namespace => namespace,
|
39
29
|
:elements => {},
|
40
30
|
:attributes => ['currency']
|
41
31
|
},
|
42
|
-
'
|
43
|
-
:
|
44
|
-
:
|
32
|
+
[namespace, 'TradePriceRequest'] => {
|
33
|
+
:name => 'TradePriceRequest',
|
34
|
+
:namespace => namespace,
|
45
35
|
:elements => {
|
46
36
|
'accountId' => {
|
47
|
-
:name
|
48
|
-
:
|
49
|
-
:type
|
50
|
-
:singular
|
37
|
+
:name => 'accountId',
|
38
|
+
:namespace => namespace,
|
39
|
+
:type => [xs, "string"],
|
40
|
+
:singular => true
|
51
41
|
},
|
52
42
|
'tickerSymbol' => {
|
53
|
-
:name
|
54
|
-
:
|
55
|
-
:type
|
56
|
-
:singular
|
43
|
+
:name => 'tickerSymbol',
|
44
|
+
:namespace => namespace,
|
45
|
+
:type => [xs, "string"],
|
46
|
+
:singular => false
|
57
47
|
},
|
58
48
|
'specialTickerSymbol' => {
|
59
|
-
:name
|
60
|
-
:
|
61
|
-
:type
|
62
|
-
:singular
|
49
|
+
:name => 'specialTickerSymbol',
|
50
|
+
:namespace => namespace,
|
51
|
+
:type => [namespace2, 'TickerSymbol'],
|
52
|
+
:singular => false
|
63
53
|
}
|
64
54
|
},
|
65
55
|
:attributes => ['signature', 'id']
|
66
56
|
},
|
67
|
-
'
|
68
|
-
:
|
69
|
-
:
|
57
|
+
[namespace, 'HistoricalPriceRequest'] => {
|
58
|
+
:name => 'HistoricalPriceRequest',
|
59
|
+
:namespace => namespace,
|
70
60
|
:elements => {
|
71
61
|
'accountId' => {
|
72
|
-
:name
|
73
|
-
:
|
74
|
-
:type
|
75
|
-
:singular
|
62
|
+
:name => 'accountId',
|
63
|
+
:namespace => namespace,
|
64
|
+
:type => [xs, "string"],
|
65
|
+
:singular => true
|
76
66
|
},
|
77
67
|
'dateRange' => {
|
78
|
-
:name
|
79
|
-
:
|
80
|
-
:type
|
81
|
-
:
|
68
|
+
:name => 'dateRange',
|
69
|
+
:namespace => namespace,
|
70
|
+
:type => {
|
71
|
+
:namespace => namespace,
|
72
|
+
:elements => {
|
82
73
|
'startDate' => {
|
83
|
-
:name
|
84
|
-
:
|
85
|
-
:type
|
86
|
-
:singular
|
74
|
+
:name => 'startDate',
|
75
|
+
:namespace => namespace,
|
76
|
+
:type => [xs, "string"],
|
77
|
+
:singular => true
|
87
78
|
},
|
88
79
|
'endDate' => {
|
89
|
-
:name
|
90
|
-
:
|
91
|
-
:type
|
92
|
-
:singular
|
80
|
+
:name => 'endDate',
|
81
|
+
:namespace => namespace,
|
82
|
+
:type => [xs, "string"],
|
83
|
+
:singular => true
|
93
84
|
}
|
94
85
|
},
|
95
86
|
:attributes => []
|
@@ -99,15 +90,15 @@ module LolSoap
|
|
99
90
|
},
|
100
91
|
:attributes => ['signature']
|
101
92
|
},
|
102
|
-
'
|
103
|
-
:
|
104
|
-
:
|
105
|
-
:elements
|
93
|
+
[namespace2, 'TickerSymbol'] => {
|
94
|
+
:name => 'TickerSymbol',
|
95
|
+
:namespace => namespace2,
|
96
|
+
:elements => {
|
106
97
|
'name' => {
|
107
|
-
:name
|
108
|
-
:
|
109
|
-
:type
|
110
|
-
:singular
|
98
|
+
:name => 'name',
|
99
|
+
:namespace => namespace2,
|
100
|
+
:type => [xs, "string"],
|
101
|
+
:singular => true
|
111
102
|
}
|
112
103
|
},
|
113
104
|
:attributes => []
|
@@ -119,47 +110,49 @@ module LolSoap
|
|
119
110
|
describe '#elements' do
|
120
111
|
it 'returns the elements with inline types' do
|
121
112
|
subject.elements.must_equal({
|
122
|
-
"
|
123
|
-
:name
|
124
|
-
:
|
125
|
-
:type
|
113
|
+
[namespace, "tradePriceRequest"] => {
|
114
|
+
:name => "tradePriceRequest",
|
115
|
+
:namespace => namespace,
|
116
|
+
:type => [namespace, "TradePriceRequest"]
|
126
117
|
},
|
127
|
-
"
|
128
|
-
:name
|
129
|
-
:
|
130
|
-
:type
|
118
|
+
[namespace, "TradePrice"] => {
|
119
|
+
:name => "TradePrice",
|
120
|
+
:namespace => namespace,
|
121
|
+
:type => {
|
122
|
+
:namespace => namespace,
|
131
123
|
:elements => {
|
132
|
-
'
|
133
|
-
:name
|
134
|
-
:
|
135
|
-
:type
|
136
|
-
:singular
|
124
|
+
'Price' => {
|
125
|
+
:name => 'Price',
|
126
|
+
:namespace => namespace,
|
127
|
+
:type => [namespace, 'price'],
|
128
|
+
:singular => true
|
137
129
|
}
|
138
130
|
},
|
139
131
|
:attributes => []
|
140
132
|
}
|
141
133
|
},
|
142
|
-
"
|
143
|
-
:name
|
144
|
-
:
|
145
|
-
:type
|
134
|
+
[namespace, "historicalPriceRequest"] => {
|
135
|
+
:name => "historicalPriceRequest",
|
136
|
+
:namespace => namespace,
|
137
|
+
:type => [namespace, "HistoricalPriceRequest"]
|
146
138
|
},
|
147
|
-
"
|
148
|
-
:name
|
149
|
-
:
|
150
|
-
:type
|
139
|
+
[namespace, "HistoricalPrice"] => {
|
140
|
+
:name => "HistoricalPrice",
|
141
|
+
:namespace => namespace,
|
142
|
+
:type => {
|
143
|
+
:namespace => namespace,
|
151
144
|
:elements => {
|
152
145
|
'date' => {
|
153
|
-
:name
|
154
|
-
:
|
155
|
-
:type
|
156
|
-
:singular
|
146
|
+
:name => 'date',
|
147
|
+
:namespace => namespace,
|
148
|
+
:type => [xs, 'date'],
|
149
|
+
:singular => true
|
157
150
|
},
|
158
151
|
'price' => {
|
159
|
-
:name
|
160
|
-
:
|
161
|
-
:type
|
162
|
-
:singular
|
152
|
+
:name => 'price',
|
153
|
+
:namespace => namespace,
|
154
|
+
:type => [xs, 'float'],
|
155
|
+
:singular => true
|
163
156
|
}
|
164
157
|
},
|
165
158
|
:attributes => []
|
@@ -172,10 +165,10 @@ module LolSoap
|
|
172
165
|
describe '#messages' do
|
173
166
|
it 'maps message names to types' do
|
174
167
|
subject.messages.must_equal({
|
175
|
-
'GetLastTradePriceInput' => '
|
176
|
-
'GetLastTradePriceOutput' => '
|
177
|
-
'GetHistoricalPriceInput' => '
|
178
|
-
'GetHistoricalPriceOutput' => '
|
168
|
+
'GetLastTradePriceInput' => [namespace, 'tradePriceRequest'],
|
169
|
+
'GetLastTradePriceOutput' => [namespace, 'TradePrice'],
|
170
|
+
'GetHistoricalPriceInput' => [namespace, 'historicalPriceRequest'],
|
171
|
+
'GetHistoricalPriceOutput' => [namespace, 'HistoricalPrice']
|
179
172
|
})
|
180
173
|
end
|
181
174
|
end
|
@@ -184,12 +177,12 @@ module LolSoap
|
|
184
177
|
it 'is a hash containing input and output types' do
|
185
178
|
subject.port_type_operations.must_equal({
|
186
179
|
'GetLastTradePrice' => {
|
187
|
-
:input => '
|
188
|
-
:output => '
|
180
|
+
:input => [namespace, 'tradePriceRequest'],
|
181
|
+
:output => [namespace, 'TradePrice']
|
189
182
|
},
|
190
183
|
'GetHistoricalPrice' => {
|
191
|
-
:input => '
|
192
|
-
:output => '
|
184
|
+
:input => [namespace, 'historicalPriceRequest'],
|
185
|
+
:output => [namespace, 'HistoricalPrice']
|
193
186
|
}
|
194
187
|
})
|
195
188
|
end
|
@@ -200,13 +193,13 @@ module LolSoap
|
|
200
193
|
subject.operations.must_equal({
|
201
194
|
'GetLastTradePrice' => {
|
202
195
|
:action => 'http://example.com/GetLastTradePrice',
|
203
|
-
:input => '
|
204
|
-
:output => '
|
196
|
+
:input => [namespace, 'tradePriceRequest'],
|
197
|
+
:output => [namespace, 'TradePrice']
|
205
198
|
},
|
206
199
|
'GetHistoricalPrice' => {
|
207
200
|
:action => 'http://example.com/GetHistoricalPrice',
|
208
|
-
:input => '
|
209
|
-
:output => '
|
201
|
+
:input => [namespace, 'historicalPriceRequest'],
|
202
|
+
:output => [namespace, 'HistoricalPrice']
|
210
203
|
}
|
211
204
|
})
|
212
205
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lolsoap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Leighton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -162,3 +162,4 @@ signing_key:
|
|
162
162
|
specification_version: 4
|
163
163
|
summary: A library for dealing with SOAP requests and responses.
|
164
164
|
test_files: []
|
165
|
+
has_rdoc:
|