xommelier 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -105,6 +105,75 @@ will output:
105
105
  </feed>
106
106
  ```
107
107
 
108
+ ### Building from hash
109
+
110
+ ```ruby
111
+ feed = Xommelier::Atom::Feed.new(
112
+ {
113
+ title: 'Xommelier nest elements',
114
+ subtitle: 'Xommelier is able to build complex objects from very nested hash',
115
+ author: {name: 'Alexander', email: 'al@semyonov.us'},
116
+ updated: Time.utc(2012, 04, 04, 04, 04),
117
+ contributors: [
118
+ {name: 'Ivan', email: 'ivan@example.com'},
119
+ {name: 'Pyotr', email: 'pyotr@example.com'},
120
+ {name: 'Sidor', email: 'sidor@example.com'},
121
+ ],
122
+ entries: [
123
+ {title: 'First article', updated: Time.utc(2012, 01, 01, 01, 01)},
124
+ {title: 'Second article', updated: Time.utc(2012, 02, 02, 02, 02)},
125
+ {title: 'Third article', updated: Time.utc(2012, 03, 03, 03, 03)},
126
+ ]
127
+ }
128
+ )
129
+
130
+ feed.author # Xommelier::Atom::Person
131
+ feed.contributors[1] # Xommelier::Atom::Person
132
+ feed.entries[2] # Xommelier::Atom::Entry
133
+
134
+ puts feed.to_xml
135
+ ```
136
+
137
+ will output
138
+
139
+ ```xml
140
+ <?xml version="1.0" encoding="utf-8"?>
141
+ <feed xmlns="http://www.w3.org/2005/Atom">
142
+ <title>Xommelier nest elements</title>
143
+ <subtitle>Xommelier is able to build complex objects from very nested hash</subtitle>
144
+ <author>
145
+ <name>Alexander</name>
146
+ <email>al@semyonov.us</email>
147
+ </author>
148
+ <updated>2012-04-04T04:04:00Z</updated>
149
+ <contributor>
150
+ <name>Ivan</name>
151
+ <email>ivan@example.com</email>
152
+ </contributor>
153
+ <contributor>
154
+ <name>Pyotr</name>
155
+ <email>pyotr@example.com</email>
156
+ </contributor>
157
+ <contributor>
158
+ <name>Sidor</name>
159
+ <email>sidor@example.com</email>
160
+ </contributor>
161
+ <entry>
162
+ <title>First article</title>
163
+ <updated>2012-01-01T01:01:00Z</updated>
164
+ </entry>
165
+ <entry>
166
+ <title>Second article</title>
167
+ <updated>2012-02-02T02:02:00Z</updated>
168
+ </entry>
169
+ <entry>
170
+ <title>Third article</title>
171
+ <updated>2012-03-03T03:03:00Z</updated>
172
+ </entry>
173
+ </feed>
174
+ ```
175
+
176
+
108
177
  ## TODO
109
178
 
110
179
  * Validating built XML against RelaxNG and XML Schema
data/Termfile CHANGED
@@ -3,23 +3,21 @@
3
3
  #setup 'bundle'
4
4
 
5
5
  def title(title)
6
- run "echo -e \"\\033];#{title}\\007\""
6
+ run %(echo -e "\\033];#{title}\\007" && clear)
7
7
  end
8
8
 
9
9
  title 'Editor'
10
- run 'vim Gemfile'
10
+ run 'vim Gemfile && clear'
11
11
 
12
12
  tab(:bash) do
13
13
  title('Shell')
14
14
  end
15
- #tab(:log) do
16
- #title 'Logs'
17
- #run 'tail -f log/development.log'
18
- #end
19
- tab :guard do
15
+
16
+ tab(:guard) do
20
17
  title 'Guard'
21
18
  run 'guard'
22
19
  end
20
+
23
21
  tab(:console) do
24
22
  title 'Console'
25
23
  run './console'
@@ -1,3 +1,3 @@
1
1
  module Xommelier
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  end
@@ -73,7 +73,7 @@ module Xommelier
73
73
  hash
74
74
  end
75
75
  attribute_values.delete("xmlns:#{xmlns.as.to_s}")
76
- attribute_values.delete("xmlns:xml")
76
+ attribute_values.delete('xmlns:xml')
77
77
  namespaces = attribute_values
78
78
  prefix = nil
79
79
  end
@@ -103,6 +103,25 @@ module Xommelier
103
103
  end
104
104
  alias_method :to_xommelier, :to_xml
105
105
 
106
+ def to_hash
107
+ attributes.dup.tap do |hash|
108
+ @elements.each do |name, value|
109
+ options = element_options(name)
110
+ type = options[:type]
111
+ value = Array.wrap(value)
112
+ if type < Xml::Element
113
+ value = value.map(&:to_hash)
114
+ end
115
+ if value.count > 1
116
+ name = name.to_s.pluralize.to_sym
117
+ else
118
+ value = value.first
119
+ end
120
+ hash[name] = value
121
+ end
122
+ end
123
+ end
124
+
106
125
  protected
107
126
 
108
127
  def element_xpath(xmldoc = self.xml_document, name = nil)
@@ -151,7 +170,7 @@ module Xommelier
151
170
  end
152
171
 
153
172
  def typecast_element(type, node, options)
154
- if type < Xommelier::Xml::Element
173
+ if type < Xml::Element
155
174
  type.from_xommelier(xml_document, options.merge(node: node))
156
175
  else
157
176
  type.from_xommelier(node.text)
@@ -131,7 +131,9 @@ module Xommelier
131
131
 
132
132
  define_method(plural) do |*args|
133
133
  if args.any?
134
- @elements[name] = args.flatten
134
+ args.flatten.each_with_index do |object, index|
135
+ write_element(name, object, index)
136
+ end
135
137
  end
136
138
  @elements[name] ||= []
137
139
  end
@@ -184,11 +186,11 @@ module Xommelier
184
186
  self.class.elements[name.to_sym]
185
187
  end
186
188
 
187
- def read_element(name)
188
- @elements[name.to_sym]
189
+ def read_element(name, index = nil)
190
+ index ? @elements[name.to_sym][index] : @elements[name.to_sym]
189
191
  end
190
192
 
191
- def write_element(name, value)
193
+ def write_element(name, value, index = nil)
192
194
  type = element_options(name)[:type]
193
195
  unless value.is_a?(type)
194
196
  value = if (type < Xommelier::Xml::Element) && !value.is_a?(Nokogiri::XML::Node)
@@ -197,7 +199,12 @@ module Xommelier
197
199
  type.from_xommelier(value)
198
200
  end
199
201
  end
200
- @elements[name.to_sym] = value
202
+ if index
203
+ @elements[name.to_sym] ||= []
204
+ @elements[name.to_sym][index] = value
205
+ else
206
+ @elements[name.to_sym] = value
207
+ end
201
208
  end
202
209
 
203
210
  def remove_element(name)
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <feed xmlns="http://www.w3.org/2005/Atom">
3
+ <title>Xommelier nest elements</title>
4
+ <subtitle>Xommelier is able to build complex objects from very nested hash</subtitle>
5
+ <author>
6
+ <name>Alexander</name>
7
+ <email>al@semyonov.us</email>
8
+ </author>
9
+ <updated>2012-04-04T04:04:00Z</updated>
10
+ <contributor>
11
+ <name>Artyom</name>
12
+ <email>sevenov@gmail.com</email>
13
+ </contributor>
14
+ <contributor>
15
+ <name>Ivan</name>
16
+ <email>ivan@example.com</email>
17
+ </contributor>
18
+ <contributor>
19
+ <name>Pyotr</name>
20
+ <email>pyotr@example.com</email>
21
+ </contributor>
22
+ <entry>
23
+ <title>First article</title>
24
+ <updated>2012-01-01T01:01:00Z</updated>
25
+ </entry>
26
+ <entry>
27
+ <title>Second article</title>
28
+ <updated>2012-02-02T02:02:00Z</updated>
29
+ </entry>
30
+ <entry>
31
+ <title>Third article</title>
32
+ <updated>2012-03-03T03:03:00Z</updated>
33
+ </entry>
34
+ </feed>
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Build document from nested hash' do
4
+ let(:hash) do
5
+ {
6
+ title: 'Xommelier nest elements',
7
+ subtitle: 'Xommelier is able to build complex objects from very nested hash',
8
+ author: {name: 'Alexander', email: 'al@semyonov.us'},
9
+ updated: Time.utc(2012, 04, 04, 04, 04),
10
+ contributors: [
11
+ {name: 'Artyom', email: 'sevenov@gmail.com'},
12
+ {name: 'Ivan', email: 'ivan@example.com'},
13
+ {name: 'Pyotr', email: 'pyotr@example.com'},
14
+ ],
15
+ entries: [
16
+ {title: 'First article', updated: Time.utc(2012, 01, 01, 01, 01)},
17
+ {title: 'Second article', updated: Time.utc(2012, 02, 02, 02, 02)},
18
+ {title: 'Third article', updated: Time.utc(2012, 03, 03, 03, 03)},
19
+ ]
20
+ }
21
+ end
22
+
23
+ let(:doc) do
24
+ Xommelier::Atom::Feed.new(hash)
25
+ end
26
+
27
+ subject { doc }
28
+
29
+ its(:to_xml) { should == load_xml_file('nested_atom').read }
30
+ it { should have(1).authors }
31
+ it { should have(3).contributors }
32
+ it { should have(3).entries }
33
+
34
+ it { doc.author.should be_an(Xommelier::Atom::Person) }
35
+ it { doc.contributors[2].should be_an(Xommelier::Atom::Person) }
36
+ it { doc.entries[1].should be_an(Xommelier::Atom::Entry) }
37
+
38
+ its(:to_hash) { should == hash}
39
+ end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Xommelier do
4
- it { Xommelier::VERSION.should == '0.1.5' }
4
+ it { Xommelier::VERSION.should == '0.1.6' }
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xommelier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-05 00:00:00.000000000 Z
12
+ date: 2012-03-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &70275292162600 !ruby/object:Gem::Requirement
16
+ requirement: &70238176342500 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.5.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70275292162600
24
+ version_requirements: *70238176342500
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &70275292149460 !ruby/object:Gem::Requirement
27
+ requirement: &70238176254700 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 3.2.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70275292149460
35
+ version_requirements: *70238176254700
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activemodel
38
- requirement: &70275292120260 !ruby/object:Gem::Requirement
38
+ requirement: &70238176252980 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 3.2.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70275292120260
46
+ version_requirements: *70238176252980
47
47
  description: XML-Object Mapper with many built-in XML formats supported
48
48
  email:
49
49
  - al@semyonov.us
@@ -97,10 +97,12 @@ files:
97
97
  - spec/fixtures/atom.xsd.xml
98
98
  - spec/fixtures/feed.atom.xml
99
99
  - spec/fixtures/multi_namespace_feed.atom.xml
100
+ - spec/fixtures/nested_atom.xml
100
101
  - spec/fixtures/simple_feed.atom.xml
101
102
  - spec/functional/atom_feed_building_spec.rb
102
103
  - spec/functional/atom_feed_parsing_spec.rb
103
104
  - spec/functional/atom_feed_thread_building_spec.rb
105
+ - spec/functional/build_nested_document_from_hash_spec.rb
104
106
  - spec/lib/xommelier/atom/entry_spec.rb
105
107
  - spec/lib/xommelier/xml/element/serialization_spec.rb
106
108
  - spec/lib/xommelier/xml/element/structure_spec.rb
@@ -140,10 +142,12 @@ test_files:
140
142
  - spec/fixtures/atom.xsd.xml
141
143
  - spec/fixtures/feed.atom.xml
142
144
  - spec/fixtures/multi_namespace_feed.atom.xml
145
+ - spec/fixtures/nested_atom.xml
143
146
  - spec/fixtures/simple_feed.atom.xml
144
147
  - spec/functional/atom_feed_building_spec.rb
145
148
  - spec/functional/atom_feed_parsing_spec.rb
146
149
  - spec/functional/atom_feed_thread_building_spec.rb
150
+ - spec/functional/build_nested_document_from_hash_spec.rb
147
151
  - spec/lib/xommelier/atom/entry_spec.rb
148
152
  - spec/lib/xommelier/xml/element/serialization_spec.rb
149
153
  - spec/lib/xommelier/xml/element/structure_spec.rb