oxmlk 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/examples/example.rb +9 -9
- data/lib/oxmlk/attr.rb +34 -0
- data/lib/oxmlk/elem.rb +97 -0
- data/lib/oxmlk/xml.rb +0 -7
- data/lib/oxmlk.rb +28 -27
- data/oxmlk.gemspec +9 -6
- data/spec/oxmlk/attr_spec.rb +56 -0
- data/spec/oxmlk/elem_spec.rb +142 -0
- data/spec/oxmlk_spec.rb +23 -11
- data/spec/xml_spec.rb +0 -25
- metadata +9 -6
- data/lib/oxmlk/description.rb +0 -144
- data/spec/description_spec.rb +0 -266
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/examples/example.rb
CHANGED
@@ -3,8 +3,8 @@ class Number
|
|
3
3
|
|
4
4
|
ox_tag :number
|
5
5
|
|
6
|
-
ox_attr :group
|
7
|
-
|
6
|
+
ox_attr :group
|
7
|
+
ox_elem(:value, :from => :content)
|
8
8
|
end
|
9
9
|
|
10
10
|
class Email
|
@@ -12,8 +12,8 @@ class Email
|
|
12
12
|
|
13
13
|
ox_tag :email
|
14
14
|
|
15
|
-
ox_attr :group
|
16
|
-
|
15
|
+
ox_attr :group
|
16
|
+
ox_elem(:value, :from => :content)
|
17
17
|
end
|
18
18
|
|
19
19
|
class Person
|
@@ -21,12 +21,12 @@ class Person
|
|
21
21
|
|
22
22
|
ox_tag :person
|
23
23
|
|
24
|
-
ox_attr
|
25
|
-
ox_attr
|
24
|
+
ox_attr :category
|
25
|
+
ox_attr :alternate, :from => 'alt'
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
ox_elem :name
|
28
|
+
ox_elem :contacts, :as => [Number,Email]
|
29
|
+
ox_elem :friends, :as => [Person], :in => :friends
|
30
30
|
|
31
31
|
def say_hello(xml)
|
32
32
|
'hello'
|
data/lib/oxmlk/attr.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module OxMlk
|
2
|
+
class Attr
|
3
|
+
PROCS = (Hash.new {|h,k| k.to_proc rescue nil}).merge(
|
4
|
+
Integer => :to_i.to_proc,
|
5
|
+
Float => :to_f.to_proc,
|
6
|
+
String => :to_s.to_proc,
|
7
|
+
Symbol => :to_sym.to_proc,
|
8
|
+
:bool => proc {|a| fetch_bool(a)})
|
9
|
+
|
10
|
+
attr_reader :accessor, :setter,:from, :as, :procs, :tag
|
11
|
+
|
12
|
+
def initialize(name,o={},&block)
|
13
|
+
name = name.to_s
|
14
|
+
@accessor = name.chomp('?').intern
|
15
|
+
@setter = "#{@accessor}=".intern
|
16
|
+
@from = o.delete(:from)
|
17
|
+
@tag = (from || accessor).to_s
|
18
|
+
@as = o.delete(:as) || (:bool if name.ends_with?('?'))
|
19
|
+
@procs = ([*as].map {|k| PROCS[k]} + [block]).compact
|
20
|
+
end
|
21
|
+
|
22
|
+
def from_xml(data)
|
23
|
+
procs.inject(XML::Node.from(data)[tag]) {|d,p| p.call(d) rescue d}
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.fetch_bool(value)
|
27
|
+
value = value.to_s.downcase
|
28
|
+
return true if %w{true yes 1 t}.include? value
|
29
|
+
return false if %w{false no 0 f}.include? value
|
30
|
+
value
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/oxmlk/elem.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
module OxMlk
|
2
|
+
class Elem
|
3
|
+
PROCS = (Hash.new {|h,k| default_proc(k)}).merge(
|
4
|
+
Integer => :to_i.to_proc,
|
5
|
+
Float => :to_f.to_proc,
|
6
|
+
String => :to_s.to_proc,
|
7
|
+
Symbol => :to_sym.to_proc,
|
8
|
+
:raw => proc {|e| e},
|
9
|
+
:name => proc {|e| e.name},
|
10
|
+
:value => proc {|e| e.value},
|
11
|
+
:bool => proc {|e| fetch_bool(e.value)})
|
12
|
+
|
13
|
+
attr_reader :accessor, :setter, :collection, :from, :as, :in, :procs, :block, :tag
|
14
|
+
|
15
|
+
def initialize(name,o={},&blk)
|
16
|
+
@tag = name.to_s
|
17
|
+
@accessor = @tag.chomp('?').intern
|
18
|
+
@setter = "#{@accessor}=".intern
|
19
|
+
@collection = o[:as].is_a?(Array)
|
20
|
+
|
21
|
+
@from = o[:from]
|
22
|
+
@as = [*o.delete(:as)].compact
|
23
|
+
@in = o.delete(:in)
|
24
|
+
|
25
|
+
@procs = as.map {|k| PROCS[k]}
|
26
|
+
@procs = [PROCS[:value]] + procs unless [:raw,:name,:value].include?(as.first) || ox?
|
27
|
+
@block = blk || (collection ? proc {|x| x} : proc {|x| x.first})
|
28
|
+
end
|
29
|
+
|
30
|
+
def ox?
|
31
|
+
return false if as.empty?
|
32
|
+
as.all? {|x| x.ox? rescue false}
|
33
|
+
end
|
34
|
+
|
35
|
+
def content?
|
36
|
+
@from == :content || @from == '.'
|
37
|
+
end
|
38
|
+
|
39
|
+
def from_xml(data)
|
40
|
+
xml = XML::Node.from(data)
|
41
|
+
block.call(xml.find(xpath).map do |node|
|
42
|
+
procs.inject(node) do |n,p|
|
43
|
+
p.call(n)
|
44
|
+
end
|
45
|
+
end)
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_xml(data)
|
49
|
+
value = data.send(accessor)
|
50
|
+
|
51
|
+
return [] if value.nil?
|
52
|
+
|
53
|
+
nodes = [*value].map do |node|
|
54
|
+
if node.respond_to?(:to_xml)
|
55
|
+
node.to_xml
|
56
|
+
elsif content?
|
57
|
+
XML::Node.new_text(node.to_s)
|
58
|
+
else
|
59
|
+
XML::Node.new(tag, node.to_s)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
return [] if nodes.empty?
|
63
|
+
@in ? [nodes.inject(XML::Node.new(@in)) {|o,n| o << n}] : nodes
|
64
|
+
end
|
65
|
+
|
66
|
+
def xpath
|
67
|
+
wrap case @from
|
68
|
+
when nil
|
69
|
+
ox? ? as.map(&:ox_tag).join('|') : tag
|
70
|
+
when String
|
71
|
+
from
|
72
|
+
when :content
|
73
|
+
'.'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.fetch_bool(value)
|
78
|
+
value = value.to_s.downcase
|
79
|
+
return true if %w{true yes 1 t}.include? value
|
80
|
+
return false if %w{false no 0 f}.include? value
|
81
|
+
value
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.default_proc(value)
|
85
|
+
return value if value.is_a?(Proc)
|
86
|
+
return proc {|x| value.from_xml(x) rescue x} if (value.ox? rescue false)
|
87
|
+
return value.to_proc rescue proc {|x| x} if value.respond_to?(:to_proc)
|
88
|
+
proc {|x| x.value}
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def wrap(xpath)
|
94
|
+
(xpath.split('|').map {|x| [@in,x].compact.join('/') }).join('|')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/oxmlk/xml.rb
CHANGED
@@ -28,13 +28,6 @@ module OxMlk
|
|
28
28
|
raise 'Invalid XML data'
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
|
-
def self.build(name,nodes=[],attributes={})
|
33
|
-
node = new(name)
|
34
|
-
nodes.each {|n| node << n}
|
35
|
-
attributes.each {|x| node[x.first.to_s] = x.last.to_s unless x.last.to_s.blank?}
|
36
|
-
node
|
37
|
-
end
|
38
31
|
end
|
39
32
|
end
|
40
33
|
end
|
data/lib/oxmlk.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
dir = File.dirname(__FILE__)
|
2
|
-
|
3
|
-
require
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
4
|
require 'activesupport'
|
5
5
|
|
6
|
+
require File.join(dir, 'oxmlk/xml')
|
7
|
+
require File.join(dir, 'oxmlk/attr')
|
8
|
+
require File.join(dir, 'oxmlk/elem')
|
9
|
+
|
6
10
|
module OxMlk
|
7
11
|
|
8
12
|
def self.included(base)
|
9
13
|
base.class_eval do
|
10
14
|
include InstanceMethods
|
11
15
|
extend ClassMethods
|
16
|
+
|
17
|
+
@ox_attrs, @ox_elems = [], []
|
12
18
|
end
|
13
19
|
end
|
14
20
|
|
@@ -19,32 +25,26 @@ module OxMlk
|
|
19
25
|
end
|
20
26
|
|
21
27
|
module ClassMethods
|
22
|
-
|
23
|
-
@ox_attrs ||= []
|
24
|
-
end
|
28
|
+
attr_accessor :ox_attrs, :ox_elems
|
25
29
|
|
26
30
|
def ox_attr(name,o={})
|
27
|
-
new_attr =
|
28
|
-
ox_attrs << new_attr
|
29
|
-
|
31
|
+
new_attr = Attr.new(name, o)
|
32
|
+
(@ox_attrs ||= []) << new_attr
|
33
|
+
attr_accessor new_attr.accessor
|
30
34
|
end
|
31
35
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def ox_elems
|
37
|
-
ox_attrs.select {|x| x.elem?}
|
36
|
+
def ox_elem(name,o={})
|
37
|
+
new_elem = Elem.new(name, o)
|
38
|
+
(@ox_elems ||= []) << new_elem
|
39
|
+
attr_accessor new_elem.accessor
|
38
40
|
end
|
39
41
|
|
40
42
|
def ox_tag(tag=false)
|
41
43
|
@ox_tag ||= (tag || self).to_s.split('::').last
|
42
44
|
end
|
43
45
|
|
44
|
-
def
|
45
|
-
|
46
|
-
ox_elems.map {|x| x.to_xml(data)}.flatten,
|
47
|
-
ox_attributes.map {|x| x.to_xml(data)} ]
|
46
|
+
def ox?
|
47
|
+
true
|
48
48
|
end
|
49
49
|
|
50
50
|
def from_xml(data)
|
@@ -52,19 +52,20 @@ module OxMlk
|
|
52
52
|
raise 'invalid XML' unless xml.name == ox_tag
|
53
53
|
|
54
54
|
ox = new
|
55
|
-
ox_attrs.each
|
56
|
-
value = a.from_xml(xml,ox)
|
57
|
-
if ox.respond_to?(a.setter)
|
58
|
-
ox.send(a.setter,value)
|
59
|
-
else
|
60
|
-
ox.instance_variable_set(a.instance_variable,value)
|
61
|
-
end
|
62
|
-
end
|
55
|
+
(ox_attrs + ox_elems).each {|e| ox.send(e.setter,e.from_xml(xml))}
|
63
56
|
ox
|
64
57
|
end
|
65
58
|
|
66
59
|
def to_xml(data)
|
67
|
-
XML::Node.
|
60
|
+
ox = XML::Node.new(ox_tag)
|
61
|
+
ox_elems.each do |elem|
|
62
|
+
elem.to_xml(data).each{|e| ox << e}
|
63
|
+
end
|
64
|
+
ox_attrs.each do |a|
|
65
|
+
val = data.send(a.accessor).to_s
|
66
|
+
ox[a.tag]= val if val.present?
|
67
|
+
end
|
68
|
+
ox
|
68
69
|
end
|
69
70
|
|
70
71
|
end
|
data/oxmlk.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{oxmlk}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Josh Robinson"]
|
12
|
-
s.date = %q{2009-
|
12
|
+
s.date = %q{2009-09-01}
|
13
13
|
s.description = %q{OxMlk gives you a simple way to map you ruby objects to XML and then convert one to the other.}
|
14
14
|
s.email = %q{hexorx@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,10 +28,12 @@ Gem::Specification.new do |s|
|
|
28
28
|
"examples/xml/example.xml",
|
29
29
|
"examples/xml/posts.xml",
|
30
30
|
"lib/oxmlk.rb",
|
31
|
-
"lib/oxmlk/
|
31
|
+
"lib/oxmlk/attr.rb",
|
32
|
+
"lib/oxmlk/elem.rb",
|
32
33
|
"lib/oxmlk/xml.rb",
|
33
34
|
"oxmlk.gemspec",
|
34
|
-
"spec/
|
35
|
+
"spec/oxmlk/attr_spec.rb",
|
36
|
+
"spec/oxmlk/elem_spec.rb",
|
35
37
|
"spec/oxmlk_spec.rb",
|
36
38
|
"spec/spec.opts",
|
37
39
|
"spec/spec_helper.rb",
|
@@ -40,10 +42,11 @@ Gem::Specification.new do |s|
|
|
40
42
|
s.homepage = %q{http://github.com/hexorx/oxmlk}
|
41
43
|
s.rdoc_options = ["--charset=UTF-8"]
|
42
44
|
s.require_paths = ["lib"]
|
43
|
-
s.rubygems_version = %q{1.3.
|
45
|
+
s.rubygems_version = %q{1.3.5}
|
44
46
|
s.summary = %q{Object 2 XML kit for ruby}
|
45
47
|
s.test_files = [
|
46
|
-
"spec/
|
48
|
+
"spec/oxmlk/attr_spec.rb",
|
49
|
+
"spec/oxmlk/elem_spec.rb",
|
47
50
|
"spec/oxmlk_spec.rb",
|
48
51
|
"spec/spec_helper.rb",
|
49
52
|
"spec/xml_spec.rb",
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe OxMlk::Attr do
|
4
|
+
describe '#accessor' do
|
5
|
+
it 'should be attr name as Symbol' do
|
6
|
+
ox_attr.accessor.should == :name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#setter' do
|
11
|
+
it 'should be name + = as Symbol' do
|
12
|
+
ox_attr.setter.should == :'name='
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#from_xml' do
|
17
|
+
it 'should return attr with name by default' do
|
18
|
+
ox_attr.from_xml('<test name="joe"/>').should == 'joe'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should return attr by :from if specified' do
|
22
|
+
ox_attr(:name, :from => 'firstName').from_xml('<test firstName="joe"/>').should == 'joe'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return type specified in :as' do
|
26
|
+
ox_attr(:age, :as => Integer).from_xml('<test age="30"/>').should == 30
|
27
|
+
ox_attr(:age, :as => Float).from_xml('<test age="30"/>').should == 30.0
|
28
|
+
ox_attr(:age, :as => String).from_xml('<test age="30"/>').should == '30'
|
29
|
+
ox_attr(:age, :as => Symbol).from_xml('<test age="30"/>').should == :'30'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return true or false if :as is :bool' do
|
33
|
+
ox_attr(:odd, :as => :bool).from_xml('<test odd="true"/>').should == true
|
34
|
+
ox_attr(:odd, :as => :bool).from_xml('<test odd="false"/>').should == false
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should act like a bool if name ends in ? and :as is not set' do
|
38
|
+
ox_attr(:odd?).from_xml('<test odd="true"/>').should == true
|
39
|
+
ox_attr(:odd?).from_xml('<test odd="false"/>').should == false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#tag' do
|
44
|
+
it 'should be :from if set' do
|
45
|
+
ox_attr(:name, :from => 'FullName').tag.should == 'FullName'
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should default to name cleaned up' do
|
49
|
+
ox_attr(:name).tag.should == 'name'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def ox_attr(name=:name,o={})
|
55
|
+
OxMlk::Attr.new(name,o)
|
56
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe OxMlk::Elem do
|
4
|
+
describe '#accessor' do
|
5
|
+
it 'should be attr name as Symbol' do
|
6
|
+
ox_elem.accessor.should == :name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#setter' do
|
11
|
+
it 'should be name + = as Symbol' do
|
12
|
+
ox_elem.setter.should == :'name='
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#ox?' do
|
17
|
+
it 'should be true if :as class is ox?' do
|
18
|
+
ox_elem(:name, :as => OxKlass).ox?.should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be true if :as is an array of ox objects' do
|
22
|
+
ox_elem(:name, :as => [OxKlass]).ox?.should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should be false if :as does not responds to ox?' do
|
26
|
+
ox_elem(:name, :as => 1).ox?.should be_false
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should be false if any of the items in :as array do not respond to from_xml' do
|
30
|
+
ox_elem(:name, :as => [OxKlass,1]).ox?.should be_false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#from_xml' do
|
35
|
+
before(:all) do
|
36
|
+
@xml = OxMlk::XML::Node.from(xml_for(:example))
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should default to :value' do
|
40
|
+
ox_elem.from_xml(@xml).should == 'Joe'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should return a :value if :as is :value' do
|
44
|
+
ox_elem(:name, :as => :value).from_xml(@xml).should == 'Joe'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return an Integer if :as is Integer' do
|
48
|
+
ox_elem(:name, :as => Integer).from_xml(@xml).should be_an(Integer)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should return an Float if :as is Float' do
|
52
|
+
ox_elem(:name, :as => Float).from_xml(@xml).should be_an(Float)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should return an Array of Integers if :as is [Integer]' do
|
56
|
+
ox_elem(:name, :as => [Integer]).from_xml(@xml).each do |x|
|
57
|
+
x.should be_an(Integer)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should run procs passed to :as' do
|
62
|
+
ox_elem(:name, :as => proc {|x| 'hi'}).from_xml(@xml).should == 'hi'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should return an OxMlk object if one is passed to :as' do
|
66
|
+
ox_elem(:name, :as => OxKlass).from_xml(@xml).should be_a(OxKlass)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should match class to ox_tag if array of ox_objects is passed to :as' do
|
70
|
+
ox_elem(:contact, :as => [Email,Number]).from_xml(@xml).first.should be_a(Number)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should turn symbol to proc if possible' do
|
74
|
+
ox_elem(:name, :as => :to_i).from_xml(@xml).should be_a(Integer)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#to_xml' do
|
79
|
+
before(:all) do
|
80
|
+
require example(:example)
|
81
|
+
@ox = Person.from_xml(xml_for(:example))
|
82
|
+
@elem = Person.ox_elems.first
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should return an Array of nodes if it is an elem' do
|
86
|
+
@elem.to_xml(@ox).should be_a(Array)
|
87
|
+
@elem.to_xml(@ox).first.should be_a(OxMlk::XML::Node)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#xpath' do
|
92
|
+
it 'should be name by default' do
|
93
|
+
ox_elem.xpath.should == 'name'
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should be the string if :from is a string' do
|
97
|
+
ox_elem(:name, :from => 'String').xpath.should == 'String'
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should be . if :from is :content' do
|
101
|
+
ox_elem(:name, :from => :content).xpath.should == '.'
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should be ox_tag if :as is a ox_object' do
|
105
|
+
ox_elem(:name, :as => OxKlass).xpath.should == 'name'
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should be list of ox_tag if :as is an array of ox_objects' do
|
109
|
+
ox_elem(:name, :as => [OxKlass,OxKlass]).xpath.should == 'name|name'
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should add :in + / to xpath if :in is passed' do
|
113
|
+
ox_elem(:name, :in => :friends).xpath.should == 'friends/name'
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should add :in + / to all items in array of ox objects' do
|
117
|
+
ox_elem(:name, :as => [OxKlass,OxKlass], :in => :friends).xpath.should == 'friends/name|friends/name'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def ox_elem(name=:name,o={})
|
123
|
+
OxMlk::Elem.new(name,o)
|
124
|
+
end
|
125
|
+
|
126
|
+
class OxKlass
|
127
|
+
include OxMlk
|
128
|
+
|
129
|
+
ox_tag :name
|
130
|
+
end
|
131
|
+
|
132
|
+
class Number
|
133
|
+
include OxMlk
|
134
|
+
|
135
|
+
ox_tag :number
|
136
|
+
end
|
137
|
+
|
138
|
+
class Email
|
139
|
+
include OxMlk
|
140
|
+
|
141
|
+
ox_tag :email
|
142
|
+
end
|
data/spec/oxmlk_spec.rb
CHANGED
@@ -40,6 +40,12 @@ describe OxMlk::InstanceMethods do
|
|
40
40
|
@oxml.to_s.should == OxMlk::XML::Node.from(@xml).to_s
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
describe '#ox?' do
|
45
|
+
it 'should return true' do
|
46
|
+
Person.ox?.should be_true
|
47
|
+
end
|
48
|
+
end
|
43
49
|
end
|
44
50
|
|
45
51
|
describe OxMlk::ClassMethods do
|
@@ -49,25 +55,31 @@ describe OxMlk::ClassMethods do
|
|
49
55
|
@klass = Person
|
50
56
|
end
|
51
57
|
|
52
|
-
describe '#
|
53
|
-
it 'should add an OxMlk::Description to the
|
54
|
-
@klass.
|
58
|
+
describe '#ox_elem' do
|
59
|
+
it 'should add an OxMlk::Description to the ox_elems list' do
|
60
|
+
@klass.ox_elems.first.should be_a(OxMlk::Elem)
|
55
61
|
end
|
56
62
|
|
57
63
|
it 'should add a reader method' do
|
58
64
|
@klass.new.should respond_to(:name)
|
59
65
|
end
|
60
66
|
|
61
|
-
it 'should add a writter method
|
67
|
+
it 'should add a writter method' do
|
62
68
|
@klass.new.should respond_to(:name=)
|
63
69
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#ox_attr' do
|
73
|
+
it 'should add an OxMlk::Attr to the ox_attrs list' do
|
74
|
+
@klass.ox_attrs.first.should be_a(OxMlk::Attr)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should add a reader method' do
|
78
|
+
@klass.new.should respond_to(:alternate)
|
67
79
|
end
|
68
80
|
|
69
|
-
it 'should add a writter method
|
70
|
-
@klass.new.should respond_to(:
|
81
|
+
it 'should add a writter method' do
|
82
|
+
@klass.new.should respond_to(:alternate=)
|
71
83
|
end
|
72
84
|
end
|
73
85
|
|
@@ -105,9 +117,9 @@ describe OxMlk::ClassMethods do
|
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
108
|
-
describe '#
|
120
|
+
describe '#ox_attrs' do
|
109
121
|
it 'should return a list of attributes' do
|
110
|
-
@klass.
|
122
|
+
@klass.ox_attrs.size.should == 2
|
111
123
|
end
|
112
124
|
end
|
113
125
|
|
data/spec/xml_spec.rb
CHANGED
@@ -38,31 +38,6 @@ describe OxMlk::XML::Node, '#from' do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
describe OxMlk::XML::Node, '#build' do
|
42
|
-
before(:all) do
|
43
|
-
@node = OxMlk::XML::Node
|
44
|
-
@nodes = [@node.new('one'),@node.new('two'),@node.new('three')]
|
45
|
-
@attributes = [[1,2],[3,4]]
|
46
|
-
@args = ['name',@nodes,@attributes]
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'should return a new node' do
|
50
|
-
@node.build(*@args).should be_a(@node)
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should set its name to the first argument' do
|
54
|
-
@node.build(*@args).name.should == 'name'
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'should set its children to second argument' do
|
58
|
-
@node.build(*@args).children.should == @nodes
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should set its attributes to the third argument' do
|
62
|
-
@node.build(*@args).should be_attributes
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
41
|
describe OxMlk::XML::Node, '#value' do
|
67
42
|
before(:all) do
|
68
43
|
@node = OxMlk::XML::Node.new('test')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oxmlk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Robinson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-01 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -63,10 +63,12 @@ files:
|
|
63
63
|
- examples/xml/example.xml
|
64
64
|
- examples/xml/posts.xml
|
65
65
|
- lib/oxmlk.rb
|
66
|
-
- lib/oxmlk/
|
66
|
+
- lib/oxmlk/attr.rb
|
67
|
+
- lib/oxmlk/elem.rb
|
67
68
|
- lib/oxmlk/xml.rb
|
68
69
|
- oxmlk.gemspec
|
69
|
-
- spec/
|
70
|
+
- spec/oxmlk/attr_spec.rb
|
71
|
+
- spec/oxmlk/elem_spec.rb
|
70
72
|
- spec/oxmlk_spec.rb
|
71
73
|
- spec/spec.opts
|
72
74
|
- spec/spec_helper.rb
|
@@ -95,12 +97,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
97
|
requirements: []
|
96
98
|
|
97
99
|
rubyforge_project:
|
98
|
-
rubygems_version: 1.3.
|
100
|
+
rubygems_version: 1.3.5
|
99
101
|
signing_key:
|
100
102
|
specification_version: 3
|
101
103
|
summary: Object 2 XML kit for ruby
|
102
104
|
test_files:
|
103
|
-
- spec/
|
105
|
+
- spec/oxmlk/attr_spec.rb
|
106
|
+
- spec/oxmlk/elem_spec.rb
|
104
107
|
- spec/oxmlk_spec.rb
|
105
108
|
- spec/spec_helper.rb
|
106
109
|
- spec/xml_spec.rb
|
data/lib/oxmlk/description.rb
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
module OxMlk
|
2
|
-
|
3
|
-
class Description
|
4
|
-
PROCESSORS = {
|
5
|
-
:value => proc {|x| x.value rescue nil},
|
6
|
-
Integer => proc {|x| x.value.to_i rescue nil},
|
7
|
-
Float => proc {|x| x.value.to_f rescue nil}
|
8
|
-
}
|
9
|
-
|
10
|
-
attr_reader :xpath
|
11
|
-
|
12
|
-
def initialize(name,o={},&block)
|
13
|
-
@froze = o.delete(:freeze)
|
14
|
-
@from = o.delete(:from)
|
15
|
-
@as = o.delete(:as)
|
16
|
-
@in = o.delete(:in)
|
17
|
-
@tag = o.delete(:tag)
|
18
|
-
@name = name.to_s
|
19
|
-
|
20
|
-
@is_attribute = computed_is_attribute
|
21
|
-
@processors = [coputed_processor, block].compact
|
22
|
-
@xpath = computed_xpath
|
23
|
-
end
|
24
|
-
|
25
|
-
def accessor
|
26
|
-
@accessor ||= @name.intern
|
27
|
-
end
|
28
|
-
|
29
|
-
def setter
|
30
|
-
:"#{accessor}="
|
31
|
-
end
|
32
|
-
|
33
|
-
def instance_variable
|
34
|
-
:"@#{accessor}"
|
35
|
-
end
|
36
|
-
|
37
|
-
def froze?
|
38
|
-
@froze ||= false
|
39
|
-
end
|
40
|
-
|
41
|
-
def writable?
|
42
|
-
!froze?
|
43
|
-
end
|
44
|
-
|
45
|
-
def attribute?
|
46
|
-
@is_attribute ||= false
|
47
|
-
end
|
48
|
-
|
49
|
-
def elem?
|
50
|
-
!attribute?
|
51
|
-
end
|
52
|
-
|
53
|
-
def ox_type
|
54
|
-
elem? ? :elem : :attribute
|
55
|
-
end
|
56
|
-
|
57
|
-
def collection?
|
58
|
-
@as.is_a?(Array)
|
59
|
-
end
|
60
|
-
|
61
|
-
def content?
|
62
|
-
@from == :content || @from == '.'
|
63
|
-
end
|
64
|
-
|
65
|
-
def ox_object?
|
66
|
-
return false if [*@as].empty?
|
67
|
-
[*@as].all? {|x| x.respond_to?(:from_xml)}
|
68
|
-
end
|
69
|
-
|
70
|
-
def process(node,instance)
|
71
|
-
@processors.inject(node) do |memo,processor|
|
72
|
-
case processor
|
73
|
-
when Proc
|
74
|
-
processor.call(memo)
|
75
|
-
when Symbol
|
76
|
-
instance.send(processor,memo)
|
77
|
-
else
|
78
|
-
processor.from_xml(memo)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def from_xml(data,instance)
|
84
|
-
xml = XML::Node.from(data)
|
85
|
-
nodes = xml.find(@xpath)
|
86
|
-
return nil if nodes.first.nil?
|
87
|
-
return process(nodes.first,instance) unless collection?
|
88
|
-
(nodes).map {|n| process(n,instance)}
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_xml(data)
|
92
|
-
value = data.send(accessor)
|
93
|
-
|
94
|
-
return [] if value.nil?
|
95
|
-
return [accessor.to_s,value.to_s] if attribute?
|
96
|
-
|
97
|
-
nodes = [*value].map do |node|
|
98
|
-
if node.respond_to?(:to_xml)
|
99
|
-
node.to_xml
|
100
|
-
elsif content?
|
101
|
-
XML::Node.new_text(node.to_s)
|
102
|
-
else
|
103
|
-
XML::Node.new(accessor, node.to_s)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
@in ? XML::Node.build(@in, nodes) : nodes
|
107
|
-
end
|
108
|
-
|
109
|
-
protected
|
110
|
-
|
111
|
-
def computed_xpath
|
112
|
-
wrap case @from
|
113
|
-
when nil
|
114
|
-
if ox_object?
|
115
|
-
[*@as].map(&:ox_tag).join('|')
|
116
|
-
elsif collection?
|
117
|
-
@name.to_s.singularize
|
118
|
-
else
|
119
|
-
@name.to_s
|
120
|
-
end
|
121
|
-
when String
|
122
|
-
@from
|
123
|
-
when :attr
|
124
|
-
"@#{accessor}"
|
125
|
-
when :content
|
126
|
-
'.'
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def computed_is_attribute
|
131
|
-
@from.to_s[0,1] == '@' || @from == :attr
|
132
|
-
end
|
133
|
-
|
134
|
-
def coputed_processor
|
135
|
-
return proc {|x| Hash[*@as.map{|o| [o.ox_tag,o]}.flatten][x.name].from_xml(x) } if collection? && ox_object?
|
136
|
-
processor = [*@as].first || :value
|
137
|
-
PROCESSORS[processor] || processor
|
138
|
-
end
|
139
|
-
|
140
|
-
def wrap(xpath=nil)
|
141
|
-
(xpath.split('|').map {|x| [@in,x].compact.join('/') }).join('|')
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
data/spec/description_spec.rb
DELETED
@@ -1,266 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
describe OxMlk::Description do
|
4
|
-
|
5
|
-
before(:all) do
|
6
|
-
require example(:example)
|
7
|
-
|
8
|
-
@xml = OxMlk::XML::Node.from(xml_for(:example))
|
9
|
-
@klass = Person
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#xpath' do
|
13
|
-
it 'should be name by default' do
|
14
|
-
@desc = OxMlk::Description.new(:name)
|
15
|
-
@desc.xpath.should == 'name'
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'should be the string if :from is a string' do
|
19
|
-
@desc = OxMlk::Description.new(:name, :from => 'String')
|
20
|
-
@desc.xpath.should == 'String'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'should be @+accessor if :from is :attr' do
|
24
|
-
@desc = OxMlk::Description.new(:name, :from => :attr)
|
25
|
-
@desc.xpath.should == '@name'
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should be . if :from is :content' do
|
29
|
-
@desc = OxMlk::Description.new(:name, :from => :content)
|
30
|
-
@desc.xpath.should == '.'
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should be singular if plural name and is a collection' do
|
34
|
-
@desc = OxMlk::Description.new(:numbers, :as => [])
|
35
|
-
@desc.xpath.should == 'number'
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should be ox_tag if :as is a ox_object' do
|
39
|
-
@desc = OxMlk::Description.new(:digits, :as => Number)
|
40
|
-
@desc.xpath.should == 'number'
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'should be list of ox_tag if :as is an array of ox_objects' do
|
44
|
-
@desc = OxMlk::Description.new(:digits, :as => [Number,Person])
|
45
|
-
@desc.xpath.should == 'number|person'
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'should add :in + / to xpath if :in is passed' do
|
49
|
-
@desc = OxMlk::Description.new(:person, :in => :friends)
|
50
|
-
@desc.xpath.should == 'friends/person'
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should add :in + / to all items in array of ox_objetcs' do
|
54
|
-
@desc = OxMlk::Description.new(:digits, :as => [Number,Person], :in => :friends)
|
55
|
-
@desc.xpath.should == 'friends/number|friends/person'
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe '#accessor' do
|
60
|
-
it 'should be attr name as Symbol' do
|
61
|
-
@desc = OxMlk::Description.new(:name)
|
62
|
-
@desc.accessor.should == :name
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe '#setter' do
|
67
|
-
it 'should be accessor with = on the end' do
|
68
|
-
@desc = OxMlk::Description.new(:name)
|
69
|
-
@desc.setter.should == :'name='
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#instance_variable' do
|
74
|
-
it 'should be accessor with @ on the front' do
|
75
|
-
@desc = OxMlk::Description.new(:name)
|
76
|
-
@desc.instance_variable.should == :'@name'
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe '#writable?' do
|
81
|
-
it 'should be true by default' do
|
82
|
-
@desc = OxMlk::Description.new(:name)
|
83
|
-
@desc.writable?.should be_true
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'should be true if :freeze is false' do
|
87
|
-
@desc = OxMlk::Description.new(:name, :freeze => false)
|
88
|
-
@desc.writable?.should be_true
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'should be false if :freeze is true' do
|
92
|
-
@desc = OxMlk::Description.new(:name, :freeze => true)
|
93
|
-
@desc.writable?.should be_false
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
describe '#attribute?' do
|
98
|
-
it 'should be true if :from starts with @' do
|
99
|
-
@desc = OxMlk::Description.new(:name, :from => '@name')
|
100
|
-
@desc.attribute?.should be_true
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'should be true if :from is :attribute' do
|
104
|
-
@desc = OxMlk::Description.new(:name, :from => :attr)
|
105
|
-
@desc.attribute?.should be_true
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
describe '#elem?' do
|
110
|
-
it 'should be true if attribute? is false' do
|
111
|
-
@desc = OxMlk::Description.new(:name)
|
112
|
-
@desc.elem?.should be_true
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'should be false if attribute? is true' do
|
116
|
-
@desc = OxMlk::Description.new(:name, :from => :attr)
|
117
|
-
@desc.elem?.should be_false
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe '#ox_type' do
|
122
|
-
it 'should be :elem if elem? is true' do
|
123
|
-
@desc = OxMlk::Description.new(:name)
|
124
|
-
@desc.ox_type.should == :elem
|
125
|
-
end
|
126
|
-
|
127
|
-
it 'should be :attribute if attribute? is true' do
|
128
|
-
@desc = OxMlk::Description.new(:name, :from => :attr)
|
129
|
-
@desc.ox_type.should == :attribute
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
describe '#collection?' do
|
134
|
-
it 'should be true if :as is an Array' do
|
135
|
-
@desc = OxMlk::Description.new(:name, :as => [])
|
136
|
-
@desc.collection?.should be_true
|
137
|
-
end
|
138
|
-
|
139
|
-
it 'should be false if :as is not Array' do
|
140
|
-
@desc = OxMlk::Description.new(:name)
|
141
|
-
@desc.collection?.should be_false
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe '#ox_object?' do
|
146
|
-
it 'should be true if :as responds to from_xml' do
|
147
|
-
@desc = OxMlk::Description.new(:number, :as => Person)
|
148
|
-
@desc.ox_object?.should be_true
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'should be true if :as is an array of objects that respond to from_xml' do
|
152
|
-
@desc = OxMlk::Description.new(:number, :as => [Person,Number])
|
153
|
-
@desc.ox_object?.should be_true
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'should be false if :as does not responds to from_xml' do
|
157
|
-
@desc = OxMlk::Description.new(:number, :as => 1)
|
158
|
-
@desc.ox_object?.should be_false
|
159
|
-
end
|
160
|
-
|
161
|
-
it 'should be false if any of the items in :as array do not respond to from_xml' do
|
162
|
-
@desc = OxMlk::Description.new(:number, :as => [Person,Number,1])
|
163
|
-
@desc.ox_object?.should be_false
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
describe '#content?' do
|
168
|
-
it 'should return true if :from is :content' do
|
169
|
-
@desc = OxMlk::Description.new(:number, :from => :content)
|
170
|
-
@desc.content?.should be_true
|
171
|
-
end
|
172
|
-
|
173
|
-
it 'should return true if :from is "."' do
|
174
|
-
@desc = OxMlk::Description.new(:number, :from => '.')
|
175
|
-
@desc.content?.should be_true
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'should return false if :from is nil' do
|
179
|
-
@desc = OxMlk::Description.new(:number)
|
180
|
-
@desc.content?.should be_false
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'should return false if :from is string other than "."' do
|
184
|
-
@desc = OxMlk::Description.new(:number, :from => 'hi')
|
185
|
-
@desc.content?.should be_false
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
describe '#from_xml' do
|
190
|
-
|
191
|
-
it 'should accept xml argument' do
|
192
|
-
@desc = OxMlk::Description.new(:name)
|
193
|
-
@desc.from_xml(@xml, @klass.new).should be_a(String)
|
194
|
-
end
|
195
|
-
|
196
|
-
it 'should return an array if :as is an array' do
|
197
|
-
@desc = OxMlk::Description.new(:name, :as => [])
|
198
|
-
@desc.from_xml(@xml, @klass.new).should be_an(Array)
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'should return a String if :as is :value' do
|
202
|
-
@desc = OxMlk::Description.new(:name, :as => :value)
|
203
|
-
@desc.from_xml(@xml, @klass.new).should be_an(String)
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'should return a String if :as is nil' do
|
207
|
-
@desc = OxMlk::Description.new(:name)
|
208
|
-
@desc.from_xml(@xml, @klass.new).should be_an(String)
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'should return an Integer if :as is Integer' do
|
212
|
-
@desc = OxMlk::Description.new(:name, :as => Integer)
|
213
|
-
@desc.from_xml(@xml, @klass.new).should be_an(Integer)
|
214
|
-
end
|
215
|
-
|
216
|
-
it 'should return an Float if :as is Float' do
|
217
|
-
@desc = OxMlk::Description.new(:name, :as => Float)
|
218
|
-
@desc.from_xml(@xml, @klass.new).should be_an(Float)
|
219
|
-
end
|
220
|
-
|
221
|
-
it 'should return an Array of Integers if :as is [Integer]' do
|
222
|
-
@desc = OxMlk::Description.new(:name, :as => [Integer])
|
223
|
-
@desc.from_xml(@xml, @klass.new).each do |x|
|
224
|
-
x.should be_an(Integer)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
it 'should run procs passed to :as' do
|
229
|
-
@desc = OxMlk::Description.new(:name, :as => proc {|x| 'hi'})
|
230
|
-
@desc.from_xml(@xml, @klass.new).should == 'hi'
|
231
|
-
end
|
232
|
-
|
233
|
-
it 'should run method when symbol is passed to :as' do
|
234
|
-
@desc = OxMlk::Description.new(:name, :as => :say_hello)
|
235
|
-
@desc.from_xml(@xml, @klass.new).should == 'hello'
|
236
|
-
end
|
237
|
-
|
238
|
-
it 'should return an OxMlk object if one is passed to :as' do
|
239
|
-
@desc = OxMlk::Description.new(:number, :as => Number)
|
240
|
-
@desc.from_xml(@xml, @klass.new).should be_a(Number)
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'should match class to ox_tag if array of ox_objects is passed to :as' do
|
244
|
-
@desc = OxMlk::Description.new(:contact, :as => [Number,Email])
|
245
|
-
@desc.from_xml(@xml, @klass.new).first.should be_a(Number)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
describe '#to_xml' do
|
250
|
-
before(:all) do
|
251
|
-
@ox = Person.from_xml(@xml)
|
252
|
-
@attr = Person.ox_attributes.first
|
253
|
-
@elem = Person.ox_elems.first
|
254
|
-
end
|
255
|
-
|
256
|
-
it 'should return an Array of Strings if it is an attribute' do
|
257
|
-
@attr.to_xml(@ox).should be_a(Array)
|
258
|
-
@attr.to_xml(@ox).first.should be_a(String)
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'should return an Array of nodes if it is an elem' do
|
262
|
-
@elem.to_xml(@ox).should be_a(Array)
|
263
|
-
@elem.to_xml(@ox).first.should be_a(OxMlk::XML::Node)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|