gyoku 1.2.3 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +30 -0
- data/CHANGELOG.md +35 -1
- data/Gemfile +1 -7
- data/README.md +125 -4
- data/gyoku.gemspec +3 -2
- data/lib/gyoku/array.rb +25 -10
- data/lib/gyoku/hash.rb +19 -7
- data/lib/gyoku/prettifier.rb +29 -0
- data/lib/gyoku/version.rb +1 -1
- data/lib/gyoku/xml_value.rb +3 -1
- data/spec/gyoku/array_spec.rb +49 -0
- data/spec/gyoku/hash_spec.rb +27 -0
- data/spec/gyoku/prettifier_spec.rb +39 -0
- data/spec/gyoku/xml_value_spec.rb +5 -0
- metadata +25 -9
- data/.travis.yml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e0e1b8945f273ca620ea7dc841fdfa127b319e8f29a15b6eb6095bcbe0ccf5f2
|
4
|
+
data.tar.gz: 639ba4fef0c00f5b678f8c826fa7d7d52ecb21bfd6fc00b32863315e0a6962eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff954c52c3e30435704b6bb6c33c1b8fd91c02ba9b4150149b8cabf8e565603fa9f75dbc11f2b02689cd657e2da60af874c4cf08f8023fd270b6c5e9010abba9
|
7
|
+
data.tar.gz: 2eed9a99654259749f59d48d4f792f90ed8935234af864ced0e406f851e102c7487e8626b44889c91e2f105e70e719ecfe95ca859bf8afa69b4626a097ccb91d
|
@@ -0,0 +1,30 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
ruby-version:
|
17
|
+
- 3.1
|
18
|
+
- "3.0"
|
19
|
+
- 2.7
|
20
|
+
- 2.6
|
21
|
+
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v3
|
24
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
25
|
+
uses: ruby/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
ruby-version: ${{ matrix.ruby-version }}
|
28
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
29
|
+
- name: Run tests
|
30
|
+
run: bundle exec rake
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,40 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
|
3
|
+
## 1.4.0 (2022-04-01)
|
4
|
+
|
5
|
+
### Fixed
|
6
|
+
|
7
|
+
- Fix [Issue #56](https://github.com/savonrb/gyoku/issue/56) with PR [#57](https://github.com/savonrb/gyoku/pull/57). Thanks, [@jpmoral]!
|
8
|
+
- Avoid circular reference [#69](https://github.com/savonrb/gyoku/pull/69), thanks [@ccarruitero]!
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Unwrap specific keys [#54](https://github.com/savonrb/gyoku/pull/54), by [@rlburkes]. Documented by [@mahemoff]. Thanks to you both!
|
13
|
+
- Add `:pretty_print`, `:indent` and `:compact` options to allow prettified XML output. [#59](https://github.com/savonrb/gyoku/pull/59), by [@Jeiwan]. Thanks!
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- Removed Rubinius support, by [@olleolleolle]
|
18
|
+
- Clean-up, CI setup, and changelog authoring, by [@olleolleolle]
|
19
|
+
|
20
|
+
[@jpmoral]: https://github.com/jpmoral
|
21
|
+
[@ccarruitero]: https://github.com/ccarruitero
|
22
|
+
[@rlburkes]: https://github.com/rlburkes
|
23
|
+
[@mahemoff]: https://github.com/mahemoff
|
24
|
+
[@Jeiwan]: https://github.com/Jeiwan
|
25
|
+
[@olleolleolle]: https://github.com/olleolleolle
|
26
|
+
|
27
|
+
## 1.3.1 (2015-04-05)
|
28
|
+
|
29
|
+
* Feature: [#53](https://github.com/savonrb/gyoku/pull/53) Improved serialization of hashes nested in arrays. Thanks to @riburkes for this!
|
30
|
+
|
31
|
+
## 1.3.0 (2015-03-30)
|
32
|
+
|
33
|
+
* Formally drop support for ruby 1.8.7
|
34
|
+
|
1
35
|
## 1.2.3 (2015-03-10)
|
2
36
|
|
3
|
-
|
37
|
+
* Feature: [#52](https://github.com/savonrb/gyoku/pull/52) Adds an :unwrap option that allows an array of hashes to be unwrapped into a single array xml node, rather than one per hash.
|
4
38
|
|
5
39
|
## 1.2.2 (2014-09-22)
|
6
40
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,10 +7,10 @@ Gyoku.xml(:find_user => { :id => 123, "v1:Key" => "api" })
|
|
7
7
|
# => "<findUser><id>123</id><v1:Key>api</v1:Key></findUser>"
|
8
8
|
```
|
9
9
|
|
10
|
-
[![Build
|
11
|
-
[![Gem Version](https://badge.fury.io/rb/gyoku.
|
12
|
-
[![Code Climate](https://codeclimate.com/github/savonrb/gyoku.
|
13
|
-
[![Coverage Status](https://coveralls.io/repos/savonrb/gyoku/badge.
|
10
|
+
[![Build status](https://github.com/savonrb/gyoku/actions/workflows/ci.yml/badge.svg)](https://github.com/savonrb/gyoku/actions/workflows/ci.yml)
|
11
|
+
[![Gem Version](https://badge.fury.io/rb/gyoku.svg)](http://badge.fury.io/rb/gyoku)
|
12
|
+
[![Code Climate](https://codeclimate.com/github/savonrb/gyoku.svg)](https://codeclimate.com/github/savonrb/gyoku)
|
13
|
+
[![Coverage Status](https://coveralls.io/repos/savonrb/gyoku/badge.svg?branch=master)](https://coveralls.io/r/savonrb/gyoku)
|
14
14
|
|
15
15
|
|
16
16
|
## Installation
|
@@ -45,6 +45,16 @@ Gyoku.xml({ :camel_case => "key" }, { :key_converter => :camelcase })
|
|
45
45
|
# => "<CamelCase>key</CamelCase>"
|
46
46
|
```
|
47
47
|
|
48
|
+
Custom key converters. You can use a lambda/Proc to provide customer key converters.
|
49
|
+
This is a great way to leverage active support inflections for domain specific acronyms.
|
50
|
+
|
51
|
+
``` ruby
|
52
|
+
# Use camelize lower which will hook into active support if installed.
|
53
|
+
Gyoku.xml({ acronym_abc: "value" }, key_converter: lambda { |key| key.camelize(:lower) })
|
54
|
+
# => "<acronymABC>value</acronymABC>"
|
55
|
+
|
56
|
+
```
|
57
|
+
|
48
58
|
Hash key Strings are not converted and may contain namespaces.
|
49
59
|
|
50
60
|
``` ruby
|
@@ -62,6 +72,21 @@ Gyoku.xml("XML" => "key")
|
|
62
72
|
* These conventions are also applied to the return value of objects responding to :call
|
63
73
|
* All other objects are converted to Strings using :to_s
|
64
74
|
|
75
|
+
## Array values
|
76
|
+
|
77
|
+
Array items are by default wrapped with the containiner tag, which may be unexpected.
|
78
|
+
|
79
|
+
``` ruby
|
80
|
+
> Gyoku.xml({languages: [{language: 'ruby'},{language: 'java'}]})
|
81
|
+
# => "<languages><language>ruby</language></languages><languages><language>java</language></languages>"
|
82
|
+
```
|
83
|
+
|
84
|
+
You can set the `unwrap` option to remove this behavior.
|
85
|
+
|
86
|
+
``` ruby
|
87
|
+
> Gyoku.xml({languages: [{language: 'ruby'},{language: 'java'}]}, { unwrap: true})
|
88
|
+
# => "<languages><language>ruby</language><language>java</language></languages>"
|
89
|
+
```
|
65
90
|
|
66
91
|
## Special characters
|
67
92
|
|
@@ -152,6 +177,42 @@ Gyoku.xml(
|
|
152
177
|
# => "<foo name=\"bar\">gyoku</foo><foo name=\"baz\" some=\"attr\">rocks!</foo>"
|
153
178
|
```
|
154
179
|
|
180
|
+
Unwrapping Arrays. You can specify an optional `unwrap` argument to modify the default Array
|
181
|
+
behavior. `unwrap` accepts a boolean flag (false by default) or an Array whitelist of keys to unwrap.
|
182
|
+
``` ruby
|
183
|
+
# Default Array behavior
|
184
|
+
Gyoku.xml({
|
185
|
+
"foo" => [
|
186
|
+
{:is => 'great' },
|
187
|
+
{:is => 'awesome'}
|
188
|
+
]
|
189
|
+
})
|
190
|
+
# => "<foo><is>great</is></foo><foo><is>awesome</is></foo>"
|
191
|
+
|
192
|
+
# Unwrap Array behavior
|
193
|
+
Gyoku.xml({
|
194
|
+
"foo" => [
|
195
|
+
{:is => 'great' },
|
196
|
+
{:is => 'awesome'}
|
197
|
+
]
|
198
|
+
}, unwrap: true)
|
199
|
+
# => "<foo><is>great</is><is>awesome</is></foo>"
|
200
|
+
|
201
|
+
# Unwrap Array, whitelist.
|
202
|
+
# foo is not unwrapped, bar is.
|
203
|
+
Gyoku.xml({
|
204
|
+
"foo" => [
|
205
|
+
{:is => 'great' },
|
206
|
+
{:is => 'awesome'}
|
207
|
+
],
|
208
|
+
"bar" => [
|
209
|
+
{:is => 'rad' },
|
210
|
+
{:is => 'cool'}
|
211
|
+
]
|
212
|
+
}, unwrap: [:bar])
|
213
|
+
# => "<foo><is>great</is></foo><foo><is>awesome</is></foo><bar><is>rad</is><is>cool</is></bar>"
|
214
|
+
```
|
215
|
+
|
155
216
|
Naturally, it would ignore :content! if tag is self-closing:
|
156
217
|
|
157
218
|
``` ruby
|
@@ -190,3 +251,63 @@ The example above shows an example of how you can use all three at the same time
|
|
190
251
|
|
191
252
|
Notice that we have the attribute "lang" defined twice.
|
192
253
|
The `@lang` value takes precedence over the `:attribute![:subtitle]["lang"]` value.
|
254
|
+
|
255
|
+
## Pretty Print
|
256
|
+
|
257
|
+
You can prettify the output XML to make it more readable. Use these options:
|
258
|
+
* `pretty_print` – controls pretty mode (default: `false`)
|
259
|
+
* `indent` – specifies indentation in spaces (default: `2`)
|
260
|
+
* `compact` – controls compact mode (default: `true`)
|
261
|
+
|
262
|
+
**This feature is not available for XML documents generated from arrays with unwrap option set to false as such documents are not valid**
|
263
|
+
|
264
|
+
**Examples**
|
265
|
+
|
266
|
+
``` ruby
|
267
|
+
puts Gyoku.xml({user: { name: 'John', job: { title: 'Programmer' }, :@status => 'active' }}, pretty_print: true)
|
268
|
+
#<user status='active'>
|
269
|
+
# <name>John</name>
|
270
|
+
# <job>
|
271
|
+
# <title>Programmer</title>
|
272
|
+
# </job>
|
273
|
+
#</user>
|
274
|
+
```
|
275
|
+
|
276
|
+
``` ruby
|
277
|
+
puts Gyoku.xml({user: { name: 'John', job: { title: 'Programmer' }, :@status => 'active' }}, pretty_print: true, indent: 4)
|
278
|
+
#<user status='active'>
|
279
|
+
# <name>John</name>
|
280
|
+
# <job>
|
281
|
+
# <title>Programmer</title>
|
282
|
+
# </job>
|
283
|
+
#</user>
|
284
|
+
```
|
285
|
+
|
286
|
+
``` ruby
|
287
|
+
puts Gyoku.xml({user: { name: 'John', job: { title: 'Programmer' }, :@status => 'active' }}, pretty_print: true, compact: false)
|
288
|
+
#<user status='active'>
|
289
|
+
# <name>
|
290
|
+
# John
|
291
|
+
# </name>
|
292
|
+
# <job>
|
293
|
+
# <title>
|
294
|
+
# Programmer
|
295
|
+
# </title>
|
296
|
+
# </job>
|
297
|
+
#</user>
|
298
|
+
```
|
299
|
+
|
300
|
+
**Generate XML from an array with `unwrap` option set to `true`**
|
301
|
+
``` ruby
|
302
|
+
puts Gyoku::Array.to_xml(["john", "jane"], "user", true, {}, pretty_print: true, unwrap: true)
|
303
|
+
#<user>
|
304
|
+
# <user>john</user>
|
305
|
+
# <user>jane</user>
|
306
|
+
#</user>
|
307
|
+
```
|
308
|
+
|
309
|
+
**Generate XML from an array with `unwrap` option unset (`false` by default)**
|
310
|
+
``` ruby
|
311
|
+
puts Gyoku::Array.to_xml(["john", "jane"], "user", true, {}, pretty_print: true)
|
312
|
+
#<user>john</user><user>jane</user>
|
313
|
+
```
|
data/gyoku.gemspec
CHANGED
@@ -10,17 +10,18 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = "https://github.com/savonrb/#{s.name}"
|
11
11
|
s.summary = "Translates Ruby Hashes to XML"
|
12
12
|
s.description = "Gyoku translates Ruby Hashes to XML"
|
13
|
+
s.required_ruby_version = '>= 1.9.2'
|
13
14
|
|
14
|
-
s.rubyforge_project = "gyoku"
|
15
15
|
s.license = "MIT"
|
16
16
|
|
17
17
|
s.add_dependency "builder", ">= 2.1.2"
|
18
|
+
s.add_dependency "rexml", "~> 3.0"
|
18
19
|
|
19
20
|
s.add_development_dependency "rake"
|
20
21
|
s.add_development_dependency "rspec"
|
21
22
|
|
22
23
|
s.files = `git ls-files`.split("\n")
|
23
24
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
-
|
25
|
+
|
25
26
|
s.require_paths = ["lib"]
|
26
27
|
end
|
data/lib/gyoku/array.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "builder"
|
2
2
|
|
3
|
-
require "gyoku/
|
3
|
+
require "gyoku/prettifier.rb"
|
4
4
|
require "gyoku/xml_value"
|
5
5
|
|
6
6
|
module Gyoku
|
@@ -8,12 +8,25 @@ module Gyoku
|
|
8
8
|
|
9
9
|
NESTED_ELEMENT_NAME = "element"
|
10
10
|
|
11
|
+
# Builds XML and prettifies it if +pretty_print+ option is set to +true+
|
12
|
+
def self.to_xml(array, key, escape_xml = true, attributes = {}, options = {})
|
13
|
+
xml = build_xml(array, key, escape_xml, attributes, options)
|
14
|
+
|
15
|
+
if options[:pretty_print] && options[:unwrap]
|
16
|
+
Prettifier.prettify(xml, options)
|
17
|
+
else
|
18
|
+
xml
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
11
24
|
# Translates a given +array+ to XML. Accepts the XML +key+ to add the elements to,
|
12
25
|
# whether to +escape_xml+ and an optional Hash of +attributes+.
|
13
|
-
def self.
|
26
|
+
def self.build_xml(array, key, escape_xml = true, attributes = {}, options = {})
|
14
27
|
|
15
28
|
self_closing = options.delete(:self_closing)
|
16
|
-
unwrap =
|
29
|
+
unwrap = unwrap?(options.fetch(:unwrap, false), key)
|
17
30
|
|
18
31
|
iterate_with_xml array, key, attributes, options do |xml, item, attrs, index|
|
19
32
|
if self_closing
|
@@ -24,10 +37,10 @@ module Gyoku
|
|
24
37
|
if unwrap
|
25
38
|
xml << Hash.to_xml(item, options)
|
26
39
|
else
|
27
|
-
xml.tag!(key, attrs) { xml << Hash.
|
40
|
+
xml.tag!(key, attrs) { xml << Hash.build_xml(item, options) }
|
28
41
|
end
|
29
42
|
when ::Array then
|
30
|
-
xml.tag!(key, attrs) { xml << Array.
|
43
|
+
xml.tag!(key, attrs) { xml << Array.build_xml(item, NESTED_ELEMENT_NAME) }
|
31
44
|
when NilClass then
|
32
45
|
xml.tag!(key, "xsi:nil" => "true")
|
33
46
|
else
|
@@ -37,17 +50,15 @@ module Gyoku
|
|
37
50
|
end
|
38
51
|
end
|
39
52
|
|
40
|
-
private
|
41
|
-
|
42
53
|
# Iterates over a given +array+ with a Hash of +attributes+ and yields a builder +xml+
|
43
54
|
# instance, the current +item+, any XML +attributes+ and the current +index+.
|
44
55
|
def self.iterate_with_xml(array, key, attributes, options, &block)
|
45
56
|
|
46
57
|
xml = Builder::XmlMarkup.new
|
47
|
-
unwrap =
|
58
|
+
unwrap = unwrap?(options.fetch(:unwrap, false), key)
|
48
59
|
|
49
|
-
if
|
50
|
-
xml.tag!(key) { iterate_array(xml, array, attributes, &block) }
|
60
|
+
if unwrap
|
61
|
+
xml.tag!(key, attributes) { iterate_array(xml, array, attributes, &block) }
|
51
62
|
else
|
52
63
|
iterate_array(xml, array, attributes, &block)
|
53
64
|
end
|
@@ -85,5 +96,9 @@ module Gyoku
|
|
85
96
|
end
|
86
97
|
end
|
87
98
|
|
99
|
+
def self.unwrap?(unwrap, key)
|
100
|
+
unwrap.kind_of?(::Array) ? unwrap.include?(key.to_sym) : unwrap
|
101
|
+
end
|
102
|
+
|
88
103
|
end
|
89
104
|
end
|
data/lib/gyoku/hash.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "builder"
|
2
2
|
|
3
|
+
require "gyoku/prettifier.rb"
|
3
4
|
require "gyoku/array"
|
4
5
|
require "gyoku/xml_key"
|
5
6
|
require "gyoku/xml_value"
|
@@ -7,26 +8,37 @@ require "gyoku/xml_value"
|
|
7
8
|
module Gyoku
|
8
9
|
class Hash
|
9
10
|
|
10
|
-
#
|
11
|
+
# Builds XML and prettifies it if +pretty_print+ option is set to +true+
|
11
12
|
def self.to_xml(hash, options = {})
|
13
|
+
xml = build_xml(hash, options)
|
14
|
+
|
15
|
+
if options[:pretty_print]
|
16
|
+
Prettifier.prettify(xml, options)
|
17
|
+
else
|
18
|
+
xml
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Translates a given +hash+ with +options+ to XML.
|
25
|
+
def self.build_xml(hash, options = {})
|
12
26
|
iterate_with_xml hash do |xml, key, value, attributes|
|
13
27
|
self_closing = key.to_s[-1, 1] == "/"
|
14
28
|
escape_xml = key.to_s[-1, 1] != "!"
|
15
29
|
xml_key = XMLKey.create key, options
|
16
30
|
|
17
31
|
case
|
18
|
-
when :content! === key then xml << XMLValue.create(value, escape_xml)
|
19
|
-
when ::Array === value then xml << Array.
|
20
|
-
when ::Hash === value then xml.tag!(xml_key, attributes) { xml <<
|
32
|
+
when :content! === key then xml << XMLValue.create(value, escape_xml, options)
|
33
|
+
when ::Array === value then xml << Array.build_xml(value, xml_key, escape_xml, attributes, options.merge(:self_closing => self_closing))
|
34
|
+
when ::Hash === value then xml.tag!(xml_key, attributes) { xml << build_xml(value, options) }
|
21
35
|
when self_closing then xml.tag!(xml_key, attributes)
|
22
36
|
when NilClass === value then xml.tag!(xml_key, "xsi:nil" => "true")
|
23
|
-
else xml.tag!(xml_key, attributes) { xml << XMLValue.create(value, escape_xml) }
|
37
|
+
else xml.tag!(xml_key, attributes) { xml << XMLValue.create(value, escape_xml, options) }
|
24
38
|
end
|
25
39
|
end
|
26
40
|
end
|
27
41
|
|
28
|
-
private
|
29
|
-
|
30
42
|
# Iterates over a given +hash+ and yields a builder +xml+ instance, the current
|
31
43
|
# Hash +key+ and any XML +attributes+.
|
32
44
|
#
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module Gyoku
|
4
|
+
class Prettifier
|
5
|
+
DEFAULT_INDENT = 2
|
6
|
+
DEFAULT_COMPACT = true
|
7
|
+
|
8
|
+
attr_accessor :indent, :compact
|
9
|
+
|
10
|
+
def self.prettify(xml, options = {})
|
11
|
+
new(options).prettify(xml)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@indent = options[:indent] || DEFAULT_INDENT
|
16
|
+
@compact = options[:compact].nil? ? DEFAULT_COMPACT : options[:compact]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds intendations and newlines to +xml+ to make it more readable
|
20
|
+
def prettify(xml)
|
21
|
+
result = ''
|
22
|
+
formatter = REXML::Formatters::Pretty.new indent
|
23
|
+
formatter.compact = compact
|
24
|
+
doc = REXML::Document.new xml
|
25
|
+
formatter.write doc, result
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/gyoku/version.rb
CHANGED
data/lib/gyoku/xml_value.rb
CHANGED
@@ -15,7 +15,7 @@ module Gyoku
|
|
15
15
|
XS_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%Z"
|
16
16
|
|
17
17
|
# Converts a given +object+ to an XML value.
|
18
|
-
def create(object, escape_xml = true)
|
18
|
+
def create(object, escape_xml = true, options = {})
|
19
19
|
if Time === object
|
20
20
|
object.strftime XS_TIME_FORMAT
|
21
21
|
elsif DateTime === object
|
@@ -28,6 +28,8 @@ module Gyoku
|
|
28
28
|
create object.to_datetime
|
29
29
|
elsif object.respond_to?(:call)
|
30
30
|
create object.call
|
31
|
+
elsif ::Hash === object
|
32
|
+
Gyoku::Hash.to_xml(object, options)
|
31
33
|
else
|
32
34
|
object.to_s
|
33
35
|
end
|
data/spec/gyoku/array_spec.rb
CHANGED
@@ -45,6 +45,17 @@ describe Gyoku::Array do
|
|
45
45
|
expect(to_xml(array, "value", :escape_xml, :active => true)).to eq(result)
|
46
46
|
end
|
47
47
|
|
48
|
+
it "adds attributes to tags when :unwrap is true" do
|
49
|
+
array = [{:item=>"abc"}]
|
50
|
+
key = "items"
|
51
|
+
escape_xml = :escape_xml
|
52
|
+
attributes = { "amount"=>"1" }
|
53
|
+
options = { :unwrap => true }
|
54
|
+
result = "<items amount=\"1\"><item>abc</item></items>"
|
55
|
+
|
56
|
+
expect(to_xml(array, key, escape_xml, attributes, options)).to eq result
|
57
|
+
end
|
58
|
+
|
48
59
|
it "adds attributes to duplicate tags" do
|
49
60
|
array = ["adam", "eve"]
|
50
61
|
result = '<value id="1">adam</value><value id="2">eve</value>'
|
@@ -65,6 +76,44 @@ describe Gyoku::Array do
|
|
65
76
|
|
66
77
|
expect(to_xml(array, "value")).to eq(result)
|
67
78
|
end
|
79
|
+
|
80
|
+
context "when :pretty_print option is set to true" do
|
81
|
+
context "when :unwrap option is set to true" do
|
82
|
+
it "returns prettified xml" do
|
83
|
+
array = ["one", "two", {"three" => "four"}]
|
84
|
+
options = { pretty_print: true, unwrap: true }
|
85
|
+
result = "<test>\n <test>one</test>\n <test>two</test>\n <three>four</three>\n</test>"
|
86
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when :indent option is specified" do
|
90
|
+
it "returns prettified xml with specified indent" do
|
91
|
+
array = ["one", "two", {"three" => "four"}]
|
92
|
+
options = { pretty_print: true, indent: 3, unwrap: true }
|
93
|
+
result = "<test>\n <test>one</test>\n <test>two</test>\n <three>four</three>\n</test>"
|
94
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when :compact option is specified" do
|
99
|
+
it "returns prettified xml with specified compact mode" do
|
100
|
+
array = ["one", {"two" => "three"}]
|
101
|
+
options = { pretty_print: true, compact: false, unwrap: true }
|
102
|
+
result = "<test>\n <test>\n one\n </test>\n <two>\n three \n </two>\n</test>"
|
103
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when :unwrap option is not set" do
|
109
|
+
it "returns non-prettified xml" do
|
110
|
+
array = ["one", "two", {"three" => "four"}]
|
111
|
+
options = { pretty_print: true }
|
112
|
+
result = "<test>one</test><test>two</test><test><three>four</three></test>"
|
113
|
+
expect(to_xml(array, "test", true, {}, options)).to eq(result)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
68
117
|
end
|
69
118
|
|
70
119
|
def to_xml(*args)
|
data/spec/gyoku/hash_spec.rb
CHANGED
@@ -52,6 +52,33 @@ describe Gyoku::Hash do
|
|
52
52
|
expect(to_xml(:some => [{ :new => "user" }, { :old => "gorilla" }])).
|
53
53
|
to eq("<some><new>user</new></some><some><old>gorilla</old></some>")
|
54
54
|
end
|
55
|
+
|
56
|
+
context "when :pretty_print option is set to true" do
|
57
|
+
it "returns prettified xml" do
|
58
|
+
hash = { some: { user: { name: "John", groups: ["admin", "editor"] } } }
|
59
|
+
options = { pretty_print: true }
|
60
|
+
result = "<some>\n <user>\n <name>John</name>\n <groups>admin</groups>\n <groups>editor</groups>\n </user>\n</some>"
|
61
|
+
expect(to_xml(hash, options)).to eq(result)
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when :indent option is specified" do
|
65
|
+
it "returns prettified xml with specified indent" do
|
66
|
+
hash = { some: { user: { name: "John" } } }
|
67
|
+
options = { pretty_print: true, indent: 4 }
|
68
|
+
result = "<some>\n <user>\n <name>John</name>\n </user>\n</some>"
|
69
|
+
expect(to_xml(hash, options)).to eq(result)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when :compact option is specified" do
|
74
|
+
it "returns prettified xml with specified compact mode" do
|
75
|
+
hash = { some: { user: { name: "John" } } }
|
76
|
+
options = { pretty_print: true, compact: false }
|
77
|
+
result = "<some>\n <user>\n <name>\n John\n </name>\n </user>\n</some>"
|
78
|
+
expect(to_xml(hash, options)).to eq(result)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
55
82
|
end
|
56
83
|
|
57
84
|
it "converts Hash key Symbols to lowerCamelCase" do
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Gyoku::Prettifier do
|
4
|
+
describe "#prettify" do
|
5
|
+
context "when xml is valid" do
|
6
|
+
let!(:xml) { Gyoku::Hash.build_xml(test: { pretty: "xml" }) }
|
7
|
+
|
8
|
+
it "returns prettified xml" do
|
9
|
+
expect(subject.prettify(xml)).to eql("<test>\n <pretty>xml</pretty>\n</test>")
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when indent option is specified" do
|
13
|
+
it "returns prettified xml with indent" do
|
14
|
+
options = { indent: 3 }
|
15
|
+
subject = Gyoku::Prettifier.new(options)
|
16
|
+
expect(subject.prettify(xml)).to eql("<test>\n <pretty>xml</pretty>\n</test>")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when compact option is specified" do
|
21
|
+
it "returns prettified xml with indent" do
|
22
|
+
options = { compact: false }
|
23
|
+
subject = Gyoku::Prettifier.new(options)
|
24
|
+
expect(subject.prettify(xml)).to eql("<test>\n <pretty>\n xml\n </pretty>\n</test>")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when xml is not valid" do
|
30
|
+
let!(:xml) do
|
31
|
+
Gyoku::Array.build_xml(["one", "two"], "test")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "raises an error" do
|
35
|
+
expect{ subject.prettify(xml) }.to raise_error REXML::ParseException
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -46,6 +46,11 @@ describe Gyoku::XMLValue do
|
|
46
46
|
expect(create(object)).to eq("2012-03-22T16:22:33+00:00")
|
47
47
|
end
|
48
48
|
|
49
|
+
it "hash objects get converted to xml" do
|
50
|
+
object = { document!: { "@version" => "2.0", content!: { key!: "value", other_key: { "@attribute" => 'value', content!: { key: "value" } } } } }
|
51
|
+
expect(create(object)).to eq("<document version=\"2.0\"><key>value</key><otherKey attribute=\"value\"><key>value</key></otherKey></document>")
|
52
|
+
end
|
53
|
+
|
49
54
|
it "calls #to_s unless the Object responds to #to_datetime" do
|
50
55
|
expect(create("value")).to eq("value")
|
51
56
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gyoku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Harrington
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: builder
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.1.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rexml
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,9 +72,9 @@ executables: []
|
|
58
72
|
extensions: []
|
59
73
|
extra_rdoc_files: []
|
60
74
|
files:
|
75
|
+
- ".github/workflows/ci.yml"
|
61
76
|
- ".gitignore"
|
62
77
|
- ".rspec"
|
63
|
-
- ".travis.yml"
|
64
78
|
- CHANGELOG.md
|
65
79
|
- Gemfile
|
66
80
|
- MIT-LICENSE
|
@@ -70,11 +84,13 @@ files:
|
|
70
84
|
- lib/gyoku.rb
|
71
85
|
- lib/gyoku/array.rb
|
72
86
|
- lib/gyoku/hash.rb
|
87
|
+
- lib/gyoku/prettifier.rb
|
73
88
|
- lib/gyoku/version.rb
|
74
89
|
- lib/gyoku/xml_key.rb
|
75
90
|
- lib/gyoku/xml_value.rb
|
76
91
|
- spec/gyoku/array_spec.rb
|
77
92
|
- spec/gyoku/hash_spec.rb
|
93
|
+
- spec/gyoku/prettifier_spec.rb
|
78
94
|
- spec/gyoku/xml_key_spec.rb
|
79
95
|
- spec/gyoku/xml_value_spec.rb
|
80
96
|
- spec/gyoku_spec.rb
|
@@ -83,7 +99,7 @@ homepage: https://github.com/savonrb/gyoku
|
|
83
99
|
licenses:
|
84
100
|
- MIT
|
85
101
|
metadata: {}
|
86
|
-
post_install_message:
|
102
|
+
post_install_message:
|
87
103
|
rdoc_options: []
|
88
104
|
require_paths:
|
89
105
|
- lib
|
@@ -91,21 +107,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
107
|
requirements:
|
92
108
|
- - ">="
|
93
109
|
- !ruby/object:Gem::Version
|
94
|
-
version:
|
110
|
+
version: 1.9.2
|
95
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
112
|
requirements:
|
97
113
|
- - ">="
|
98
114
|
- !ruby/object:Gem::Version
|
99
115
|
version: '0'
|
100
116
|
requirements: []
|
101
|
-
|
102
|
-
|
103
|
-
signing_key:
|
117
|
+
rubygems_version: 3.2.7
|
118
|
+
signing_key:
|
104
119
|
specification_version: 4
|
105
120
|
summary: Translates Ruby Hashes to XML
|
106
121
|
test_files:
|
107
122
|
- spec/gyoku/array_spec.rb
|
108
123
|
- spec/gyoku/hash_spec.rb
|
124
|
+
- spec/gyoku/prettifier_spec.rb
|
109
125
|
- spec/gyoku/xml_key_spec.rb
|
110
126
|
- spec/gyoku/xml_value_spec.rb
|
111
127
|
- spec/gyoku_spec.rb
|