gyoku 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 86c09dfdeb5eacb718d25f139c3adfd7ac6689b2
4
+ data.tar.gz: 1e319e7f75f041a0b4896b2d16985c49a4aa408c
5
+ SHA512:
6
+ metadata.gz: e81eccda0f368004b95d6a5f6aff630b82d2ac6c677bfa1295cb5eec69a2b41c34a9ff818087a58e77cc20cb4a4ca3397f90e4aa528db97e793f717fa0547c75
7
+ data.tar.gz: 946a0e3ed65e4eda0b2fb2fef501229cd57f00b548443be5d4d7219ce6d2bfeec04d9b7b6b0d6329386d601d0c1497ddf509ce0e27fbd3587f6bbb84e751fcc0
@@ -4,6 +4,7 @@ rvm:
4
4
  - 1.8.7
5
5
  - 1.9.2
6
6
  - 1.9.3
7
+ - 2.0.0
7
8
  - jruby-18mode
8
9
  - jruby-19mode
9
10
  - rbx-18mode
@@ -1,3 +1,11 @@
1
+ ## 1.1.0 (2013-07-26)
2
+
3
+ * Feature: [#30](https://github.com/savonrb/gyoku/pull/30) support for building Arrays
4
+ of parent tags using @attributes.
5
+
6
+ * Fix: [#21](https://github.com/savonrb/gyoku/pull/21) stop modifying the original Hash.
7
+ The original issue is [savonrb/savon#410](https://github.com/savonrb/savon/issues/410).
8
+
1
9
  ## 1.0.0 (2012-12-17)
2
10
 
3
11
  * Refactoring: Removed the global configuration. This should really only affect the
data/Gemfile CHANGED
@@ -1,2 +1,5 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
  gemspec
3
+
4
+ gem 'simplecov', :require => false
5
+ gem 'coveralls', :require => false
File without changes
data/README.md CHANGED
@@ -1,25 +1,34 @@
1
- Gyoku [![Build Status](https://secure.travis-ci.org/rubiii/gyoku.png)](http://travis-ci.org/rubiii/gyoku)
2
- =====
1
+ # Gyoku
3
2
 
4
- ##### Translates Ruby Hashes to XML
5
-
6
- Gyoku is available through [Rubygems](http://rubygems.org/gems/gyoku) and can
7
- be installed via:
3
+ Gyoku translates Ruby Hashes to XML.
8
4
 
5
+ ``` ruby
6
+ Gyoku.xml(:find_user => { :id => 123, "v1:Key" => "api" })
7
+ # => "<findUser><id>123</id><v1:Key>api</v1:Key></findUser>"
9
8
  ```
9
+
10
+ [![Build Status](https://secure.travis-ci.org/savonrb/gyoku.png?branch=master)](http://travis-ci.org/savonrb/gyoku)
11
+ [![Gem Version](https://badge.fury.io/rb/gyoku.png)](http://badge.fury.io/rb/gyoku)
12
+ [![Code Climate](https://codeclimate.com/github/savonrb/gyoku.png)](https://codeclimate.com/github/savonrb/gyoku)
13
+ [![Coverage Status](https://coveralls.io/repos/savonrb/gyoku/badge.png?branch=master)](https://coveralls.io/r/savonrb/gyoku)
14
+
15
+
16
+ ## Installation
17
+
18
+ Gyoku is available through [Rubygems](http://rubygems.org/gems/gyoku) and can be installed via:
19
+
20
+ ``` bash
10
21
  $ gem install gyoku
11
22
  ```
12
23
 
13
- Gyoku is based on a few conventions.
24
+ or add it to your Gemfile like this:
14
25
 
15
26
  ``` ruby
16
- Gyoku.xml(:find_user => { :id => 123, "v1:Key" => "api" })
17
- # => "<findUser><id>123</id><v1:Key>api</v1:Key></findUser>"
27
+ gem 'gyoku', '~> 1.0'
18
28
  ```
19
29
 
20
30
 
21
- Hash keys
22
- ---------
31
+ ## Hash keys
23
32
 
24
33
  Hash key Symbols are converted to lowerCamelCase Strings.
25
34
 
@@ -28,10 +37,11 @@ Gyoku.xml(:lower_camel_case => "key")
28
37
  # => "<lowerCamelCase>key</lowerCamelCase>"
29
38
  ```
30
39
 
31
- You can change the default conversion formula to :camelcase, :upcase or :none.
40
+ You can change the default conversion formula to `:camelcase`, `:upcase` or `:none`.
41
+ Note that options are passed as a second Hash to the `.xml` method.
32
42
 
33
43
  ``` ruby
34
- Gyoku.xml(:camel_case => "key", :key_converter => :camelcase)
44
+ Gyoku.xml({ :camel_case => "key" }, { :key_converter => :camelcase })
35
45
  # => "<CamelCase>key</CamelCase>"
36
46
  ```
37
47
 
@@ -43,8 +53,7 @@ Gyoku.xml("XML" => "key")
43
53
  ```
44
54
 
45
55
 
46
- Hash values
47
- -----------
56
+ ## Hash values
48
57
 
49
58
  * DateTime objects are converted to xs:dateTime Strings
50
59
  * Objects responding to :to_datetime (except Strings) are converted to xs:dateTime Strings
@@ -54,8 +63,7 @@ Hash values
54
63
  * All other objects are converted to Strings using :to_s
55
64
 
56
65
 
57
- Special characters
58
- ------------------
66
+ ## Special characters
59
67
 
60
68
  Gyoku escapes special characters unless the Hash key ends with an exclamation mark.
61
69
 
@@ -65,8 +73,7 @@ Gyoku.xml(:escaped => "<tag />", :not_escaped! => "<tag />")
65
73
  ```
66
74
 
67
75
 
68
- Self-closing tags
69
- -----------------
76
+ ## Self-closing tags
70
77
 
71
78
  Hash Keys ending with a forward slash create self-closing tags.
72
79
 
@@ -76,10 +83,10 @@ Gyoku.xml(:"self_closing/" => "", "selfClosing/" => nil)
76
83
  ```
77
84
 
78
85
 
79
- Sort XML tags
80
- -------------
86
+ ## Sort XML tags
81
87
 
82
- In case you need the XML tags to be in a specific order, you can specify the order through an additional Array stored under an `:order!` key.
88
+ In case you need the XML tags to be in a specific order, you can specify the order
89
+ through an additional Array stored under the `:order!` key.
83
90
 
84
91
  ``` ruby
85
92
  Gyoku.xml(:name => "Eve", :id => 1, :order! => [:id, :name])
@@ -87,21 +94,21 @@ Gyoku.xml(:name => "Eve", :id => 1, :order! => [:id, :name])
87
94
  ```
88
95
 
89
96
 
90
- XML attributes
91
- --------------
97
+ ## XML attributes
92
98
 
93
- Adding XML attributes is rather ugly, but it can be done by specifying an additional Hash stored under an `:attributes!` key.
99
+ Adding XML attributes is rather ugly, but it can be done by specifying an additional
100
+ Hash stored under the`:attributes!` key.
94
101
 
95
102
  ``` ruby
96
103
  Gyoku.xml(:person => "Eve", :attributes! => { :person => { :id => 1 } })
97
104
  # => "<person id=\"1\">Eve</person>"
98
105
  ```
99
106
 
100
- Explicit XML Attributes
101
- -----------------------
102
- In addition to using :attributes!, you may also specify attributes with key names beginning with "@".
107
+ ## Explicit XML Attributes
103
108
 
104
- Since you'll need to set the attribute within the hash containing the node's contents, a :content! key can be used to explicity set the content of the node. The ":content!" value may be a String, Hash, or Array.
109
+ In addition to using the `:attributes!` key, you may also specify attributes through keys beginning with an "@" sign.
110
+ Since you'll need to set the attribute within the hash containing the node's contents, a `:content!` key can be used
111
+ to explicity set the content of the node. The `:content!` value may be a String, Hash, or Array.
105
112
 
106
113
  This is particularly useful for self-closing tags.
107
114
 
@@ -133,17 +140,41 @@ Gyoku.xml(
133
140
  })
134
141
  # => "<foo baz=\"3\" bar=\"1\" biz=\"2\"/>"
135
142
  ```
143
+
144
+ **Example using "@" to get Array of parent tags each with @attributes & :content!**
145
+
146
+ ``` ruby
147
+ Gyoku.xml(
148
+ "foo" => [
149
+ {:@name => "bar", :content! => 'gyoku'}
150
+ {:@name => "baz", :@some => "attr", :content! => 'rocks!'}
151
+ ])
152
+ # => "<foo name=\"bar\">gyoku</foo><foo name=\"baz\" some=\"attr\">rocks!</foo>"
153
+ ```
154
+
155
+ Naturally, it would ignore :content! if tag is self-closing:
156
+
157
+ ``` ruby
158
+ Gyoku.xml(
159
+ "foo/" => [
160
+ {:@name => "bar", :content! => 'gyoku'}
161
+ {:@name => "baz", :@some => "attr", :content! => 'rocks!'}
162
+ ])
163
+ # => "<foo name=\"bar\"/><foo name=\"baz\" some=\"attr\"/>"
164
+ ```
165
+
136
166
  This seems a bit more explicit with the attributes rather than having to maintain a hash of attributes.
137
167
 
138
- For backward compatibility, :attributes! will still work. However, "@" keys will override :attributes! keys if there is a conflict.
168
+ For backward compatibility, `:attributes!` will still work. However, "@" keys will override `:attributes!` keys
169
+ if there is a conflict.
139
170
 
140
171
  ``` ruby
141
172
  Gyoku.xml(:person => {:content! => "Adam", :@id! => 0})
142
173
  # => "<person id=\"0\">Adam</person>"
143
174
  ```
144
175
 
145
- Example with ":content!", :attributes! and "@" keys
146
- --------------------------------------------------
176
+ **Example with ":content!", :attributes! and "@" keys**
177
+
147
178
  ``` ruby
148
179
  Gyoku.xml({
149
180
  :subtitle => {
@@ -158,4 +189,4 @@ Gyoku.xml({
158
189
  The example above shows an example of how you can use all three at the same time.
159
190
 
160
191
  Notice that we have the attribute "lang" defined twice.
161
- The "@lang" value takes precedence over the :attribute![:subtitle]["lang"] value.
192
+ The `@lang` value takes precedence over the `:attribute![:subtitle]["lang"]` value.
@@ -7,11 +7,12 @@ Gem::Specification.new do |s|
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = "Daniel Harrington"
9
9
  s.email = "me@rubiii.com"
10
- s.homepage = "http://github.com/rubiii/#{s.name}"
11
- s.summary = %q{Converts Ruby Hashes to XML}
12
- s.description = %q{Gyoku converts Ruby Hashes to XML}
10
+ s.homepage = "https://github.com/savonrb/#{s.name}"
11
+ s.summary = "Translates Ruby Hashes to XML"
12
+ s.description = "Gyoku translates Ruby Hashes to XML"
13
13
 
14
14
  s.rubyforge_project = "gyoku"
15
+ s.license = "MIT"
15
16
 
16
17
  s.add_dependency "builder", ">= 2.1.2"
17
18
 
@@ -9,11 +9,17 @@ module Gyoku
9
9
  # Translates a given +array+ to XML. Accepts the XML +key+ to add the elements to,
10
10
  # whether to +escape_xml+ and an optional Hash of +attributes+.
11
11
  def self.to_xml(array, key, escape_xml = true, attributes = {}, options = {})
12
+ self_closing = options.delete(:self_closing)
12
13
  iterate_with_xml array, attributes do |xml, item, attrs, index|
13
- case item
14
- when ::Hash then xml.tag!(key, attrs) { xml << Hash.to_xml(item, options) }
15
- when NilClass then xml.tag!(key, "xsi:nil" => "true")
16
- else xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) }
14
+ if self_closing
15
+ xml.tag!(key, attrs)
16
+
17
+ else
18
+ case item
19
+ when ::Hash then xml.tag!(key, attrs) { xml << Hash.to_xml(item, options) }
20
+ when NilClass then xml.tag!(key, "xsi:nil" => "true")
21
+ else xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) }
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -25,7 +31,16 @@ module Gyoku
25
31
  def self.iterate_with_xml(array, attributes)
26
32
  xml = Builder::XmlMarkup.new
27
33
  array.each_with_index do |item, index|
28
- yield xml, item, tag_attributes(attributes, index), index
34
+ if item.respond_to?(:keys)
35
+ attrs = item.reduce({}) do |st, v|
36
+ k = v[0].to_s
37
+ st[k[1..-1]] = v[1].to_s if k =~ /^@/
38
+ st
39
+ end
40
+ else
41
+ attrs = {}
42
+ end
43
+ yield xml, item, tag_attributes(attributes, index).merge(attrs), index
29
44
  end
30
45
  xml.target!
31
46
  end
@@ -15,7 +15,8 @@ module Gyoku
15
15
  xml_key = XMLKey.create key, options
16
16
 
17
17
  case
18
- when ::Array === value then xml << Array.to_xml(value, xml_key, escape_xml, attributes, options)
18
+ when :content! === key then xml << XMLValue.create(value, escape_xml)
19
+ when ::Array === value then xml << Array.to_xml(value, xml_key, escape_xml, attributes, options.merge(:self_closing => self_closing))
19
20
  when ::Hash === value then xml.tag!(xml_key, attributes) { xml << Hash.to_xml(value, options) }
20
21
  when self_closing then xml.tag!(xml_key, attributes)
21
22
  when NilClass === value then xml.tag!(xml_key, "xsi:nil" => "true")
@@ -41,7 +42,7 @@ module Gyoku
41
42
  node_attr = attributes[key] || {}
42
43
  # node_attr must be kind of ActiveSupport::HashWithIndifferentAccess
43
44
  node_attr = ::Hash[node_attr.map { |k,v| [k.to_s, v] }]
44
- node_value = hash[key]
45
+ node_value = hash[key].respond_to?(:keys) ? hash[key].clone : hash[key]
45
46
 
46
47
  if node_value.respond_to?(:keys)
47
48
  explicit_keys = node_value.keys.select{|k| k.to_s =~ /^@/ }
@@ -69,8 +70,8 @@ module Gyoku
69
70
  order = hash_without_order.keys unless order.kind_of? ::Array
70
71
 
71
72
  # Ignore Explicit Attributes
72
- orderable = order.delete_if{|k| k =~ /^@/ }
73
- hashable = hash_without_order.keys.select{|k| !(k =~ /^@/) }
73
+ orderable = order.delete_if{|k| k.to_s =~ /^@/ }
74
+ hashable = hash_without_order.keys.select{|k| !(k.to_s =~ /^@/) }
74
75
 
75
76
  missing, spurious = hashable - orderable, orderable - hashable
76
77
  raise ArgumentError, "Missing elements in :order! #{missing.inspect}" unless missing.empty?
@@ -1,5 +1,5 @@
1
1
  module Gyoku
2
2
 
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
 
5
5
  end
@@ -207,6 +207,50 @@ describe Gyoku::Hash do
207
207
  to_xml(hash).should == "<category/>"
208
208
  end
209
209
 
210
+ it "recognizes array of attributes" do
211
+ hash = {
212
+ "category" => [{:@name => 'one'}, {:@name => 'two'}]
213
+ }
214
+ to_xml(hash).should == '<category name="one"></category><category name="two"></category>'
215
+
216
+ # issue #31.
217
+ hash = {
218
+ :order! => ['foo', 'bar'],
219
+ 'foo' => { :@foo => 'foo' },
220
+ 'bar' => { :@bar => 'bar', 'baz' => { } },
221
+ }
222
+ to_xml(hash).should == '<foo foo="foo"></foo><bar bar="bar"><baz></baz></bar>'
223
+ end
224
+
225
+ it "recognizes array of attributes with content in each" do
226
+ hash = {
227
+ "foo" => [{:@name => "bar", :content! => 'gyoku'}, {:@name => "baz", :@some => "attr", :content! => 'rocks!'}]
228
+ }
229
+
230
+ [
231
+ '<foo name="bar">gyoku</foo><foo name="baz" some="attr">rocks!</foo>',
232
+ '<foo name="bar">gyoku</foo><foo some="attr" name="baz">rocks!</foo>'
233
+ ].should include to_xml(hash)
234
+ end
235
+
236
+ it "recognizes array of attributes but ignores content in each if selfclosing" do
237
+ hash = {
238
+ "foo/" => [{:@name => "bar", :content! => 'gyoku'}, {:@name => "baz", :@some => "attr", :content! => 'rocks!'}]
239
+ }
240
+
241
+ [
242
+ '<foo name="bar"/><foo name="baz" some="attr"/>',
243
+ '<foo name="bar"/><foo some="attr" name="baz"/>'
244
+ ].should include to_xml(hash)
245
+ end
246
+
247
+ it "recognizes array of attributes with selfclosing tag" do
248
+ hash = {
249
+ "category/" => [{:@name => 'one'}, {:@name => 'two'}]
250
+ }
251
+ to_xml(hash).should == '<category name="one"/><category name="two"/>'
252
+ end
253
+
210
254
  context "with :element_form_default set to :qualified and a :namespace" do
211
255
  it "adds the given :namespace to every element" do
212
256
  hash = { :first => { "first_name" => "Lucy" }, ":second" => { :":first_name" => "Anna" }, "v2:third" => { "v2:firstName" => "Danie" } }
@@ -256,6 +300,12 @@ describe Gyoku::Hash do
256
300
  end
257
301
  end
258
302
 
303
+ it "doesn't modify original hash parameter by deleting its attribute keys" do
304
+ hash = { :person => {:name => "Johnny", :surname => "Bravo", :"@xsi:type" => "People"} }
305
+ to_xml(hash)
306
+ hash.should == {:person=>{:name=>"Johnny", :surname=>"Bravo", :"@xsi:type"=>"People"}}
307
+ end
308
+
259
309
  def to_xml(hash, options = {})
260
310
  Gyoku::Hash.to_xml hash, options
261
311
  end
@@ -1,2 +1,15 @@
1
- require "bundler"
2
- Bundler.require :default, :development
1
+ require 'bundler'
2
+ Bundler.setup(:default, :development)
3
+
4
+ unless RUBY_PLATFORM =~ /java/
5
+ require 'simplecov'
6
+ require 'coveralls'
7
+
8
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
9
+ SimpleCov.start do
10
+ add_filter 'spec'
11
+ end
12
+ end
13
+
14
+ require 'gyoku'
15
+ require 'rspec'
metadata CHANGED
@@ -1,36 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gyoku
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Daniel Harrington
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
11
+ date: 2013-07-26 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: builder
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 2.1.2
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 2.1.2
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,12 +48,11 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
61
54
  version: '2.10'
62
- description: Gyoku converts Ruby Hashes to XML
55
+ description: Gyoku translates Ruby Hashes to XML
63
56
  email: me@rubiii.com
64
57
  executables: []
65
58
  extensions: []
@@ -70,7 +63,7 @@ files:
70
63
  - .travis.yml
71
64
  - CHANGELOG.md
72
65
  - Gemfile
73
- - LICENSE
66
+ - MIT-LICENSE
74
67
  - README.md
75
68
  - Rakefile
76
69
  - gyoku.gemspec
@@ -86,36 +79,30 @@ files:
86
79
  - spec/gyoku/xml_value_spec.rb
87
80
  - spec/gyoku_spec.rb
88
81
  - spec/spec_helper.rb
89
- homepage: http://github.com/rubiii/gyoku
90
- licenses: []
82
+ homepage: https://github.com/savonrb/gyoku
83
+ licenses:
84
+ - MIT
85
+ metadata: {}
91
86
  post_install_message:
92
87
  rdoc_options: []
93
88
  require_paths:
94
89
  - lib
95
90
  required_ruby_version: !ruby/object:Gem::Requirement
96
- none: false
97
91
  requirements:
98
- - - ! '>='
92
+ - - '>='
99
93
  - !ruby/object:Gem::Version
100
94
  version: '0'
101
- segments:
102
- - 0
103
- hash: 2627220150066470254
104
95
  required_rubygems_version: !ruby/object:Gem::Requirement
105
- none: false
106
96
  requirements:
107
- - - ! '>='
97
+ - - '>='
108
98
  - !ruby/object:Gem::Version
109
99
  version: '0'
110
- segments:
111
- - 0
112
- hash: 2627220150066470254
113
100
  requirements: []
114
101
  rubyforge_project: gyoku
115
- rubygems_version: 1.8.24
102
+ rubygems_version: 2.0.6
116
103
  signing_key:
117
- specification_version: 3
118
- summary: Converts Ruby Hashes to XML
104
+ specification_version: 4
105
+ summary: Translates Ruby Hashes to XML
119
106
  test_files:
120
107
  - spec/gyoku/array_spec.rb
121
108
  - spec/gyoku/hash_spec.rb