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 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: