rss 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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