oxmlk 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|