syndication 0.4.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.
@@ -0,0 +1,314 @@
1
+
2
+ require 'syndication/rss'
3
+ require 'test/unit'
4
+ require 'syndication/dublincore'
5
+ require 'syndication/content'
6
+ require 'syndication/podcast'
7
+
8
+ module Syndication
9
+
10
+ # This class contains the unit tests for the Syndication module.
11
+ class Tests < Test::Unit::TestCase
12
+
13
+ # A set of minimal assertions that can be applied to every well-formed parsed
14
+ # feed.
15
+ def baseline_assertions(feed)
16
+ assert_not_nil(feed)
17
+ assert_kind_of(Syndication::RSS::Feed, feed)
18
+ loi = feed.items
19
+ assert_not_nil(loi)
20
+ assert_kind_of(Array, loi)
21
+ assert(loi.length >= 1)
22
+ assert_not_nil(loi[0])
23
+ assert_not_nil(loi[0].description)
24
+ end
25
+
26
+ # Test a minimal well-formed RSS2.0 feed
27
+ def test_rss2_wf_minimal
28
+ xml = <<-EOF
29
+ <rss version="2.0">
30
+ <channel>
31
+ <title>I like coffee</title>
32
+ <link>http://www.coffeegeek.com/</link>
33
+ <description>Hand over the latte &amp; nobody gets hurt.</description>
34
+ </channel>
35
+ <item>
36
+ <description>A day without coffee is incomplete.</description>
37
+ </item>
38
+ </rss>
39
+ EOF
40
+ f = Syndication::RSS::Parser.new.parse(xml)
41
+ baseline_assertions(f)
42
+ assert(f.channel.title == 'I like coffee')
43
+ assert(f.channel.link == 'http://www.coffeegeek.com/')
44
+ assert(f.channel.description == 'Hand over the latte & nobody gets hurt.')
45
+ assert(f.items.first.description == 'A day without coffee is incomplete.')
46
+ c = f.channel
47
+ assert_not_nil(c)
48
+ assert_kind_of(Syndication::RSS::Channel, c)
49
+ assert_not_nil(c.title)
50
+ assert_not_nil(c.link)
51
+ assert_not_nil(c.description)
52
+ end
53
+
54
+ # Test a minimal well-formed RSS1.0 feed
55
+ def test_rss1_wf_minimal
56
+ xml = <<-EOF
57
+ <?xml version="1.0"?>
58
+ <rdf:RDF
59
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
60
+ xmlns="http://purl.org/rss/1.0/">
61
+ <channel rdf:about="http://www.otternet.com/">
62
+ <title>OtterNet</title>
63
+ <link>http://www.otternet.com/</link>
64
+ <description>Otternet has pages &amp; pages of information about otters.</description>
65
+ </channel>
66
+ <item rdf:about="http://www.otternet.com/species/seaotter.htm">
67
+ <title>The Sea Otter</title>
68
+ <link>http://www.otternet.com/species/seaotter.htm</link>
69
+ <description>The enticingly cute enhydra lontris.</description>
70
+ </item>
71
+ </rdf:RDF>
72
+ EOF
73
+ f = Syndication::RSS::Parser.new.parse(xml)
74
+ baseline_assertions(f)
75
+ assert(f.channel.title == 'OtterNet')
76
+ assert(f.channel.link == 'http://www.otternet.com/')
77
+ assert(f.channel.description == 'Otternet has pages & pages of information about otters.')
78
+ assert(f.items.first.title == 'The Sea Otter')
79
+ assert(f.items.first.link == 'http://www.otternet.com/species/seaotter.htm')
80
+ assert(f.items.first.description == 'The enticingly cute enhydra lontris.')
81
+ c = f.channel
82
+ assert_not_nil(c)
83
+ assert_kind_of(Syndication::RSS::Channel, c)
84
+ assert_not_nil(c.title)
85
+ assert_not_nil(c.link)
86
+ assert_not_nil(c.description)
87
+ end
88
+
89
+ # Test a well-formed RSS2 feed with every element possible and more than
90
+ # one item
91
+ def test_rss2_wf_full
92
+ xml = <<-EOF
93
+ <rss version="2">
94
+ <channel>
95
+ <title>Example Feed</title>
96
+ <link>http://www.example.com/</link>
97
+ <description>This is merely an example.</description>
98
+ <language>en-us</language>
99
+ <copyright>Copyright 2004 The Example Corporation.</copyright>
100
+ <managingEditor>editor@example.com</managingEditor>
101
+ <webMaster>webmaster@example.com</webMaster>
102
+ <pubDate>Sat, 07 Sep 2002 00:01:02 EDT</pubDate>
103
+ <lastBuildDate>Sat, 7 Sep 02 13:14:15 -0600</lastBuildDate>
104
+ <category>examples</category>
105
+ <category>boring</category>
106
+ <generator>vim of course</generator>
107
+ <docs>http://blogs.law.harvard.edu/tech/rss</docs>
108
+ <cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap"/>
109
+ <ttl>90</ttl>
110
+ <image>
111
+ <title>Example Inc</title>
112
+ <url>http://www.example.com/images/logo.jpg</url>
113
+ <link>http://www.example.com</link>
114
+ <width>42</width>
115
+ <height>23</height>
116
+ <description>The Example Logo</description>
117
+ </image>
118
+ <rating>(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))</rating>
119
+ <textInput>
120
+ <title>Submit</title>
121
+ <description>Enter keywords</description>
122
+ <name>SearchKeywords</name>
123
+ <link>http://www.example.com/cgi-bin/search.pl</link>
124
+ </textInput>
125
+ <skipHours>
126
+ <hour>0</hour>
127
+ <hour>23</hour>
128
+ </skipHours>
129
+ <skipDays>
130
+ <day>Monday</day>
131
+ <day>Sunday</day>
132
+ </skipDays>
133
+ <item>
134
+ <title>Our stock price shot up</title>
135
+ <link>http://www.example.com/news/2.html</link>
136
+ <description>We were hyped in the press!</description>
137
+ </item>
138
+ <item>
139
+ <title>A dull example of little value.</title>
140
+ <link>http://www.example.com/news/1.html</link>
141
+ <description>If this was any less interesting, it would be amazing.</description>
142
+ <author>fred@example.com</author>
143
+ <pubDate>Sat, 07 Sep 2002 00:01:02 EDT</pubDate>
144
+ <category>dull</category>
145
+ <category>amazingly</category>
146
+ <comments>http://www.example.com/news/comments/1.html</comments>
147
+ <enclosure url="http://www.example.com/mp3/advertisement.mp3" length="123987" type="audio/mpeg" />
148
+ <guid>4asd98dgf9a74@example.com</guid>
149
+ <source url="http://www.example.com/news.xml">Example News</source>
150
+ </item>
151
+ </channel>
152
+ </rss>
153
+ EOF
154
+ f = Syndication::RSS::Parser.new.parse(xml)
155
+ baseline_assertions(f)
156
+ for elem in %w(title link description language copyright managingeditor webmaster pubdate lastbuilddate category generator docs cloud ttl textinput rating skiphours skipdays)
157
+ assert_not_nil(f.channel.send(elem), "feed.channel.#{elem} is nil, it shouldn't be")
158
+ assert(f.channel.send(elem).to_s.length > 0)
159
+ end
160
+ items = f.items
161
+ assert(items.length == 2)
162
+ i = items.last
163
+ for elem in %w(title link description author pubdate category comments enclosure guid source)
164
+ assert_not_nil(i.send(elem), "feed.channel.item[1].#{elem} is nil, it shouldn't be")
165
+ end
166
+ cats = i.category
167
+ assert(cats.length == 2)
168
+ assert(cats.first == 'dull')
169
+ assert(cats.last == 'amazingly')
170
+ assert(f.channel.skiphours.length == 2)
171
+ assert(f.channel.skiphours.first == 0)
172
+ assert(f.channel.skiphours.last == 23)
173
+ assert(f.channel.pubdate.kind_of?(DateTime))
174
+ assert(f.channel.lastbuilddate.kind_of?(DateTime))
175
+ assert(f.channel.pubdate.mday == 7)
176
+ assert(f.channel.pubdate.month == 9)
177
+ assert(f.channel.lastbuilddate.mday == 7)
178
+ assert(f.channel.lastbuilddate.month == 9)
179
+ c = f.channel
180
+ assert_not_nil(c)
181
+ assert_kind_of(Syndication::RSS::Channel, c)
182
+ assert_not_nil(c.title)
183
+ assert_not_nil(c.link)
184
+ assert_not_nil(c.description)
185
+ end
186
+
187
+ # Test a well-formed RSS 1.0 feed with every element possible, more
188
+ # than one item, and rdf:resource links in the channel
189
+ def test_rss1_wf_full
190
+ xml = <<-EOF
191
+ <rdf:RDF
192
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
193
+ xmlns="http://purl.org/rss/1.0/">
194
+ <channel>
195
+ <title>Example Dot Org</title>
196
+ <link>http://www.example.org</link>
197
+ <description>the Example Organization web site</description>
198
+ <image rdf:resource="http://www.example.org/images/logo.gif"/>
199
+ <items>
200
+ <rdf:Seq>
201
+ <rdf:li resource="http://www.example.org/items/1"/>
202
+ <rdf:li resource="http://www.example.org/items/2"/>
203
+ </rdf:Seq>
204
+ </items>
205
+ <textinput rdf:resource="http://www.example.org/cgi-bin/input.pl"/>
206
+ </channel>
207
+ <textinput rdf:about="http://www.example.org/cgi-bin/input.pl">
208
+ <title>Search example.org</title>
209
+ <description>Search the example.org web site</description>
210
+ <name>query</name>
211
+ <link>http://www.example.org/cgi-bin/input.pl</link>
212
+ </textinput>
213
+ <image rdf:about="http://www.example.org/images/logo.gif">
214
+ <title>Example.org logo</title>
215
+ <link>http://www.example.org/</link>
216
+ <url>http://www.example.org/images/logo.gif</url>
217
+ </image>
218
+ <item rdf:about="http://www.example.org/items/1">
219
+ <title>Welcome</title>
220
+ <link>http://www.example.org/items/1</link>
221
+ <description>Welcome to our new news feed</description>
222
+ </item>
223
+ <item rdf:about="http://www.example.org/items/2">
224
+ <title>New Status Update</title>
225
+ <link>http://www.example.org/items/1</link>
226
+ <description>News about the Example project</description>
227
+ </item>
228
+ </rdf:RDF>
229
+ EOF
230
+ f = Syndication::RSS::Parser.new.parse(xml)
231
+ baseline_assertions(f)
232
+ for elem in %w(title link description textinput)
233
+ assert_not_nil(f.channel.send(elem), "feed.channel.#{elem} is nil, it shouldn't be")
234
+ assert(f.channel.send(elem).to_s.length > 0)
235
+ end
236
+ il = f.items
237
+ assert(il.length == 2)
238
+ i = il.last
239
+ assert(i.link == 'http://www.example.org/items/1')
240
+ assert(i.title == 'New Status Update')
241
+ assert(i.description == 'News about the Example project')
242
+ assert(f.textinput.title == 'Search example.org')
243
+ f.channel.image.strip
244
+ assert(f.image.url == 'http://www.example.org/images/logo.gif')
245
+ c = f.channel
246
+ assert_not_nil(c)
247
+ assert_kind_of(Syndication::RSS::Channel, c)
248
+ assert_not_nil(c.title)
249
+ assert_not_nil(c.link)
250
+ assert_not_nil(c.description)
251
+ end
252
+
253
+ # Test HTML encoded content in RSS 1.0 and namespace remapping
254
+ def test_rss1_content
255
+ xml = <<-EOF
256
+ <?xml version="1.0"?>
257
+ <rdf:RDF
258
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
259
+ xmlns:html="http://purl.org/rss/1.0/modules/content/"
260
+ xmlns="http://purl.org/rss/1.0/">
261
+ <channel rdf:about="http://www.otternet.com/">
262
+ <title>OtterNet</title>
263
+ <link>http://www.otternet.com/</link>
264
+ <description>Otternet has dozens of pages of information about otters.</description>
265
+ <content:encoded><![CDATA[<p><cite>OtterNet</cite> has <em>dozens</em> of pages of information about otters.</p>]]></content:encoded>
266
+ </channel>
267
+ <item rdf:about="http://www.otternet.com/species/seaotter.htm">
268
+ <title>The Sea Otter</title>
269
+ <link>http://www.otternet.com/species/seaotter.htm</link>
270
+ <description>The enticingly cute enhydra lontris.</description>
271
+ <html:encoded>The enticingly cute &lt;i&gt;enhydra lontris&lt;/i&gt;</html:encoded>
272
+ </item>
273
+ <item rdf:about="http://www.ruby-lang.org/">
274
+ <title>Ruby</title>
275
+ <link>http://www.ruby-lang.org/</link>
276
+ <description>There's this language called Ruby, you may have heard of it.</description>
277
+ <html:encoded>There's this language called &lt;strong&gt;Ruby&lt;/strong&gt;, you &lt;em&gt;may&lt;/em&gt; have heard of it.</html:encoded>
278
+ </item>
279
+ </rdf:RDF>
280
+ EOF
281
+ f = Syndication::RSS::Parser.new.parse(xml)
282
+ baseline_assertions(f)
283
+ il = f.items
284
+ assert(il.length == 2)
285
+ i1 = il.first
286
+ i2 = il.last
287
+ assert_not_nil(i1.content_encoded, "content_encoded nil, shouldn't be")
288
+ assert_not_nil(i2.content_encoded, "content_encoded nil, shouldn't be")
289
+ assert(i1.content_decoded == 'The enticingly cute <i>enhydra lontris</i>')
290
+ assert(i2.content_decoded == "There's this language called <strong>Ruby</strong>, you <em>may</em> have heard of it.")
291
+ c = f.channel
292
+ assert_not_nil(c)
293
+ assert_kind_of(Syndication::RSS::Channel, c)
294
+ assert_not_nil(c.title)
295
+ assert_not_nil(c.link)
296
+ assert_not_nil(c.description)
297
+ end
298
+
299
+ # Test iTunes-specific duration parsing
300
+ def test_itunes
301
+ i = Syndication::RSS::Item.new(nil)
302
+ i.itunes_duration = "12:34:56"
303
+ assert(i.itunes_duration == 45296, "Duration computed incorrectly")
304
+ i.itunes_duration = "5:43:21"
305
+ assert(i.itunes_duration == 20601, "Duration computed incorrectly")
306
+ i.itunes_duration = "20:01"
307
+ assert(i.itunes_duration == 1201, "Duration computed incorrectly")
308
+ i.itunes_duration = "3:52"
309
+ assert(i.itunes_duration == 232, "Duration computed incorrectly")
310
+ end
311
+
312
+ end
313
+
314
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: syndication
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.4.0
7
+ date: 2005-09-29 00:00:00 -05:00
8
+ summary: A web syndication parser for Atom and RSS with a uniform API
9
+ require_paths:
10
+ - lib
11
+ email: meta@pobox.com
12
+ homepage: http://www.pobox.com/~meta/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - mathew
31
+ files:
32
+ - lib/syndication
33
+ - lib/syndication/dublincore.rb
34
+ - lib/syndication/common.rb
35
+ - lib/syndication/podcast.rb
36
+ - lib/syndication/content.rb
37
+ - lib/syndication/rss.rb
38
+ - lib/syndication/syndication.rb
39
+ - lib/syndication/atom.rb
40
+ - test/rsstest.rb
41
+ - test/atomtest.rb
42
+ - examples/yahoo.rb
43
+ - README
44
+ - IMPLEMENTATION
45
+ test_files:
46
+ - test/atomtest.rb
47
+ - test/rsstest.rb
48
+ rdoc_options: []
49
+ extra_rdoc_files:
50
+ - README
51
+ - IMPLEMENTATION
52
+ executables: []
53
+ extensions: []
54
+ requirements: []
55
+ dependencies: []