smacks-apricoteatsgorilla 0.3.6 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
data/lib/apricoteatsgorilla.rb
CHANGED
@@ -47,6 +47,15 @@ class ApricotEatsGorilla
|
|
47
47
|
# Flag to enable optional sorting of Hash keys.
|
48
48
|
attr_accessor :sort_keys
|
49
49
|
|
50
|
+
# Flag to disable conversion of tag names to lowerCamelCase.
|
51
|
+
attr_accessor :disable_tag_names_to_lower_camel_case
|
52
|
+
|
53
|
+
# Flag to disable conversion of Hash keys to snake_case.
|
54
|
+
attr_accessor :disable_hash_keys_to_snake_case
|
55
|
+
|
56
|
+
# Flag to disable conversion of Hash keys to Symbols.
|
57
|
+
attr_accessor :disable_hash_keys_to_symbol
|
58
|
+
|
50
59
|
# Shortcut method for translating between XML Strings and Ruby Hashes.
|
51
60
|
# Delegates to xml_to_hash in case +source+ is of type String or delegates
|
52
61
|
# to hash_to_xml in case +source+ is of type Hash. Returns nil otherwise.
|
@@ -66,6 +75,12 @@ class ApricotEatsGorilla
|
|
66
75
|
end
|
67
76
|
end
|
68
77
|
|
78
|
+
# Yields this class object in case a +block+ was given. Nice way for setting
|
79
|
+
# multiple options at once.
|
80
|
+
def setup
|
81
|
+
yield self if block_given?
|
82
|
+
end
|
83
|
+
|
69
84
|
# Converts a given +xml+ String into a Ruby Hash. Starts parsing at root
|
70
85
|
# node by default. The optional +root_node+ parameter can be used to specify
|
71
86
|
# a custom root node to start parsing at via XPath (Hpricot search).
|
@@ -171,7 +186,9 @@ class ApricotEatsGorilla
|
|
171
186
|
key, value = child.name, xml_node_to_hash(child)
|
172
187
|
end
|
173
188
|
|
174
|
-
key =
|
189
|
+
key = remove_namespace(key)
|
190
|
+
key = to_snake_case(key) unless disable_hash_keys_to_snake_case
|
191
|
+
key = key.intern unless disable_hash_keys_to_symbol
|
175
192
|
current = this_node[key]
|
176
193
|
case current
|
177
194
|
when Array
|
@@ -194,16 +211,16 @@ class ApricotEatsGorilla
|
|
194
211
|
# * +item+ - A Hash value to translate into an XML String.
|
195
212
|
def nested_data_to_xml(name, item)
|
196
213
|
case item
|
197
|
-
when String
|
198
|
-
tag(name) { item }
|
214
|
+
when String, Symbol
|
215
|
+
tag(name) { item.to_s }
|
199
216
|
when Array
|
200
217
|
item.map { |subitem| nested_data_to_xml(name, subitem) }.join
|
201
218
|
when Hash
|
202
219
|
tag(name) do
|
203
220
|
opt_order(item).map { |tag, value|
|
204
221
|
case value
|
205
|
-
when String
|
206
|
-
tag(tag) { value }
|
222
|
+
when String, Symbol
|
223
|
+
tag(tag) { value.to_s }
|
207
224
|
when Array
|
208
225
|
value.map { |subitem| nested_data_to_xml(tag, subitem) }.join
|
209
226
|
when Hash
|
@@ -222,6 +239,7 @@ class ApricotEatsGorilla
|
|
222
239
|
# * +name+ - The name of the XML tag.
|
223
240
|
# * +attributes+ - Optional. Hash of attributes for the XML tag.
|
224
241
|
def tag(name, attributes = {})
|
242
|
+
name = to_lower_camel_case(name) unless disable_tag_names_to_lower_camel_case
|
225
243
|
return "<#{name} />" unless block_given?
|
226
244
|
|
227
245
|
attr = opt_order(attributes).map { |k, v| %Q( xmlns:#{k}="#{v}") }.to_s
|
@@ -231,13 +249,15 @@ class ApricotEatsGorilla
|
|
231
249
|
|
232
250
|
# Removes line breaks and whitespace between tags from a given +xml+ String.
|
233
251
|
def clean_xml(xml)
|
234
|
-
xml
|
235
|
-
xml.gsub(/(>)\s*(<)/, '\1\2')
|
252
|
+
xml.gsub!(/\n+/, "")
|
253
|
+
xml.gsub!(/(>)\s*(<)/, '\1\2')
|
254
|
+
xml
|
236
255
|
end
|
237
256
|
|
238
257
|
# Removes the namespace from a given XML +tag+.
|
239
258
|
def remove_namespace(tag)
|
240
|
-
tag.sub(/.+:(.+)/, '\1')
|
259
|
+
tag.sub!(/.+:(.+)/, '\1')
|
260
|
+
tag
|
241
261
|
end
|
242
262
|
|
243
263
|
# Converts a given +string+ from CamelCase/lowerCamelCase to snake_case.
|
@@ -247,6 +267,11 @@ class ApricotEatsGorilla
|
|
247
267
|
string
|
248
268
|
end
|
249
269
|
|
270
|
+
# Converts a given +string+ from snake_case to lowerCamelCase.
|
271
|
+
def to_lower_camel_case(string)
|
272
|
+
string.to_s.gsub(/_(.)/) { $1.upcase }
|
273
|
+
end
|
274
|
+
|
250
275
|
# Checks to see if a given +string+ matches "true" or "false" and converts
|
251
276
|
# these values to actual Boolean objects. Returns the original string in
|
252
277
|
# case it does not match "true" or "false".
|
@@ -3,10 +3,17 @@ require File.join(File.dirname(__FILE__), "..", "helper")
|
|
3
3
|
class HashToXmlTest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "Calling hash_to_xml" do
|
6
|
-
setup
|
6
|
+
setup do
|
7
|
+
ApricotEatsGorilla.setup do |s|
|
8
|
+
s.sort_keys = true
|
9
|
+
s.disable_tag_names_to_lower_camel_case = false
|
10
|
+
s.disable_hash_keys_to_snake_case = false
|
11
|
+
s.disable_hash_keys_to_symbol = false
|
12
|
+
end
|
13
|
+
end
|
7
14
|
|
8
15
|
context "with a Hash consisting of a single key-value-pair" do
|
9
|
-
should "
|
16
|
+
should "return an XML String containing one node and a value" do
|
10
17
|
hash = { "apricot" => "eats gorilla" }
|
11
18
|
expected = "<apricot>eats gorilla</apricot>"
|
12
19
|
|
@@ -16,7 +23,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|
16
23
|
end
|
17
24
|
|
18
25
|
context "with a Hash containing another Hash" do
|
19
|
-
should "
|
26
|
+
should "return an XML String representing the given structure" do
|
20
27
|
hash = { "apricot" => { "eats" => "gorilla", "drinks" => "beer" } }
|
21
28
|
expected = "<apricot><drinks>beer</drinks><eats>gorilla</eats></apricot>"
|
22
29
|
|
@@ -26,7 +33,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|
26
33
|
end
|
27
34
|
|
28
35
|
context "with a Hash containing a Hash containing an Array" do
|
29
|
-
should "
|
36
|
+
should "return an XML String representing the given structure" do
|
30
37
|
hash = { "apricot" => { "eats" => [ "gorilla", "snake" ] } }
|
31
38
|
expected = "<apricot><eats>gorilla</eats><eats>snake</eats></apricot>"
|
32
39
|
|
@@ -36,7 +43,7 @@ class HashToXmlTest < Test::Unit::TestCase
|
|
36
43
|
end
|
37
44
|
|
38
45
|
context "with a Hash containing a Hash containing an Array containing a Hash" do
|
39
|
-
should "
|
46
|
+
should "return an XML String representing the given structure" do
|
40
47
|
hash = { "apricot" =>
|
41
48
|
{ "eats" => [ { "lotsOf" => "gorillas" }, { "justSome" => "snakes" } ]
|
42
49
|
} }
|
@@ -47,6 +54,38 @@ class HashToXmlTest < Test::Unit::TestCase
|
|
47
54
|
assert_equal expected, result
|
48
55
|
end
|
49
56
|
end
|
57
|
+
|
58
|
+
context "with a Hash containing Symbols" do
|
59
|
+
should "returns an XML String with Symbols converted into Strings" do
|
60
|
+
hash = { :apricot => { :eats => [ :gorilla, "snake" ] } }
|
61
|
+
expected = "<apricot><eats>gorilla</eats><eats>snake</eats></apricot>"
|
62
|
+
|
63
|
+
result = ApricotEatsGorilla.hash_to_xml(hash)
|
64
|
+
assert_equal expected, result
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with a Hash containing snake_case keys" do
|
69
|
+
should "convert snake_case Hash keys to lowerCamelCase" do
|
70
|
+
hash = { :apricot => { :eats => { :lots_of => "gorillas" } } }
|
71
|
+
expected = "<apricot><eats><lotsOf>gorillas</lotsOf></eats></apricot>"
|
72
|
+
|
73
|
+
result = ApricotEatsGorilla.hash_to_xml(hash)
|
74
|
+
assert_equal expected, result
|
75
|
+
end
|
76
|
+
|
77
|
+
context "and converting snake_case tag names to lowerCamelCase turned off" do
|
78
|
+
setup { ApricotEatsGorilla.disable_tag_names_to_lower_camel_case = true }
|
79
|
+
|
80
|
+
should "not convert snake_case tag names to lowerCamelCase" do
|
81
|
+
hash = { :apricot => { :eats => { :lots_of => "gorillas" } } }
|
82
|
+
expected = "<apricot><eats><lots_of>gorillas</lots_of></eats></apricot>"
|
83
|
+
|
84
|
+
result = ApricotEatsGorilla.hash_to_xml(hash)
|
85
|
+
assert_equal expected, result
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
50
89
|
end
|
51
90
|
|
52
91
|
end
|
@@ -3,7 +3,14 @@ require File.join(File.dirname(__FILE__), "..", "helper")
|
|
3
3
|
class ShortcutMethodTest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "Calling []" do
|
6
|
-
setup
|
6
|
+
setup do
|
7
|
+
ApricotEatsGorilla.setup do |s|
|
8
|
+
s.sort_keys = true
|
9
|
+
s.disable_tag_names_to_lower_camel_case = false
|
10
|
+
s.disable_hash_keys_to_snake_case = false
|
11
|
+
s.disable_hash_keys_to_symbol = false
|
12
|
+
end
|
13
|
+
end
|
7
14
|
|
8
15
|
context "with an XML String" do
|
9
16
|
should "return a Hash containing the XML content" do
|
@@ -3,7 +3,14 @@ require File.join(File.dirname(__FILE__), "..", "helper")
|
|
3
3
|
class XmlToHashTest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "Calling xml_to_hash" do
|
6
|
-
setup
|
6
|
+
setup do
|
7
|
+
ApricotEatsGorilla.setup do |s|
|
8
|
+
s.sort_keys = true
|
9
|
+
s.disable_tag_names_to_lower_camel_case = false
|
10
|
+
s.disable_hash_keys_to_snake_case = false
|
11
|
+
s.disable_hash_keys_to_symbol = false
|
12
|
+
end
|
13
|
+
end
|
7
14
|
|
8
15
|
context "with a SOAP response example and a custom root node" do
|
9
16
|
should "return a Hash containing the XML content" do
|
@@ -56,14 +63,48 @@ class XmlToHashTest < Test::Unit::TestCase
|
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
59
|
-
context "with XML containing nodes
|
60
|
-
should "
|
61
|
-
xml = "<
|
62
|
-
expected = { :
|
66
|
+
context "with XML containing lowerCamelCase nodes" do
|
67
|
+
should "convert lowerCamelCase nodes to snake_case" do
|
68
|
+
xml = "<contact><firstName>Jungle</firstName><lastName>Julia</lastName></contact>"
|
69
|
+
expected = { :first_name => "Jungle", :last_name => "Julia" }
|
70
|
+
|
71
|
+
result = ApricotEatsGorilla.xml_to_hash(xml)
|
72
|
+
assert_equal expected, result
|
73
|
+
end
|
74
|
+
|
75
|
+
context "and converting lowerCamelCase Hash keys to snake_case turned off" do
|
76
|
+
setup { ApricotEatsGorilla.disable_hash_keys_to_snake_case = true }
|
77
|
+
|
78
|
+
should "not convert lowerCamelCase Hash keys to snake_case" do
|
79
|
+
xml = "<contact><firstName>Jungle</firstName><lastName>Julia</lastName></contact>"
|
80
|
+
expected = { :firstName => "Jungle", :lastName => "Julia" }
|
81
|
+
|
82
|
+
result = ApricotEatsGorilla.xml_to_hash(xml)
|
83
|
+
assert_equal expected, result
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "with some XML" do
|
89
|
+
should "convert Hash keys to Symbols" do
|
90
|
+
xml = "<contact><name>Jungle Julia</name><address/></contact>"
|
91
|
+
expected = { :name => "Jungle Julia", :address => nil }
|
63
92
|
|
64
93
|
result = ApricotEatsGorilla.xml_to_hash(xml)
|
65
94
|
assert_equal expected, result
|
66
95
|
end
|
96
|
+
|
97
|
+
context "and converting Hash keys to Symbols turned off" do
|
98
|
+
setup { ApricotEatsGorilla.disable_hash_keys_to_symbol = true }
|
99
|
+
|
100
|
+
should "not convert Hash keys to Symbols" do
|
101
|
+
xml = "<contact><name>Jungle Julia</name><address/></contact>"
|
102
|
+
expected = { "name" => "Jungle Julia", "address" => nil }
|
103
|
+
|
104
|
+
result = ApricotEatsGorilla.xml_to_hash(xml)
|
105
|
+
assert_equal expected, result
|
106
|
+
end
|
107
|
+
end
|
67
108
|
end
|
68
109
|
end
|
69
110
|
|