rss 0.2.8 → 0.2.9

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +16 -0
  3. data/Rakefile +8 -1
  4. data/lib/rss/itunes.rb +49 -1
  5. data/lib/rss/maker/itunes.rb +13 -0
  6. data/lib/rss/parser.rb +1 -1
  7. data/lib/rss/version.rb +1 -1
  8. data/rss.gemspec +6 -56
  9. data/test/dot.png +0 -0
  10. data/test/rss-assertions.rb +2116 -0
  11. data/test/rss-testcase.rb +479 -0
  12. data/test/run-test.rb +15 -0
  13. data/test/test_1.0.rb +308 -0
  14. data/test/test_2.0.rb +412 -0
  15. data/test/test_accessor.rb +104 -0
  16. data/test/test_atom.rb +684 -0
  17. data/test/test_content.rb +105 -0
  18. data/test/test_dublincore.rb +270 -0
  19. data/test/test_image.rb +215 -0
  20. data/test/test_inherit.rb +41 -0
  21. data/test/test_itunes.rb +360 -0
  22. data/test/test_maker_0.9.rb +477 -0
  23. data/test/test_maker_1.0.rb +519 -0
  24. data/test/test_maker_2.0.rb +758 -0
  25. data/test/test_maker_atom_entry.rb +394 -0
  26. data/test/test_maker_atom_feed.rb +455 -0
  27. data/test/test_maker_content.rb +48 -0
  28. data/test/test_maker_dc.rb +150 -0
  29. data/test/test_maker_image.rb +63 -0
  30. data/test/test_maker_itunes.rb +488 -0
  31. data/test/test_maker_slash.rb +38 -0
  32. data/test/test_maker_sy.rb +45 -0
  33. data/test/test_maker_taxo.rb +82 -0
  34. data/test/test_maker_trackback.rb +42 -0
  35. data/test/test_maker_xml-stylesheet.rb +84 -0
  36. data/test/test_parser.rb +122 -0
  37. data/test/test_parser_1.0.rb +529 -0
  38. data/test/test_parser_2.0.rb +123 -0
  39. data/test/test_parser_atom_entry.rb +164 -0
  40. data/test/test_parser_atom_feed.rb +277 -0
  41. data/test/test_setup_maker_0.9.rb +247 -0
  42. data/test/test_setup_maker_1.0.rb +551 -0
  43. data/test/test_setup_maker_2.0.rb +309 -0
  44. data/test/test_setup_maker_atom_entry.rb +410 -0
  45. data/test/test_setup_maker_atom_feed.rb +446 -0
  46. data/test/test_setup_maker_itunes.rb +146 -0
  47. data/test/test_setup_maker_slash.rb +39 -0
  48. data/test/test_slash.rb +65 -0
  49. data/test/test_syndication.rb +126 -0
  50. data/test/test_taxonomy.rb +173 -0
  51. data/test/test_to_s.rb +701 -0
  52. data/test/test_trackback.rb +136 -0
  53. data/test/test_xml-stylesheet.rb +109 -0
  54. metadata +109 -7
  55. data/.gitignore +0 -9
  56. data/.travis.yml +0 -26
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: false
2
+ require_relative "rss-testcase"
3
+
4
+ require "rss/maker"
5
+
6
+ module RSS
7
+ class TestSetupMakerSlash < TestCase
8
+ def test_setup_maker
9
+ elements = {
10
+ "section" => "articles",
11
+ "department" => "not-an-ocean-unless-there-are-lobsters",
12
+ "comments" => 177,
13
+ "hit_parades" => [177, 155, 105, 33, 6, 3, 0],
14
+ }
15
+
16
+ rss = RSS::Maker.make("rss1.0") do |maker|
17
+ setup_dummy_channel(maker)
18
+ setup_dummy_item(maker)
19
+
20
+ item = maker.items.last
21
+ item.slash_section = elements["section"]
22
+ item.slash_department = elements["department"]
23
+ item.slash_comments = elements["comments"]
24
+ item.slash_hit_parade = elements["hit_parades"].join(",")
25
+ end
26
+ assert_not_nil(rss)
27
+
28
+ new_rss = RSS::Maker.make("rss1.0") do |maker|
29
+ rss.setup_maker(maker)
30
+ end
31
+ assert_not_nil(new_rss)
32
+
33
+ item = new_rss.items.last
34
+ assert_not_nil(item)
35
+
36
+ assert_slash_elements(elements, item)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: false
2
+ require "cgi"
3
+ require "rexml/document"
4
+
5
+ require_relative "rss-testcase"
6
+
7
+ require "rss/1.0"
8
+ require "rss/slash"
9
+
10
+ module RSS
11
+ class TestSlash < TestCase
12
+ def setup
13
+ @elements = {
14
+ "section" => "articles",
15
+ "department" => "not-an-ocean-unless-there-are-lobsters",
16
+ "comments" => 177,
17
+ "hit_parades" => [177, 155, 105, 33, 6, 3, 0],
18
+ }
19
+
20
+ slash_nodes = @elements.collect do |name, value|
21
+ if name == "hit_parades"
22
+ name = "hit_parade"
23
+ value = value.join(",")
24
+ end
25
+ "<slash:#{name}>#{value}</slash:#{name}>"
26
+ end.join("\n")
27
+
28
+ slash_ns = {"slash" => "http://purl.org/rss/1.0/modules/slash/"}
29
+ @source = make_RDF(<<-EOR, slash_ns)
30
+ #{make_channel}
31
+ #{make_image}
32
+ #{make_item(slash_nodes)}
33
+ #{make_textinput}
34
+ EOR
35
+ end
36
+
37
+ def test_parser
38
+ rss = RSS::Parser.parse(@source)
39
+
40
+ assert_not_nil(rss)
41
+
42
+ item = rss.items[0]
43
+ assert_not_nil(item)
44
+
45
+ assert_slash_elements(item)
46
+ end
47
+
48
+ def test_to_s
49
+ rss = RSS::Parser.parse(@source)
50
+ rss = RSS::Parser.parse(rss.to_s)
51
+
52
+ assert_not_nil(rss)
53
+
54
+ item = rss.items[0]
55
+ assert_not_nil(item)
56
+
57
+ assert_slash_elements(item)
58
+ end
59
+
60
+ private
61
+ def assert_slash_elements(target)
62
+ super(@elements, target)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: false
2
+ require "cgi"
3
+ require "rexml/document"
4
+
5
+ require_relative "rss-testcase"
6
+
7
+ require "rss/1.0"
8
+ require "rss/syndication"
9
+
10
+ module RSS
11
+ class TestSyndication < TestCase
12
+
13
+ def setup
14
+ @prefix = "sy"
15
+ @uri = "http://purl.org/rss/1.0/modules/syndication/"
16
+
17
+ @parents = %w(channel)
18
+
19
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
20
+ class << t
21
+ alias_method(:to_s, :iso8601)
22
+ end
23
+
24
+ @elems = {
25
+ :updatePeriod => "hourly",
26
+ :updateFrequency => "2",
27
+ :updateBase => t,
28
+ }
29
+
30
+ @sy_nodes = @elems.collect do |name, value|
31
+ "<#{@prefix}:#{name}>#{CGI.escapeHTML(value.to_s)}</#{@prefix}:#{name}>"
32
+ end.join("\n")
33
+
34
+ @rss_source = make_RDF(<<-EOR, {@prefix => @uri})
35
+ #{make_channel(@sy_nodes)}
36
+ #{make_image()}
37
+ #{make_item()}
38
+ #{make_textinput()}
39
+ EOR
40
+
41
+ @rss = Parser.parse(@rss_source)
42
+ end
43
+
44
+ def test_parser
45
+
46
+ assert_nothing_raised do
47
+ Parser.parse(@rss_source)
48
+ end
49
+
50
+ @elems.each do |tag, value|
51
+ assert_too_much_tag(tag.to_s, "channel") do
52
+ Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
53
+ #{make_channel(("<" + @prefix + ":" + tag.to_s + ">" +
54
+ CGI.escapeHTML(value.to_s) +
55
+ "</" + @prefix + ":" + tag.to_s + ">") * 2)}
56
+ #{make_item}
57
+ EOR
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ def test_accessor
64
+
65
+ t = Time.iso8601("2003-01-01T12:00:23+09:00")
66
+ class << t
67
+ alias_method(:to_s, :iso8601)
68
+ end
69
+
70
+ new_value = {
71
+ :updatePeriod => "daily",
72
+ :updateFrequency => "11",
73
+ :updateBase => t,
74
+ }
75
+
76
+ @elems.each do |name, value|
77
+ value = value.to_i if name == :updateFrequency
78
+ @parents.each do |parent|
79
+ assert_equal(value, @rss.__send__(parent).__send__("sy_#{name}"))
80
+ @rss.__send__(parent).__send__("sy_#{name}=", new_value[name])
81
+ new_val = new_value[name]
82
+ new_val = new_val.to_i if name == :updateFrequency
83
+ assert_equal(new_val, @rss.__send__(parent).__send__("sy_#{name}"))
84
+ end
85
+ end
86
+
87
+ %w(hourly daily weekly monthly yearly).each do |x|
88
+ @parents.each do |parent|
89
+ assert_nothing_raised do
90
+ @rss.__send__(parent).sy_updatePeriod = x
91
+ end
92
+ end
93
+ end
94
+
95
+ %w(-2 0.3 -0.4).each do |x|
96
+ @parents.each do |parent|
97
+ assert_not_available_value("sy:updateBase", x) do
98
+ @rss.__send__(parent).sy_updateBase = x
99
+ end
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ def test_to_s
106
+
107
+ @elems.each do |name, value|
108
+ excepted = "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
109
+ @parents.each do |parent|
110
+ assert_equal(excepted,
111
+ @rss.__send__(parent).__send__("sy_#{name}_element"))
112
+ end
113
+ end
114
+
115
+ REXML::Document.new(@rss_source).root.each_element do |parent|
116
+ if @parents.include?(parent.name)
117
+ parent.each_element do |elem|
118
+ if elem.namespace == @uri
119
+ assert_equal(elem.text, @elems[elem.name.intern].to_s)
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: false
2
+ require "cgi"
3
+
4
+ require_relative "rss-testcase"
5
+
6
+ require "rss/1.0"
7
+ require "rss/2.0"
8
+ require "rss/taxonomy"
9
+
10
+ module RSS
11
+ class TestTaxonomy < TestCase
12
+
13
+ def setup
14
+ @prefix = "taxo"
15
+ @uri = "http://purl.org/rss/1.0/modules/taxonomy/"
16
+ @dc_prefix = "dc"
17
+ @dc_uri = "http://purl.org/dc/elements/1.1/"
18
+
19
+ @ns = {
20
+ @prefix => @uri,
21
+ @dc_prefix => @dc_uri,
22
+ }
23
+
24
+ @topics_parents = %w(channel item)
25
+
26
+ @topics_lis = [
27
+ "http://meerkat.oreillynet.com/?c=cat23",
28
+ "http://meerkat.oreillynet.com/?c=47",
29
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
30
+ ]
31
+
32
+ @topics_node = "<#{@prefix}:topics>\n"
33
+ @topics_node << " <rdf:Bag>\n"
34
+ @topics_lis.each do |value|
35
+ resource = CGI.escapeHTML(value)
36
+ @topics_node << " <rdf:li resource=\"#{resource}\"/>\n"
37
+ end
38
+ @topics_node << " </rdf:Bag>\n"
39
+ @topics_node << "</#{@prefix}:topics>"
40
+
41
+ @topic_topics_lis = \
42
+ [
43
+ "http://meerkat.oreillynet.com/?c=cat23",
44
+ "http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/",
45
+ "http://dmoz.org/Computers/Programming/Internet/",
46
+ ]
47
+
48
+ @topic_contents = \
49
+ [
50
+ {
51
+ :link => "http://meerkat.oreillynet.com/?c=cat23",
52
+ :title => "Data: XML",
53
+ :description => "A Meerkat channel",
54
+ },
55
+ {
56
+ :link => "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
57
+ :title => "XML",
58
+ :subject => "XML",
59
+ :description => "DMOZ category",
60
+ :topics => @topic_topics_lis,
61
+ }
62
+ ]
63
+
64
+ @topic_nodes = @topic_contents.collect do |info|
65
+ link = info[:link]
66
+ rv = "<#{@prefix}:topic rdf:about=\"#{link}\">\n"
67
+ info.each do |name, value|
68
+ case name
69
+ when :topics
70
+ rv << " <#{@prefix}:topics>\n"
71
+ rv << " <rdf:Bag>\n"
72
+ value.each do |li|
73
+ resource = CGI.escapeHTML(li)
74
+ rv << " <rdf:li resource=\"#{resource}\"/>\n"
75
+ end
76
+ rv << " </rdf:Bag>\n"
77
+ rv << " </#{@prefix}:topics>\n"
78
+ else
79
+ prefix = (name == :link ? @prefix : @dc_prefix)
80
+ rv << " <#{prefix}:#{name}>#{value}</#{prefix}:#{name}>\n"
81
+ end
82
+ end
83
+ rv << "</#{@prefix}:topic>"
84
+ end
85
+
86
+ @rss_source = make_RDF(<<-EOR, @ns)
87
+ #{make_channel(@topics_node)}
88
+ #{make_image()}
89
+ #{make_item(@topics_node)}
90
+ #{make_textinput()}
91
+ #{@topic_nodes.join("\n")}
92
+ EOR
93
+
94
+ @rss = Parser.parse(@rss_source)
95
+ end
96
+
97
+ def test_parser
98
+ assert_nothing_raised do
99
+ Parser.parse(@rss_source)
100
+ end
101
+
102
+ assert_too_much_tag("topics", "channel") do
103
+ Parser.parse(make_RDF(<<-EOR, @ns))
104
+ #{make_channel(@topics_node * 2)}
105
+ #{make_item()}
106
+ EOR
107
+ end
108
+
109
+ assert_too_much_tag("topics", "item") do
110
+ Parser.parse(make_RDF(<<-EOR, @ns))
111
+ #{make_channel()}
112
+ #{make_item(@topics_node * 2)}
113
+ EOR
114
+ end
115
+ end
116
+
117
+ def test_accessor
118
+ topics = @rss.channel.taxo_topics
119
+ assert_equal(@topics_lis.sort,
120
+ topics.Bag.lis.collect {|li| li.resource}.sort)
121
+ assert_equal(@topics_lis.sort, topics.resources.sort)
122
+
123
+ assert_equal(@rss.taxo_topics.first, @rss.taxo_topic)
124
+
125
+ @topic_contents.each_with_index do |info, i|
126
+ topic = @rss.taxo_topics[i]
127
+ info.each do |name, value|
128
+ case name
129
+ when :link
130
+ assert_equal(value, topic.about)
131
+ assert_equal(value, topic.taxo_link)
132
+ when :topics
133
+ assert_equal(value.sort, topic.taxo_topics.resources.sort)
134
+ else
135
+ assert_equal(value, topic.__send__("dc_#{name}"))
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ def test_to_s
142
+ @topics_parents.each do |parent|
143
+ meth = "taxo_topics_element"
144
+ assert_equal(@topics_node, @rss.__send__(parent).__send__(meth))
145
+ end
146
+
147
+ @topic_nodes.each_with_index do |node, i|
148
+ expected_xml = taxo_xmlns_container(node)
149
+ expected = REXML::Document.new(expected_xml).root.elements[1]
150
+ actual_xml = taxo_xmlns_container(@rss.taxo_topics[i].to_s(true, ""))
151
+ actual = REXML::Document.new(actual_xml).root.elements[1]
152
+ expected_elems = expected.reject {|x| x.is_a?(REXML::Text)}
153
+ actual_elems = actual.reject {|x| x.is_a?(REXML::Text)}
154
+ expected_elems.sort! {|x, y| x.name <=> y.name}
155
+ actual_elems.sort! {|x, y| x.name <=> y.name}
156
+ assert_equal(expected_elems.collect {|x| x.to_s},
157
+ actual_elems.collect {|x| x.to_s})
158
+ assert_equal(expected.attributes.sort, actual.attributes.sort)
159
+ end
160
+ end
161
+
162
+ private
163
+ def taxo_xmlns_container(content)
164
+ xmlns_container({
165
+ @prefix => @uri,
166
+ "dc" => "http://purl.org/dc/elements/1.1/",
167
+ "rdf" => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
168
+ },
169
+ content)
170
+ end
171
+ end
172
+ end
173
+
@@ -0,0 +1,701 @@
1
+ # frozen_string_literal: false
2
+ require "rexml/document"
3
+
4
+ require_relative "rss-testcase"
5
+
6
+ require "rss/maker"
7
+ require "rss/1.0"
8
+ require "rss/2.0"
9
+ require "rss/content"
10
+ require "rss/dublincore"
11
+ require "rss/syndication"
12
+ require "rss/trackback"
13
+
14
+ module RSS
15
+ class TestToS < TestCase
16
+ def setup
17
+ @image_url = "http://example.com/foo.png"
18
+ @textinput_link = "http://example.com/search.cgi"
19
+ @item_links = [
20
+ "http://example.com/1",
21
+ "http://example.com/2",
22
+ ]
23
+
24
+ setup_xml_declaration_info
25
+ setup_xml_stylesheet_infos
26
+ setup_channel_info
27
+ setup_item_infos
28
+ setup_image_info
29
+ setup_textinput_info
30
+
31
+ setup_dublin_core_info
32
+ setup_syndication_info
33
+ setup_content_info
34
+ setup_trackback_info
35
+ end
36
+
37
+ def test_to_s_10
38
+ rss = RSS::Maker.make("1.0") do |maker|
39
+ setup_full(maker)
40
+ end
41
+
42
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
43
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
44
+ assert_channel10(@channel_info, rss.channel)
45
+ assert_items10(@item_infos, rss.items)
46
+ rss.items.each do |item|
47
+ assert_trackback(@trackback_info, item)
48
+ end
49
+ assert_image10(@image_info, rss.image)
50
+ assert_textinput10(@textinput_info, rss.textinput)
51
+
52
+ rss = RSS::Parser.parse(rss.to_s)
53
+
54
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
55
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
56
+ assert_channel10(@channel_info, rss.channel)
57
+ assert_items10(@item_infos, rss.items)
58
+ assert_image10(@image_info, rss.image)
59
+ assert_textinput10(@textinput_info, rss.textinput)
60
+ end
61
+
62
+ def test_to_s_09
63
+ rss = RSS::Maker.make("0.91") do |maker|
64
+ setup_full(maker)
65
+ end
66
+
67
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
68
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
69
+ assert_channel09(@channel_info, rss.channel)
70
+ assert_items09(@item_infos, rss.items)
71
+ assert_image09(@image_info, rss.image)
72
+ assert_textinput09(@textinput_info, rss.textinput)
73
+
74
+ rss = RSS::Parser.parse(rss.to_s)
75
+
76
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
77
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
78
+ assert_channel09(@channel_info, rss.channel)
79
+ assert_items09(@item_infos, rss.items)
80
+ assert_image09(@image_info, rss.image)
81
+ assert_textinput09(@textinput_info, rss.textinput)
82
+ end
83
+
84
+ def test_to_s_20
85
+ rss = RSS::Maker.make("2.0") do |maker|
86
+ setup_full(maker)
87
+ end
88
+
89
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
90
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
91
+ assert_channel20(@channel_info, rss.channel)
92
+ assert_items20(@item_infos, rss.items)
93
+ assert_image20(@image_info, rss.image)
94
+ assert_textinput20(@textinput_info, rss.textinput)
95
+
96
+ rss = RSS::Parser.parse(rss.to_s)
97
+
98
+ assert_xml_declaration(@version, @encoding, @standalone, rss)
99
+ assert_xml_stylesheets(@xs_infos, rss.xml_stylesheets)
100
+ assert_channel20(@channel_info, rss.channel)
101
+ assert_items20(@item_infos, rss.items)
102
+ assert_image20(@image_info, rss.image)
103
+ assert_textinput20(@textinput_info, rss.textinput)
104
+ end
105
+
106
+ def test_time_w3cdtf
107
+ assert_equal("2015-09-05T01:25:48.0001Z",
108
+ Time.utc(2015, 9, 5, 1, 25, 48, 100).w3cdtf,
109
+ '[ruby-core:70667] [Bug #11509]')
110
+ end
111
+
112
+ def test_20_empty_text
113
+ title = "Blog entries"
114
+ link = "http://blog.example.com/"
115
+ description = ""
116
+ rss = RSS::Maker.make("2.0") do |maker|
117
+ maker.channel.title = title
118
+ maker.channel.link = link
119
+ maker.channel.description = description
120
+ end
121
+
122
+ parsed_rss = RSS::Parser.parse(rss.to_s)
123
+ assert_equal({
124
+ title: title,
125
+ link: link,
126
+ description: description,
127
+ },
128
+ {
129
+ title: parsed_rss.channel.title,
130
+ link: parsed_rss.channel.link,
131
+ description: parsed_rss.channel.description,
132
+ },
133
+ "[ruby-core:80965] [Bug #13531]")
134
+ end
135
+
136
+ private
137
+ def setup_xml_declaration_info
138
+ @version = "1.0"
139
+ @encoding = "UTF-8"
140
+ @standalone = false
141
+ end
142
+
143
+ def setup_xml_stylesheet_infos
144
+ @xs_infos = [
145
+ {
146
+ "href" => "XXX.xsl",
147
+ "type" => "text/xsl",
148
+ "title" => "XXX",
149
+ "media" => "print",
150
+ "alternate" => "no",
151
+ },
152
+ {
153
+ "href" => "YYY.css",
154
+ "type" => "text/css",
155
+ "title" => "YYY",
156
+ "media" => "all",
157
+ "alternate" => "no",
158
+ },
159
+ ]
160
+ end
161
+
162
+ def setup_channel_info
163
+ @channel_info = {
164
+ "about" => "http://example.com/index.rdf",
165
+ "title" => "Sample RSS",
166
+ "link" => "http://example.com/",
167
+ "description" => "Sample\n\n\n\n\nSite",
168
+ "language" => "en",
169
+ "copyright" => "FDL",
170
+ "managingEditor" => "foo@example.com",
171
+ "webMaster" => "webmaster@example.com",
172
+ "rating" => '(PICS-1.1 "http://www.rsac.org/ratingsv01.html" l gen true comment "RSACi North America Server" for "http://www.rsac.org" on "1996.04.16T08:15-0500" r (n 0 s 0 v 0 l 0))',
173
+ "docs" => "http://backend.userland.com/rss091",
174
+ "skipDays" => [
175
+ "Monday",
176
+ "Friday",
177
+ ],
178
+ "skipHours" => [
179
+ "12",
180
+ "23",
181
+ ],
182
+ "date" => Time.now,
183
+ "lastBuildDate" => Time.now - 3600,
184
+ "generator" => "RSS Maker",
185
+ "ttl" => "60",
186
+ "cloud" => {
187
+ "domain" => "rpc.sys.com",
188
+ "port" => "80",
189
+ "path" => "/RPC2",
190
+ "registerProcedure" => "myCloud.rssPleaseNotify",
191
+ "protocol" => "xml-rpc",
192
+ },
193
+ "category" => {
194
+ "domain" => "http://example.com/misc/",
195
+ "content" => "misc",
196
+ },
197
+
198
+ "image" => {
199
+ "resource" => @image_url,
200
+ },
201
+
202
+ "textinput" => {
203
+ "resource" => @textinput_link,
204
+ },
205
+
206
+ "items" => @item_links.collect{|link| {"resource" => link}},
207
+ }
208
+ end
209
+
210
+ def setup_item_infos
211
+ @item_infos = [
212
+ {
213
+ "title" => "Sample item1",
214
+ "link" => @item_links[0],
215
+ "description" => "Sample description1",
216
+ "date" => Time.now - 3600,
217
+ "author" => "foo@example.com",
218
+ "comments" => "http://example.com/1/comments",
219
+ "guid" => {
220
+ "isPermaLink" => "true",
221
+ "content" => "http://example.com/1",
222
+ },
223
+ "enclosure" => {
224
+ "url" => "http://example.com/1.mp3",
225
+ "length" => "100",
226
+ "type" => "audio/mpeg",
227
+ },
228
+ "source" => {
229
+ "url" => "http:/example.com/",
230
+ "content" => "Sample site",
231
+ },
232
+ "category" => {
233
+ "domain" => "http://example.com/misc/",
234
+ "content" => "misc",
235
+ },
236
+ },
237
+
238
+ {
239
+ "title" => "Sample item2",
240
+ "link" => @item_links[1],
241
+ "description" => "Sample description2",
242
+ "date" => Time.now - 7200,
243
+ "author" => "foo@example.com",
244
+ "comments" => "http://example.com/2/comments",
245
+ "guid" => {
246
+ "isPermaLink" => "false",
247
+ "content" => "http://example.com/2",
248
+ },
249
+ "enclosure" => {
250
+ "url" => "http://example.com/2.mp3",
251
+ "length" => "200",
252
+ "type" => "audio/mpeg",
253
+ },
254
+ "source" => {
255
+ "url" => "http:/example.com/",
256
+ "content" => "Sample site",
257
+ },
258
+ "category" => {
259
+ "domain" => "http://example.com/misc/",
260
+ "content" => "misc",
261
+ },
262
+ },
263
+ ]
264
+ end
265
+
266
+ def setup_image_info
267
+ @image_info = {
268
+ "title" => "Sample image",
269
+ "url" => @image_url,
270
+ "width" => "88",
271
+ "height" => "31",
272
+ "description" => "Sample",
273
+ }
274
+ end
275
+
276
+ def setup_textinput_info
277
+ @textinput_info = {
278
+ "title" => "Sample textinput",
279
+ "description" => "Search",
280
+ "name" => "key",
281
+ "link" => @textinput_link,
282
+ }
283
+ end
284
+
285
+ def setup_dublin_core_info
286
+ @dc_info = {
287
+ "title" => "DC title",
288
+ "description" => "DC desc",
289
+ "creator" => "DC creator",
290
+ "subject" => "DC subject",
291
+ "publisher" => "DC publisher",
292
+ "contributor" => "DC contributor",
293
+ "type" => "DC type",
294
+ "format" => "DC format",
295
+ "identifier" => "DC identifier",
296
+ "source" => "DC source",
297
+ "language" => "ja",
298
+ "relation" => "DC relation",
299
+ "coverage" => "DC coverage",
300
+ "rights" => "DC rights",
301
+ "date" => Time.now - 60,
302
+ }
303
+ end
304
+
305
+ def setup_syndication_info
306
+ @sy_info = {
307
+ "updatePeriod" => "hourly",
308
+ "updateFrequency" => "2",
309
+ "updateBase" => Time.now - 3600,
310
+ }
311
+ end
312
+
313
+ def setup_content_info
314
+ @content_info = {
315
+ "encoded" => "<p>p</p>",
316
+ }
317
+ end
318
+
319
+ def setup_trackback_info
320
+ @trackback_info = {
321
+ "ping" => "http://example.com/tb.cgi?tb_id=XXX",
322
+ "abouts" => [
323
+ "http://example.net/tb.cgi?tb_id=YYY",
324
+ "http://example.org/tb.cgi?tb_id=ZZZ",
325
+ ]
326
+ }
327
+ end
328
+
329
+
330
+ def setup_full(maker)
331
+ setup_xml_declaration(maker)
332
+ setup_xml_stylesheets(maker)
333
+ setup_channel(maker)
334
+ setup_image(maker)
335
+ setup_items(maker)
336
+ setup_textinput(maker)
337
+ end
338
+
339
+ def setup_xml_declaration(maker)
340
+ %w(version encoding standalone).each do |name|
341
+ maker.__send__("#{name}=", instance_eval("@#{name}"))
342
+ end
343
+ end
344
+
345
+ def setup_xml_stylesheets(maker)
346
+ @xs_infos.each do |info|
347
+ xs = maker.xml_stylesheets.new_xml_stylesheet
348
+ info.each do |name, value|
349
+ xs.__send__("#{name}=", value)
350
+ end
351
+ end
352
+ end
353
+
354
+ def setup_channel(maker)
355
+ channel = maker.channel
356
+ info = @channel_info
357
+
358
+ %w(about title link description language copyright
359
+ managingEditor webMaster rating docs date
360
+ lastBuildDate generator ttl).each do |name|
361
+ channel.__send__("#{name}=", info[name])
362
+ end
363
+
364
+ skipDays = channel.skipDays
365
+ info["skipDays"].each do |day|
366
+ new_day = skipDays.new_day
367
+ new_day.content = day
368
+ end
369
+
370
+ skipHours = channel.skipHours
371
+ info["skipHours"].each do |hour|
372
+ new_hour = skipHours.new_hour
373
+ new_hour.content = hour
374
+ end
375
+
376
+ cloud = channel.cloud
377
+ %w(domain port path registerProcedure protocol).each do |name|
378
+ cloud.__send__("#{name}=", info["cloud"][name])
379
+ end
380
+
381
+ category = channel.categories.new_category
382
+ %w(domain content).each do |name|
383
+ category.__send__("#{name}=", info["category"][name])
384
+ end
385
+ end
386
+
387
+ def setup_image(maker)
388
+ image = maker.image
389
+ info = @image_info
390
+
391
+ %w(title url width height description).each do |name|
392
+ image.__send__("#{name}=", info[name])
393
+ end
394
+ end
395
+
396
+ def setup_items(maker)
397
+ items = maker.items
398
+
399
+ @item_infos.each do |info|
400
+ item = items.new_item
401
+ %w(title link description date author comments).each do |name|
402
+ item.__send__("#{name}=", info[name])
403
+ end
404
+
405
+ guid = item.guid
406
+ %w(isPermaLink content).each do |name|
407
+ guid.__send__("#{name}=", info["guid"][name])
408
+ end
409
+
410
+ enclosure = item.enclosure
411
+ %w(url length type).each do |name|
412
+ enclosure.__send__("#{name}=", info["enclosure"][name])
413
+ end
414
+
415
+ source = item.source
416
+ %w(url content).each do |name|
417
+ source.__send__("#{name}=", info["source"][name])
418
+ end
419
+
420
+ category = item.categories.new_category
421
+ %w(domain content).each do |name|
422
+ category.__send__("#{name}=", info["category"][name])
423
+ end
424
+
425
+ setup_trackback(item)
426
+ end
427
+ end
428
+
429
+ def setup_textinput(maker)
430
+ textinput = maker.textinput
431
+ info = @textinput_info
432
+
433
+ %w(title description name link).each do |name|
434
+ textinput.__send__("#{name}=", info[name])
435
+ end
436
+ end
437
+
438
+ def setup_content(target)
439
+ prefix = "content"
440
+ %w(encoded).each do |name|
441
+ target.__send__("#{prefix}_#{name}=", @content_info[name])
442
+ end
443
+ end
444
+
445
+ def setup_dublin_core(target)
446
+ prefix = "dc"
447
+ %w(title description creator subject publisher
448
+ contributor type format identifier source language
449
+ relation coverage rights).each do |name|
450
+ target.__send__("#{prefix}_#{name}=", @dc_info[name])
451
+ end
452
+ end
453
+
454
+ def setup_syndicate(target)
455
+ prefix = "sy"
456
+ %w(updatePeriod updateFrequency updateBase).each do |name|
457
+ target.__send__("#{prefix}_#{name}=", @sy_info[name])
458
+ end
459
+ end
460
+
461
+ def setup_trackback(target)
462
+ target.trackback_ping = @trackback_info["ping"]
463
+ @trackback_info["abouts"].each do |about|
464
+ new_about = target.trackback_abouts.new_about
465
+ new_about.value = about
466
+ end
467
+ end
468
+
469
+
470
+ def assert_channel10(attrs, channel)
471
+ _wrap_assertion do
472
+ n_attrs = normalized_attrs(attrs)
473
+
474
+ names = %w(about title link description)
475
+ assert_attributes(attrs, names, channel)
476
+
477
+ %w(image items textinput).each do |name|
478
+ value = n_attrs[name]
479
+ if value
480
+ target = channel.__send__(name)
481
+ __send__("assert_channel10_#{name}", value, target)
482
+ end
483
+ end
484
+ end
485
+ end
486
+
487
+ def assert_channel10_image(attrs, image)
488
+ _wrap_assertion do
489
+ assert_attributes(attrs, %w(resource), image)
490
+ end
491
+ end
492
+
493
+ def assert_channel10_textinput(attrs, textinput)
494
+ _wrap_assertion do
495
+ assert_attributes(attrs, %w(resource), textinput)
496
+ end
497
+ end
498
+
499
+ def assert_channel10_items(attrs, items)
500
+ _wrap_assertion do
501
+ assert_equal(items.resources, items.Seq.lis.collect {|x| x.resource})
502
+ items.Seq.lis.each_with_index do |li, i|
503
+ assert_attributes(attrs[i], %w(resource), li)
504
+ end
505
+ end
506
+ end
507
+
508
+ def assert_image10(attrs, image)
509
+ _wrap_assertion do
510
+ names = %w(about title url link)
511
+ assert_attributes(attrs, names, image)
512
+ end
513
+ end
514
+
515
+ def assert_items10(attrs, items)
516
+ _wrap_assertion do
517
+ names = %w(about title link description)
518
+ items.each_with_index do |item, i|
519
+ assert_attributes(attrs[i], names, item)
520
+ end
521
+ end
522
+ end
523
+
524
+ def assert_textinput10(attrs, textinput)
525
+ _wrap_assertion do
526
+ names = %w(about title description name link)
527
+ assert_attributes(attrs, names, textinput)
528
+ end
529
+ end
530
+
531
+
532
+ def assert_channel09(attrs, channel)
533
+ _wrap_assertion do
534
+ n_attrs = normalized_attrs(attrs)
535
+
536
+ names = %w(title description link language rating
537
+ copyright pubDate lastBuildDate docs
538
+ managingEditor webMaster)
539
+ assert_attributes(attrs, names, channel)
540
+
541
+ %w(skipHours skipDays).each do |name|
542
+ value = n_attrs[name]
543
+ if value
544
+ target = channel.__send__(name)
545
+ __send__("assert_channel09_#{name}", value, target)
546
+ end
547
+ end
548
+ end
549
+ end
550
+
551
+ def assert_channel09_skipDays(contents, skipDays)
552
+ _wrap_assertion do
553
+ days = skipDays.days
554
+ contents.each_with_index do |content, i|
555
+ assert_equal(content, days[i].content)
556
+ end
557
+ end
558
+ end
559
+
560
+ def assert_channel09_skipHours(contents, skipHours)
561
+ _wrap_assertion do
562
+ hours = skipHours.hours
563
+ contents.each_with_index do |content, i|
564
+ assert_equal(content.to_i, hours[i].content)
565
+ end
566
+ end
567
+ end
568
+
569
+ def assert_image09(attrs, image)
570
+ _wrap_assertion do
571
+ names = %w(url link title description)
572
+ names << ["width", :integer]
573
+ names << ["height", :integer]
574
+ assert_attributes(attrs, names, image)
575
+ end
576
+ end
577
+
578
+ def assert_items09(attrs, items)
579
+ _wrap_assertion do
580
+ names = %w(title link description)
581
+ items.each_with_index do |item, i|
582
+ assert_attributes(attrs[i], names, item)
583
+ end
584
+ end
585
+ end
586
+
587
+ def assert_textinput09(attrs, textinput)
588
+ _wrap_assertion do
589
+ names = %w(title description name link)
590
+ assert_attributes(attrs, names, textinput)
591
+ end
592
+ end
593
+
594
+
595
+ def assert_channel20(attrs, channel)
596
+ _wrap_assertion do
597
+ n_attrs = normalized_attrs(attrs)
598
+
599
+ names = %w(title link description language copyright
600
+ managingEditor webMaster pubDate
601
+ lastBuildDate generator docs rating)
602
+ names << ["ttl", :integer]
603
+ assert_attributes(attrs, names, channel)
604
+
605
+ %w(cloud categories skipHours skipDays).each do |name|
606
+ value = n_attrs[name]
607
+ if value
608
+ target = channel.__send__(name)
609
+ __send__("assert_channel20_#{name}", value, target)
610
+ end
611
+ end
612
+ end
613
+ end
614
+
615
+ def assert_channel20_skipDays(contents, skipDays)
616
+ assert_channel09_skipDays(contents, skipDays)
617
+ end
618
+
619
+ def assert_channel20_skipHours(contents, skipHours)
620
+ assert_channel09_skipHours(contents, skipHours)
621
+ end
622
+
623
+ def assert_channel20_cloud(attrs, cloud)
624
+ _wrap_assertion do
625
+ names = %w(domain path registerProcedure protocol)
626
+ names << ["port", :integer]
627
+ assert_attributes(attrs, names, cloud)
628
+ end
629
+ end
630
+
631
+ def assert_channel20_categories(attrs, categories)
632
+ _wrap_assertion do
633
+ names = %w(domain content)
634
+ categories.each_with_index do |category, i|
635
+ assert_attributes(attrs[i], names, category)
636
+ end
637
+ end
638
+ end
639
+
640
+ def assert_image20(attrs, image)
641
+ _wrap_assertion do
642
+ names = %w(url link title description)
643
+ names << ["width", :integer]
644
+ names << ["height", :integer]
645
+ assert_attributes(attrs, names, image)
646
+ end
647
+ end
648
+
649
+ def assert_items20(attrs, items)
650
+ _wrap_assertion do
651
+ names = %w(about title link description)
652
+ items.each_with_index do |item, i|
653
+ assert_attributes(attrs[i], names, item)
654
+
655
+ n_attrs = normalized_attrs(attrs[i])
656
+
657
+ %w(source enclosure categories guid).each do |name|
658
+ value = n_attrs[name]
659
+ if value
660
+ target = item.__send__(name)
661
+ __send__("assert_items20_#{name}", value, target)
662
+ end
663
+ end
664
+ end
665
+ end
666
+ end
667
+
668
+ def assert_items20_source(attrs, source)
669
+ _wrap_assertion do
670
+ assert_attributes(attrs, %w(url content), source)
671
+ end
672
+ end
673
+
674
+ def assert_items20_enclosure(attrs, enclosure)
675
+ _wrap_assertion do
676
+ names = ["url", ["length", :integer], "type"]
677
+ assert_attributes(attrs, names, enclosure)
678
+ end
679
+ end
680
+
681
+ def assert_items20_categories(attrs, categories)
682
+ _wrap_assertion do
683
+ assert_channel20_categories(attrs, categories)
684
+ end
685
+ end
686
+
687
+ def assert_items20_guid(attrs, guid)
688
+ _wrap_assertion do
689
+ names = [["isPermaLink", :boolean], ["content"]]
690
+ assert_attributes(attrs, names, guid)
691
+ end
692
+ end
693
+
694
+ def assert_textinput20(attrs, textinput)
695
+ _wrap_assertion do
696
+ names = %w(title description name link)
697
+ assert_attributes(attrs, names, textinput)
698
+ end
699
+ end
700
+ end
701
+ end