xommelier 0.1.16 → 0.1.18

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.
@@ -0,0 +1,136 @@
1
+ module Xommelier
2
+ module Xml
3
+ class Element
4
+ module Structure
5
+ class Property
6
+ def initialize(name, options)
7
+ @name = name
8
+ @options = self.class.const_get(:DEFAULTS).merge(options)
9
+ end
10
+
11
+ attr_reader :name, :options
12
+
13
+ def writer
14
+ @writer ||= "#{name}="
15
+ end
16
+
17
+ # @return [Xommelier::Xml::Namespace]
18
+ def ns
19
+ options[:ns]
20
+ end
21
+
22
+ def default
23
+ options[:default]
24
+ end
25
+
26
+ # @return [Class]
27
+ def type
28
+ options[:type]
29
+ end
30
+
31
+ # @return [true, false] has default value?
32
+ def default?
33
+ options.key?(:default) && required?
34
+ end
35
+
36
+ def inspect
37
+ "#<Xommelier::X::E::S::#{self.class.name.demodulize}:0x#{object_id.to_s(16)} #{instance_variables.map { |ivar| "#{ivar}=#{instance_variable_get(ivar).inspect}"}.join(' ')}>"
38
+ end
39
+
40
+ protected
41
+
42
+ def overrides
43
+ @overrides ||= {}
44
+ end
45
+ end
46
+
47
+ class Element < Property
48
+ DEFAULTS = {
49
+ type: String,
50
+ count: :one
51
+ }
52
+
53
+ def node_type
54
+ :element
55
+ end
56
+
57
+ def element_name
58
+ @element_name ||= options.delete(:as) { name }.to_s
59
+ end
60
+
61
+ def serializable_element_name
62
+ @serializable_element_name ||= if %w(class id text).include?(element_name)
63
+ element_name + '_'
64
+ else
65
+ element_name
66
+ end
67
+ end
68
+
69
+ def required?
70
+ options[:count] == :one || options[:count] == :many
71
+ end
72
+
73
+ def multiple?
74
+ return overrides[:multiple] if overrides.key?(:multiple)
75
+ options[:count] == :many || options[:count] == :any
76
+ end
77
+
78
+ def plural
79
+ @plural ||= name.to_s.pluralize.to_sym
80
+ end
81
+
82
+ def plural_writer
83
+ @plural_writer ||= "#{plural}="
84
+ end
85
+
86
+ def numbers_equal?
87
+ plural == name
88
+ end
89
+
90
+ def overridden_xmlns
91
+ overrides[:xmlns]
92
+ end
93
+
94
+ def override(overrides)
95
+ @overrides = overrides
96
+ yield
97
+ @overrides = {}
98
+ end
99
+ end
100
+
101
+ class Attribute < Property
102
+ DEFAULTS = {
103
+ type: String,
104
+ required: false
105
+ }
106
+
107
+ def node_type
108
+ :attribute
109
+ end
110
+
111
+ def required?
112
+ options[:required]
113
+ end
114
+
115
+ def attribute_name
116
+ @attribute_name ||= options.delete(:as) { name }.to_s
117
+ end
118
+ end
119
+
120
+ class Text < Property
121
+ DEFAULTS = {
122
+ type: String
123
+ }
124
+
125
+ def node_type
126
+ :text
127
+ end
128
+
129
+ def required?
130
+ options[:required]
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -81,8 +81,12 @@ module Xommelier
81
81
  {as.to_s => uri.to_s}
82
82
  end
83
83
 
84
+ def attribute_name
85
+ default? ? 'xmlns' : "xmlns:#{as}"
86
+ end
87
+
84
88
  def inspect
85
- %(xmlns:#{as}="#{uri}")
89
+ %(#{attribute_name}="#{uri}")
86
90
  end
87
91
  end
88
92
  end
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0"?>
2
+ <rss version="2.0">
3
+ <channel>
4
+ <title>Liftoff News</title>
5
+ <link>http://liftoff.msfc.nasa.gov/</link>
6
+ <description>Liftoff to Space Exploration.</description>
7
+ <language>en-us</language>
8
+ <pubDate>Tue, 10 Jun 2003 04:00:00 GMT</pubDate>
9
+ <lastBuildDate>Tue, 10 Jun 2003 09:41:01 GMT</lastBuildDate>
10
+ <docs>http://blogs.law.harvard.edu/tech/rss</docs>
11
+ <generator>Weblog Editor 2.0</generator>
12
+ <managingEditor>editor@example.com</managingEditor>
13
+ <webMaster>webmaster@example.com</webMaster>
14
+ <item>
15
+ <title>Star City</title>
16
+ <link>http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp</link>
17
+ <description>How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's &lt;a href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm"&gt;Star City&lt;/a&gt;.</description>
18
+ <pubDate>Tue, 03 Jun 2003 09:39:21 GMT</pubDate>
19
+ <guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
20
+ </item>
21
+ <item>
22
+ <description>Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a &lt;a href="http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&gt;partial eclipse of the Sun&lt;/a&gt; on Saturday, May 31st.</description>
23
+ <pubDate>Fri, 30 May 2003 11:06:42 GMT</pubDate>
24
+ <guid>http://liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
25
+ </item>
26
+ <item>
27
+ <title>The Engine That Does More</title>
28
+ <link>http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp</link>
29
+ <description>Before man travels to Mars, NASA hopes to design new engines that will let us fly through the Solar System more quickly. The proposed VASIMR engine would do that.</description>
30
+ <pubDate>Tue, 27 May 2003 08:37:32 GMT</pubDate>
31
+ <guid>http://liftoff.msfc.nasa.gov/2003/05/27.html#item571</guid>
32
+ </item>
33
+ <item>
34
+ <title>Astronauts' Dirty Laundry</title>
35
+ <link>http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp</link>
36
+ <description>Compared to earlier spacecraft, the International Space Station has many luxuries, but laundry facilities are not one of them. Instead, astronauts have other options.</description>
37
+ <pubDate>Tue, 20 May 2003 08:56:02 GMT</pubDate>
38
+ <guid>http://liftoff.msfc.nasa.gov/2003/05/20.html#item570</guid>
39
+ </item>
40
+ </channel>
41
+ </rss>
@@ -0,0 +1,78 @@
1
+ <rss version="2.0"
2
+ xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
3
+ xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
4
+ <channel>
5
+ <creativeCommons:license>http://www.creativecommons.org/licenses/by-nd/1.0</creativeCommons:license>
6
+ <description>Current headlines from the Dallas Times-Herald newspaper</description>
7
+ <link>http://dallas.example.com</link>
8
+ <title>Dallas Times-Herald</title>
9
+ <category>Media</category>
10
+ <category domain="Newspapers/Regional/United_States">Texas</category>
11
+ <cloud domain="server.example.com" path="/rpc" port="80" protocol="xml-rpc" registerProcedure="cloud.notify" />
12
+ <copyright>Copyright 2006 Dallas Times-Herald</copyright>
13
+ <docs>http://www.rssboard.org/rss-specification</docs>
14
+ <generator>Radio UserLand v8.2.1</generator>
15
+ <image>
16
+ <link>http://dallas.example.com</link>
17
+ <title>Dallas Times-Herald</title>
18
+ <url>http://dallas.example.com/masthead.gif</url>
19
+ <description>Read the Dallas Times-Herald</description>
20
+ <height>32</height>
21
+ <width>96</width>
22
+ </image>
23
+ <language>epo</language>
24
+ <lastBuildDate>Sun, 29 Jan 2006 17:17:44 GMT</lastBuildDate>
25
+ <managingEditor>jlehrer@dallas.example.com (Jim Lehrer)</managingEditor>
26
+ <pubDate>Sun, 29 Jan 2006 05:00:00 GMT</pubDate>
27
+ <rating>(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l by "webmaster@example.com" on "2006.01.29T10:09-0800" r (n 0 s 0 v 0 l 0))</rating>
28
+ <skipDays>
29
+ <day>Saturday</day>
30
+ <day>Sunday</day>
31
+ </skipDays>
32
+ <skipHours>
33
+ <hour>0</hour>
34
+ <hour>1</hour>
35
+ <hour>2</hour>
36
+ <hour>22</hour>
37
+ <hour>23</hour>
38
+ </skipHours>
39
+ <textInput>
40
+ <description>Your aggregator supports the textInput element. What software are you using?</description>
41
+ <link>http://www.cadenhead.org/textinput.php</link>
42
+ <name>query</name>
43
+ <title>TextInput Inquiry</title>
44
+ </textInput>
45
+ <ttl>60</ttl>
46
+ <webMaster>helpdesk@dallas.example.com</webMaster>
47
+ <item>
48
+ <trackback:ping>http://dallas.example.com/trackback/tb.php?id=1991/05/02/nolan.htm</trackback:ping>
49
+ <title>Seventh Heaven! Ryan Hurls Another No Hitter</title>
50
+ <link>http://dallas.example.com/1991/05/02/nolan.htm</link>
51
+ <description>Texas Rangers pitcher Nolan Ryan hurled the seventh no-hitter of his legendary career on Arlington Appreciation Night, defeating the Toronto Blue Jays 3-0. The 44-year-old struck out 16 batters before a crowd of 33,439.</description>
52
+ <guid>http://dallas.example.com/1991/05/02/nolan.htm</guid>
53
+ </item>
54
+ <item>
55
+ <trackback:ping>http://dallas.example.com/trackback/tb.php?id=1983/06/joebob.htm</trackback:ping>
56
+ <author>jbb@dallas.example.com (Joe Bob Briggs)</author>
57
+ <category>rec.arts.movies.reviews</category>
58
+ <comments>http://dallas.example.com/feedback/1983/06/joebob.htm</comments>
59
+ <description>I'm headed for France. I wasn't gonna go this year, but then last week "Valley Girl" came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description>
60
+ <enclosure length="24986239" type="audio/mpeg" url="http://dallas.example.com/joebob_050689.mp3" />
61
+ <guid>http://dallas.example.com/1983/05/06/joebob.htm</guid>
62
+ <link>http://dallas.example.com/1983/05/06/joebob.htm</link>
63
+ <pubDate>Fri, 06 May 1983 09:00:00 CST</pubDate>
64
+ <source url="http://la.example.com/rss.xml">Los Angeles Herald-Examiner</source>
65
+ <title>Joe Bob Goes to the Drive-In</title>
66
+ </item>
67
+ <item>
68
+ <trackback:ping>http://dallas.example.com/trackback/tb.php?id=1983/06/joebob2.htm</trackback:ping>
69
+ <trackback:about>http://www.imdb.com/title/tt0086525/</trackback:about>
70
+ <description>I'm headed for France. I wasn't gonna go this year, but then last week &lt;a href="http://www.imdb.com/title/tt0086525/"&gt;Valley Girl&lt;/a&gt; came out and I said to myself, Joe Bob, you gotta get out of the country for a while.</description>
71
+ <guid isPermaLink="false">tag:dallas.example.com,4131:news</guid>
72
+ </item>
73
+ <item>
74
+ <description><![CDATA[I'm headed for France. I wasn't gonna go this year, but then last week <a href="http://www.imdb.com/title/tt0086525/">Valley Girl</a> came out and I said to myself, Joe Bob, you gotta get out of the country for a while.]]></description>
75
+ <guid isPermaLink="false">1983-05-06+lifestyle+joebob+2</guid>
76
+ </item>
77
+ </channel>
78
+ </rss>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <rss version="2.0">
3
+ <channel>
4
+ <title>Example Feed</title>
5
+ <link>http://example.com</link>
6
+ <managingEditor>john.doe@example.com</managingEditor>
7
+ <pubDate>Tue, 10 Jun 2003 04:00:00 -0000</pubDate>
8
+ <lastBuildDate>Sat, 13 Dec 2003 18:30:02 -0000</lastBuildDate>
9
+ <item>
10
+ <guid>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</guid>
11
+ <title>RSS-Powered Robots Run Amok</title>
12
+ <description>Some text.</description>
13
+ <link>http://example.org/2003/12/13/atom03</link>
14
+ <pubDate>Sat, 13 Dec 2003 18:30:02 -0000</pubDate>
15
+ </item>
16
+ </channel>
17
+ </rss>
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Atom feed building' do
4
- let(:feed) do
4
+ subject(:feed) do
5
5
  Xommelier::Atom::Feed.new.tap do |feed|
6
6
  feed.id = 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
7
7
  feed.title = 'Example Feed'
@@ -19,21 +19,13 @@ describe 'Atom feed building' do
19
19
  end
20
20
  end
21
21
 
22
- let(:built_xml) { feed.to_xml }
23
- let(:parsed_xml) { Nokogiri::XML(built_xml) }
22
+ let(:parsed_xml) { Nokogiri::XML(feed.to_xml) }
24
23
  let(:rng) { Nokogiri::XML::RelaxNG(load_xml_file('atom.rng')) }
25
- let(:xsd) { Nokogiri::XML::Schema(load_xml_file('atom.xsd')) }
24
+ let(:xsd) { Xommelier::Atom.schema }
26
25
 
27
- subject { built_xml }
26
+ it { should be_valid }
28
27
 
29
- it { feed.should be_valid }
30
-
31
- it { should == load_xml_file('simple_feed.atom').read }
32
- it do
33
- rng.validate(parsed_xml).each do |error|
34
- pp error
35
- end
36
- end
28
+ its(:to_xml) { should == load_xml_file('simple_feed.atom') }
37
29
  it('should conform to RelaxNG schema') { rng.valid?(parsed_xml).should == true }
38
30
  it('should conform to XML Schema') { xsd.valid?(parsed_xml).should == true }
39
31
  end
@@ -35,6 +35,6 @@ describe 'Atom feed building' do
35
35
 
36
36
  subject { built_xml }
37
37
 
38
- it { should == load_xml_file('multi_namespace_feed.atom').read }
38
+ it { should == load_xml_file('multi_namespace_feed.atom') }
39
39
  it('should conform to RelaxNG schema') { rng.valid?(parsed_xml).should == true }
40
40
  end
@@ -26,7 +26,7 @@ describe 'Build document from nested hash' do
26
26
 
27
27
  subject { doc }
28
28
 
29
- its(:to_xml) { should == load_xml_file('nested_atom').read }
29
+ its(:to_xml) { should == load_xml_file('nested_atom') }
30
30
  it { should have(1).authors }
31
31
  it { should have(3).contributors }
32
32
  it { should have(3).entries }
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'RSS feed building' do
4
+ subject(:rss) do
5
+ Xommelier::RSS::Rss.new(
6
+ channel: {
7
+ title: 'Example Feed',
8
+ link: 'http://example.com',
9
+ pub_date: Time.utc(2003, 6, 10, 04),
10
+ last_build_date: Time.utc(2003, 12, 13, 18, 30, 02),
11
+ managing_editor: 'john.doe@example.com',
12
+ items: [{
13
+ title: 'RSS-Powered Robots Run Amok',
14
+ guid: 'urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a',
15
+ pub_date: Time.utc(2003, 12, 13, 18, 30, 02),
16
+ description: 'Some text.',
17
+ link: 'http://example.org/2003/12/13/atom03'
18
+ }]
19
+ }
20
+ )
21
+ end
22
+
23
+ it { should be_valid }
24
+ its(:to_xml) { should == load_xml_file('simple_feed.rss') }
25
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+ require 'active_support/core_ext/numeric/time'
4
+ require 'xommelier/rss'
5
+
6
+ describe 'RSS feed' do
7
+ describe 'parsing' do
8
+ let(:rss_xml) { load_xml_file('feed.rss2.0') }
9
+ let(:feed) { Xommelier::RSS::Rss.parse(rss_xml) }
10
+
11
+ subject { feed }
12
+
13
+ it { should be_kind_of(Xommelier::RSS::Rss) }
14
+
15
+ its(:title) { should == 'Liftoff News' }
16
+ its(:last_build_date) { should == Time.utc(2003, 6, 10, 9, 41, 01) }
17
+ its(:pub_date) { should == Time.utc(2003, 6, 10, 04) }
18
+ its(:description) { should == 'Liftoff to Space Exploration.' }
19
+ its(:link) { should == URI.parse('http://liftoff.msfc.nasa.gov/') }
20
+ its(:docs) { should == 'http://blogs.law.harvard.edu/tech/rss' }
21
+ its(:description) { should == 'Liftoff to Space Exploration.' }
22
+ its(:generator) { should == 'Weblog Editor 2.0' }
23
+ its(:managing_editor) { should == 'editor@example.com' }
24
+ its(:web_master) { should == 'webmaster@example.com' }
25
+
26
+ it { feed.should have(4).items }
27
+ describe 'Item' do
28
+ let(:item) { feed.items[0] }
29
+ subject { item }
30
+
31
+ its(:guid) { should be_an Xommelier::RSS::Guid }
32
+ its('guid.text') { should == 'http://liftoff.msfc.nasa.gov/2003/06/03.html#item573' }
33
+ its('guid.to_s') { should == 'http://liftoff.msfc.nasa.gov/2003/06/03.html#item573' }
34
+ its(:guid) { should == 'http://liftoff.msfc.nasa.gov/2003/06/03.html#item573' }
35
+ its(:title) { should == 'Star City' }
36
+ its(:pub_date) { should == Time.utc(2003, 6, 3, 9, 39, 21) }
37
+ its(:description) { should == 'How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia\'s <a href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm">Star City</a>.' }
38
+ its(:link) { should == URI.parse('http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp') }
39
+ end
40
+ end
41
+ end
@@ -8,6 +8,7 @@ Dir[File.join(SPEC_ROOT, 'spec/support/**/*.rb')].each {|f| require f}
8
8
 
9
9
  ATOM_XMLNS = 'http://www.w3.org/2005/Atom'
10
10
 
11
+ #noinspection RubyResolve
11
12
  RSpec.configure do |config|
12
13
  config.mock_with :rspec
13
14
  config.order = 'random'
@@ -1,3 +1,3 @@
1
1
  def load_xml_file(file_name)
2
- open(File.join(SPEC_ROOT, 'spec', 'fixtures', "#{file_name}.xml"))
2
+ open(File.join(SPEC_ROOT, 'spec', 'fixtures', "#{file_name}.xml")).read
3
3
  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.16
4
+ version: 0.1.18
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-08 00:00:00.000000000 Z
12
+ date: 2013-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -93,6 +93,7 @@ files:
93
93
  - lib/xommelier/atom/source.rb
94
94
  - lib/xommelier/atom/threading.rb
95
95
  - lib/xommelier/collection.rb
96
+ - lib/xommelier/common.rb
96
97
  - lib/xommelier/core_ext.rb
97
98
  - lib/xommelier/core_ext/boolean.rb
98
99
  - lib/xommelier/core_ext/date.rb
@@ -103,23 +104,31 @@ files:
103
104
  - lib/xommelier/core_ext/time.rb
104
105
  - lib/xommelier/core_ext/uri.rb
105
106
  - lib/xommelier/open_search.rb
107
+ - lib/xommelier/opml.rb
108
+ - lib/xommelier/rss.rb
106
109
  - lib/xommelier/schemas/atom.xsd
110
+ - lib/xommelier/schemas/rss.xsd
107
111
  - lib/xommelier/version.rb
108
112
  - lib/xommelier/xml.rb
109
113
  - lib/xommelier/xml/element.rb
110
114
  - lib/xommelier/xml/element/serialization.rb
111
115
  - lib/xommelier/xml/element/structure.rb
116
+ - lib/xommelier/xml/element/structure/property.rb
112
117
  - lib/xommelier/xml/namespace.rb
113
118
  - spec/fixtures/atom.rng.xml
114
- - spec/fixtures/atom.xsd.xml
115
119
  - spec/fixtures/feed.atom.xml
120
+ - spec/fixtures/feed.rss2.0.xml
116
121
  - spec/fixtures/multi_namespace_feed.atom.xml
117
122
  - spec/fixtures/nested_atom.xml
123
+ - spec/fixtures/rss-2.0-namespace.xml
118
124
  - spec/fixtures/simple_feed.atom.xml
125
+ - spec/fixtures/simple_feed.rss.xml
119
126
  - spec/functional/atom_feed_building_spec.rb
120
127
  - spec/functional/atom_feed_parsing_spec.rb
121
128
  - spec/functional/atom_feed_thread_building_spec.rb
122
129
  - spec/functional/build_nested_document_from_hash_spec.rb
130
+ - spec/functional/rss_feed_building_spec.rb
131
+ - spec/functional/rss_feed_parsing_spec.rb
123
132
  - spec/lib/xommelier/atom/entry_spec.rb
124
133
  - spec/lib/xommelier/xml/element/serialization_spec.rb
125
134
  - spec/lib/xommelier/xml/element/structure_spec.rb
@@ -156,15 +165,19 @@ specification_version: 3
156
165
  summary: Xommelier is an XML Sommelier
157
166
  test_files:
158
167
  - spec/fixtures/atom.rng.xml
159
- - spec/fixtures/atom.xsd.xml
160
168
  - spec/fixtures/feed.atom.xml
169
+ - spec/fixtures/feed.rss2.0.xml
161
170
  - spec/fixtures/multi_namespace_feed.atom.xml
162
171
  - spec/fixtures/nested_atom.xml
172
+ - spec/fixtures/rss-2.0-namespace.xml
163
173
  - spec/fixtures/simple_feed.atom.xml
174
+ - spec/fixtures/simple_feed.rss.xml
164
175
  - spec/functional/atom_feed_building_spec.rb
165
176
  - spec/functional/atom_feed_parsing_spec.rb
166
177
  - spec/functional/atom_feed_thread_building_spec.rb
167
178
  - spec/functional/build_nested_document_from_hash_spec.rb
179
+ - spec/functional/rss_feed_building_spec.rb
180
+ - spec/functional/rss_feed_parsing_spec.rb
168
181
  - spec/lib/xommelier/atom/entry_spec.rb
169
182
  - spec/lib/xommelier/xml/element/serialization_spec.rb
170
183
  - spec/lib/xommelier/xml/element/structure_spec.rb