lolsoap 0.4.2 → 0.5.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: 70c9d43e10a4416609eb3eb5a9af91f71f279c3f
4
- data.tar.gz: edebdbc665e6f41416241807e6166669f4504de4
3
+ metadata.gz: d15ac33320b9b7a7f32e1fd15e111ba323683c75
4
+ data.tar.gz: d9fdcb8040c0e9e714b0512f73c69c15ca70d686
5
5
  SHA512:
6
- metadata.gz: 13e9cee35f6f3beee983e302df03902ad407e1a9a9f0d41dde9fe3ed00564c1b7f997a192fd3f352225378f57f8db295f2dc1351a45f0ee29f143b40f3412fcc
7
- data.tar.gz: d54666737a235460e8165b410475cc62d62d7352a3f605530bc71cab1fc6ff5c4ce968346ebe171212447518f57d82035bc7f9c5fb7ac8f9724fcd736b46f403
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.4.2
1
+ 0.5.0
@@ -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.type_namespaces.map { |prefix, uri| [prefix, root.add_namespace(prefix, uri)] }]
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
- @name = name
7
- @wsdl = wsdl
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
@@ -36,7 +36,7 @@ class LolSoap::WSDL
36
36
  end
37
37
 
38
38
  def inspect
39
- "<#{self.class} name=\"#{prefix_and_name.inspect}\" " \
39
+ "<#{self.class} name=\"#{prefix_and_name}\" " \
40
40
  "elements=#{elements.inspect} " \
41
41
  "attributes=#{attributes.inspect}>"
42
42
  end
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 namespaces used in the WSDL document (keys are prefixes)
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
- @types = load_types(parser)
35
- @operations = load_operations(parser)
36
- @endpoint = parser.endpoint
37
- @namespaces = parser.namespaces
38
- @type_namespaces = load_type_namespaces(parser)
39
- @prefixes = parser.prefixes
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.dup
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 supports by the SOAP service
49
+ # Hash of operations that are supported by the SOAP service
54
50
  def operations
55
- @operations.dup
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=#{@namespaces.inspect} " \
66
- "operations=#{@operations.keys.inspect} " \
67
- "types=#{@types.keys.inspect}>"
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 |prefixed_name, type|
76
- [prefixed_name, build_type(type)]
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 load_type_namespaces(parser)
92
- Hash[
93
- parser.types.merge(parser.elements).values.map do |el|
94
- [el[:prefix], namespaces[el[:prefix]]]
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[:prefix],
104
- build_elements(params[:elements]),
105
- params[:attributes]
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[:prefix],
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.respond_to?(:to_str)
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[element])
147
+ build_element(parser.elements.fetch(element))
141
148
  end
142
149
  end
143
150
  end
@@ -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, :prefix
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
- @prefix, @name = prefix_and_name(node.attr('name'))
14
+ @namespace, @name = parser.namespace_and_name(node, node.attr('name').to_s, target_namespace)
15
15
  end
16
16
 
17
- def name_with_prefix
18
- "#{prefix}:#{name}"
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
- else
35
- prefix_and_name(node.attr('type').to_s).join(':')
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 => element.name,
76
- :prefix => element.prefix,
77
- :type => element.type,
78
- :singular => element.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| Element.new(parser, el, target_namespace) }
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.name_with_prefix] = {
127
+ types[type.id] = {
142
128
  :name => type.name,
143
- :prefix => type.prefix,
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 = prefix_and_name(name).last
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.name_with_prefix] = {
166
- :name => element.name,
167
- :prefix => element.prefix,
168
- :type => element.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, prefix_and_name(element).join(':')]
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 prefix_and_name(prefixed_name, default_namespace = nil)
231
- prefix, name = prefixed_name.to_s.split(':')
232
-
233
- if name
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 = prefix
238
- prefix = prefixes.fetch(default_namespace)
221
+ name = prefixed_name
222
+ namespace = default_namespace
239
223
  end
240
224
 
241
- [prefix, name]
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.4.2 ruby lib
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.4.2"
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-09"
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="xsd3:price" type="Price"/>
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="xsd3:TradePrice"/>
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/xsd1:tradePriceRequest', doc.namespaces)
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('//xsd1:tradePriceRequest/xsd1:tickerSymbol', doc.namespaces)
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('//xsd1:tradePriceRequest/xsd1:specialTickerSymbol/xsd2:name', doc.namespaces)
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('//xsd1:tradePriceRequest/@id', doc.namespaces)
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['xsd1'].verySpecialBoolean true
41
+ h['ns0'].verySpecialBoolean true
42
42
  end
43
43
 
44
- el = doc.at_xpath('/soap:Envelope/soap:Header/xsd1:verySpecialBoolean', doc.namespaces)
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['GetLastTradePrice'].tap do |o|
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['xsd1:TradePriceRequest'].tap do |t|
17
- t.prefix.must_equal 'xsd1'
16
+ subject.types.fetch('TradePriceRequest').tap do |t|
17
+ t.prefix.must_equal 'ns0'
18
18
  end
19
19
  end
20
20
 
@@ -5,25 +5,25 @@ module LolSoap
5
5
  describe Envelope do
6
6
  let(:wsdl) do
7
7
  OpenStruct.new(
8
- :type_namespaces => { 'foo' => 'http://example.com/foo' },
9
- :soap_version => '1.2'
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 => 'foo', :name => 'WashHandsRequest'))
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/foo:WashHandsRequest', doc.namespaces) }
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:foo' => 'http://example.com/foo'
26
+ 'xmlns:ns0' => 'http://example.com/foo'
27
27
  )
28
28
 
29
29
  header.wont_equal nil
@@ -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 => 'bla:brush',
16
- :output => 'bla:Color'
16
+ :input => [namespace, 'brush'],
17
+ :output => [namespace, 'Color']
17
18
  }
18
19
  },
19
20
  :types => {
20
- 'bla:Brush' => {
21
+ [namespace, 'Brush'] => {
22
+ :name => 'Brush',
21
23
  :elements => {
22
24
  'handleColor' => {
23
- :name => 'handleColor',
24
- :prefix => 'bla',
25
- :type => {
25
+ :name => 'handleColor',
26
+ :namespace => namespace,
27
+ :type => {
26
28
  :elements => {
27
29
  'name' => {
28
- :name => 'name',
29
- :prefix => 'bla',
30
- :type => 'xs:string',
31
- :singular => true
30
+ :name => 'name',
31
+ :namespace => namespace,
32
+ :singular => true
32
33
  },
33
34
  'hex' => {
34
- :name => 'hex',
35
- :prefix => 'bla',
36
- :type => 'xs:string',
37
- :singular => true
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 => 'age',
46
- :prefix => 'bla',
47
- :type => 'xs:int',
48
- :singular => false
47
+ :name => 'age',
48
+ :namespace => namespace,
49
+ :type => [xs, "int"],
50
+ :singular => false
49
51
  }
50
52
  },
51
53
  :attributes => ['id'],
52
- :prefix => 'bla'
54
+ :namespace => namespace
53
55
  }
54
56
  },
55
57
  :elements => {
56
- 'bla:brush' => {
57
- :name => 'brush',
58
- :prefix => 'bla',
59
- :type => 'bla:Brush'
58
+ [namespace, 'brush'] => {
59
+ :name => 'brush',
60
+ :namespace => namespace,
61
+ :type => [namespace, 'Brush']
60
62
  },
61
- 'bla:Color' => {
62
- :name => 'Color',
63
- :prefix => 'bla',
64
- :type => {
63
+ [namespace, 'Color'] => {
64
+ :name => 'Color',
65
+ :namespace => namespace,
66
+ :type => {
65
67
  :elements => {
66
68
  'name' => {
67
- :name => 'name',
68
- :prefix => 'bla',
69
- :type => 'xs:string',
70
- :singular => true
69
+ :name => 'name',
70
+ :namespace => namespace,
71
+ :type => [xs, "string"],
72
+ :singular => true
71
73
  },
72
74
  'hex' => {
73
- :name => 'hex',
74
- :prefix => 'bla',
75
- :type => 'xs:string',
76
- :singular => true
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({ 'bla' => namespace })
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['bla:Brush'].tap do |t|
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 'bla'
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('bla:Brush').must_equal subject.types['bla:Brush']
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) { Nokogiri::XML(raw_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
- 'xsd1:Price' => {
37
- :prefix => 'xsd1',
26
+ [namespace, 'Price'] => {
38
27
  :name => 'Price',
28
+ :namespace => namespace,
39
29
  :elements => {},
40
30
  :attributes => ['currency']
41
31
  },
42
- 'xsd1:TradePriceRequest' => {
43
- :prefix => 'xsd1',
44
- :name => 'TradePriceRequest',
32
+ [namespace, 'TradePriceRequest'] => {
33
+ :name => 'TradePriceRequest',
34
+ :namespace => namespace,
45
35
  :elements => {
46
36
  'accountId' => {
47
- :name => 'accountId',
48
- :prefix => 'xsd1',
49
- :type => 'xs:string',
50
- :singular => true
37
+ :name => 'accountId',
38
+ :namespace => namespace,
39
+ :type => [xs, "string"],
40
+ :singular => true
51
41
  },
52
42
  'tickerSymbol' => {
53
- :name => 'tickerSymbol',
54
- :prefix => 'xsd1',
55
- :type => 'xs:string',
56
- :singular => false
43
+ :name => 'tickerSymbol',
44
+ :namespace => namespace,
45
+ :type => [xs, "string"],
46
+ :singular => false
57
47
  },
58
48
  'specialTickerSymbol' => {
59
- :name => 'specialTickerSymbol',
60
- :prefix => 'xsd1',
61
- :type => 'xsd2:TickerSymbol',
62
- :singular => false
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
- 'xsd1:HistoricalPriceRequest' => {
68
- :prefix => 'xsd1',
69
- :name => 'HistoricalPriceRequest',
57
+ [namespace, 'HistoricalPriceRequest'] => {
58
+ :name => 'HistoricalPriceRequest',
59
+ :namespace => namespace,
70
60
  :elements => {
71
61
  'accountId' => {
72
- :name => 'accountId',
73
- :prefix => 'xsd1',
74
- :type => 'xs:string',
75
- :singular => true
62
+ :name => 'accountId',
63
+ :namespace => namespace,
64
+ :type => [xs, "string"],
65
+ :singular => true
76
66
  },
77
67
  'dateRange' => {
78
- :name => 'dateRange',
79
- :prefix => 'xsd1',
80
- :type => {
81
- :elements => {
68
+ :name => 'dateRange',
69
+ :namespace => namespace,
70
+ :type => {
71
+ :namespace => namespace,
72
+ :elements => {
82
73
  'startDate' => {
83
- :name => 'startDate',
84
- :prefix => 'xsd1',
85
- :type => 'xs:string',
86
- :singular => true
74
+ :name => 'startDate',
75
+ :namespace => namespace,
76
+ :type => [xs, "string"],
77
+ :singular => true
87
78
  },
88
79
  'endDate' => {
89
- :name => 'endDate',
90
- :prefix => 'xsd1',
91
- :type => 'xs:string',
92
- :singular => true
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
- 'xsd2:TickerSymbol' => {
103
- :prefix => 'xsd2',
104
- :name => 'TickerSymbol',
105
- :elements => {
93
+ [namespace2, 'TickerSymbol'] => {
94
+ :name => 'TickerSymbol',
95
+ :namespace => namespace2,
96
+ :elements => {
106
97
  'name' => {
107
- :name => 'name',
108
- :prefix => 'xsd2',
109
- :type => 'xs:string',
110
- :singular => true
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
- "xsd1:tradePriceRequest" => {
123
- :name => "tradePriceRequest",
124
- :prefix => "xsd1",
125
- :type => "xsd1:TradePriceRequest"
113
+ [namespace, "tradePriceRequest"] => {
114
+ :name => "tradePriceRequest",
115
+ :namespace => namespace,
116
+ :type => [namespace, "TradePriceRequest"]
126
117
  },
127
- "xsd1:TradePrice" => {
128
- :name => "TradePrice",
129
- :prefix => "xsd1",
130
- :type => {
118
+ [namespace, "TradePrice"] => {
119
+ :name => "TradePrice",
120
+ :namespace => namespace,
121
+ :type => {
122
+ :namespace => namespace,
131
123
  :elements => {
132
- 'price' => {
133
- :name => 'price',
134
- :prefix => 'xsd1',
135
- :type => 'xsd1:Price',
136
- :singular => true
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
- "xsd1:historicalPriceRequest" => {
143
- :name => "historicalPriceRequest",
144
- :prefix => "xsd1",
145
- :type => "xsd1:HistoricalPriceRequest"
134
+ [namespace, "historicalPriceRequest"] => {
135
+ :name => "historicalPriceRequest",
136
+ :namespace => namespace,
137
+ :type => [namespace, "HistoricalPriceRequest"]
146
138
  },
147
- "xsd1:HistoricalPrice" => {
148
- :name => "HistoricalPrice",
149
- :prefix => "xsd1",
150
- :type => {
139
+ [namespace, "HistoricalPrice"] => {
140
+ :name => "HistoricalPrice",
141
+ :namespace => namespace,
142
+ :type => {
143
+ :namespace => namespace,
151
144
  :elements => {
152
145
  'date' => {
153
- :name => 'date',
154
- :prefix => 'xsd1',
155
- :type => 'xs:date',
156
- :singular => true
146
+ :name => 'date',
147
+ :namespace => namespace,
148
+ :type => [xs, 'date'],
149
+ :singular => true
157
150
  },
158
151
  'price' => {
159
- :name => 'price',
160
- :prefix => 'xsd1',
161
- :type => 'xs:float',
162
- :singular => true
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' => 'xsd1:tradePriceRequest',
176
- 'GetLastTradePriceOutput' => 'xsd1:TradePrice',
177
- 'GetHistoricalPriceInput' => 'xsd1:historicalPriceRequest',
178
- 'GetHistoricalPriceOutput' => 'xsd1:HistoricalPrice'
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 => 'xsd1:tradePriceRequest',
188
- :output => 'xsd1:TradePrice'
180
+ :input => [namespace, 'tradePriceRequest'],
181
+ :output => [namespace, 'TradePrice']
189
182
  },
190
183
  'GetHistoricalPrice' => {
191
- :input => 'xsd1:historicalPriceRequest',
192
- :output => 'xsd1:HistoricalPrice'
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 => 'xsd1:tradePriceRequest',
204
- :output => 'xsd1:TradePrice'
196
+ :input => [namespace, 'tradePriceRequest'],
197
+ :output => [namespace, 'TradePrice']
205
198
  },
206
199
  'GetHistoricalPrice' => {
207
200
  :action => 'http://example.com/GetHistoricalPrice',
208
- :input => 'xsd1:historicalPriceRequest',
209
- :output => 'xsd1:HistoricalPrice'
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.2
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-09 00:00:00.000000000 Z
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: