xommelier 0.0.1 → 0.0.2
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/.gitignore +1 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/README.md +19 -0
- data/Rakefile +20 -0
- data/Termfile +38 -0
- data/console +7 -0
- data/examples/atom.rb +4 -4
- data/lib/xommelier/atom/category.rb +1 -1
- data/lib/xommelier/atom/entry.rb +1 -1
- data/lib/xommelier/atom/generator.rb +1 -1
- data/lib/xommelier/atom/link.rb +1 -1
- data/lib/xommelier/atom/person.rb +1 -1
- data/lib/xommelier/atom/thread.rb +38 -0
- data/lib/xommelier/atom.rb +4 -20
- data/lib/xommelier/core_ext/{integer.rb → numeric.rb} +1 -1
- data/lib/xommelier/core_ext/symbol.rb +9 -0
- data/lib/xommelier/core_ext/uri.rb +11 -5
- data/lib/xommelier/core_ext.rb +2 -1
- data/lib/xommelier/version.rb +1 -1
- data/lib/xommelier/xml/class_methods.rb +1 -0
- data/lib/xommelier/xml/element/serialization.rb +148 -0
- data/lib/xommelier/xml/element/structure.rb +236 -0
- data/lib/xommelier/xml/element.rb +23 -93
- data/lib/xommelier/xml/namespace.rb +0 -1
- data/lib/xommelier/xml.rb +1 -2
- data/spec/fixtures/feed.atom +39 -0
- data/spec/fixtures/simple_feed.atom +17 -0
- data/spec/lib/xommelier/atom/entry_spec.rb +18 -0
- data/spec/lib/xommelier/xml/element/serialization_spec.rb +36 -0
- data/spec/lib/xommelier/xml/element/structure_spec.rb +27 -0
- data/spec/lib/xommelier/xml/element_spec.rb +21 -38
- data/spec/lib/xommelier/xml_spec.rb +2 -4
- data/spec/lib/xommelier_spec.rb +1 -1
- data/spec/namespaced_module.rb +0 -3
- data/spec/spec_helper.rb +5 -3
- data/xommelier.gemspec +2 -2
- metadata +62 -49
- data/lib/xommelier/xml/attribute.rb +0 -8
- data/lib/xommelier/xml/element/dsl.rb +0 -51
@@ -0,0 +1,236 @@
|
|
1
|
+
require 'xommelier/xml/element'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
require 'active_support/core_ext/object/with_options'
|
4
|
+
require 'active_support/core_ext/string/inflections'
|
5
|
+
require 'active_support/inflections'
|
6
|
+
|
7
|
+
module Xommelier
|
8
|
+
module Xml
|
9
|
+
class Element
|
10
|
+
module Structure
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
included do
|
14
|
+
class_attribute :elements, :attributes
|
15
|
+
attr_writer :element_name
|
16
|
+
|
17
|
+
self.elements = {}
|
18
|
+
self.attributes = {}
|
19
|
+
|
20
|
+
class << self
|
21
|
+
include SingletonClassMethods
|
22
|
+
end
|
23
|
+
|
24
|
+
delegate :xmlns, to: 'self.class'
|
25
|
+
end
|
26
|
+
|
27
|
+
module SingletonClassMethods
|
28
|
+
def containing_module
|
29
|
+
@containing_module ||= ("::#{name.gsub(/::[^:]+$/, '')}").constantize
|
30
|
+
end
|
31
|
+
|
32
|
+
def xmlns(value = nil)
|
33
|
+
if value
|
34
|
+
@xmlns = case value
|
35
|
+
when Module
|
36
|
+
value.xmlns
|
37
|
+
else
|
38
|
+
value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
@xmlns ||= find_namespace
|
42
|
+
end
|
43
|
+
alias_method :xmlns=, :xmlns
|
44
|
+
|
45
|
+
def element_name(element_name = nil)
|
46
|
+
@element_name = element_name if element_name
|
47
|
+
@element_name ||= find_element_name
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def find_namespace
|
53
|
+
if self == containing_module
|
54
|
+
Xommelier::Xml::DEFAULT_NS
|
55
|
+
else
|
56
|
+
containing_module.xmlns
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_element_name
|
61
|
+
name.demodulize.underscore.dasherize
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module ClassMethods
|
66
|
+
def inherited(child)
|
67
|
+
child.elements = elements.dup
|
68
|
+
child.attributes = attributes.dup
|
69
|
+
end
|
70
|
+
|
71
|
+
# Defines containing element
|
72
|
+
# @example
|
73
|
+
# element :author, class_name: 'Xommelier::Atom::Person'
|
74
|
+
def element(name, options = {})
|
75
|
+
options[:element_name] = name
|
76
|
+
elements[name] = DEFAULT_ELEMENT_OPTIONS.merge(options)
|
77
|
+
define_element_accessors(name)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Defines containing attribute
|
81
|
+
def attribute(name, options = {})
|
82
|
+
attributes[name] = DEFAULT_OPTIONS.merge(options)
|
83
|
+
define_attribute_accessors(name)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Defines containing text
|
87
|
+
def text(options = {})
|
88
|
+
define_text_accessors
|
89
|
+
end
|
90
|
+
|
91
|
+
def any(&block)
|
92
|
+
with_options(count: :any) { |any| any.instance_eval(&block) }
|
93
|
+
end
|
94
|
+
|
95
|
+
def many(&block)
|
96
|
+
with_options(count: :many) { |many| many.instance_eval(&block) }
|
97
|
+
end
|
98
|
+
|
99
|
+
def may(&block)
|
100
|
+
with_options(count: :may) { |may| may.instance_eval(&block) }
|
101
|
+
end
|
102
|
+
|
103
|
+
def root; end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def define_element_accessors(name)
|
108
|
+
element_options = elements[name]
|
109
|
+
case element_options[:count]
|
110
|
+
when :one, :may
|
111
|
+
name = name.to_sym
|
112
|
+
define_method(name) do |*args|
|
113
|
+
if args[0]
|
114
|
+
write_element(name, args[0])
|
115
|
+
end
|
116
|
+
read_element(name)
|
117
|
+
end
|
118
|
+
alias_method "#{name}=", name
|
119
|
+
when :many, :any
|
120
|
+
plural = name.to_s.pluralize.to_sym
|
121
|
+
element_options[:plural] = plural
|
122
|
+
|
123
|
+
define_method(plural) do |*args|
|
124
|
+
if args.any?
|
125
|
+
@elements[name] = args.flatten
|
126
|
+
end
|
127
|
+
@elements[name] ||= []
|
128
|
+
end
|
129
|
+
alias_method "#{plural}=", plural
|
130
|
+
|
131
|
+
unless plural == name
|
132
|
+
define_method(name) do |*args|
|
133
|
+
if args[0]
|
134
|
+
send(plural, [args[0]])
|
135
|
+
else
|
136
|
+
send(plural)[0]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
alias_method "#{name}=", name
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def define_attribute_accessors(name)
|
147
|
+
define_method(name) do |*args|
|
148
|
+
if args[0]
|
149
|
+
write_attribute(name.to_s, args[0])
|
150
|
+
end
|
151
|
+
read_attribute(name)
|
152
|
+
end
|
153
|
+
alias_method "#{name}=", name
|
154
|
+
end
|
155
|
+
|
156
|
+
def define_text_accessors
|
157
|
+
define_method(:text) do |*args|
|
158
|
+
if args[0]
|
159
|
+
write_text(args[0])
|
160
|
+
end
|
161
|
+
read_text
|
162
|
+
end
|
163
|
+
alias_method :text=, :text
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
protected
|
168
|
+
|
169
|
+
def element_name(value = nil)
|
170
|
+
if value
|
171
|
+
@element_name = value
|
172
|
+
end
|
173
|
+
@element_name ||= self.class.element_name
|
174
|
+
end
|
175
|
+
|
176
|
+
def element_options(name)
|
177
|
+
self.class.elements[name.to_sym]
|
178
|
+
end
|
179
|
+
|
180
|
+
def read_element(name)
|
181
|
+
@elements[name.to_sym]
|
182
|
+
end
|
183
|
+
|
184
|
+
def write_element(name, value)
|
185
|
+
type = element_options(name)[:type]
|
186
|
+
unless value.is_a?(type)
|
187
|
+
value = if (type < Xommelier::Xml::Element) && !value.is_a?(Nokogiri::XML::Node)
|
188
|
+
type.new(value)
|
189
|
+
else
|
190
|
+
type.from_xommelier(value)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
@elements[name.to_sym] = value
|
194
|
+
end
|
195
|
+
|
196
|
+
def remove_element(name)
|
197
|
+
@elements.delete(name.to_sym)
|
198
|
+
end
|
199
|
+
|
200
|
+
def attribute_options(name)
|
201
|
+
self.class.attributes[name.to_sym]
|
202
|
+
end
|
203
|
+
|
204
|
+
def read_attribute(name)
|
205
|
+
@attributes[name.to_sym]
|
206
|
+
end
|
207
|
+
|
208
|
+
def write_attribute(name, value)
|
209
|
+
type = attribute_options(name)[:type]
|
210
|
+
value = type.from_xommelier(value) unless value.is_a?(type)
|
211
|
+
@attributes[name.to_sym] = value
|
212
|
+
end
|
213
|
+
|
214
|
+
def remove_attribute(name)
|
215
|
+
@attributes.delete(name.to_sym)
|
216
|
+
end
|
217
|
+
|
218
|
+
def text?
|
219
|
+
respond_to?(:text)
|
220
|
+
end
|
221
|
+
|
222
|
+
def read_text
|
223
|
+
@text
|
224
|
+
end
|
225
|
+
|
226
|
+
def write_text(text)
|
227
|
+
@text = text
|
228
|
+
end
|
229
|
+
|
230
|
+
def remove_text
|
231
|
+
@text = nil
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'xommelier/xml'
|
2
|
-
require 'xommelier/xml/element/
|
3
|
-
require '
|
2
|
+
require 'xommelier/xml/element/structure'
|
3
|
+
require 'xommelier/xml/element/serialization'
|
4
4
|
require 'active_support/core_ext/string/inflections'
|
5
5
|
require 'active_support/core_ext/array/extract_options'
|
6
6
|
require 'active_support/core_ext/class/attribute'
|
@@ -15,48 +15,13 @@ module Xommelier
|
|
15
15
|
)
|
16
16
|
|
17
17
|
class Element
|
18
|
-
|
18
|
+
include Xommelier::Xml::Element::Structure
|
19
|
+
include Xommelier::Xml::Element::Serialization
|
19
20
|
|
20
|
-
|
21
|
-
self.elements = {}
|
22
|
-
self.attributes = {}
|
23
|
-
|
24
|
-
class << self
|
25
|
-
def xmlns(value = nil)
|
26
|
-
if value
|
27
|
-
@xmlns = case ns
|
28
|
-
when Module
|
29
|
-
ns.xmlns
|
30
|
-
else
|
31
|
-
ns
|
32
|
-
end
|
33
|
-
end
|
34
|
-
@xmlns ||= find_namespace
|
35
|
-
end
|
36
|
-
alias xmlns= xmlns
|
37
|
-
|
38
|
-
def element_name(element_name = nil)
|
39
|
-
@element_name = element_name if element_name
|
40
|
-
@element_name ||= find_element_name
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def containing_module
|
46
|
-
@containing_module ||= ("::#{name.gsub(/::[^:]+$/, '')}").constantize
|
47
|
-
end
|
48
|
-
|
49
|
-
def find_namespace
|
50
|
-
containing_module.xmlns
|
51
|
-
end
|
52
|
-
|
53
|
-
def find_element_name
|
54
|
-
name.demodulize.tableize.dasherize
|
55
|
-
end
|
56
|
-
end
|
21
|
+
attr_reader :options
|
57
22
|
|
58
23
|
def initialize(contents = {}, options = {})
|
59
|
-
|
24
|
+
self.options = options
|
60
25
|
|
61
26
|
@elements = {}
|
62
27
|
@attributes = {}
|
@@ -72,70 +37,35 @@ module Xommelier
|
|
72
37
|
end
|
73
38
|
end
|
74
39
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
builder = Nokogiri::XML::Builder.new(options)
|
82
|
-
attribute_values = {xmlns: xmlns.to_s}
|
83
|
-
end
|
84
|
-
attributes.each do |name, value|
|
85
|
-
serialize_attribute(name, value, attribute_values)
|
86
|
-
end
|
87
|
-
builder.send(element_name, attribute_values) do |xml|
|
88
|
-
if respond_to?(:text)
|
89
|
-
xml.text @text
|
90
|
-
else
|
91
|
-
elements.each do |name, value|
|
92
|
-
serialize_element(name, value, xml)
|
93
|
-
end
|
94
|
-
end
|
40
|
+
def options=(options = {})
|
41
|
+
@options = options
|
42
|
+
@options.delete(:type)
|
43
|
+
|
44
|
+
if @options.key?(:element_name)
|
45
|
+
element_name(@options.delete(:element_name))
|
95
46
|
end
|
96
|
-
builder.to_xml
|
97
47
|
end
|
98
48
|
|
99
|
-
|
100
|
-
|
101
|
-
def element_options(name)
|
102
|
-
self.class.elements[name]
|
49
|
+
def inspect
|
50
|
+
%(#<#{self.class.name}:0x#{object_id.to_s(16)} #{inspect_contents}>)
|
103
51
|
end
|
104
52
|
|
105
|
-
|
106
|
-
self.class.attributes[name]
|
107
|
-
end
|
53
|
+
private
|
108
54
|
|
109
|
-
def
|
110
|
-
|
55
|
+
def inspect_contents
|
56
|
+
[inspect_attributes, inspect_elements, inspect_text].compact.join(' ')
|
111
57
|
end
|
112
58
|
|
113
|
-
def
|
114
|
-
|
59
|
+
def inspect_attributes
|
60
|
+
"@attributes={#{@attributes.map { |name, value| "#{name}: #{value.inspect}"}.join(', ')}}" if @attributes.any?
|
115
61
|
end
|
116
62
|
|
117
|
-
def
|
118
|
-
|
119
|
-
attribute_class = attribute_options[:type]
|
120
|
-
value = attribute_class.new(value) unless value.is_a?(attribute_class)
|
121
|
-
attributes[name] = value.to_xommelier
|
63
|
+
def inspect_elements
|
64
|
+
"#{@elements.map { |name, value| "@#{name}=#{value.inspect}"}.join(' ')}" if @elements.any?
|
122
65
|
end
|
123
66
|
|
124
|
-
def
|
125
|
-
|
126
|
-
if element_options[:count] == :many
|
127
|
-
single_element = element_options.merge(count: :one)
|
128
|
-
value.each { |item| serialize_element(name, item, xml, single_element) }
|
129
|
-
else
|
130
|
-
element_class = element_options[:type]
|
131
|
-
value = element_class.new(value) unless value.is_a?(element_class)
|
132
|
-
case value
|
133
|
-
when Xommelier::Xml::Element
|
134
|
-
value.to_xml(builder: xml, element_name: name)
|
135
|
-
else
|
136
|
-
xml.send(name) { xml.text value.to_xommelier }
|
137
|
-
end
|
138
|
-
end
|
67
|
+
def inspect_text
|
68
|
+
text.inspect if text?
|
139
69
|
end
|
140
70
|
end
|
141
71
|
end
|
@@ -17,7 +17,6 @@ module Xommelier
|
|
17
17
|
@uri = uri
|
18
18
|
@options = {}
|
19
19
|
@elements = Xommelier::Collection.new(Xommelier::Xml::Element)
|
20
|
-
@attributes = Xommelier::Collection.new(Xommelier::Xml::Attribute)
|
21
20
|
@as = options.delete(:as)
|
22
21
|
|
23
22
|
Xommelier::Xml::Namespace.registry[as] = self
|
data/lib/xommelier/xml.rb
CHANGED
@@ -6,7 +6,7 @@ module Xommelier
|
|
6
6
|
module Xml
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
|
9
|
+
DEFAULT_NS = 'http://www.w3.org/XML/1998/namespace'
|
10
10
|
|
11
11
|
included do
|
12
12
|
instance_variable_set :@_xmlns, nil
|
@@ -14,6 +14,5 @@ module Xommelier
|
|
14
14
|
|
15
15
|
autoload :Namespace, 'xommelier/xml/namespace'
|
16
16
|
autoload :Element, 'xommelier/xml/element'
|
17
|
-
autoload :Attribute, 'xommelier/xml/attribute'
|
18
17
|
end
|
19
18
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
|
4
|
+
<title type="text">Example Feed</title>
|
5
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
6
|
+
<subtitle type="html">A <em>lot</em> of effort went into making this effortless</subtitle>
|
7
|
+
<link rel="alternate" type="text/html" href="http://example.ru/" />
|
8
|
+
<link rel="self" type="application/atom+xml" href="http://example.ru/feed.atom" />
|
9
|
+
<rights>© Mark Pilgrim, 2003</rights>
|
10
|
+
<generator uri="http://example.com/" version="1.0">Example Toolkit</generator>
|
11
|
+
<author>
|
12
|
+
<name>John Doe</name>
|
13
|
+
</author>
|
14
|
+
<entry>
|
15
|
+
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
|
16
|
+
<title type="text">Atom-Powered Robots Run Amok</title>
|
17
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
18
|
+
<published>2003-12-13T08:29:29-04:00</published>
|
19
|
+
<link rel="alternate" type="text/html" href="http://example.ru/2003/12/13/atom03"/>
|
20
|
+
<link rel="enclosure" type="audio/mpeg" href="http://example.org/audio/ph34r_my_podcast.mp3" length="1337"/>
|
21
|
+
<author>
|
22
|
+
<name>Mark Pilgrim</name>
|
23
|
+
<uri>http://example.org/</uri>
|
24
|
+
<email>f8dy@example.com</email>
|
25
|
+
</author>
|
26
|
+
<contributor>
|
27
|
+
<name>Sam Ruby</name>
|
28
|
+
</contributor>
|
29
|
+
<contributor>
|
30
|
+
<name>Joe Gregorio</name>
|
31
|
+
</contributor>
|
32
|
+
<summary>Some text.</summary>
|
33
|
+
<content type="xhtml" xml:lang="en" xml:base="http://diveintomark.org/">
|
34
|
+
<div xmlns="http://www.w3.org/1999/xhtml">
|
35
|
+
<p><i>[Update: The Atom draft is finished.]</i></p>
|
36
|
+
</div>
|
37
|
+
</content>
|
38
|
+
</entry>
|
39
|
+
</feed>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
3
|
+
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
|
4
|
+
<title>Example Feed</title>
|
5
|
+
<link href="http://example.org/"/>
|
6
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
7
|
+
<author>
|
8
|
+
<name>John Doe</name>
|
9
|
+
</author>
|
10
|
+
<entry>
|
11
|
+
<title>Atom-Powered Robots Run Amok</title>
|
12
|
+
<link href="http://example.org/2003/12/13/atom03"/>
|
13
|
+
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
|
14
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
15
|
+
<summary>Some text.</summary>
|
16
|
+
</entry>
|
17
|
+
</feed>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xommelier::Atom::Entry do
|
4
|
+
describe 'instance' do
|
5
|
+
subject { Xommelier::Atom::Entry.new }
|
6
|
+
|
7
|
+
[:id, :title, :updated].each do |must_field|
|
8
|
+
it { should respond_to(must_field) }
|
9
|
+
end
|
10
|
+
[:content, :published, :rights, :source, :summary].each do |may_field|
|
11
|
+
it { should respond_to(may_field) }
|
12
|
+
end
|
13
|
+
%w(author category contributor link).each do |any_field|
|
14
|
+
it { should respond_to(any_field) }
|
15
|
+
it('have plural methods for embedded collections') { should respond_to(any_field.pluralize) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xommelier::Xml::Element::Serialization do
|
4
|
+
describe 'class' do
|
5
|
+
subject { Xommelier::Atom::Feed }
|
6
|
+
|
7
|
+
it { should respond_to(:parse) }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'parsing simple_feed' do
|
11
|
+
let(:feed) { @feed = Xommelier::Atom::Feed.parse(open(File.join(SPEC_ROOT, 'spec', 'fixtures', 'simple_feed.atom'))) }
|
12
|
+
|
13
|
+
it { feed.id.should == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' }
|
14
|
+
it { feed.title.should == 'Example Feed' }
|
15
|
+
it { feed.link.href.should == URI.parse('http://example.org/') }
|
16
|
+
it { feed.updated.should == Time.utc(2003, 12, 13, 18, 30, 02) }
|
17
|
+
it { feed.should have(1).authors }
|
18
|
+
it { feed.author.name.should == 'John Doe' }
|
19
|
+
it { feed.should have(1).entries }
|
20
|
+
it { feed.entry.title.should == 'Atom-Powered Robots Run Amok' }
|
21
|
+
it { feed.entry.link.href.should == URI.parse('http://example.org/2003/12/13/atom03') }
|
22
|
+
it { feed.entry.id.should == 'urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a' }
|
23
|
+
it { feed.entry.updated.should == Time.utc(2003, 12, 13, 18, 30, 02) }
|
24
|
+
it { feed.entry.summary.should == 'Some text.' }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'parsing feed' do
|
28
|
+
let(:feed) { Xommelier::Atom::Feed.parse(open(File.join(SPEC_ROOT, 'spec', 'fixtures', 'feed.atom'))) }
|
29
|
+
|
30
|
+
it { feed.should have(2).links }
|
31
|
+
it { feed.subtitle.should == 'A <em>lot</em> of effort went into making this effortless' }
|
32
|
+
it { feed.entry.should have(2).links }
|
33
|
+
it { feed.entry.should have(1).authors }
|
34
|
+
it { feed.entry.should have(2).contributors }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xommelier::Xml::Element::Structure do
|
4
|
+
subject { NamespacedModule::RootWithSimpleSubelement }
|
5
|
+
|
6
|
+
it { should respond_to(:elements) }
|
7
|
+
it { should respond_to(:element) }
|
8
|
+
it 'defines subelement' do
|
9
|
+
NamespacedModule::RootWithSimpleSubelement.elements.should have_key(:some)
|
10
|
+
end
|
11
|
+
|
12
|
+
it { should respond_to(:attributes) }
|
13
|
+
it { should respond_to(:attribute) }
|
14
|
+
it 'defines attribute' do
|
15
|
+
NamespacedModule::RootWithAttribute.attributes.should have_key(:another)
|
16
|
+
end
|
17
|
+
|
18
|
+
it { should respond_to(:text) }
|
19
|
+
it 'defines as containing text' do
|
20
|
+
NamespacedModule::RootWithText.new.should respond_to(:text)
|
21
|
+
end
|
22
|
+
|
23
|
+
it { should respond_to(:xmlns) }
|
24
|
+
it { NamespacedModule::RootWithText.xmlns.uri.should == 'http://example.org/'}
|
25
|
+
it { NamespacedModule::RootWithAttribute.xmlns.uri.should == 'http://example.org/'}
|
26
|
+
it { Xommelier::Atom::Feed.xmlns.uri.should == 'http://www.w3.org/2005/Atom'}
|
27
|
+
end
|
@@ -2,67 +2,46 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Xommelier::Xml::Element do
|
4
4
|
describe 'class' do
|
5
|
-
subject {
|
5
|
+
subject { Xommelier::Atom::Link }
|
6
6
|
|
7
7
|
it { should respond_to(:xmlns) }
|
8
|
-
it { subject.xmlns.to_s.should ==
|
8
|
+
it { subject.xmlns.to_s.should == ATOM_XMLNS }
|
9
9
|
|
10
10
|
it { should respond_to(:element_name) }
|
11
|
-
it { subject.element_name.should == '
|
12
|
-
|
13
|
-
it { should respond_to(:elements) }
|
14
|
-
it { should respond_to(:attributes) }
|
15
|
-
end
|
16
|
-
|
17
|
-
describe 'DSL' do
|
18
|
-
subject { NamespacedModule::RootWithSimpleSubelement }
|
19
|
-
|
20
|
-
it { should respond_to(:element) }
|
21
|
-
it 'defines subelement' do
|
22
|
-
NamespacedModule::RootWithSimpleSubelement.elements.should have_key(:some)
|
23
|
-
end
|
24
|
-
|
25
|
-
it { should respond_to(:attribute) }
|
26
|
-
it 'defines attribute' do
|
27
|
-
NamespacedModule::RootWithAttribute.attributes.should have_key(:another)
|
28
|
-
end
|
29
|
-
|
30
|
-
it { should respond_to(:text) }
|
31
|
-
it 'defines as containing text' do
|
32
|
-
NamespacedModule::RootWithText.new.should respond_to(:text)
|
33
|
-
end
|
11
|
+
it { subject.element_name.should == 'link' }
|
34
12
|
end
|
35
13
|
|
36
14
|
describe 'instance' do
|
37
|
-
subject {
|
15
|
+
subject { Xommelier::Atom::Link.new }
|
38
16
|
|
39
17
|
it { should respond_to(:to_xml) }
|
40
|
-
it { subject.to_xml.should == %(<?xml version="1.0"?>\n<
|
18
|
+
it { subject.to_xml.should == %(<?xml version="1.0" encoding="utf-8"?>\n<link xmlns="#{ATOM_XMLNS}"/>\n) }
|
41
19
|
|
42
20
|
describe 'with text' do
|
43
21
|
subject { NamespacedModule::RootWithText.new('Text') }
|
44
22
|
|
45
23
|
it { should respond_to(:text) }
|
46
24
|
it { subject.text.should == 'Text' }
|
47
|
-
it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-text xmlns="http://example.org/">Text</root-with-text>\n) }
|
25
|
+
it { subject.to_xml.should == %(<?xml version="1.0" encoding="utf-8"?>\n<root-with-text xmlns="http://example.org/">Text</root-with-text>\n) }
|
48
26
|
end
|
49
27
|
|
50
28
|
describe 'with simple subelements' do
|
51
|
-
subject {
|
29
|
+
subject { Xommelier::Atom::Person.new(name: 'Ivan') }
|
52
30
|
|
53
|
-
it { should respond_to(:
|
54
|
-
it { subject.
|
55
|
-
it { subject.to_xml.should == %(<?xml version="1.0"?>\n<
|
31
|
+
it { should respond_to(:name) }
|
32
|
+
it { subject.name.should == 'Ivan' }
|
33
|
+
it { subject.to_xml.should == %(<?xml version="1.0" encoding="utf-8"?>\n<person xmlns="#{ATOM_XMLNS}">\n <name>Ivan</name>\n</person>\n) }
|
56
34
|
end
|
57
35
|
|
58
36
|
describe 'with many simple subelements' do
|
59
37
|
subject do
|
60
|
-
NamespacedModule::RootWithManySimpleSubelements.new(
|
38
|
+
NamespacedModule::RootWithManySimpleSubelements.new(foos: ['bar', 'baz'])
|
61
39
|
end
|
62
40
|
|
63
41
|
it { should respond_to(:foo) }
|
64
|
-
it { subject.
|
65
|
-
it { subject.
|
42
|
+
it { subject.foos.should == ['bar', 'baz'] }
|
43
|
+
it { subject.foo.should == 'bar' }
|
44
|
+
it { subject.to_xml.should == %(<?xml version="1.0" encoding="utf-8"?>\n<root-with-many-simple-subelements xmlns="http://example.org/">\n <foo>bar</foo>\n <foo>baz</foo>\n</root-with-many-simple-subelements>\n) }
|
66
45
|
end
|
67
46
|
|
68
47
|
describe 'with attribute' do
|
@@ -70,7 +49,7 @@ describe Xommelier::Xml::Element do
|
|
70
49
|
|
71
50
|
it { should respond_to(:another) }
|
72
51
|
it { subject.another.should == 'Difference' }
|
73
|
-
it { subject.to_xml.should == %(<?xml version="1.0"?>\n<root-with-attribute xmlns="http://example.org/" another="Difference"/>\n) }
|
52
|
+
it { subject.to_xml.should == %(<?xml version="1.0" encoding="utf-8"?>\n<root-with-attribute xmlns="http://example.org/" another="Difference"/>\n) }
|
74
53
|
end
|
75
54
|
|
76
55
|
describe 'with subelements' do
|
@@ -84,8 +63,12 @@ describe Xommelier::Xml::Element do
|
|
84
63
|
end
|
85
64
|
|
86
65
|
it { should respond_to(:one) }
|
87
|
-
it {
|
88
|
-
it {
|
66
|
+
it { should respond_to(:two) }
|
67
|
+
it { should respond_to(:some) }
|
68
|
+
it { should respond_to(:another) }
|
69
|
+
it { subject.another.class.should == NamespacedModule::RootWithSimpleSubelement }
|
70
|
+
it { subject.another.some.should == 'Text' }
|
71
|
+
it { subject.to_xml.should == %(<?xml version="1.0" encoding="utf-8"?>\n<root-with-subelement xmlns="http://example.org/" one="2011-08-15" two="2">\n <some>Text</some>\n <another>\n <some>Text</some>\n </another>\n</root-with-subelement>\n) }
|
89
72
|
end
|
90
73
|
end
|
91
74
|
end
|
@@ -3,9 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Xommelier::Xml do
|
4
4
|
end
|
5
5
|
|
6
|
-
describe
|
7
|
-
subject { NamespacedModule }
|
8
|
-
|
6
|
+
describe Xommelier::Atom do
|
9
7
|
it { should respond_to(:xmlns) }
|
10
|
-
it { subject.xmlns.to_s.should ==
|
8
|
+
it { subject.xmlns.to_s.should == ATOM_XMLNS }
|
11
9
|
end
|
data/spec/lib/xommelier_spec.rb
CHANGED