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 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
- # Translates a given +hash+ with +options+ to XML.
7
- def self.xml(hash, options = {})
8
- Hash.to_xml hash, options
9
- end
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 << to_xml_value(item, escape_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
- str = dup
8
- str.gsub!(/\/(.?)/) { "::#{$1.upcase}" }
9
- str.gsub!(/(?:_+|-+)([a-z])/) { $1.upcase }
10
- str.gsub!(/(\A|\s)([A-Z])/) { $1 + $2.downcase }
11
- str
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 = to_xml_key key, options
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 << to_xml_value(value, escape_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
@@ -1,5 +1,5 @@
1
1
  module Gyoku
2
2
 
3
- VERSION = "0.3.1"
3
+ VERSION = "0.4.0"
4
4
 
5
5
  end
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
- # Converts a given +object+ with +options+ to an XML key.
7
- def to_xml_key(key, options = {})
8
- xml_key = chop_special_characters key.to_s
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
- case key
17
- when Symbol then xml_key.lower_camelcase
18
- else xml_key
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
- private
43
+ private
23
44
 
24
- # Chops special characters from the end of a given +string+.
25
- def chop_special_characters(string)
26
- ["!", "/"].include?(string[-1, 1]) ? string.chop : string
27
- end
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
- # Returns whether to remove the namespace from a given +key+.
30
- def unqualify?(key)
31
- key[0, 1] == ":"
32
- end
50
+ # Returns whether to remove the namespace from a given +key+.
51
+ def unqualify?(key)
52
+ key[0, 1] == ":"
53
+ end
33
54
 
34
- # Returns whether to namespace all keys (elementFormDefault).
35
- def qualify?(options)
36
- options[:element_form_default] == :qualified && options[:namespace]
37
- end
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
@@ -2,24 +2,26 @@ require "cgi"
2
2
 
3
3
  module Gyoku
4
4
  module XMLValue
5
+ class << self
5
6
 
6
- # xs:dateTime format.
7
- XS_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%Z"
7
+ # xs:dateTime format.
8
+ XS_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%Z"
8
9
 
9
- # Converts a given +object+ to an XML value.
10
- def to_xml_value(object, escape_xml = true)
11
- if DateTime === object
12
- object.strftime XS_DATETIME_FORMAT
13
- elsif String === object
14
- escape_xml ? CGI.escapeHTML(object) : object
15
- elsif object.respond_to?(:to_datetime)
16
- to_xml_value object.to_datetime
17
- elsif object.respond_to?(:call)
18
- to_xml_value object.call
19
- else
20
- object.to_s
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
@@ -8,4 +8,10 @@ describe String do
8
8
  end
9
9
  end
10
10
 
11
+ describe "#camelcase" do
12
+ it "converts a snakecase String to CamelCase" do
13
+ "camel_case".camelcase.should == "CamelCase"
14
+ end
15
+ end
16
+
11
17
  end
@@ -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 "#to_xml_key" do
5
+ describe ".create" do
7
6
  it "should remove exclamation marks from the end of a String" do
8
- to_xml_key("value!").should == "value"
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
- to_xml_key("self-closing/").should == "self-closing"
11
+ create("self-closing/").should == "self-closing"
13
12
  end
14
13
 
15
14
  it "should not convert snake_case Strings" do
16
- to_xml_key("lower_camel_case").should == "lower_camel_case"
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
- to_xml_key(:lower_camel_case).should == "lowerCamelCase"
21
- to_xml_key(:lower_camel_case!).should == "lowerCamelCase"
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 = to_xml_key :qualify, :element_form_default => :qualified, :namespace => :v1
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 = to_xml_key ":qualify", :element_form_default => :qualified, :namespace => :v1
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 "#to_xml_value" do
7
+
8
+ describe ".create" do
10
9
  context "for DateTime objects" do
11
10
  it "should return an xs:dateTime compliant String" do
12
- to_xml_value(datetime).should == datetime_string
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
- to_xml_value("string").should == "string"
18
- to_xml_value("<tag>").should == "&lt;tag&gt;"
19
- to_xml_value("at&t").should == "at&amp;t"
20
- to_xml_value('"quotes"').should == "&quot;quotes&quot;"
16
+ create("string").should == "string"
17
+ create("<tag>").should == "&lt;tag&gt;"
18
+ create("at&t").should == "at&amp;t"
19
+ create('"quotes"').should == "&quot;quotes&quot;"
21
20
  end
22
21
 
23
22
  it "should just return the String value without escaping special characters" do
24
- to_xml_value("<tag>", false).should == "<tag>"
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
- to_xml_value(singleton).should == "2012-03-22T16:22:33+00:00"
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
- to_xml_value(object).should == "2012-03-22T16:22:33+00:00"
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
- to_xml_value("value").should == "value"
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: 17
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 1
10
- version: 0.3.1
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-01-26 00:00:00 +01:00
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.1
144
+ rubygems_version: 1.4.2
144
145
  signing_key:
145
146
  specification_version: 3
146
147
  summary: Converts Ruby Hashes to XML