shapewear 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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"