xml-fu 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ### 0.1.2
2
+
3
+ * Additional nesting support
4
+ * Further encapsulated functionality into Node
5
+ * xml.tag! is only used in Node
6
+ * Array collection vs content logic moved to Node
7
+ * Hash iteration logic reduced to a single Node call
8
+ * Node
9
+ * New attribute: "content_type"
10
+ * Special tag characters (\*, \/, !) can be mixed and matched
11
+ * "foo/\*" will return a collection of <foo/> siblings
12
+ * 12 new spec tests
13
+ * Removed development dependencies for:
14
+ * autotest
15
+ * mocha
16
+
17
+ ### 0.1.1
18
+
19
+ * Rescue false positives when setting Node.value due to interaction with ActiveSupport
20
+
1
21
  ### 0.1.0
2
22
 
3
23
  * Initial version. born as a replacement of
data/lib/xml-fu/array.rb CHANGED
@@ -24,10 +24,6 @@ module XmlFu
24
24
  raise(MissingKeyException, "Key name missing for collection") if key.empty?
25
25
 
26
26
  case
27
- when key[-1,1] == "/"
28
- xml << Node.new(key, nil, attributes).to_xml
29
- when ::Hash === item
30
- xml.tag!(key, attributes) { xml << Hash.to_xml(item,options) }
31
27
  when ::Array === item
32
28
  xml << Array.to_xml(item.flatten,options)
33
29
  else
@@ -42,9 +38,10 @@ module XmlFu
42
38
  xml << Array.to_xml(item, options)
43
39
  when XmlFu.infer_simple_value_nodes == true
44
40
  xml << infer_node(item, attributes)
41
+ when item.respond_to?(:to_xml)
42
+ xml << item.to_xml
45
43
  else
46
- # only act on item if it responds to to_xml
47
- xml << item.to_xml if item.respond_to?(:to_xml)
44
+ # unknown xml tranfromation process
48
45
  end
49
46
  end
50
47
  end
@@ -83,11 +80,14 @@ module XmlFu
83
80
 
84
81
  if item.respond_to?(:keys)
85
82
  filtered = Hash.filter(item)
86
- attributes = filtered.last
87
- item_content = filtered.first
83
+ item_content, attributes = filtered.first, filtered.last
88
84
  end
89
85
 
90
- yield xml, key, item_content, attributes
86
+ item_name = ( Symbol === key ?
87
+ XmlFu::Node.symbol_conversion_algorithm.call(key) :
88
+ key.to_s )
89
+
90
+ yield xml, item_name, item_content, attributes
91
91
  end
92
92
 
93
93
  xml.target!
data/lib/xml-fu/hash.rb CHANGED
@@ -11,33 +11,8 @@ module XmlFu
11
11
 
12
12
  # Convert Hash to XML String
13
13
  def self.to_xml(hash, options={})
14
- each_with_xml hash do |xml, key, value, attributes|
15
- # Use symbol conversion algorithm to set tag name
16
- tag_name = ( Symbol === key ?
17
- XmlFu::Node.symbol_conversion_algorithm.call(key) :
18
- key.to_s )
19
-
20
- case
21
- when tag_name[-1,1] == "/"
22
- xml << Node.new(tag_name, nil, attributes).to_xml
23
- when ::Array === value
24
- if tag_name[-1,1] == '*'
25
- options.merge!({
26
- :content_type => "collection",
27
- :key => tag_name.chop,
28
- :attributes => attributes
29
- })
30
- # Collection is merely a set of sibling nodes
31
- xml << Array.to_xml(value.flatten, options)
32
- else
33
- # Contents will contain a parent node
34
- xml.tag!(tag_name, attributes) { xml << Array.to_xml(value, options) }
35
- end
36
- when ::Hash === value
37
- xml.tag!(tag_name, attributes) { xml << Hash.to_xml(value, options) }
38
- else
39
- xml << Node.new(tag_name, value, attributes).to_xml
40
- end
14
+ each_with_xml hash do |xml, name, value, attributes|
15
+ xml << Node.new(name, value, attributes).to_xml
41
16
  end
42
17
  end#self.to_xml
43
18
 
@@ -72,11 +47,15 @@ module XmlFu
72
47
  # yank the attribute keys into their own hash
73
48
  if value.respond_to?(:keys)
74
49
  filtered = Hash.filter(value)
75
- node_attrs = filtered.last
76
- node_value = filtered.first
50
+ node_value, node_attrs = filtered.first, filtered.last
77
51
  end
78
52
 
79
- yield xml, key, node_value, node_attrs
53
+ # Use symbol conversion algorithm to set tag name
54
+ node_name = ( Symbol === key ?
55
+ XmlFu::Node.symbol_conversion_algorithm.call(key) :
56
+ key.to_s )
57
+
58
+ yield xml, node_name, node_value, node_attrs
80
59
  end
81
60
 
82
61
  xml.target!
data/lib/xml-fu/node.rb CHANGED
@@ -39,6 +39,7 @@ module XmlFu
39
39
 
40
40
  attr_accessor :escape_xml
41
41
  attr_accessor :self_closing
42
+ attr_accessor :content_type
42
43
 
43
44
  # Create XmlFu::Node object
44
45
  # @param [String, Symbol] name Name of node
@@ -47,6 +48,7 @@ module XmlFu
47
48
  def initialize(name, value, attributes={})
48
49
  @escape_xml = true
49
50
  @self_closing = false
51
+ @content_type = "container"
50
52
  self.attributes = attributes
51
53
  self.value = value
52
54
  self.name = name
@@ -85,21 +87,25 @@ module XmlFu
85
87
  def name_parse_special_characters(val)
86
88
  use_this = val.dup
87
89
 
88
- # Will this be a self closing node?
89
- if use_this.to_s[-1,1] == '/'
90
- @self_closing = true
91
- use_this.chop!
92
- end
93
-
94
- # Will this node contain escaped XML?
95
- if use_this.to_s[-1,1] == '!'
96
- @escape_xml = false
97
- use_this.chop!
98
- end
99
-
100
90
  # Ensure that we don't have special characters at end of name
101
91
  while ["!","/","*"].include?(use_this.to_s[-1,1]) do
102
- use_this.chop!
92
+ # Will this node contain escaped XML?
93
+ if use_this.to_s[-1,1] == '!'
94
+ @escape_xml = false
95
+ use_this.chop!
96
+ end
97
+
98
+ # Will this be a self closing node?
99
+ if use_this.to_s[-1,1] == '/'
100
+ @self_closing = true
101
+ use_this.chop!
102
+ end
103
+
104
+ # Will this node contain a collection of sibling nodes?
105
+ if use_this.to_s[-1,1] == '*'
106
+ @content_type = "collection"
107
+ use_this.chop!
108
+ end
103
109
  end
104
110
 
105
111
  return use_this
@@ -107,16 +113,22 @@ module XmlFu
107
113
 
108
114
  # Custom Setter for @value instance method
109
115
  def value=(val)
110
- if DateTime === val || Time === val || Date === val
111
- @value = val.strftime XS_DATETIME_FORMAT
112
- elsif val.respond_to?(:to_datetime)
113
- @value = val.to_datetime
114
- elsif val.respond_to?(:call)
115
- @value = val.call
116
- elsif val.nil?
117
- @value = nil
116
+ case val
117
+ when ::Hash then @value = val
118
+ when ::Array then @value = val
119
+ when ::DateTime then @value = val.strftime XS_DATETIME_FORMAT
120
+ when ::Time then @value = val.strftime XS_DATETIME_FORMAT
121
+ when ::Date then @value = val.strftime XS_DATETIME_FORMAT
118
122
  else
119
- @value = val.to_s
123
+ if val.respond_to?(:to_datetime)
124
+ @value = val.to_datetime
125
+ elsif val.respond_to?(:call)
126
+ @value = val.call
127
+ elsif val.nil?
128
+ @value = nil
129
+ else
130
+ @value = val.to_s
131
+ end
120
132
  end
121
133
  rescue => e
122
134
  @value = val.to_s
@@ -133,9 +145,27 @@ module XmlFu
133
145
  def to_xml
134
146
  xml = Builder::XmlMarkup.new
135
147
  case
136
- when @self_closing then xml.tag!(@name, @attributes)
137
- when @value.nil? then xml.tag!(@name, @attributes.merge!("xsi:nil" => "true"))
138
- else xml.tag!(@name, @attributes) { xml << self.value }
148
+ when @self_closing && @content_type == 'container'
149
+ xml.tag!(@name, @attributes)
150
+ when @value.nil?
151
+ xml.tag!(@name, @attributes.merge!("xsi:nil" => "true"))
152
+ when ::Hash === @value
153
+ xml.tag!(@name, @attributes) { xml << XmlFu::Hash.to_xml(@value) }
154
+ when ::Array === @value
155
+ case @content_type
156
+ when "collection"
157
+ xml << XmlFu::Array.to_xml(@value.flatten, {
158
+ :key => (@self_closing ? "#{@name}/" : @name),
159
+ :attributes => @attributes,
160
+ :content_type => "collection"
161
+ })
162
+ when "container"
163
+ xml.tag!(@name, @attributes) { xml << XmlFu::Array.to_xml(@value) }
164
+ else
165
+ # Shouldn't be anything else
166
+ end
167
+ else
168
+ xml.tag!(@name, @attributes) { xml << self.value }
139
169
  end
140
170
  xml.target!
141
171
  end#to_xml
@@ -1,3 +1,3 @@
1
1
  module XmlFu
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/xml-fu.rb CHANGED
@@ -5,13 +5,12 @@ require "xml-fu/array"
5
5
  module XmlFu
6
6
  class << self
7
7
 
8
- @@infer_simple_value_nodes = false
9
-
10
8
  # Convert construct into XML
11
9
  def xml(construct, options={})
12
10
  case construct
13
11
  when ::Hash then Hash.to_xml( construct.dup, options )
14
12
  when ::Array then Array.to_xml( construct.dup, options )
13
+ else nil
15
14
  end
16
15
  end#convert
17
16
 
@@ -25,13 +24,19 @@ module XmlFu
25
24
  # an array of one hash (the root node hash)
26
25
  #
27
26
  # <foo><bar/><baz/></foo> => [{"foo" => [{"bar/" => ""},{"baz/" => ""}] }]
28
- def hash(xml, options)
27
+ def parse(xml, options)
29
28
  end
30
29
 
31
30
  def configure
32
31
  yield self
33
32
  end
34
33
 
34
+ ################################################################################
35
+ ## CONFIGURATIONS
36
+ ################################################################################
37
+
38
+ @@infer_simple_value_nodes = false
39
+
35
40
  # Set configuration option to be used with future releases
36
41
  def infer_simple_value_nodes=(val)
37
42
  @@infer_simple_value_nodes = val
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe XmlFu::Array do
4
-
5
4
  describe ".to_xml" do
6
5
  #after do
7
6
  # XmlFu.infer_simple_value_nodes = false
@@ -33,8 +33,10 @@ describe XmlFu::Hash do
33
33
 
34
34
  describe "with a key that will contain multiple nodes" do
35
35
  describe "when key explicitly denotes value is a collection" do
36
- hash = { "foo*" => ["bar", "biz"] }
37
- XmlFu::Hash.to_xml(hash).should == "<foo>bar</foo><foo>biz</foo>"
36
+ it "should return the correct collection" do
37
+ hash = { "foo*" => ["bar", "biz"] }
38
+ XmlFu::Hash.to_xml(hash).should == "<foo>bar</foo><foo>biz</foo>"
39
+ end
38
40
  end
39
41
 
40
42
  describe "when key denotes value contains children" do
@@ -1,6 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe XmlFu::Node do
4
+ it "should remove special characters from name no matter how many times they appear at the end" do
5
+ node = XmlFu::Node.new("foo/*!", 'something')
6
+ node.name.should == 'foo'
7
+
8
+ node = XmlFu::Node.new("foo/*/**/!!!", 'something')
9
+ node.name.should == 'foo'
10
+ end
11
+
12
+ describe "with hash as value" do
13
+ it "should store the value as a hash" do
14
+ node = XmlFu::Node.new("foo", {"bar" => "biz"})
15
+ node.value.class.should == Hash
16
+ end
17
+
18
+ it "should create nested nodes with simple hash" do
19
+ node = XmlFu::Node.new("foo", {"bar" => "biz"})
20
+ node.to_xml.should == "<foo><bar>biz</bar></foo>"
21
+ end
22
+ end
23
+
24
+ describe "with array as value" do
25
+ it "should store the value as an array" do
26
+ node = XmlFu::Node.new("foo", ["bar", "biz"])
27
+ node.value.class.should == Array
28
+ end
29
+
30
+ it "should create nodes with simple collection array" do
31
+ node = XmlFu::Node.new("foo*", ["bar", "biz"])
32
+ node.to_xml.should == "<foo>bar</foo><foo>biz</foo>"
33
+ end
34
+
35
+ it "should create nodes with simple contents array" do
36
+ node = XmlFu::Node.new("foo*", [{:bar => "biz"}])
37
+ node.to_xml.should == "<foo><bar>biz</bar></foo>"
38
+ end
39
+ end
4
40
 
5
41
  describe "setting instance variables" do
6
42
  it "should correctly remove special characters from a name" do
@@ -12,6 +48,9 @@ describe XmlFu::Node do
12
48
 
13
49
  node = XmlFu::Node.new("foo!", "something")
14
50
  node.name.should == "foo"
51
+
52
+ node = XmlFu::Node.new("foo:bar!", "something")
53
+ node.name.should == "foo:bar"
15
54
  end
16
55
 
17
56
  it "should set self-closing with special name character" do
@@ -24,6 +63,14 @@ describe XmlFu::Node do
24
63
  node.escape_xml.should == false
25
64
  end
26
65
 
66
+ it "should set content_type with special name character" do
67
+ node = XmlFu::Node.new("foo", "something")
68
+ node.content_type.should == "container"
69
+
70
+ node = XmlFu::Node.new("foo*", "something")
71
+ node.content_type.should == "collection"
72
+ end
73
+
27
74
  it "should set attributes with a hash" do
28
75
  node = XmlFu::Node.new("foo", "bar", {:this => "that"})
29
76
  node.attributes.should == {:this => "that"}
@@ -54,13 +101,14 @@ describe XmlFu::Node do
54
101
  it "should properly preserve namespaceds names" do
55
102
  node = XmlFu::Node.new("foo:bar", "biz")
56
103
  node.name.should == "foo:bar"
104
+
105
+ node = XmlFu::Node.new("foo:bar!", "biz")
106
+ node.name.should == "foo:bar"
57
107
  end
58
108
  end
59
109
 
60
110
  describe "to_xml" do
61
-
62
111
  describe "should return self-closing nil XML node for nil value" do
63
-
64
112
  it "provided ANY non-blank name" do
65
113
  nil_foo = "<foo xsi:nil=\"true\"/>"
66
114
  node = XmlFu::Node.new("foo", nil)
@@ -75,9 +123,12 @@ describe XmlFu::Node do
75
123
 
76
124
  it "with additional attributes provided" do
77
125
  node = XmlFu::Node.new("foo", nil, {:this => "that"})
78
- node.to_xml.should == "<foo this=\"that\" xsi:nil=\"true\"/>"
126
+ # Depending on the version of ruby, one of
127
+ # these two acceptible values would be returned
128
+ [ "<foo this=\"that\" xsi:nil=\"true\"/>",
129
+ "<foo xsi:nil=\"true\" this=\"that\"/>"
130
+ ].should include(node.to_xml)
79
131
  end
80
-
81
132
  end
82
133
 
83
134
  it "should escape values by default" do
@@ -108,5 +159,4 @@ describe XmlFu::Node do
108
159
  end
109
160
  end
110
161
  end
111
-
112
162
  end
data/spec/xmlfu_spec.rb CHANGED
@@ -2,6 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  describe XmlFu do
4
4
  describe ".xml" do
5
+ it "should return nil for value that isn't a Hash or Array" do
6
+ XmlFu.xml(1).should == nil
7
+ XmlFu.xml(nil).should == nil
8
+ XmlFu.xml(Object.new).should == nil
9
+ end
10
+
5
11
  it "translates a given Hash to XML" do
6
12
  XmlFu.xml( :id => 1 ).should == "<id>1</id>"
7
13
  end
@@ -41,6 +47,16 @@ describe XmlFu do
41
47
  XmlFu.xml(hash).should == "<foo bar=\"biz\"></foo><foo biz=\"bang\"></foo>"
42
48
  end
43
49
 
50
+ it "should return list of self-closing nodes" do
51
+ hash = {
52
+ "foo/*" => [
53
+ {"@bar" => "biz"},
54
+ {"@biz" => "bang"}
55
+ ]
56
+ }
57
+ XmlFu.xml(hash).should == "<foo bar=\"biz\"/><foo biz=\"bang\"/>"
58
+ end
59
+
44
60
  it "should ignore nested values for content array" do
45
61
  output = XmlFu.xml("foo/" => [{:bar => "biz"}, {:bar => "biz"}])
46
62
  output.should == "<foo/>"
@@ -53,7 +69,6 @@ describe XmlFu do
53
69
  output = XmlFu.xml("foo/" => {"@id" => "0"})
54
70
  output.should == "<foo id=\"0\"/>"
55
71
  end
56
-
57
72
  end
58
73
 
59
74
  describe "configure" do
@@ -71,5 +86,4 @@ describe XmlFu do
71
86
  XmlFu.infer_simple_value_nodes = false
72
87
  XmlFu.infer_simple_value_nodes.should == false
73
88
  end
74
-
75
89
  end
data/xml-fu.gemspec CHANGED
@@ -19,8 +19,6 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency "builder", ">= 2.1.2"
20
20
 
21
21
  gem.add_development_dependency "rspec", ">= 2.4.0"
22
- gem.add_development_dependency "autotest"
23
- gem.add_development_dependency "mocha", "~> 0.9.9"
24
22
 
25
23
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
24
  gem.files = `git ls-files`.split("\n")
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xml-fu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 2
10
+ version: 0.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Johnson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-03-13 00:00:00 Z
18
+ date: 2012-03-16 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: builder
@@ -49,36 +49,6 @@ dependencies:
49
49
  version: 2.4.0
50
50
  type: :development
51
51
  version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: autotest
54
- prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 3
61
- segments:
62
- - 0
63
- version: "0"
64
- type: :development
65
- version_requirements: *id003
66
- - !ruby/object:Gem::Dependency
67
- name: mocha
68
- prerelease: false
69
- requirement: &id004 !ruby/object:Gem::Requirement
70
- none: false
71
- requirements:
72
- - - ~>
73
- - !ruby/object:Gem::Version
74
- hash: 41
75
- segments:
76
- - 0
77
- - 9
78
- - 9
79
- version: 0.9.9
80
- type: :development
81
- version_requirements: *id004
82
52
  description: "\n Inspired by the Gyoku gem for hash to xml conversion, \n XmlFu is designed to require no meta tagging for \n node attributes and content. (i.e. no :attributes! and no :order!)\n "
83
53
  email:
84
54
  - rhino.citguy@gmail.com