xommelier 0.1.5 → 0.1.6

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/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