smacks-apricoteatsgorilla 0.5.0 → 0.5.1

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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ nbproject
3
+ .autotest
data/README.rdoc CHANGED
@@ -11,7 +11,8 @@ for working with SOAP services.
11
11
  == Dependencies
12
12
 
13
13
  hpricot 0.8.241 (the latest JRuby-compatible version)
14
- Also available from the Github download page of Apricot eats Gorilla.
14
+
15
+ Also available at: {GitHub Downloads}[http://github.com/smacks/apricoteatsgorilla/downloads]
15
16
 
16
17
  == Translate an XML String into a Ruby Hash
17
18
 
data/Rakefile CHANGED
@@ -17,3 +17,27 @@ Rake::RDocTask.new do |rdoc|
17
17
  rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
18
18
  rdoc.options = ["--line-numbers", "--inline-source"]
19
19
  end
20
+
21
+ begin
22
+ require "jeweler"
23
+ Jeweler::Tasks.new do |spec|
24
+ spec.name = "apricoteatsgorilla"
25
+ spec.author = "Daniel Harrington"
26
+ spec.email = "me@d-harrington.com"
27
+ spec.homepage = "http://github.com/smacks/apricoteatsgorilla"
28
+ spec.summary = "SOAP communication helper."
29
+ spec.description = spec.summary
30
+
31
+ spec.rdoc_options += [
32
+ "--title", "Apricot eats Gorilla",
33
+ "--main", "README.rdoc",
34
+ "--line-numbers",
35
+ "--inline-source"
36
+ ]
37
+
38
+ spec.add_runtime_dependency("hpricot", "0.8.241")
39
+ spec.add_development_dependency("rspec", ">= 1.2.8")
40
+ end
41
+ rescue LoadError
42
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.1
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{apricoteatsgorilla}
8
+ s.version = "0.5.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Daniel Harrington"]
12
+ s.date = %q{2009-08-29}
13
+ s.description = %q{SOAP communication helper.}
14
+ s.email = %q{me@d-harrington.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "apricoteatsgorilla.gemspec",
24
+ "lib/apricoteatsgorilla.rb",
25
+ "lib/apricoteatsgorilla/apricoteatsgorilla.rb",
26
+ "lib/apricoteatsgorilla/xml_node.rb",
27
+ "spec/apricoteatsgorilla/apricoteatsgorilla_hash_to_xml_spec.rb",
28
+ "spec/apricoteatsgorilla/apricoteatsgorilla_spec.rb",
29
+ "spec/apricoteatsgorilla/apricoteatsgorilla_xml_to_hash_spec.rb",
30
+ "spec/apricoteatsgorilla/xml_node_spec.rb",
31
+ "spec/spec_helper.rb"
32
+ ]
33
+ s.has_rdoc = true
34
+ s.homepage = %q{http://github.com/smacks/apricoteatsgorilla}
35
+ s.rdoc_options = ["--charset=UTF-8", "--title", "Apricot eats Gorilla", "--main", "README.rdoc", "--line-numbers", "--inline-source"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.1}
38
+ s.summary = %q{SOAP communication helper.}
39
+ s.test_files = [
40
+ "spec/apricoteatsgorilla/apricoteatsgorilla_hash_to_xml_spec.rb",
41
+ "spec/apricoteatsgorilla/apricoteatsgorilla_spec.rb",
42
+ "spec/apricoteatsgorilla/apricoteatsgorilla_xml_to_hash_spec.rb",
43
+ "spec/apricoteatsgorilla/xml_node_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 2
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<hpricot>, ["= 0.8.241"])
53
+ s.add_development_dependency(%q<rspec>, [">= 1.2.8"])
54
+ else
55
+ s.add_dependency(%q<hpricot>, ["= 0.8.241"])
56
+ s.add_dependency(%q<rspec>, [">= 1.2.8"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<hpricot>, ["= 0.8.241"])
60
+ s.add_dependency(%q<rspec>, [">= 1.2.8"])
61
+ end
62
+ end
@@ -0,0 +1,3 @@
1
+ %w(apricoteatsgorilla xml_node).each do |file|
2
+ require File.join(File.dirname(__FILE__), "apricoteatsgorilla", file)
3
+ end
@@ -0,0 +1,239 @@
1
+ %w(rubygems hpricot).each do |gem|
2
+ require gem
3
+ end
4
+
5
+ # == ApricotEatsGorilla
6
+ #
7
+ # Apricot eats Gorilla is a SOAP communication helper. It translates between
8
+ # SOAP messages (XML) and Ruby Hashes and comes with some additional helpers
9
+ # for working with SOAP services.
10
+ class ApricotEatsGorilla
11
+ class << self
12
+
13
+ # Flag to enable sorting of Hash keys.
14
+ attr_accessor :sort_keys
15
+
16
+ # Flag to disable conversion of XML tags to lowerCamelCase.
17
+ attr_accessor :disable_tag_names_to_lower_camel_case
18
+
19
+ # Flag to disable conversion of Hash keys to snake_case.
20
+ attr_accessor :disable_hash_keys_to_snake_case
21
+
22
+ # Flag to disable conversion of Hash keys to Symbols.
23
+ attr_accessor :disable_hash_keys_to_symbols
24
+
25
+ # Hash of namespaces and XML nodes to apply these namespaces to.
26
+ attr_accessor :nodes_to_namespace
27
+
28
+ # Shortcut method for translating between XML Strings and Ruby Hashes.
29
+ # Delegates to +xml_to_hash+ in case +source+ is a String or delegates
30
+ # to +hash_to_xml+ in case +source+ is a Hash. Returns nil otherwise.
31
+ def [](source, root_node = nil)
32
+ case source
33
+ when String
34
+ xml_to_hash(source, root_node)
35
+ when Hash
36
+ hash_to_xml(source)
37
+ else
38
+ nil
39
+ end
40
+ end
41
+
42
+ # Yields this class in case a +block+ was given.
43
+ def setup
44
+ yield self if block_given?
45
+ end
46
+
47
+ # Translates a given +xml+ String into a Ruby Hash.
48
+ #
49
+ # Starts parsing at the XML root node by default. Accepts an optional
50
+ # +root_node+ parameter for defining a custom root node to start parsing
51
+ # at using an XPath-Expression (Hpricot search).
52
+ #
53
+ # Notice that the root node itself won't be included in the Hash.
54
+ #
55
+ # ==== Example
56
+ #
57
+ # xml = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
58
+ # <soap:Body>
59
+ # <ns2:authenticateResponse xmlns:ns2="http://v1_0.ws.example.com/">
60
+ # <return>
61
+ # <apricot>
62
+ # <eats>Gorilla</eats>
63
+ # </apricot>
64
+ # </return>
65
+ # </ns2:authenticateResponse>
66
+ # </soap:Body>
67
+ # </soap:Envelope>'
68
+ #
69
+ # ApricotEatsGorilla.xml_to_hash(xml, "//return")
70
+ # # => { :apricot => { :eats => "Gorilla" } }
71
+ def xml_to_hash(xml, root_node = nil)
72
+ doc = Hpricot.XML remove_whitespace(xml)
73
+ root = root_node ? doc.search(root_node) : doc.root
74
+
75
+ return nil if root.nil?
76
+ if !root.respond_to? :each
77
+ xml_node_to_hash(root)
78
+ elsif root.size == 1
79
+ single_xml_root_node_to_hash(root)
80
+ else
81
+ multiple_xml_root_nodes_to_hash(root)
82
+ end
83
+ end
84
+
85
+ # Translates a given Ruby +hash+ into an XML String.
86
+ #
87
+ # ==== Example
88
+ #
89
+ # hash = { :apricot => { :eats => "Gorilla" } }
90
+ #
91
+ # ApricotEatsGorilla.hash_to_xml(hash)
92
+ # # => "<apricot><eats>Gorilla</eats></apricot>"
93
+ def hash_to_xml(hash)
94
+ nested_data_to_xml(hash.keys.first, hash.values.first)
95
+ end
96
+
97
+ # Builds a SOAP request envelope and includes the content from a given
98
+ # +block+ into the envelope body. Accepts a Hash of +namespaces+ to set.
99
+ #
100
+ # ==== Example
101
+ #
102
+ # ApricotEatsGorilla.soap_envelope do
103
+ # "<apricot><eats>Gorilla</eats></apricot>"
104
+ # end
105
+ #
106
+ # # => '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
107
+ # # => <env:Body>
108
+ # # => <apricot><eats>Gorilla</eats></apricot>
109
+ # # => </env:Body>
110
+ # # => </env:Envelope>'
111
+ def soap_envelope(namespaces = {})
112
+ namespaces[:env] = "http://schemas.xmlsoap.org/soap/envelope/"
113
+
114
+ xml_node("env:Envelope", namespaces) do
115
+ xml_node("env:Body") { yield if block_given? }
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ # Translates a single XML root node to a Ruby Hash.
122
+ def single_xml_root_node_to_hash(root)
123
+ if root.first.children.first.kind_of? Hpricot::Text
124
+ map_xml_value(root.first.children.to_s)
125
+ else
126
+ xml_node_to_hash(root.first)
127
+ end
128
+ end
129
+
130
+ # Translates multiple XML root nodes to a Ruby Hash.
131
+ def multiple_xml_root_nodes_to_hash(root)
132
+ root.map do |node|
133
+ if node.children.first.kind_of? Hpricot::Text
134
+ map_xml_value(node.children.to_s)
135
+ else
136
+ xml_node_to_hash(node)
137
+ end
138
+ end
139
+ end
140
+
141
+ # Iterates through a given Hpricot +element+ and returns a Ruby Hash
142
+ # equal to the XML content of the given element.
143
+ def xml_node_to_hash(element)
144
+ hash = {}
145
+
146
+ element.each_child do |child|
147
+ key = create_hash_key(child.name)
148
+ value = create_hash_value(child)
149
+
150
+ case hash[key]
151
+ when Array
152
+ hash[key] << value
153
+ when nil
154
+ hash[key] = value
155
+ else
156
+ hash[key] = [ hash[key].dup, value ]
157
+ end
158
+ end
159
+
160
+ hash
161
+ end
162
+
163
+ # Returns a Hash key for +xml_node_to_hash+ by a given +name+.
164
+ def create_hash_key(name)
165
+ key = XMLNode.new(name)
166
+ key.strip_namespace!
167
+ key.to_snake_case! unless disable_hash_keys_to_snake_case
168
+ key = disable_hash_keys_to_symbols ? key.to_s : key.to_sym
169
+ end
170
+
171
+ # Returns a Hash value for +xml_node_to_hash+ by a given +value+.
172
+ def create_hash_value(value)
173
+ if value.children.nil? || value.children.empty?
174
+ nil
175
+ elsif value.children.size == 1 && value.children.first.text?
176
+ map_xml_value(value.children.first.to_html)
177
+ else
178
+ xml_node_to_hash(value)
179
+ end
180
+ end
181
+
182
+ # Expects a Hash +key+ and a Hash +value+. Iterates through the given Hash
183
+ # +value+ and returns an XML String of the given Hash structure.
184
+ def nested_data_to_xml(key, value)
185
+ case value
186
+ when Array
187
+ value.map { |subitem| nested_data_to_xml(key, subitem) }.join
188
+ when Hash
189
+ xml_node(key) do
190
+ sort_hash_keys(value).map do |subkey, subvalue|
191
+ case subvalue
192
+ when Array
193
+ subvalue.map { |subitem| nested_data_to_xml(subkey, subitem) }.join
194
+ when Hash
195
+ nested_data_to_xml(subkey, subvalue)
196
+ else
197
+ xml_node(subkey) { subvalue.to_s } if subvalue.respond_to? :to_s
198
+ end
199
+ end.join
200
+ end
201
+ else
202
+ xml_node(key) { value.to_s } if value.respond_to? :to_s
203
+ end
204
+ end
205
+
206
+ # Returns an XML tag with a given +name+. Accepts a +block+ for tag content.
207
+ # Defaults to returning an empty-element tag in case no block was given.
208
+ # Also accepts a Hash of +attributes+ to be added to the XML tag.
209
+ def xml_node(name, attributes = {})
210
+ node = XMLNode.new(name.to_s)
211
+ node.to_lower_camel_case! unless disable_tag_names_to_lower_camel_case
212
+ node.namespace_from_hash!(nodes_to_namespace)
213
+ node.attributes = sort_hash_keys(attributes)
214
+ node.body = yield if block_given?
215
+ node.to_tag
216
+ end
217
+
218
+ # Removes whitespace between tags of a given +xml+ String.
219
+ def remove_whitespace(xml)
220
+ xml.gsub(/(>)\s*(<)/, '\1\2')
221
+ end
222
+
223
+ # Converts XML values to more natural Ruby objects.
224
+ def map_xml_value(value)
225
+ case value
226
+ when "true" then true
227
+ when "false" then false
228
+ else value
229
+ end
230
+ end
231
+
232
+ # Returns a sorted version of a given +hash+ if +sort_keys+ is enabled.
233
+ def sort_hash_keys(hash)
234
+ return hash unless sort_keys
235
+ hash.keys.sort_by { |key| key.to_s }.map { |key| [ key, hash[key] ] }
236
+ end
237
+
238
+ end
239
+ end
@@ -0,0 +1,72 @@
1
+ # == XMLNode
2
+ #
3
+ # Representation of an XML node. Inherits from String and includes some
4
+ # useful methods for namespaces, attributes, body content etc.
5
+ class XMLNode < String
6
+
7
+ # Hash of attributes.
8
+ attr_writer :attributes
9
+
10
+ # Body content.
11
+ attr_writer :body
12
+
13
+ # Strips the namespace from this node.
14
+ def strip_namespace!
15
+ sub!(/.+:(.+)/, '\1')
16
+ end
17
+
18
+ # Converts this node to snake_case.
19
+ def to_snake_case!
20
+ gsub!(/[A-Z]/, '_\0')
21
+ gsub!(/^_/, '')
22
+ downcase!
23
+ end
24
+
25
+ # Converts this node to lowerCamelCase.
26
+ def to_lower_camel_case!
27
+ gsub!(/_(.)/) { $1.upcase }
28
+ end
29
+
30
+ # Checks if this node is included in a given Hash of +namespaces+ and
31
+ # sets the namespace for this node in case it was found in the Hash.
32
+ def namespace_from_hash!(namespaces)
33
+ namespaces.each do |namespace, nodes|
34
+ @namespace = namespace if self_included? nodes
35
+ end unless namespaces.nil? || namespaces.empty?
36
+ end
37
+
38
+ # Returns this node as an XML tag including a namespace, attributes
39
+ # and a body in case these values were supplied.
40
+ def to_tag
41
+ return "<#{namespace}#{self}#{attributes} />" unless @body
42
+ "<#{namespace}#{self}#{attributes}>#{body}</#{namespace}#{self}>"
43
+ end
44
+
45
+ private
46
+
47
+ # Returns +true+ if self as a String or a Symbol is included in a
48
+ # given +array+. Returns +false+ otherwise.
49
+ def self_included?(array)
50
+ array.include?(self.to_s) || array.include?(self.to_sym)
51
+ end
52
+
53
+ # Returns the namespace of this node. Defaults to an empty String
54
+ # in case no namespace was defined.
55
+ def namespace
56
+ @namespace ? "#{@namespace}:" : ""
57
+ end
58
+
59
+ # Returns the attributes of this node. Defaults to an empty String
60
+ # in case no attributes were defined.
61
+ def attributes
62
+ return "" if @attributes.nil?
63
+ @attributes.map { |key, value| %Q( xmlns:#{key}="#{value}") }
64
+ end
65
+
66
+ # Returns the body of this node. Defaults to an empty String in case
67
+ # no body was defined.
68
+ def body
69
+ @body ? @body : ""
70
+ end
71
+
72
+ end
@@ -0,0 +1,67 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe ApricotEatsGorilla do
4
+ include SpecHelper
5
+
6
+ # hash_to_xml
7
+ describe "hash_to_xml" do
8
+ before { reset_library_options }
9
+
10
+ it "converts Hash key Symbols into Strings" do
11
+ hash = { :apricot => { :eats => [ :gorilla, "snake" ] } }
12
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
13
+ "<apricot><eats>gorilla</eats><eats>snake</eats></apricot>"
14
+ end
15
+
16
+ it "converts lowerCamelCase Hash keys to snake_case" do
17
+ hash = { :apricot => { :eats => { :lots_of => "gorillas" } } }
18
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
19
+ "<apricot><eats><lotsOf>gorillas</lotsOf></eats></apricot>"
20
+ end
21
+
22
+ it "does not convert lowerCamelCase Hash keys to snake_case if this was disabled" do
23
+ ApricotEatsGorilla.disable_tag_names_to_lower_camel_case = true
24
+ hash = { :apricot => { :eats => { :lots_of => "gorillas" } } }
25
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
26
+ "<apricot><eats><lots_of>gorillas</lots_of></eats></apricot>"
27
+ end
28
+
29
+ it "converts values responding to to_s into Strings" do
30
+ date_time = DateTime.now
31
+ hash = { :apricot => {
32
+ :at => date_time,
33
+ :with => 100.01,
34
+ :when => nil,
35
+ :what => :gorillas
36
+ }}
37
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
38
+ "<apricot><at>#{date_time}</at><what>gorillas</what>" <<
39
+ "<when></when><with>100.01</with></apricot>"
40
+ end
41
+
42
+ it "applies namespaces nodes defined via nodes_to_namespace" do
43
+ ApricotEatsGorilla.nodes_to_namespace = { :wsdl => [ :apricot ] }
44
+ hash = { :apricot => { :eats => "Gorilla" } }
45
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
46
+ "<wsdl:apricot><eats>Gorilla</eats></wsdl:apricot>"
47
+ end
48
+
49
+ it "converts a Hash containing only one key and a value into one node with content" do
50
+ hash = { "apricot" => "eats Gorilla" }
51
+ ApricotEatsGorilla.hash_to_xml(hash).should == "<apricot>eats Gorilla</apricot>"
52
+ end
53
+
54
+ it "converts a nested Hash into nested nodes" do
55
+ hash = { "apricot" => { "eats" => "gorilla", "drinks" => "beer" } }
56
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
57
+ "<apricot><drinks>beer</drinks><eats>gorilla</eats></apricot>"
58
+ end
59
+
60
+ it "converts a Hash containing an Array into multiple nodes" do
61
+ hash = { "apricot" => { "eats" => [ "gorilla", "snake" ] } }
62
+ ApricotEatsGorilla.hash_to_xml(hash).should ==
63
+ "<apricot><eats>gorilla</eats><eats>snake</eats></apricot>"
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,56 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe ApricotEatsGorilla do
4
+ include SpecHelper
5
+
6
+ # setup
7
+ describe "setup" do
8
+ it "yields self to a given block" do
9
+ ApricotEatsGorilla.setup do |yielded|
10
+ yielded.should == ApricotEatsGorilla
11
+ end
12
+ end
13
+ end
14
+
15
+ # soap_envelope
16
+ describe "soap_envelope" do
17
+ before { ApricotEatsGorilla.sort_keys = true }
18
+
19
+ it "returns a SOAP envelope with an empty-element body tag" do
20
+ ApricotEatsGorilla.soap_envelope.should ==
21
+ '<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">' <<
22
+ '<env:Body /></env:Envelope>'
23
+ end
24
+
25
+ it "returns a SOAP envelope with a custom namespace and body content" do
26
+ result = ApricotEatsGorilla.soap_envelope(:wsdl => "http://example.com") do
27
+ "<id>123</id>"
28
+ end
29
+ result.should == '<env:Envelope' <<
30
+ ' xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"' <<
31
+ ' xmlns:wsdl="http://example.com">' <<
32
+ '<env:Body><id>123</id></env:Body></env:Envelope>'
33
+ end
34
+ end
35
+
36
+ # []
37
+ describe "[]" do
38
+ before { reset_library_options }
39
+
40
+ it "converts a given XML into a Hash" do
41
+ xml = "<root><name>Jungle Julia</name></root>"
42
+ ApricotEatsGorilla[xml].should == { :name => "Jungle Julia" }
43
+ end
44
+
45
+ it "converts a given XML with a custom root node into a Hash" do
46
+ xml = "<root><something><name>Jungle Julia</name></something></root>"
47
+ ApricotEatsGorilla[xml, "//something"].should == { :name => "Jungle Julia" }
48
+ end
49
+
50
+ it "converts a given Hash into XML" do
51
+ hash = { "apricot" => "eats gorilla" }
52
+ ApricotEatsGorilla[hash] == "<apricot>eats gorilla</apricot>"
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,78 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe ApricotEatsGorilla do
4
+ include SpecHelper
5
+
6
+ # xml_to_hash
7
+ describe "xml_to_hash" do
8
+ before { reset_library_options }
9
+
10
+ it "converts Hash keys to Symbols" do
11
+ xml = "<root><name>Jungle Julia</name></root>"
12
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :name => "Jungle Julia" }
13
+ end
14
+
15
+ it "does not convert Hash keys to Symbols if this was disabled" do
16
+ ApricotEatsGorilla.disable_hash_keys_to_symbols = true
17
+ xml = "<root><name>Jungle Julia</name></root>"
18
+ ApricotEatsGorilla.xml_to_hash(xml).should == { "name" => "Jungle Julia" }
19
+ end
20
+
21
+ it "converts String values of 'true' and 'false' into TrueClass and FalseClass" do
22
+ xml = "<root><yes>true</yes><no>false</no></root>"
23
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :yes => true, :no => false }
24
+ end
25
+
26
+ it "converts empty-element tags to 'nil'" do
27
+ xml = "<contact><name>Jungle Julia</name><email /></contact>"
28
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :name => "Jungle Julia", :email => nil }
29
+ end
30
+
31
+ it "converts lowerCamelCase nodes to snake_case" do
32
+ xml = "<root><firstName>Jungle</firstName><lastName>Julia</lastName></root>"
33
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :first_name => "Jungle", :last_name => "Julia" }
34
+ end
35
+
36
+ it "does not convert lowerCamelCase nodes to snake_case if this was disabled" do
37
+ ApricotEatsGorilla.disable_hash_keys_to_snake_case = true
38
+ xml = "<root><firstName>Jungle</firstName><lastName>Julia</lastName></root>"
39
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :firstName => "Jungle", :lastName => "Julia" }
40
+ end
41
+
42
+ it "removes namespaces from nodes" do
43
+ xml = "<root><wsdl:apricot><eats>Gorilla</eats></wsdl:apricot></root>"
44
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :apricot => { :eats => "Gorilla" } }
45
+ end
46
+
47
+ it "removes attributes from nodes" do
48
+ xml = '<root><contact id="123">Jungle Julia</contact></root>'
49
+ ApricotEatsGorilla.xml_to_hash(xml).should == { :contact => "Jungle Julia" }
50
+ end
51
+
52
+ it "starts translating XML at a given custom root node" do
53
+ xml = '<root><contact><name>Jungle Julia</name></contact></root>'
54
+ ApricotEatsGorilla.xml_to_hash(xml, "//contact").should == { :name => "Jungle Julia" }
55
+ end
56
+
57
+ it "returns an Array of nodes and values in case of multiple root nodes" do
58
+ xml = '<root><return><id>1</id></return><return><id>2</id></return></root>'
59
+ ApricotEatsGorilla.xml_to_hash(xml, "//return").should == [{ :id => "1" }, { :id => "2" }]
60
+ end
61
+
62
+ it "returns the value of a node if it does not contain any subnodes" do
63
+ xml = '<root><return>123</return></root>'
64
+ ApricotEatsGorilla.xml_to_hash(xml, "//return").should == "123"
65
+ end
66
+
67
+ it "returns an Array of values in case of multiple root nodes without subnodes" do
68
+ xml = '<root><return>123</return><return>456</return></root>'
69
+ ApricotEatsGorilla.xml_to_hash(xml, "//return").should == ["123", "456"]
70
+ end
71
+
72
+ it "returns a Hash containing an Array of content for multiple subnodes" do
73
+ xml = '<root><return><items>first</items><items>second</items></return></root>'
74
+ ApricotEatsGorilla.xml_to_hash(xml, "//return").should == { :items => ["first", "second"] }
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,80 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe XMLNode do
4
+
5
+ # strip_namespace!
6
+ describe "strip_namespace!" do
7
+ it "strips the namespace from the node" do
8
+ node = XMLNode.new("wsdl:apricot")
9
+ node.strip_namespace!
10
+
11
+ node.should == "apricot"
12
+ end
13
+ end
14
+
15
+ # to_snake_case!
16
+ describe "to_snake_case!" do
17
+ it "converts the node from CamelCase to snake_case" do
18
+ node = XMLNode.new("ApricotEatsGorilla")
19
+ node.to_snake_case!
20
+
21
+ node.should == "apricot_eats_gorilla"
22
+ end
23
+
24
+ it "converts the node from lowerCamelCase to snake_case" do
25
+ node = XMLNode.new("apricotEatsGorilla")
26
+ node.to_snake_case!
27
+
28
+ node.should == "apricot_eats_gorilla"
29
+ end
30
+ end
31
+
32
+ # namespace_from_hash!
33
+ describe "namespace_from_hash!" do
34
+ it "namespaces the node if it's included in the given Hash" do
35
+ node = XMLNode.new("apricot")
36
+ node.namespace_from_hash!(:wsdl => [ :apricot ])
37
+
38
+ node.should == "apricot"
39
+ node.to_tag.should == "<wsdl:apricot />"
40
+ end
41
+
42
+ it "does nothing if the node is not included in the given Hash" do
43
+ node = XMLNode.new("apricot")
44
+ node.namespace_from_hash!(:wsdl => [ :some_key ])
45
+
46
+ node.should == "apricot"
47
+ node.to_tag.should == "<apricot />"
48
+ end
49
+ end
50
+
51
+ # to_tag
52
+ describe "to_tag" do
53
+ it "returns an empty-element tag for a bare node" do
54
+ node = XMLNode.new("apricot")
55
+ node.to_tag.should == "<apricot />"
56
+ end
57
+
58
+ it "returns a namespaced empty-element tag for a namespaced node" do
59
+ node = XMLNode.new("apricot")
60
+ node.namespace_from_hash!(:wsdl => [ :apricot ])
61
+
62
+ node.to_tag.should == "<wsdl:apricot />"
63
+ end
64
+
65
+ it "returns an empty-element tag with an attribute for an attributed node" do
66
+ node = XMLNode.new("apricot")
67
+ node.attributes = { :wsdl => "http://example.com" }
68
+
69
+ node.to_tag.should == '<apricot xmlns:wsdl="http://example.com" />'
70
+ end
71
+
72
+ it "returns a node with body content for a node with content" do
73
+ node = XMLNode.new("apricot")
74
+ node.body = "eats gorilla"
75
+
76
+ node.to_tag.should == "<apricot>eats gorilla</apricot>"
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,20 @@
1
+ require "rubygems"
2
+ gem "rspec", ">= 1.2.8"
3
+ require "spec"
4
+ require File.join(File.dirname(__FILE__), "..", "lib", "apricoteatsgorilla")
5
+
6
+ Spec::Runner.configure do |config|
7
+ config.mock_with :rr
8
+ end
9
+
10
+ module SpecHelper
11
+ def reset_library_options
12
+ ApricotEatsGorilla.setup do |setup|
13
+ setup.sort_keys = true
14
+ setup.disable_tag_names_to_lower_camel_case = false
15
+ setup.disable_hash_keys_to_snake_case = false
16
+ setup.disable_hash_keys_to_symbols = false
17
+ setup.nodes_to_namespace = nil
18
+ end
19
+ end
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smacks-apricoteatsgorilla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Harrington
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-16 00:00:00 -07:00
12
+ date: 2009-08-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -41,12 +41,25 @@ extensions: []
41
41
  extra_rdoc_files:
42
42
  - README.rdoc
43
43
  files:
44
+ - .gitignore
44
45
  - README.rdoc
45
46
  - Rakefile
47
+ - VERSION
48
+ - apricoteatsgorilla.gemspec
49
+ - lib/apricoteatsgorilla.rb
50
+ - lib/apricoteatsgorilla/apricoteatsgorilla.rb
51
+ - lib/apricoteatsgorilla/xml_node.rb
52
+ - spec/apricoteatsgorilla/apricoteatsgorilla_hash_to_xml_spec.rb
53
+ - spec/apricoteatsgorilla/apricoteatsgorilla_spec.rb
54
+ - spec/apricoteatsgorilla/apricoteatsgorilla_xml_to_hash_spec.rb
55
+ - spec/apricoteatsgorilla/xml_node_spec.rb
56
+ - spec/spec_helper.rb
46
57
  has_rdoc: true
47
58
  homepage: http://github.com/smacks/apricoteatsgorilla
59
+ licenses:
48
60
  post_install_message:
49
61
  rdoc_options:
62
+ - --charset=UTF-8
50
63
  - --title
51
64
  - Apricot eats Gorilla
52
65
  - --main
@@ -70,9 +83,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
83
  requirements: []
71
84
 
72
85
  rubyforge_project:
73
- rubygems_version: 1.2.0
86
+ rubygems_version: 1.3.5
74
87
  signing_key:
75
88
  specification_version: 2
76
- summary: Translates between SOAP messages (XML) and Ruby Hashes.
77
- test_files: []
78
-
89
+ summary: SOAP communication helper.
90
+ test_files:
91
+ - spec/apricoteatsgorilla/apricoteatsgorilla_hash_to_xml_spec.rb
92
+ - spec/apricoteatsgorilla/apricoteatsgorilla_spec.rb
93
+ - spec/apricoteatsgorilla/apricoteatsgorilla_xml_to_hash_spec.rb
94
+ - spec/apricoteatsgorilla/xml_node_spec.rb
95
+ - spec/spec_helper.rb