gyoku 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/README.md +11 -0
- data/Rakefile +6 -5
- data/lib/gyoku.rb +16 -4
- data/lib/gyoku/array.rb +1 -4
- data/lib/gyoku/core_ext/string.rb +6 -5
- data/lib/gyoku/hash.rb +2 -4
- data/lib/gyoku/version.rb +1 -1
- data/lib/gyoku/xml_key.rb +47 -25
- data/lib/gyoku/xml_value.rb +17 -15
- data/spec/gyoku/core_ext/string_spec.rb +6 -0
- data/spec/gyoku/xml_key_spec.rb +40 -9
- data/spec/gyoku/xml_value_spec.rb +15 -12
- data/spec/gyoku_spec.rb +20 -0
- metadata +7 -6
data/.gemtest
ADDED
File without changes
|
data/README.md
CHANGED
@@ -37,6 +37,17 @@ Conventions
|
|
37
37
|
* These conventions are also applied to the return value of objects responding to :call
|
38
38
|
* All other objects are converted to Strings using :to_s
|
39
39
|
|
40
|
+
Symbols are converted to lowerCamelCase?
|
41
|
+
----------------------------------------
|
42
|
+
|
43
|
+
That's the default. But you can use one of the other conversion formulas:
|
44
|
+
|
45
|
+
Gyoku.convert_symbols_to :camelcase # or one of [:none, :lower_camelcase]
|
46
|
+
|
47
|
+
or even define you own one:
|
48
|
+
|
49
|
+
Gyoku.convert_symbols_to { |key| key.upcase }
|
50
|
+
|
40
51
|
Special characters
|
41
52
|
------------------
|
42
53
|
|
data/Rakefile
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
require "bundler"
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
|
-
task :default => :spec
|
5
|
-
|
6
4
|
begin
|
7
5
|
require "yard"
|
8
|
-
|
6
|
+
|
9
7
|
YARD::Rake::YardocTask.new do |t|
|
10
8
|
t.files = ["README.md", "lib/**/*.rb"]
|
11
9
|
end
|
@@ -16,7 +14,7 @@ end
|
|
16
14
|
|
17
15
|
begin
|
18
16
|
require "metric_fu"
|
19
|
-
|
17
|
+
|
20
18
|
MetricFu::Configuration.run do |c|
|
21
19
|
c.metrics = [:churn, :flog, :flay, :reek, :roodi, :saikuro] # :rcov seems to be broken
|
22
20
|
c.graphs = [:flog, :flay, :reek, :roodi]
|
@@ -30,7 +28,7 @@ end
|
|
30
28
|
|
31
29
|
begin
|
32
30
|
require "rspec/core/rake_task"
|
33
|
-
|
31
|
+
|
34
32
|
RSpec::Core::RakeTask.new do |t|
|
35
33
|
t.pattern = "spec/**/*_spec.rb"
|
36
34
|
t.rspec_opts = %w(-fd -c)
|
@@ -40,3 +38,6 @@ rescue LoadError
|
|
40
38
|
abort "Run 'gem install rspec' to be able to run specs"
|
41
39
|
end
|
42
40
|
end
|
41
|
+
|
42
|
+
task :default => :spec
|
43
|
+
task :test => :spec
|
data/lib/gyoku.rb
CHANGED
@@ -2,10 +2,22 @@ require "gyoku/version"
|
|
2
2
|
require "gyoku/hash"
|
3
3
|
|
4
4
|
module Gyoku
|
5
|
+
class << self
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# Translates a given +hash+ with +options+ to XML.
|
8
|
+
def xml(hash, options = {})
|
9
|
+
Hash.to_xml hash, options
|
10
|
+
end
|
11
|
+
|
12
|
+
# Yields this object for configuration.
|
13
|
+
def configure
|
14
|
+
yield self
|
15
|
+
end
|
10
16
|
|
17
|
+
# Sets the formula for converting Symbol keys.
|
18
|
+
def convert_symbols_to(formula = nil, &block)
|
19
|
+
XMLKey.symbol_converter = formula ? formula : block
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
11
23
|
end
|
data/lib/gyoku/array.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
require "builder"
|
2
2
|
|
3
3
|
require "gyoku/hash"
|
4
|
-
require "gyoku/xml_key"
|
5
4
|
require "gyoku/xml_value"
|
6
5
|
|
7
6
|
module Gyoku
|
8
7
|
class Array
|
9
|
-
extend XMLKey
|
10
|
-
extend XMLValue
|
11
8
|
|
12
9
|
# Translates a given +array+ to XML. Accepts the XML +key+ to add the elements to,
|
13
10
|
# whether to +escape_xml+ and an optional Hash of +attributes+.
|
@@ -16,7 +13,7 @@ module Gyoku
|
|
16
13
|
case item
|
17
14
|
when ::Hash then xml.tag!(key, attrs) { xml << Hash.to_xml(item) }
|
18
15
|
when NilClass then xml.tag!(key, "xsi:nil" => "true")
|
19
|
-
else xml.tag!(key, attrs) { xml <<
|
16
|
+
else xml.tag!(key, attrs) { xml << XMLValue.create(item, escape_xml) }
|
20
17
|
end
|
21
18
|
end
|
22
19
|
end
|
@@ -4,11 +4,12 @@ module Gyoku
|
|
4
4
|
|
5
5
|
# Returns the String in lowerCamelCase.
|
6
6
|
def lower_camelcase
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
self[0].chr.downcase + self.camelcase[1..-1]
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns the String in CamelCase.
|
11
|
+
def camelcase
|
12
|
+
self.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
12
13
|
end
|
13
14
|
|
14
15
|
end
|
data/lib/gyoku/hash.rb
CHANGED
@@ -6,22 +6,20 @@ require "gyoku/xml_value"
|
|
6
6
|
|
7
7
|
module Gyoku
|
8
8
|
class Hash
|
9
|
-
extend XMLKey
|
10
|
-
extend XMLValue
|
11
9
|
|
12
10
|
# Translates a given +hash+ with +options+ to XML.
|
13
11
|
def self.to_xml(hash, options = {})
|
14
12
|
iterate_with_xml hash do |xml, key, value, attributes|
|
15
13
|
self_closing = key.to_s[-1, 1] == "/"
|
16
14
|
escape_xml = key.to_s[-1, 1] != "!"
|
17
|
-
xml_key =
|
15
|
+
xml_key = XMLKey.create key, options
|
18
16
|
|
19
17
|
case
|
20
18
|
when ::Array === value then xml << Array.to_xml(value, xml_key, escape_xml, attributes)
|
21
19
|
when ::Hash === value then xml.tag!(xml_key, attributes) { xml << Hash.to_xml(value, options) }
|
22
20
|
when self_closing then xml.tag!(xml_key, attributes)
|
23
21
|
when NilClass === value then xml.tag!(xml_key, "xsi:nil" => "true")
|
24
|
-
else xml.tag!(xml_key, attributes) { xml <<
|
22
|
+
else xml.tag!(xml_key, attributes) { xml << XMLValue.create(value, escape_xml) }
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
data/lib/gyoku/version.rb
CHANGED
data/lib/gyoku/xml_key.rb
CHANGED
@@ -2,39 +2,61 @@ require "gyoku/core_ext/string"
|
|
2
2
|
|
3
3
|
module Gyoku
|
4
4
|
module XMLKey
|
5
|
+
class << self
|
6
|
+
|
7
|
+
FORMULAS = {
|
8
|
+
:lower_camelcase => lambda { |key| key.lower_camelcase },
|
9
|
+
:camelcase => lambda { |key| key.camelcase },
|
10
|
+
:none => lambda { |key| key }
|
11
|
+
}
|
12
|
+
|
13
|
+
# Converts a given +object+ with +options+ to an XML key.
|
14
|
+
def create(key, options = {})
|
15
|
+
xml_key = chop_special_characters key.to_s
|
16
|
+
|
17
|
+
if unqualify?(xml_key)
|
18
|
+
xml_key = xml_key.split(":").last
|
19
|
+
elsif qualify?(options) && !xml_key.include?(":")
|
20
|
+
xml_key = "#{options[:namespace]}:#{xml_key}"
|
21
|
+
end
|
22
|
+
|
23
|
+
case key
|
24
|
+
when Symbol then symbol_converter.call(xml_key)
|
25
|
+
else xml_key
|
26
|
+
end
|
27
|
+
end
|
5
28
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
if unqualify?(xml_key)
|
11
|
-
xml_key = xml_key.split(":").last
|
12
|
-
elsif qualify?(options) && !xml_key.include?(":")
|
13
|
-
xml_key = "#{options[:namespace]}:#{xml_key}"
|
29
|
+
# Returns the formula for converting Symbol keys.
|
30
|
+
def symbol_converter
|
31
|
+
@symbol_converter ||= FORMULAS[:lower_camelcase]
|
14
32
|
end
|
15
33
|
|
16
|
-
|
17
|
-
|
18
|
-
|
34
|
+
# Sets the +formula+ for converting Symbol keys.
|
35
|
+
# Accepts one of +FORMULAS+ of an object responding to <tt>:call</tt>.
|
36
|
+
def symbol_converter=(formula)
|
37
|
+
formula = FORMULAS[formula] unless formula.respond_to? :call
|
38
|
+
raise ArgumentError, "Invalid symbol_converter formula" unless formula
|
39
|
+
|
40
|
+
@symbol_converter = formula
|
19
41
|
end
|
20
|
-
end
|
21
42
|
|
22
|
-
|
43
|
+
private
|
23
44
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
45
|
+
# Chops special characters from the end of a given +string+.
|
46
|
+
def chop_special_characters(string)
|
47
|
+
["!", "/"].include?(string[-1, 1]) ? string.chop : string
|
48
|
+
end
|
28
49
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
50
|
+
# Returns whether to remove the namespace from a given +key+.
|
51
|
+
def unqualify?(key)
|
52
|
+
key[0, 1] == ":"
|
53
|
+
end
|
33
54
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
55
|
+
# Returns whether to namespace all keys (elementFormDefault).
|
56
|
+
def qualify?(options)
|
57
|
+
options[:element_form_default] == :qualified && options[:namespace]
|
58
|
+
end
|
38
59
|
|
60
|
+
end
|
39
61
|
end
|
40
62
|
end
|
data/lib/gyoku/xml_value.rb
CHANGED
@@ -2,24 +2,26 @@ require "cgi"
|
|
2
2
|
|
3
3
|
module Gyoku
|
4
4
|
module XMLValue
|
5
|
+
class << self
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
# xs:dateTime format.
|
8
|
+
XS_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%Z"
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
# Converts a given +object+ to an XML value.
|
11
|
+
def create(object, escape_xml = true)
|
12
|
+
if DateTime === object
|
13
|
+
object.strftime XS_DATETIME_FORMAT
|
14
|
+
elsif String === object
|
15
|
+
escape_xml ? CGI.escapeHTML(object) : object
|
16
|
+
elsif object.respond_to?(:to_datetime)
|
17
|
+
create object.to_datetime
|
18
|
+
elsif object.respond_to?(:call)
|
19
|
+
create object.call
|
20
|
+
else
|
21
|
+
object.to_s
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
data/spec/gyoku/xml_key_spec.rb
CHANGED
@@ -1,37 +1,68 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Gyoku::XMLKey do
|
4
|
-
include Gyoku::XMLKey
|
5
4
|
|
6
|
-
describe "
|
5
|
+
describe ".create" do
|
7
6
|
it "should remove exclamation marks from the end of a String" do
|
8
|
-
|
7
|
+
create("value!").should == "value"
|
9
8
|
end
|
10
9
|
|
11
10
|
it "should remove forward slashes from the end of a String" do
|
12
|
-
|
11
|
+
create("self-closing/").should == "self-closing"
|
13
12
|
end
|
14
13
|
|
15
14
|
it "should not convert snake_case Strings" do
|
16
|
-
|
15
|
+
create("lower_camel_case").should == "lower_camel_case"
|
17
16
|
end
|
18
17
|
|
19
18
|
it "should convert snake_case Symbols to lowerCamelCase Strings" do
|
20
|
-
|
21
|
-
|
19
|
+
create(:lower_camel_case).should == "lowerCamelCase"
|
20
|
+
create(:lower_camel_case!).should == "lowerCamelCase"
|
22
21
|
end
|
23
22
|
|
24
23
|
context "with :element_form_default set to :qualified and a :namespace" do
|
25
24
|
it "should add the given namespace" do
|
26
|
-
key =
|
25
|
+
key = create :qualify, :element_form_default => :qualified, :namespace => :v1
|
27
26
|
key.should == "v1:qualify"
|
28
27
|
end
|
29
28
|
|
30
29
|
it "should not add the given namespace if the key starts with a colon" do
|
31
|
-
key =
|
30
|
+
key = create ":qualify", :element_form_default => :qualified, :namespace => :v1
|
32
31
|
key.should == "qualify"
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
36
|
+
describe ".symbol_converter" do
|
37
|
+
after { Gyoku::XMLKey.symbol_converter = :lower_camelcase } #reset
|
38
|
+
|
39
|
+
it "should return the default lower_camelcase converter" do
|
40
|
+
Gyoku::XMLKey.symbol_converter.call("snake_case").should == "snakeCase"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should accept :lower_camelcase" do
|
44
|
+
Gyoku::XMLKey.symbol_converter = :lower_camelcase
|
45
|
+
Gyoku::XMLKey.create(:snake_case).should == "snakeCase"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should accept :camelcase" do
|
49
|
+
Gyoku::XMLKey.symbol_converter = :camelcase
|
50
|
+
Gyoku::XMLKey.create(:snake_case).should == "SnakeCase"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should accept :none" do
|
54
|
+
Gyoku::XMLKey.symbol_converter = :none
|
55
|
+
Gyoku::XMLKey.create(:snake_Case).should == "snake_Case"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should allow to set a custom converter" do
|
59
|
+
Gyoku::XMLKey.symbol_converter = Proc.new { |key| key.upcase }
|
60
|
+
Gyoku::XMLKey.create(:snake_case).should == "SNAKE_CASE"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def create(key, options = {})
|
65
|
+
Gyoku::XMLKey.create key, options
|
66
|
+
end
|
67
|
+
|
37
68
|
end
|
@@ -1,27 +1,26 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Gyoku::XMLValue do
|
4
|
-
include Gyoku::XMLValue
|
5
4
|
|
6
5
|
let(:datetime) { DateTime.new 2012, 03, 22, 16, 22, 33 }
|
7
6
|
let(:datetime_string) { "2012-03-22T16:22:33+00:00" }
|
8
|
-
|
9
|
-
describe "
|
7
|
+
|
8
|
+
describe ".create" do
|
10
9
|
context "for DateTime objects" do
|
11
10
|
it "should return an xs:dateTime compliant String" do
|
12
|
-
|
11
|
+
create(datetime).should == datetime_string
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
15
|
it "should return the String value and escape special characters" do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
create("string").should == "string"
|
17
|
+
create("<tag>").should == "<tag>"
|
18
|
+
create("at&t").should == "at&t"
|
19
|
+
create('"quotes"').should == ""quotes""
|
21
20
|
end
|
22
21
|
|
23
22
|
it "should just return the String value without escaping special characters" do
|
24
|
-
|
23
|
+
create("<tag>", false).should == "<tag>"
|
25
24
|
end
|
26
25
|
|
27
26
|
it "should return an xs:dateTime compliant String for Objects responding to #to_datetime" do
|
@@ -30,17 +29,21 @@ describe Gyoku::XMLValue do
|
|
30
29
|
DateTime.new 2012, 03, 22, 16, 22, 33
|
31
30
|
end
|
32
31
|
|
33
|
-
|
32
|
+
create(singleton).should == "2012-03-22T16:22:33+00:00"
|
34
33
|
end
|
35
34
|
|
36
35
|
it "should #call Proc objects and convert their return value" do
|
37
36
|
object = lambda { DateTime.new 2012, 03, 22, 16, 22, 33 }
|
38
|
-
|
37
|
+
create(object).should == "2012-03-22T16:22:33+00:00"
|
39
38
|
end
|
40
39
|
|
41
40
|
it "should call #to_s unless the Object responds to #to_datetime" do
|
42
|
-
|
41
|
+
create("value").should == "value"
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
45
|
+
def create(object, escape_xml = true)
|
46
|
+
Gyoku::XMLValue.create object, escape_xml
|
47
|
+
end
|
48
|
+
|
46
49
|
end
|
data/spec/gyoku_spec.rb
CHANGED
@@ -9,4 +9,24 @@ describe Gyoku do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
describe ".configure" do
|
13
|
+
it "should yield the Gyoku module" do
|
14
|
+
Gyoku.configure { |config| config.should respond_to(:convert_symbols_to) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe ".convert_symbols_to" do
|
19
|
+
after { Gyoku.convert_symbols_to(:lower_camelcase) } # reset
|
20
|
+
|
21
|
+
it "should accept a predefined formula" do
|
22
|
+
Gyoku.convert_symbols_to(:camelcase)
|
23
|
+
Gyoku::XMLKey.create(:snake_case).should == "SnakeCase"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should accept a block" do
|
27
|
+
Gyoku.convert_symbols_to { |key| key.upcase }
|
28
|
+
Gyoku::XMLKey.create(:snake_case).should == "SNAKE_CASE"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
12
32
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gyoku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel Harrington
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-05 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -89,6 +89,7 @@ extensions: []
|
|
89
89
|
extra_rdoc_files: []
|
90
90
|
|
91
91
|
files:
|
92
|
+
- .gemtest
|
92
93
|
- .gitignore
|
93
94
|
- .rspec
|
94
95
|
- Gemfile
|
@@ -140,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
141
|
requirements: []
|
141
142
|
|
142
143
|
rubyforge_project: gyoku
|
143
|
-
rubygems_version: 1.4.
|
144
|
+
rubygems_version: 1.4.2
|
144
145
|
signing_key:
|
145
146
|
specification_version: 3
|
146
147
|
summary: Converts Ruby Hashes to XML
|