oxmlk 0.1.0 → 0.2.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 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