shapewear 0.1.2 → 0.1.4

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.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.4
4
+ * Parameters are now read in the correct order, as specified in the metadata;
5
+ * Complex return types are now working correctly;
6
+ * DRYed some code;
7
+ * Added more logs.
8
+
9
+ ## 0.1.3
10
+ * More fixes for .NET interoperability.
11
+
3
12
  ## 0.1.2
4
13
  * Fixed a bug when returning SOAP:Faults.
5
14
 
data/lib/shapewear/dsl.rb CHANGED
@@ -21,6 +21,7 @@ module Shapewear::DSL
21
21
  'soap' => 'http://schemas.xmlsoap.org/wsdl/soap/',
22
22
  'soap12' => 'http://schemas.xmlsoap.org/wsdl/soap12/',
23
23
  'xsd' => 'http://www.w3.org/2001/XMLSchema',
24
+ 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
24
25
  'env' => 'http://schemas.xmlsoap.org/soap/envelope/',
25
26
  'env12' => 'http://www.w3.org/2001/12/soap-envelope'
26
27
  end
@@ -49,7 +49,7 @@ module Shapewear::Request
49
49
  operations.each do |k, v|
50
50
  if v[:public_name] == op_node.name
51
51
  logger.debug "Extracting parameters from operation node..."
52
- params = extract_parameters(@op_node)
52
+ params = extract_parameters(v, op_node)
53
53
  logger.debug "Creating new instance of #{clazz}..."
54
54
  obj = clazz.new
55
55
  logger.debug "Calling #{k} with args: #{params.map(&:inspect) * ', '}"
@@ -67,9 +67,25 @@ module Shapewear::Request
67
67
  raise "Operation not found: #{@op_node.name}"
68
68
  end
69
69
 
70
- def extract_parameters(node)
71
- # TODO: use the metadata collected from the DSL to reoder the parameters and perform the appropriate conversions
72
- node.children.map { |n| n.text }
70
+ def extract_parameters(op_options, node)
71
+ logger.debug "Operation node: #{node.inspect}"
72
+ r = []
73
+ op_options[:parameters].each do |p|
74
+ logger.debug " Looking for: tns:#{p.first.to_s.camelize}"
75
+ v = node.xpath("tns:#{p.first.to_s.camelize}", namespaces).first
76
+ if v.nil?
77
+ # does nothing
78
+ elsif p.last == Fixnum
79
+ v = v.text.to_i
80
+ elsif p.last == DateTime
81
+ v = DateTime.parse(v.text) # TODO: add tests
82
+ else
83
+ v = v.text
84
+ end
85
+ logger.debug " Found: #{v.inspect}"
86
+ r << v
87
+ end
88
+ r
73
89
  end
74
90
 
75
91
  #noinspection RubyArgCount
@@ -77,15 +93,48 @@ module Shapewear::Request
77
93
  xb = Builder::XmlMarkup.new
78
94
  xb.instruct!
79
95
 
80
- xb.Envelope :xmlns => soap_env_ns do |xenv|
96
+ xb.Envelope :xmlns => soap_env_ns, 'xmlns:xsi' => namespaces['xsi'] do |xenv|
81
97
  xenv.Body do |xbody|
82
- xbody.tag! "#{op_options[:public_name]}Response", :xmlns => namespaces['tns'] do |xres|
83
- xres.body r
98
+ xbody.tag! "#{op_options[:public_name]}Response", :xmlns => namespaces['tns'] do |xresp|
99
+
100
+ if r.nil?
101
+ xresp.tag! "#{op_options[:public_name]}Result", 'xsi:nil' => 'true'
102
+ else
103
+ ret = op_options[:returns] rescue nil
104
+ case ret
105
+ when NilClass, Class
106
+ xresp.tag! "#{op_options[:public_name]}Result", r
107
+ when Hash
108
+ xresp.tag! "#{op_options[:public_name]}Result" do |xres|
109
+ ret.each do |k, v|
110
+ extract_and_serialize_value(xres, r, k, v)
111
+ end
112
+ end
113
+ else
114
+ raise "Unsupported return type: #{ret.inspect}"
115
+ end
116
+ end
84
117
  end
85
118
  end
86
119
  end
87
120
  end
88
121
 
122
+ def extract_and_serialize_value(builder, obj, field, type)
123
+ v = if obj.is_a?(Hash)
124
+ obj[field]
125
+ elsif obj.respond_to?(field)
126
+ obj.send(field)
127
+ else
128
+ raise "Could not extract #{field.inspect} from object: #{obj.inspect}"
129
+ end
130
+
131
+ if v.nil?
132
+ builder.tag! field.to_s.camelize, 'xsi:nil' => 'true'
133
+ else
134
+ builder.tag! field.to_s.camelize, v
135
+ end
136
+ end
137
+
89
138
  #noinspection RubyArgCount
90
139
  def serialize_soap_fault(ex)
91
140
  logger.debug "Serializing SOAP Fault: #{ex.inspect}"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Shapewear
4
4
 
5
- Version = "0.1.2"
5
+ Version = "0.1.4"
6
6
 
7
7
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'builder'
4
4
 
5
- #noinspection RubyArgCount,RubyResolve
5
+ #noinspection RubyArgCount,RubyResolve,RubyLiteralArrayInspection
6
6
  module Shapewear::WSDL
7
7
  # reference: http://www.w3.org/TR/wsdl
8
8
  def to_wsdl
@@ -17,7 +17,7 @@ module Shapewear::WSDL
17
17
  'xmlns:tns' => namespaces['tns'] do |xdef|
18
18
 
19
19
  xdef.types do |xtypes|
20
- xtypes.schema 'xmlns' => namespaces['xsd'], :elementFormDefault => 'qualified', 'targetNamespace' => namespaces['tns'] do |xschema|
20
+ xtypes.schema 'xmlns' => namespaces['xsd'], :elementFormDefault => 'qualified', :targetNamespace => namespaces['tns'] do |xschema|
21
21
 
22
22
  # define elements for each defined method
23
23
  operations.each do |m, op_opts|
@@ -54,16 +54,16 @@ module Shapewear::WSDL
54
54
  xop.documentation doc unless doc.nil?
55
55
  xop.tag! "soap#{sv}:operation", :soapAction => "#{namespaces['tns']}/#{op_opts[:public_name]}", :style => 'document'
56
56
  xop.input { |xin| xin.tag! "soap#{sv}:body", :use => 'literal' }
57
- xop.output { |xin| xin.tag! "soap#{sv}:body", :use => 'literal' }
57
+ xop.output { |xout| xout.tag! "soap#{sv}:body", :use => 'literal' }
58
58
  end
59
59
  end
60
60
  end
61
61
  end
62
62
 
63
63
  # service definition for soap 1.1 and 1.2
64
- ['', '12'].each do |sv|
65
- xdef.service :name => "#{options[:service_name]}#{sv}" do |xsrv|
66
- xsrv.documentation "WSDL auto-generated by shapewear."
64
+ xdef.service :name => "#{options[:service_name]}" do |xsrv|
65
+ xsrv.documentation "WSDL auto-generated by shapewear."
66
+ ['', '12'].each do |sv|
67
67
  xsrv.port :name => "#{options[:service_name]}Soap#{sv}", :binding => "tns:#{options[:service_name]}Soap#{sv}" do |xport|
68
68
  xport.tag! "soap#{sv}:address", :location => options[:endpoint_url]
69
69
  end
@@ -119,15 +119,14 @@ module Shapewear::WSDL
119
119
  xschema.element :name => "#{op_options[:public_name]}Response" do |xreq|
120
120
  xreq.complexType do |xct|
121
121
  xct.sequence do |xseq|
122
- if ret.nil?
123
- xseq.element :name => "#{op_options[:public_name]}Result", :minOccurs => 0, :maxOccurs => 1, :type => 'xsd:any'
124
- elsif ret.is_a?(Class)
125
- xseq.element :name => "#{op_options[:public_name]}Result", :minOccurs => 0, :maxOccurs => 1, :type => to_xsd_type(ret)
126
- elsif ret.is_a?(Hash)
127
- xseq.element :name => "#{op_options[:public_name]}Result", :minOccurs => 0, :maxOccurs => 1, :type => "tns:#{op_options[:public_name]}Struct"
128
- else
129
- raise "Could not interpret #{ret.inspect} as a return type definition"
130
- end
122
+ xseq.element :name => "#{op_options[:public_name]}Result", :minOccurs => 0, :maxOccurs => 1,
123
+ :type => case ret
124
+ when NilClass then 'xsd:any'
125
+ when Class then to_xsd_type(ret)
126
+ when Hash then "tns:#{op_options[:public_name]}Struct"
127
+ else
128
+ raise "Could not interpret #{ret.inspect} as a return type definition"
129
+ end
131
130
  end
132
131
  end
133
132
  end
@@ -16,13 +16,35 @@ describe Shapewear do
16
16
  it "should work for simple requests" do
17
17
  client = Savon::Client.new 'http://services.example.com/complete/soap/wsdl'
18
18
  response = client.request :echo_in_uppercase, :xmlns => 'http://services.example.com/v1' do
19
- soap.body = { :text => 'uppercase text' }
19
+ soap.body = { 'Text' => 'uppercase text' }
20
20
  end
21
21
 
22
22
  puts response.inspect
23
23
  puts response.body.inspect
24
24
 
25
- response.body[:echo_in_uppercase_response][:body].should == 'UPPERCASE TEXT'
25
+ response.body[:echo_in_uppercase_response][:echo_in_uppercase_result].should == 'UPPERCASE TEXT'
26
+ end
27
+
28
+ it "should work for structured responses from objects" do
29
+ client = Savon::Client.new 'http://services.example.com/complete/soap/wsdl'
30
+ response = client.request :get_structured_data, :xmlns => 'http://services.example.com/v1' do
31
+ soap.body = { 'Id' => 0 }
32
+ end
33
+
34
+ r = response.body[:get_structured_data_response][:get_structured_data_result]
35
+ r.should be_a Hash
36
+ r.should include :text => 'text from the struct'
37
+ end
38
+
39
+ it "should work for structured responses from hashes" do
40
+ client = Savon::Client.new 'http://services.example.com/complete/soap/wsdl'
41
+ response = client.request :get_structured_data, :xmlns => 'http://services.example.com/v1' do
42
+ soap.body = { 'Id' => 1 }
43
+ end
44
+
45
+ r = response.body[:get_structured_data_response][:get_structured_data_result]
46
+ r.should be_a Hash
47
+ r.should include :text => 'text from a hash'
26
48
  end
27
49
 
28
50
  it "should raise SOAP 1.1 Faults" do
@@ -30,7 +52,7 @@ describe Shapewear do
30
52
 
31
53
  expect {
32
54
  client.request :get_structured_data, :xmlns => 'http://services.example.com/v1' do
33
- soap.body = { :id => 55 }
55
+ soap.body = { 'Id' => 55 }
34
56
  end
35
57
  }.to raise_error Savon::SOAP::Fault, "(e:Server.RuntimeError) ID must be 0 or 1"
36
58
  end
@@ -41,7 +63,7 @@ describe Shapewear do
41
63
  expect {
42
64
  client.request :get_structured_data, :xmlns => 'http://services.example.com/v1' do
43
65
  soap.version = 2
44
- soap.body = { :id => 55 }
66
+ soap.body = { 'Id' => 55 }
45
67
  end
46
68
  }.to raise_error Savon::SOAP::Fault, "(e:Server.RuntimeError) ID must be 0 or 1"
47
69
  end
@@ -21,7 +21,7 @@ class CompleteService
21
21
  :returns => {:text => String, :random_value => Fixnum, :created_at => DateTime}
22
22
 
23
23
  def echo_in_uppercase(text)
24
- text.upcase
24
+ text.upcase unless text.nil?
25
25
  end
26
26
 
27
27
  def sum(x, y)
@@ -39,7 +39,9 @@ class CompleteService
39
39
  end
40
40
  end
41
41
 
42
- class Structured < Struct.new(:text, :random_value, :created_at)
42
+ class Structured
43
+ attr_reader :text, :random_value, :created_at
44
+
43
45
  def initialize(text)
44
46
  @text = text
45
47
  @random_value = rand(999)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shapewear
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
9
+ - 4
10
+ version: 0.1.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - "F\xC3\xA1bio Batista"