oxmlk 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -3,6 +3,7 @@ class Number
3
3
 
4
4
  ox_tag :number
5
5
 
6
+ ox_attr :group, :from => :attr
6
7
  ox_attr(:value, :from => :content)
7
8
  end
8
9
 
@@ -11,6 +12,7 @@ class Email
11
12
 
12
13
  ox_tag :email
13
14
 
15
+ ox_attr :group, :from => :attr
14
16
  ox_attr(:value, :from => :content)
15
17
  end
16
18
 
@@ -20,11 +22,11 @@ class Person
20
22
  ox_tag :person
21
23
 
22
24
  ox_attr(:category, :from => :attr)
23
- ox_attr(:two_attr, :from => '@attr2')
25
+ ox_attr(:alt, :from => '@alt')
24
26
 
25
27
  ox_attr(:name)
26
- ox_attr(:numbers, :as => [Number], :freeze => false)
27
28
  ox_attr(:contacts, :as => [Number,Email], :freeze => true)
29
+ ox_attr(:friends, :as => [Person], :in => :friends, :freeze => false)
28
30
 
29
31
  def say_hello(xml)
30
32
  'hello'
@@ -1,4 +1,4 @@
1
- <person category="meat_popsicle">
1
+ <person category="meat_popsicle" alt="human">
2
2
  <name>Joe</name>
3
3
  <number group="main">3035551212</number>
4
4
  <number group="cell">3035551234</number>
@@ -6,11 +6,19 @@ require 'activesupport'
6
6
  module OxMlk
7
7
 
8
8
  def self.included(base)
9
- base.extend ClassMethods
9
+ base.class_eval do
10
+ include InstanceMethods
11
+ extend ClassMethods
12
+ end
13
+ end
14
+
15
+ module InstanceMethods
16
+ def to_xml
17
+ self.class.to_xml(self)
18
+ end
10
19
  end
11
20
 
12
21
  module ClassMethods
13
-
14
22
  def ox_attrs
15
23
  @ox_attrs ||= []
16
24
  end
@@ -21,9 +29,26 @@ module OxMlk
21
29
  attr new_attr.accessor, new_attr.writable?
22
30
  end
23
31
 
32
+ def ox_attributes
33
+ ox_attrs.select {|x| x.attribute?}
34
+ end
35
+
36
+ def ox_elems
37
+ ox_attrs.select {|x| x.elem?}
38
+ end
39
+
40
+ def ox_tag(tag=false)
41
+ @ox_tag ||= (tag || self).to_s
42
+ end
43
+
44
+ def xml_array(data)
45
+ [ ox_tag,
46
+ ox_elems.map {|x| x.to_xml(data)}.flatten,
47
+ ox_attributes.map {|x| x.to_xml(data)} ]
48
+ end
49
+
24
50
  def from_xml(data)
25
51
  xml = XML::Node.from(data)
26
- p [xml.name, ox_tag]
27
52
  raise 'invalid XML' unless xml.name == ox_tag
28
53
 
29
54
  ox = new
@@ -38,16 +63,8 @@ module OxMlk
38
63
  ox
39
64
  end
40
65
 
41
- def ox_attributes
42
- ox_attrs.select {|x| x.attribute?}
43
- end
44
-
45
- def ox_elems
46
- ox_attrs.select {|x| x.elem?}
47
- end
48
-
49
- def ox_tag(tag=false)
50
- @ox_tag ||= (tag || self).to_s
66
+ def to_xml(data)
67
+ XML::Node.build(*xml_array(data))
51
68
  end
52
69
 
53
70
  end
@@ -18,7 +18,8 @@ module OxMlk
18
18
  @froze = o.delete(:freeze)
19
19
  @from = o.delete(:from)
20
20
  @as = o.delete(:as)
21
- @wrapper = o.delete(:wrapper)
21
+ @in = o.delete(:in)
22
+ @tag = o.delete(:tag)
22
23
  @name = name.to_s
23
24
 
24
25
  @is_attribute = computed_is_attribute
@@ -62,6 +63,10 @@ module OxMlk
62
63
  @as.is_a?(Array)
63
64
  end
64
65
 
66
+ def content?
67
+ @from == :content || @from == '.'
68
+ end
69
+
65
70
  def ox_object?
66
71
  return false if [*@as].empty?
67
72
  [*@as].all? {|x| x.respond_to?(:from_xml)}
@@ -88,6 +93,24 @@ module OxMlk
88
93
  (nodes).map {|n| process(n,instance)}
89
94
  end
90
95
 
96
+ def to_xml(data)
97
+ value = data.send(accessor)
98
+
99
+ return [] if value.nil?
100
+ return [accessor.to_s,value.to_s] if attribute?
101
+
102
+ nodes = [*value].map do |node|
103
+ if node.respond_to?(:to_xml)
104
+ node.to_xml
105
+ elsif content?
106
+ XML::Node.new_text(node.to_s)
107
+ else
108
+ XML::Node.new(accessor, node.to_s)
109
+ end
110
+ end
111
+ @in ? XML::Node.build(@in, nodes) : nodes
112
+ end
113
+
91
114
  protected
92
115
 
93
116
  def computed_xpath
@@ -120,7 +143,7 @@ module OxMlk
120
143
  end
121
144
 
122
145
  def wrap(xpath=nil)
123
- [@wrapper,xpath].compact.join('/')
146
+ [@in,xpath].compact.join('/')
124
147
  end
125
148
  end
126
149
  end
@@ -26,6 +26,13 @@ module OxMlk
26
26
  raise 'Invalid XML data'
27
27
  end
28
28
  end
29
+
30
+ def self.build(name,nodes=[],attributes={})
31
+ node = new(name)
32
+ nodes.each {|n| node << n}
33
+ attributes.each {|x| node[x.first.to_s] = x.last.to_s unless x.last.to_s.blank?}
34
+ node
35
+ end
29
36
  end
30
37
  end
31
38
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{oxmlk}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.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-08-24}
12
+ s.date = %q{2009-08-26}
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 = [
@@ -9,7 +9,7 @@ describe OxMlk::Description do
9
9
  @klass = Person
10
10
  end
11
11
 
12
- describe 'xpath' do
12
+ describe '#xpath' do
13
13
  it 'should be name by default' do
14
14
  @desc = OxMlk::Description.new(:name)
15
15
  @desc.xpath.should == 'name'
@@ -45,34 +45,34 @@ describe OxMlk::Description do
45
45
  @desc.xpath.should == 'number|person'
46
46
  end
47
47
 
48
- it 'should add wrapper + / to xpath if wrapper is passed' do
49
- @desc = OxMlk::Description.new(:person, :wrapper => :friends)
48
+ it 'should add in + / to xpath if :in is passed' do
49
+ @desc = OxMlk::Description.new(:person, :in => :friends)
50
50
  @desc.xpath.should == 'friends/person'
51
51
  end
52
52
  end
53
53
 
54
- describe 'accessor' do
54
+ describe '#accessor' do
55
55
  it 'should be attr name as Symbol' do
56
56
  @desc = OxMlk::Description.new(:name)
57
57
  @desc.accessor.should == :name
58
58
  end
59
59
  end
60
60
 
61
- describe 'setter' do
61
+ describe '#setter' do
62
62
  it 'should be accessor with = on the end' do
63
63
  @desc = OxMlk::Description.new(:name)
64
64
  @desc.setter.should == :'name='
65
65
  end
66
66
  end
67
67
 
68
- describe 'instance_variable' do
68
+ describe '#instance_variable' do
69
69
  it 'should be accessor with @ on the front' do
70
70
  @desc = OxMlk::Description.new(:name)
71
71
  @desc.instance_variable.should == :'@name'
72
72
  end
73
73
  end
74
74
 
75
- describe 'writable?' do
75
+ describe '#writable?' do
76
76
  it 'should be true by default' do
77
77
  @desc = OxMlk::Description.new(:name)
78
78
  @desc.writable?.should be_true
@@ -89,7 +89,7 @@ describe OxMlk::Description do
89
89
  end
90
90
  end
91
91
 
92
- describe 'attribute?' do
92
+ describe '#attribute?' do
93
93
  it 'should be true if :from starts with @' do
94
94
  @desc = OxMlk::Description.new(:name, :from => '@name')
95
95
  @desc.attribute?.should be_true
@@ -101,7 +101,7 @@ describe OxMlk::Description do
101
101
  end
102
102
  end
103
103
 
104
- describe 'elem?' do
104
+ describe '#elem?' do
105
105
  it 'should be true if attribute? is false' do
106
106
  @desc = OxMlk::Description.new(:name)
107
107
  @desc.elem?.should be_true
@@ -113,7 +113,7 @@ describe OxMlk::Description do
113
113
  end
114
114
  end
115
115
 
116
- describe 'ox_type' do
116
+ describe '#ox_type' do
117
117
  it 'should be :elem if elem? is true' do
118
118
  @desc = OxMlk::Description.new(:name)
119
119
  @desc.ox_type.should == :elem
@@ -125,7 +125,7 @@ describe OxMlk::Description do
125
125
  end
126
126
  end
127
127
 
128
- describe 'collection?' do
128
+ describe '#collection?' do
129
129
  it 'should be true if :as is an Array' do
130
130
  @desc = OxMlk::Description.new(:name, :as => [])
131
131
  @desc.collection?.should be_true
@@ -137,7 +137,7 @@ describe OxMlk::Description do
137
137
  end
138
138
  end
139
139
 
140
- describe 'ox_object?' do
140
+ describe '#ox_object?' do
141
141
  it 'should be true if :as responds to from_xml' do
142
142
  @desc = OxMlk::Description.new(:number, :as => Person)
143
143
  @desc.ox_object?.should be_true
@@ -159,7 +159,29 @@ describe OxMlk::Description do
159
159
  end
160
160
  end
161
161
 
162
- describe 'from_xml' do
162
+ describe '#content?' do
163
+ it 'should return true if :from is :content' do
164
+ @desc = OxMlk::Description.new(:number, :from => :content)
165
+ @desc.content?.should be_true
166
+ end
167
+
168
+ it 'should return true if :from is "."' do
169
+ @desc = OxMlk::Description.new(:number, :from => '.')
170
+ @desc.content?.should be_true
171
+ end
172
+
173
+ it 'should return false if :from is nil' do
174
+ @desc = OxMlk::Description.new(:number)
175
+ @desc.content?.should be_false
176
+ end
177
+
178
+ it 'should return false if :from is string other than "."' do
179
+ @desc = OxMlk::Description.new(:number, :from => 'hi')
180
+ @desc.content?.should be_false
181
+ end
182
+ end
183
+
184
+ describe '#from_xml' do
163
185
 
164
186
  it 'should accept xml argument' do
165
187
  @desc = OxMlk::Description.new(:name)
@@ -218,4 +240,22 @@ describe OxMlk::Description do
218
240
  @desc.from_xml(@xml, @klass.new).first.should be_a(Number)
219
241
  end
220
242
  end
243
+
244
+ describe '#to_xml' do
245
+ before(:all) do
246
+ @ox = Person.from_xml(@xml)
247
+ @attr = Person.ox_attributes.first
248
+ @elem = Person.ox_elems.first
249
+ end
250
+
251
+ it 'should return an Array of Strings if it is an attribute' do
252
+ @attr.to_xml(@ox).should be_a(Array)
253
+ @attr.to_xml(@ox).first.should be_a(String)
254
+ end
255
+
256
+ it 'should return an Array of nodes if it is an elem' do
257
+ @elem.to_xml(@ox).should be_a(Array)
258
+ @elem.to_xml(@ox).first.should be_a(OxMlk::XML::Node)
259
+ end
260
+ end
221
261
  end
@@ -1,37 +1,53 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe OxMlk do
3
+ describe OxMlk::InstanceMethods do
4
4
 
5
5
  before(:all) do
6
6
  require example(:example)
7
- @klass = Person
7
+ @xml = xml_for(:example)
8
+ @ox = Person.from_xml(@xml)
8
9
  end
9
10
 
10
- describe 'being included into another class' do
11
- it 'should set ox_attrs to an array' do
12
- @klass.ox_attrs.should be_a(Array)
11
+ describe '#to_xml' do
12
+ before(:all) do
13
+ @oxml = @ox.to_xml
14
+ @doc = OxMlk::XML::Document.new
15
+ @doc.root = @oxml
13
16
  end
14
17
 
15
- it 'should add an ox_attr method' do
16
- @klass.should respond_to(:ox_attr)
18
+ it 'should return a XML::Node' do
19
+ @oxml.should be_a(OxMlk::XML::Node)
17
20
  end
18
21
 
19
- it 'should add a from_xml method' do
20
- @klass.should respond_to(:from_xml)
22
+ it 'should set name to Class.ox_tag' do
23
+ @oxml.name.should == 'person'
21
24
  end
22
-
23
- it 'should add an ox_attributes method' do
24
- @klass.should respond_to(:ox_attributes)
25
+
26
+ it 'should set elements' do
27
+ @oxml.children.map(&:name).should == ['name','number','number','email','friends']
28
+ end
29
+
30
+ it 'should set content to text node' do
31
+ @oxml.find_first('number').child.should be_text
25
32
  end
26
33
 
27
- it 'should add an ox_elems method' do
28
- @klass.should respond_to(:ox_elems)
34
+ it 'should set attributes' do
35
+ @oxml['category'].should == 'meat_popsicle'
36
+ @oxml['alt'].should == 'human'
29
37
  end
30
38
 
31
- it 'should add a tag_name method' do
32
- @klass.should respond_to(:ox_tag)
39
+ it 'should produce same xml as created it' do
40
+ @oxml.to_s.should == OxMlk::XML::Node.from(@xml).to_s
33
41
  end
34
42
  end
43
+ end
44
+
45
+ describe OxMlk::ClassMethods do
46
+
47
+ before(:all) do
48
+ require example(:example)
49
+ @klass = Person
50
+ end
35
51
 
36
52
  describe '#ox_attr' do
37
53
  it 'should add an OxMlk::Description to the class' do
@@ -46,12 +62,12 @@ describe OxMlk do
46
62
  @klass.new.should respond_to(:name=)
47
63
  end
48
64
 
49
- it 'should add a writter method when :freeze => false' do
50
- @klass.new.should respond_to(:numbers=)
65
+ it 'should add not a writter method when :freeze => true' do
66
+ @klass.new.should_not respond_to(:contacts=)
51
67
  end
52
68
 
53
- it 'should not add a writter method when :freeze => true' do
54
- @klass.new.should_not respond_to(:contacts=)
69
+ it 'should add a writter method when :freeze => false' do
70
+ @klass.new.should respond_to(:friends=)
55
71
  end
56
72
  end
57
73
 
@@ -79,13 +95,13 @@ describe OxMlk do
79
95
  @example.category.should == 'meat_popsicle'
80
96
  end
81
97
 
82
- it 'should fetch numbers' do
83
- @example.numbers.map(&:value).should == ['3035551212','3035551234']
84
- end
85
-
86
98
  it 'should fetch contacts' do
87
99
  @example.contacts.map(&:value).should == ['3035551212','3035551234','test@example.com']
88
100
  end
101
+
102
+ it 'should fetch friends' do
103
+ @example.friends.map(&:name).should == ['Bob','John']
104
+ end
89
105
  end
90
106
  end
91
107
 
@@ -36,5 +36,29 @@ describe OxMlk::XML::Node, '#from' do
36
36
  data = File.open(@xml).read
37
37
  OxMlk::XML::Node.from(data).should be_a(OxMlk::XML::Node)
38
38
  end
39
+ end
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
39
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
40
64
  end
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.1.0
4
+ version: 0.2.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-08-24 00:00:00 -06:00
12
+ date: 2009-08-26 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency