lolsoap 0.6.1 → 0.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3681b9eceff632682da6150a24165ce5602e29f8
4
- data.tar.gz: 6fd0baf415e478dc90541ca8f35ccbbbcf7686ed
3
+ metadata.gz: 581a7842c694777a4af6b960f266eaebbf9e9431
4
+ data.tar.gz: 095e4cd38b1e59af2ff5514a560725f02d21b867
5
5
  SHA512:
6
- metadata.gz: 5f483f1121e5e187591ccad41044bfac1312c049d24486f781e99125c143717527571d2c1c9c8de554198c441ed1d2776f02eb2bbebdf7ef761cf12c4ff484c9
7
- data.tar.gz: aeef28d7bf905ee29f35ce754bbea3754aa0ef2946183cb3f9802d536283ed8e039446a8f84c28e114947da5350a539f18f91a594af61624ac495f6cbe146930
6
+ metadata.gz: d26800dfb89edd5bb9378a280d6be073d57ff8e273d1865b7b5cfde5ab5d83c9d3f757bb71df2213987c57c741947985d76127ea1e629b3c5e4cff963bcbd4e1
7
+ data.tar.gz: 44a08cfc2ecc91f15bcc54a442d37b912fe831d8a1bb013503efc52d392d2e04f2b0a5d4afeb684c28cbced4734048358544bef0b03195b566ee96966c95017e
data/README.md CHANGED
@@ -114,6 +114,16 @@ Development sponsored by [Loco2](http://loco2.com/).
114
114
 
115
115
  ## Changelog ##
116
116
 
117
+ ### 0.7 ###
118
+
119
+ * Added support for element references in type definitions
120
+ * Added support for operations with multipart header/body
121
+ * Added support for multipart messages in WSDL
122
+
123
+ ### 0.6 ###
124
+
125
+ * Support SOAP Header types
126
+
117
127
  ### 0.5 ###
118
128
 
119
129
  * Generate our own namespace prefixes rather than using ones from the
@@ -26,14 +26,14 @@ module LolSoap
26
26
  # b.some 'data'
27
27
  # end
28
28
  def body(klass = Builder)
29
- builder = klass.new(body_content, input_body_type)
29
+ builder = klass.new(body_content, input_body_content_type)
30
30
  yield builder if block_given?
31
31
  builder
32
32
  end
33
33
 
34
34
  # Build the header of the envelope
35
35
  def header(klass = Builder)
36
- builder = klass.new(header_content, input_header_type)
36
+ builder = klass.new(header_content, input_header_content_type)
37
37
  yield builder if block_given?
38
38
  builder
39
39
  end
@@ -54,16 +54,24 @@ module LolSoap
54
54
  input.header
55
55
  end
56
56
 
57
- def input_header_type
58
- input_header && input_header.type
57
+ def input_header_content
58
+ input_header.content
59
+ end
60
+
61
+ def input_header_content_type
62
+ input_header.content_type
59
63
  end
60
64
 
61
65
  def input_body
62
66
  input.body
63
67
  end
64
68
 
65
- def input_body_type
66
- input_body.type
69
+ def input_body_content
70
+ input_body.content
71
+ end
72
+
73
+ def input_body_content_type
74
+ input_body.content_type
67
75
  end
68
76
 
69
77
  def output
@@ -82,8 +90,12 @@ module LolSoap
82
90
  output.body
83
91
  end
84
92
 
85
- def output_body_type
86
- output_body.type
93
+ def output_body_content
94
+ output_body.content
95
+ end
96
+
97
+ def output_body_content_type
98
+ output_body.content_type
87
99
  end
88
100
 
89
101
  def to_xml(options = {})
@@ -105,7 +117,7 @@ module LolSoap
105
117
  private
106
118
 
107
119
  # @private
108
- def header_content; @header_content || @header; end
120
+ def header_content; @header_content; end
109
121
 
110
122
  # @private
111
123
  def body_content; @body_content; end
@@ -117,24 +129,29 @@ module LolSoap
117
129
  namespaces = Hash[wsdl.namespaces.map { |prefix, uri| [prefix, root.add_namespace(prefix, uri)] }]
118
130
  namespaces[soap_prefix] = root.add_namespace(soap_prefix, soap_namespace)
119
131
 
120
- @header = doc.create_element 'Header'
121
- if input_header
122
- @header_content = doc.create_element input_header.name
132
+ @header = doc.create_element input_header.name
133
+ @body = doc.create_element input_body.name
134
+
135
+ [root, @header, @body].each { |el| el.namespace = namespaces[soap_prefix] }
136
+
137
+ if input_header_content
138
+ @header_content = doc.create_element input_header_content.name
139
+ @header_content.namespace = namespaces[input_header_content.prefix]
123
140
  @header << @header_content
124
141
  else
125
- @header_content = nil
142
+ @header_content = @header
126
143
  end
127
144
 
128
- body = doc.create_element 'Body'
129
- @body_content = doc.create_element input_body.name
130
-
131
- [root, @header, body].each { |el| el.namespace = namespaces[soap_prefix] }
132
- @header_content.namespace = namespaces[input_header.prefix] if @header_content
133
- @body_content.namespace = namespaces[input_body.prefix]
145
+ if input_body_content
146
+ @body_content = doc.create_element input_body_content.name
147
+ @body_content.namespace = namespaces[input_body_content.prefix]
148
+ @body << @body_content
149
+ else
150
+ @body_content = @body
151
+ end
134
152
 
135
- body << @body_content
136
153
  root << @header
137
- root << body
154
+ root << @body
138
155
  end
139
156
  end
140
157
  end
@@ -36,12 +36,12 @@ module LolSoap
36
36
 
37
37
  # The type of the element sent in the request body
38
38
  def input_type
39
- envelope.input_body_type
39
+ envelope.input_body_content_type
40
40
  end
41
41
 
42
42
  # The type of the element that will be received in the response body
43
43
  def output_type
44
- envelope.output_body_type
44
+ envelope.output_body_content_type
45
45
  end
46
46
 
47
47
  # The MIME type of the request. This is always application/soap+xml,
@@ -1,3 +1,3 @@
1
1
  module LolSoap
2
- VERSION = "0.6.1"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -0,0 +1,25 @@
1
+ class LolSoap::WSDL
2
+ class OperationIOPart < Element
3
+ def initialize(wsdl, name, type_reference)
4
+ super(wsdl, name, 'soap', type_reference)
5
+ end
6
+
7
+ def single_part?
8
+ type.elements.size == 1
9
+ end
10
+
11
+ def content
12
+ if single_part?
13
+ type.element(type.elements.keys.first)
14
+ end
15
+ end
16
+
17
+ def content_type
18
+ if content
19
+ content.type
20
+ else
21
+ type
22
+ end
23
+ end
24
+ end
25
+ end
data/lib/lolsoap/wsdl.rb CHANGED
@@ -10,6 +10,7 @@ module LolSoap
10
10
  require 'lolsoap/wsdl/null_type'
11
11
  require 'lolsoap/wsdl/element'
12
12
  require 'lolsoap/wsdl/null_element'
13
+ require 'lolsoap/wsdl/operation_io_part'
13
14
 
14
15
  # Create a new instance by parsing a raw string of XML
15
16
  def self.parse(raw)
@@ -114,7 +115,7 @@ module LolSoap
114
115
  def build_type(params)
115
116
  Type.new(
116
117
  params[:name],
117
- prefix(params.fetch(:namespace)),
118
+ params[:prefix] || prefix(params.fetch(:namespace)),
118
119
  build_elements(params.fetch(:elements)),
119
120
  params.fetch(:attributes)
120
121
  )
@@ -152,9 +153,35 @@ module LolSoap
152
153
  # @private
153
154
  def build_io(io, parser)
154
155
  OperationIO.new(
155
- io[:header] && build_element(parser.elements[io[:header]]),
156
- build_element(parser.elements[io[:body]])
156
+ build_io_part('Header', io[:header], parser),
157
+ build_io_part('Body', io[:body], parser)
157
158
  )
158
159
  end
160
+
161
+ # @private
162
+ def build_io_part(name, elements, parser)
163
+ OperationIOPart.new(
164
+ self,
165
+ name,
166
+ type_reference(io_part_type(name, elements, parser))
167
+ )
168
+ end
169
+
170
+ # @private
171
+ def io_part_type(name, elements, parser)
172
+ return unless elements.any?
173
+
174
+ {
175
+ :name => name,
176
+ :prefix => 'soap',
177
+ :elements => Hash[
178
+ elements.map { |el|
179
+ element = parser.elements.fetch(el)
180
+ [element[:name], element]
181
+ }
182
+ ],
183
+ :attributes => []
184
+ }
185
+ end
159
186
  end
160
187
  end
@@ -4,6 +4,8 @@ require 'cgi'
4
4
  module LolSoap
5
5
  # @private
6
6
  class WSDLParser
7
+ class ParseError < StandardError; end
8
+
7
9
  class Node
8
10
  attr_reader :parser, :node, :target_namespace, :name, :namespace
9
11
 
@@ -44,6 +46,31 @@ module LolSoap
44
46
  end
45
47
  end
46
48
 
49
+ class ReferencedElement
50
+ attr_reader :reference, :element
51
+
52
+ def initialize(reference, element)
53
+ @reference = reference
54
+ @element = element
55
+ end
56
+
57
+ def name
58
+ element.name
59
+ end
60
+
61
+ def namespace
62
+ element.namespace
63
+ end
64
+
65
+ def type
66
+ element.type
67
+ end
68
+
69
+ def singular
70
+ reference.singular
71
+ end
72
+ end
73
+
47
74
  class Type < Node
48
75
  def elements
49
76
  parent_elements.merge(own_elements)
@@ -81,7 +108,12 @@ module LolSoap
81
108
 
82
109
  def element_nodes
83
110
  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)
111
+ element = Element.new(parser, el, target_namespace)
112
+ if reference = el.attribute('ref')
113
+ ReferencedElement.new(element, parser.element(reference.to_s))
114
+ else
115
+ element
116
+ end
85
117
  }
86
118
  end
87
119
 
@@ -115,33 +147,61 @@ module LolSoap
115
147
  end
116
148
 
117
149
  def input
118
- @input ||= OperationIO.new(
119
- header(:input),
120
- port_type_operation[:input]
121
- )
150
+ @input ||= operation_io(:input)
122
151
  end
123
152
 
124
153
  def output
125
- @output ||= OperationIO.new(
126
- header(:output),
127
- port_type_operation[:output]
128
- )
154
+ @output ||= operation_io(:output)
129
155
  end
130
156
 
131
- private
132
-
133
157
  def port_type_operation
134
158
  parser.port_type_operations.fetch(name)
135
159
  end
136
160
 
137
- def header(direction)
138
- if msg = node.at_xpath("./d:#{direction}/s:header/@message", parser.ns)
139
- parser.messages.fetch(msg.to_s.split(':').last)
140
- end
161
+ private
162
+
163
+ def operation_io(direction)
164
+ OperationIO.new(parser, self, node.at_xpath("d:#{direction}", parser.ns))
141
165
  end
142
166
  end
143
167
 
144
- class OperationIO < Struct.new(:header, :body)
168
+ class OperationIO < Struct.new(:parser, :operation, :node)
169
+ def name
170
+ node.name
171
+ end
172
+
173
+ def header
174
+ @header ||= part_elements(:header)
175
+ end
176
+
177
+ def body
178
+ @body ||= part_elements(:body)
179
+ end
180
+
181
+ private
182
+
183
+ def operation_message
184
+ operation.port_type_operation[name.to_sym]
185
+ end
186
+
187
+ def part_elements(name)
188
+ nodes = node.xpath("s:#{name}", parser.ns)
189
+ return [] unless nodes
190
+
191
+ nodes.map { |node|
192
+ parts = parser.messages.fetch((node['message'] || operation_message).to_s.split(':').last)
193
+
194
+ parts.fetch(node['parts'] || node['part']) do |part_name|
195
+ if parts.size == 1
196
+ if name == :body
197
+ parts.values.first
198
+ end
199
+ else
200
+ raise ParseError, "Can't determine which part of #{message_name} to use as #{operation.name} #{self.name} #{name}"
201
+ end
202
+ end
203
+ }.compact
204
+ end
145
205
  end
146
206
 
147
207
  SOAP_1_1 = 'http://schemas.xmlsoap.org/wsdl/soap/'
@@ -182,11 +242,7 @@ module LolSoap
182
242
  end
183
243
 
184
244
  def type(name)
185
- name = name.split(":").last
186
- if node = doc.at_xpath("//xs:complexType[@name='#{name}']", ns)
187
- target_namespace = node.at_xpath('parent::xs:schema/@targetNamespace', ns).to_s
188
- Type.new(self, node, target_namespace)
189
- end
245
+ find_node name, Type, 'complexType'
190
246
  end
191
247
 
192
248
  def elements
@@ -204,23 +260,38 @@ module LolSoap
204
260
  end
205
261
  end
206
262
 
263
+ def element(name)
264
+ find_node name, Element, 'element'
265
+ end
266
+
207
267
  def messages
208
268
  @messages ||= Hash[
209
- doc.xpath('/d:definitions/d:message', ns).map do |msg|
210
- part = msg.at_xpath("d:part", ns)
211
- [msg.attribute('name').to_s, namespace_and_name(part, part['element'])]
212
- end
269
+ doc.xpath('/d:definitions/d:message', ns).map { |msg|
270
+ [
271
+ msg.attribute('name').to_s,
272
+ Hash[
273
+ msg.xpath('d:part', ns).map { |part|
274
+ [
275
+ part.attribute('name').to_s,
276
+ namespace_and_name(part, part['element'])
277
+ ]
278
+ }
279
+ ]
280
+ ]
281
+ }
213
282
  ]
214
283
  end
215
284
 
216
285
  def port_type_operations
217
286
  @port_type_operations ||= Hash[
218
287
  doc.xpath('/d:definitions/d:portType/d:operation', ns).map do |op|
219
- input = op.at_xpath('./d:input/@message', ns).to_s.split(':').last
220
- output = op.at_xpath('./d:output/@message', ns).to_s.split(':').last
221
- name = op.attribute('name').to_s
222
-
223
- [name, { :input => messages.fetch(input), :output => messages.fetch(output) }]
288
+ [
289
+ op.attribute('name').to_s,
290
+ {
291
+ :input => op.at_xpath('./d:input/@message', ns).to_s,
292
+ :output => op.at_xpath('./d:output/@message', ns).to_s
293
+ }
294
+ ]
224
295
  end
225
296
  ]
226
297
  end
@@ -285,6 +356,13 @@ module LolSoap
285
356
  end
286
357
  end
287
358
  end
359
+
360
+ def find_node(name, node_class, selector)
361
+ name = name.split(":").last
362
+ if node = doc.at_xpath("//xs:#{selector}[@name='#{name}']", ns)
363
+ target_namespace = node.at_xpath('parent::xs:schema/@targetNamespace', ns).to_s
364
+ node_class.new(self, node, target_namespace)
365
+ end
366
+ end
288
367
  end
289
368
  end
290
-
@@ -27,19 +27,25 @@
27
27
  </all>
28
28
  </complexType>
29
29
  </element>
30
- <element name="tradePriceRequestHeader">
30
+ <element name="specialTickerSymbol" type="xsd2:TickerSymbol"/>
31
+ <element name="authentication">
31
32
  <sequence>
32
33
  <element name="username" type="xs:string"/>
33
34
  <element name="password" type="xs:string"/>
34
35
  </sequence>
35
36
  </element>
37
+ <element name="tradePriceRequestHeader">
38
+ <sequence>
39
+ <element name="requestID" type="xs:string"/>
40
+ </sequence>
41
+ </element>
36
42
  <element name="tradePriceRequest" type="xsd1:TradePriceRequest" />
37
43
  <complexType name="xsd1:TradePriceRequest" abstract="false">
38
44
  <complexContent>
39
45
  <extension base="xsd1:BaseRequest">
40
46
  <sequence>
41
47
  <element name="tickerSymbol" type="xs:string" maxOccurs="5"/>
42
- <element name="specialTickerSymbol" type="xsd2:TickerSymbol" maxOccurs="unbounded"/>
48
+ <element ref="tns:specialTickerSymbol" maxOccurs="unbounded"/>
43
49
  </sequence>
44
50
  <attribute name="id" type="xs:string"/>
45
51
  </extension>
@@ -90,9 +96,11 @@
90
96
 
91
97
  <message name="GetLastTradePriceInputHeader">
92
98
  <part name="header" element="xsd1:tradePriceRequestHeader"/>
99
+ <part name="header2" element="xsd1:authentication"/>
93
100
  </message>
94
101
 
95
102
  <message name="GetLastTradePriceInput">
103
+ <part name="foo" xmlns:foo="http://example.com/stockquote.xsd" element="xs:string"/>
96
104
  <part name="body" xmlns:foo="http://example.com/stockquote.xsd" element="foo:tradePriceRequest"/>
97
105
  </message>
98
106
 
@@ -124,8 +132,9 @@
124
132
  <operation name="GetLastTradePrice">
125
133
  <soap:operation soapAction="http://example.com/GetLastTradePrice"/>
126
134
  <input>
127
- <soap:header use="literal" message="GetLastTradePriceInputHeader" />
128
- <soap:body use="literal"/>
135
+ <soap:header use="literal" message="GetLastTradePriceInputHeader" part="header" />
136
+ <soap:header use="literal" message="GetLastTradePriceInputHeader" part="header2" />
137
+ <soap:body use="literal" parts="body"/>
129
138
  </input>
130
139
  <output>
131
140
  <soap:body use="literal"/>
@@ -37,11 +37,13 @@ module LolSoap
37
37
  end
38
38
 
39
39
  it 'creates some header' do
40
- subject.header do |h|
41
- h['ns0'].username 'LOCO2'
40
+ subject.header do |header|
41
+ header.authentication do |auth|
42
+ auth['ns0'].username 'LOCO2'
43
+ end
42
44
  end
43
45
 
44
- el = doc.at_xpath('/soap:Envelope/soap:Header/ns0:tradePriceRequestHeader/ns0:username', doc.namespaces)
46
+ el = doc.at_xpath('/soap:Envelope/soap:Header/ns0:authentication/ns0:username', doc.namespaces)
45
47
  el.wont_equal nil
46
48
  el.text.to_s.must_equal 'LOCO2'
47
49
  end
@@ -8,14 +8,24 @@ module LolSoap
8
8
  it 'should successfully parse a WSDL document' do
9
9
  subject.operations.length.must_equal 2
10
10
  subject.operations.fetch('GetLastTradePrice').tap do |o|
11
- o.input.header.name.must_equal 'tradePriceRequestHeader'
12
- o.input.body.name.must_equal 'tradePriceRequest'
11
+ o.input.header.tap do |header|
12
+ header.name.must_equal 'Header'
13
+ header.content.must_equal nil
14
+ header.content_type.elements.keys.size.must_equal 2
15
+ header.content_type.elements.keys.first.must_equal 'tradePriceRequestHeader'
16
+ header.content_type.elements.keys.last.must_equal 'authentication'
17
+ end
18
+ o.input.body.name.must_equal 'Body'
19
+ o.input.body.content.name.must_equal 'tradePriceRequest'
13
20
  o.action.must_equal 'http://example.com/GetLastTradePrice'
14
21
  end
15
22
 
16
23
  subject.operations.fetch('GetHistoricalPrice').tap do |o|
17
- o.input.header.must_equal nil
18
- o.input.body.name.must_equal 'historicalPriceRequest'
24
+ o.input.header.name.must_equal 'Header'
25
+ o.input.header.content.must_equal nil
26
+ o.input.header.content_type.class.must_equal WSDL::NullType
27
+ o.input.body.name.must_equal 'Body'
28
+ o.input.body.content.name.must_equal 'historicalPriceRequest'
19
29
  end
20
30
 
21
31
  subject.types.length.must_equal 4
@@ -11,7 +11,15 @@ module LolSoap
11
11
  end
12
12
 
13
13
  let(:operation) do
14
- OpenStruct.new(:input => OpenStruct.new(:body => OpenStruct.new(:prefix => 'ns0', :name => 'WashHandsRequest')))
14
+ OpenStruct.new(
15
+ :input => OpenStruct.new(
16
+ :header => OpenStruct.new(:name => 'Header'),
17
+ :body => OpenStruct.new(
18
+ :name => 'Body',
19
+ :content => OpenStruct.new(:prefix => 'ns0', :name => 'WashHandsRequest')
20
+ )
21
+ )
22
+ )
15
23
  end
16
24
 
17
25
  subject { Envelope.new(wsdl, operation) }
@@ -44,5 +44,13 @@ module LolSoap
44
44
  subject.mime.must_equal 'text/xml'
45
45
  end
46
46
  end
47
+
48
+ describe '#output_type' do
49
+ it 'returns output body content type' do
50
+ content_type = Object.new
51
+ envelope.output_body_content_type = content_type
52
+ subject.output_type.must_equal content_type
53
+ end
54
+ end
47
55
  end
48
56
  end
@@ -4,7 +4,14 @@ require 'lolsoap/response'
4
4
 
5
5
  module LolSoap
6
6
  describe Response do
7
- let(:request) { OpenStruct.new(:soap_namespace => Envelope::SOAP_1_2, :soap_version => '1.2', :output => Object.new) }
7
+ let(:request) {
8
+ OpenStruct.new(
9
+ :soap_namespace => Envelope::SOAP_1_2,
10
+ :soap_version => '1.2',
11
+ :output_type => Object.new
12
+ )
13
+ }
14
+
8
15
  let(:doc) { Nokogiri::XML(File.read(TEST_ROOT + '/fixtures/stock_quote_response.xml')) }
9
16
 
10
17
  subject { Response.new(request, doc) }
@@ -25,7 +32,7 @@ module LolSoap
25
32
  it 'builds a hash from the body node' do
26
33
  builder = OpenStruct.new(:output => Object.new)
27
34
  builder_klass = MiniTest::Mock.new
28
- builder_klass.expect(:new, builder, [subject.body, request.output])
35
+ builder_klass.expect(:new, builder, [subject.body, request.output_type])
29
36
 
30
37
  subject.body_hash(builder_klass).must_equal builder.output
31
38
  end
@@ -13,8 +13,14 @@ module LolSoap
13
13
  :operations => {
14
14
  'washHands' => {
15
15
  :action => 'urn:washHands',
16
- :input => { :body => [namespace, 'brush'] },
17
- :output => { :body => [namespace, 'Color'] }
16
+ :input => {
17
+ :header => [],
18
+ :body => [[namespace, 'brush']]
19
+ },
20
+ :output => {
21
+ :header => [],
22
+ :body => [[namespace, 'Color']]
23
+ }
18
24
  }
19
25
  },
20
26
  :types => {
@@ -94,10 +100,35 @@ module LolSoap
94
100
  subject.operations['washHands'].tap do |op|
95
101
  op.wsdl.must_equal subject
96
102
  op.action.must_equal 'urn:washHands'
97
- op.input.body.name.must_equal 'brush'
98
- op.output.tap do |output|
99
- output.body.is_a?(WSDL::Element).must_equal(true)
100
- output.body.type.elements.keys.sort.must_equal %w(hex name)
103
+
104
+ op.input.header.tap do |header|
105
+ header.is_a?(WSDL::OperationIOPart).must_equal(true)
106
+ header.name.must_equal 'Header'
107
+ header.content.must_equal nil
108
+ end
109
+
110
+ op.input.body.tap do |body|
111
+ body.is_a?(WSDL::OperationIOPart).must_equal(true)
112
+ body.name.must_equal 'Body'
113
+ body.content.is_a?(WSDL::Element).must_equal(true)
114
+ body.content.name.must_equal 'brush'
115
+ end
116
+
117
+ op.output.header.tap do |header|
118
+ header.is_a?(WSDL::OperationIOPart).must_equal(true)
119
+ header.name.must_equal 'Header'
120
+ header.content.must_equal nil
121
+ end
122
+
123
+ op.output.body.tap do |body|
124
+ body.is_a?(WSDL::OperationIOPart).must_equal(true)
125
+ body.name.must_equal 'Body'
126
+
127
+ body.content.tap do |content|
128
+ content.is_a?(WSDL::Element).must_equal(true)
129
+ content.name.must_equal 'Color'
130
+ content.type.elements.keys.sort.must_equal %w(hex name)
131
+ end
101
132
  end
102
133
  end
103
134
  end
@@ -110,6 +110,11 @@ module LolSoap
110
110
  describe '#elements' do
111
111
  it 'returns the elements with inline types' do
112
112
  subject.elements.must_equal({
113
+ [namespace, "authentication"] => {
114
+ :name => "authentication",
115
+ :namespace => namespace,
116
+ :type => nil
117
+ },
113
118
  [namespace, "tradePriceRequestHeader"] => {
114
119
  :name => "tradePriceRequestHeader",
115
120
  :namespace => namespace,
@@ -136,6 +141,11 @@ module LolSoap
136
141
  :attributes => []
137
142
  }
138
143
  },
144
+ [namespace, "specialTickerSymbol"] => {
145
+ :name => "specialTickerSymbol",
146
+ :namespace => namespace,
147
+ :type => [namespace2, 'TickerSymbol']
148
+ },
139
149
  [namespace, "historicalPriceRequest"] => {
140
150
  :name => "historicalPriceRequest",
141
151
  :namespace => namespace,
@@ -168,47 +178,71 @@ module LolSoap
168
178
  end
169
179
 
170
180
  describe '#messages' do
171
- it 'maps message names to types' do
181
+ it 'maps message names to part names and corresponding types' do
172
182
  subject.messages.must_equal({
173
- 'GetLastTradePriceInputHeader' => [namespace, 'tradePriceRequestHeader'],
174
- 'GetLastTradePriceInput' => [namespace, 'tradePriceRequest'],
175
- 'GetLastTradePriceOutput' => [namespace, 'TradePrice'],
176
- 'GetHistoricalPriceInput' => [namespace, 'historicalPriceRequest'],
177
- 'GetHistoricalPriceOutput' => [namespace, 'HistoricalPrice']
183
+ 'GetLastTradePriceInputHeader' => {
184
+ 'header' => [namespace, 'tradePriceRequestHeader'],
185
+ 'header2' => [namespace, 'authentication']
186
+ },
187
+ 'GetLastTradePriceInput' => {
188
+ 'foo' => [xs, 'string'],
189
+ 'body' => [namespace, 'tradePriceRequest']
190
+ },
191
+ 'GetLastTradePriceOutput' => {
192
+ 'body' => [namespace, 'TradePrice']
193
+ },
194
+ 'GetHistoricalPriceInput' => {
195
+ 'body' => [namespace, 'historicalPriceRequest']
196
+ },
197
+ 'GetHistoricalPriceOutput' => {
198
+ 'body' => [namespace, 'HistoricalPrice']
199
+ }
178
200
  })
179
201
  end
180
202
  end
181
203
 
182
204
  describe '#port_type_operations' do
183
- it 'is a hash containing input and output types' do
205
+ it 'maps operations to messages' do
184
206
  subject.port_type_operations.must_equal({
185
207
  'GetLastTradePrice' => {
186
- :input => [namespace, 'tradePriceRequest'],
187
- :output => [namespace, 'TradePrice']
208
+ :input => 'tns:GetLastTradePriceInput',
209
+ :output => 'tns:GetLastTradePriceOutput',
188
210
  },
189
211
  'GetHistoricalPrice' => {
190
- :input => [namespace, 'historicalPriceRequest'],
191
- :output => [namespace, 'HistoricalPrice']
212
+ :input => 'tns:GetHistoricalPriceInput',
213
+ :output => 'tns:GetHistoricalPriceOutput'
192
214
  }
193
215
  })
194
216
  end
195
217
  end
196
218
 
197
219
  describe '#operations' do
198
- it 'is a hash of operations with their action and input type' do
220
+ it 'maps operations to actions, input and output parts' do
199
221
  subject.operations.must_equal({
200
222
  'GetLastTradePrice' => {
201
223
  :action => 'http://example.com/GetLastTradePrice',
202
224
  :input => {
203
- header: [namespace, 'tradePriceRequestHeader'],
204
- body: [namespace, 'tradePriceRequest']
225
+ header: [
226
+ [namespace, 'tradePriceRequestHeader'],
227
+ [namespace, 'authentication']
228
+ ],
229
+ body: [[namespace, 'tradePriceRequest']]
205
230
  },
206
- :output => { header: nil, body: [namespace, 'TradePrice'] }
231
+ :output => {
232
+ header: [],
233
+ body: [[namespace, 'TradePrice']]
234
+ }
207
235
  },
208
236
  'GetHistoricalPrice' => {
209
237
  :action => 'http://example.com/GetHistoricalPrice',
210
- :input => { header: nil, body: [namespace, 'historicalPriceRequest'] },
211
- :output => { header: nil, body: [namespace, 'HistoricalPrice'] }
238
+ :input => {
239
+ header: [],
240
+ body: [[namespace, 'historicalPriceRequest']]
241
+ },
242
+ :output => {
243
+ header: [],
244
+ body: [[namespace, 'HistoricalPrice']]
245
+ }
212
246
  }
213
247
  })
214
248
  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.6.1
4
+ version: 0.7.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: 2015-03-12 00:00:00.000000000 Z
11
+ date: 2015-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -112,6 +112,7 @@ files:
112
112
  - lib/lolsoap/wsdl/null_type.rb
113
113
  - lib/lolsoap/wsdl/operation.rb
114
114
  - lib/lolsoap/wsdl/operation_io.rb
115
+ - lib/lolsoap/wsdl/operation_io_part.rb
115
116
  - lib/lolsoap/wsdl/type.rb
116
117
  - lib/lolsoap/wsdl_parser.rb
117
118
  - lolsoap.gemspec