summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--lib/rss.rb5
-rw-r--r--lib/rss/0.9.rb532
-rw-r--r--lib/rss/1.0.rb486
-rw-r--r--lib/rss/2.0.rb97
-rw-r--r--lib/rss/atom.rb749
-rw-r--r--lib/rss/content.rb25
-rw-r--r--lib/rss/converter.rb19
-rw-r--r--lib/rss/dublincore.rb62
-rw-r--r--lib/rss/dublincore/1.0.rb13
-rw-r--r--lib/rss/dublincore/2.0.rb13
-rw-r--r--lib/rss/dublincore/atom.rb17
-rw-r--r--lib/rss/image.rb116
-rw-r--r--lib/rss/maker.rb19
-rw-r--r--lib/rss/maker/0.9.rb372
-rw-r--r--lib/rss/maker/1.0.rb328
-rw-r--r--lib/rss/maker/2.0.rb134
-rw-r--r--lib/rss/maker/atom.rb172
-rw-r--r--lib/rss/maker/base.rb710
-rw-r--r--lib/rss/maker/dublincore.rb100
-rw-r--r--lib/rss/maker/entry.rb167
-rw-r--r--lib/rss/maker/feed.rb429
-rw-r--r--lib/rss/maker/image.rb100
-rw-r--r--lib/rss/maker/taxonomy.rb73
-rw-r--r--lib/rss/maker/trackback.rb85
-rw-r--r--lib/rss/parser.rb172
-rw-r--r--lib/rss/rss.rb661
-rw-r--r--lib/rss/syndication.rb32
-rw-r--r--lib/rss/taxonomy.rb128
-rw-r--r--lib/rss/trackback.rb106
-rw-r--r--lib/rss/utils.rb7
-rw-r--r--lib/rss/xml.rb71
-rwxr-xr-xsample/rss/blend.rb6
-rwxr-xr-xsample/rss/convert.rb69
-rwxr-xr-x[-rw-r--r--]sample/rss/list_description.rb13
-rwxr-xr-xsample/rss/re_read.rb10
-rwxr-xr-x[-rw-r--r--]sample/rss/rss_recent.rb19
-rw-r--r--test/rss/rss-assertions.rb2197
-rw-r--r--test/rss/rss-testcase.rb201
-rw-r--r--test/rss/test_1.0.rb81
-rw-r--r--test/rss/test_2.0.rb54
-rw-r--r--test/rss/test_atom.rb281
-rw-r--r--test/rss/test_content.rb2
-rw-r--r--test/rss/test_dublincore.rb316
-rw-r--r--test/rss/test_image.rb18
-rw-r--r--test/rss/test_maker_0.9.rb140
-rw-r--r--test/rss/test_maker_1.0.rb171
-rw-r--r--test/rss/test_maker_2.0.rb74
-rw-r--r--test/rss/test_maker_atom_entry.rb367
-rw-r--r--test/rss/test_maker_atom_feed.rb380
-rw-r--r--test/rss/test_maker_dc.rb15
-rw-r--r--test/rss/test_maker_sy.rb1
-rw-r--r--test/rss/test_maker_taxo.rb10
-rw-r--r--test/rss/test_maker_trackback.rb5
-rw-r--r--test/rss/test_maker_xml-stylesheet.rb46
-rw-r--r--test/rss/test_parser.rb586
-rw-r--r--test/rss/test_parser_1.0.rb503
-rw-r--r--test/rss/test_parser_2.0.rb122
-rw-r--r--test/rss/test_parser_atom_entry.rb163
-rw-r--r--test/rss/test_parser_atom_feed.rb276
-rw-r--r--test/rss/test_setup_maker_0.9.rb61
-rw-r--r--test/rss/test_setup_maker_1.0.rb124
-rw-r--r--test/rss/test_setup_maker_2.0.rb75
-rw-r--r--test/rss/test_setup_maker_atom_entry.rb409
-rw-r--r--test/rss/test_setup_maker_atom_feed.rb443
-rw-r--r--test/rss/test_syndication.rb6
-rw-r--r--test/rss/test_taxonomy.rb2
-rw-r--r--test/rss/test_trackback.rb2
-rw-r--r--test/rss/test_version.rb2
-rw-r--r--test/rss/test_xml-stylesheet.rb6
-rw-r--r--version.h6
71 files changed, 10239 insertions, 3030 deletions
diff --git a/ChangeLog b/ChangeLog
index d3dac8535f8..882615338ee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sat Mar 17 19:10:39 2007 Kouhei Sutou <kou@cozmixng.org>
+
+ * lib/rss, test/rss:
+ - supported Atom.
+ - bumped version 0.1.6 to 0.1.7.
+ * sample/rss/convert.rb: added new sample.
+
Fri Mar 16 22:32:20 2007 Minero Aoki <aamine@loveruby.net>
* lib/net/pop.rb: change default verification mode from
diff --git a/lib/rss.rb b/lib/rss.rb
index 495edb1b98b..bbe19ad95c5 100644
--- a/lib/rss.rb
+++ b/lib/rss.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2003-2005 Kouhei Sutou. You can redistribute it and/or
+# Copyright (c) 2003-2006 Kouhei Sutou. You can redistribute it and/or
# modify it under the same terms as Ruby.
#
# Author:: Kouhei Sutou <kou@cozmixng.org>
@@ -6,11 +6,12 @@
require 'rss/1.0'
require 'rss/2.0'
+require 'rss/atom'
require 'rss/content'
require 'rss/dublincore'
require 'rss/image'
require 'rss/syndication'
-#require 'rss/taxonomy'
+require 'rss/taxonomy'
require 'rss/trackback'
require "rss/maker"
diff --git a/lib/rss/0.9.rb b/lib/rss/0.9.rb
index 900536869de..7b24e7596da 100644
--- a/lib/rss/0.9.rb
+++ b/lib/rss/0.9.rb
@@ -9,7 +9,7 @@ module RSS
def self.append_features(klass)
super
- klass.install_must_call_validator('', nil)
+ klass.install_must_call_validator('', "")
end
end
@@ -17,22 +17,18 @@ module RSS
include RSS09
include RootElementMixin
- # include XMLStyleSheetMixin
-
- [
- ["channel", nil],
- ].each do |tag, occurs|
- install_model(tag, occurs)
- end
%w(channel).each do |name|
- install_have_child_element(name)
+ install_have_child_element(name, "", nil)
end
- attr_accessor :rss_version, :version, :encoding, :standalone
-
- def initialize(rss_version, version=nil, encoding=nil, standalone=nil)
+ attr_writer :feed_version
+ alias_method(:rss_version, :feed_version)
+ alias_method(:rss_version=, :feed_version=)
+
+ def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
super
+ @feed_type = "rss"
end
def items
@@ -58,34 +54,20 @@ module RSS
nil
end
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent, ns_declarations) do |next_indent|
- [
- channel_element(false, next_indent),
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
- private
- def children
- [@channel]
- end
-
- def _tags
- [
- [nil, 'channel'],
- ].delete_if do |uri, name|
- __send__(name).nil?
+ def setup_maker_elements(maker)
+ super
+ items.each do |item|
+ item.setup_maker(maker.items)
end
+ image.setup_maker(maker) if image
+ textinput.setup_maker(maker) if textinput
end
+ private
def _attrs
[
- ["version", true, "rss_version"],
+ ["version", true, "feed_version"],
]
end
@@ -94,119 +76,30 @@ module RSS
include RSS09
[
- ["title", nil],
- ["link", nil],
- ["description", nil],
- ["language", nil],
- ["copyright", "?"],
- ["managingEditor", "?"],
- ["webMaster", "?"],
- ["rating", "?"],
- ["docs", "?"],
- ].each do |name, occurs|
- install_text_element(name)
- install_model(name, occurs)
- end
-
- [
- ["pubDate", "?"],
- ["lastBuildDate", "?"],
- ].each do |name, occurs|
- install_date_element(name, 'rfc822')
- install_model(name, occurs)
+ ["title", nil, :text],
+ ["link", nil, :text],
+ ["description", nil, :text],
+ ["language", nil, :text],
+ ["copyright", "?", :text],
+ ["managingEditor", "?", :text],
+ ["webMaster", "?", :text],
+ ["rating", "?", :text],
+ ["pubDate", "?", :date, :rfc822],
+ ["lastBuildDate", "?", :date, :rfc822],
+ ["docs", "?", :text],
+ ["cloud", "?", :have_attribute],
+ ["skipDays", "?", :have_child],
+ ["skipHours", "?", :have_child],
+ ["image", nil, :have_child],
+ ["item", "*", :have_children],
+ ["textInput", "?", :have_child],
+ ].each do |name, occurs, type, *args|
+ __send__("install_#{type}_element", name, "", occurs, name, *args)
end
alias date pubDate
alias date= pubDate=
- [
- ["skipDays", "?"],
- ["skipHours", "?"],
- ["image", nil],
- ["textInput", "?"],
- ].each do |name, occurs|
- install_have_child_element(name)
- install_model(name, occurs)
- end
-
- [
- ["cloud", "?"]
- ].each do |name, occurs|
- install_have_attribute_element(name)
- install_model(name, occurs)
- end
-
- [
- ["item", "*"]
- ].each do |name, occurs|
- install_have_children_element(name)
- install_model(name, occurs)
- end
-
- def initialize()
- super()
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- link_element(false, next_indent),
- description_element(false, next_indent),
- language_element(false, next_indent),
- copyright_element(false, next_indent),
- managingEditor_element(false, next_indent),
- webMaster_element(false, next_indent),
- rating_element(false, next_indent),
- pubDate_element(false, next_indent),
- lastBuildDate_element(false, next_indent),
- docs_element(false, next_indent),
- cloud_element(false, next_indent),
- skipDays_element(false, next_indent),
- skipHours_element(false, next_indent),
- image_element(false, next_indent),
- item_elements(false, next_indent),
- textInput_element(false, next_indent),
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
-
private
- def children
- [@skipDays, @skipHours, @image, @textInput, @cloud, *@item]
- end
-
- def _tags
- rv = [
- "title",
- "link",
- "description",
- "language",
- "copyright",
- "managingEditor",
- "webMaster",
- "rating",
- "docs",
- "skipDays",
- "skipHours",
- "image",
- "textInput",
- "cloud",
- ].delete_if do |name|
- __send__(name).nil?
- end.collect do |elem|
- [nil, elem]
- end
-
- @item.each do
- rv << [nil, "item"]
- end
-
- rv
- end
-
def maker_target(maker)
maker.channel
end
@@ -237,29 +130,7 @@ module RSS
[
["day", "*"]
].each do |name, occurs|
- install_have_children_element(name)
- install_model(name, occurs)
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- day_elements(false, next_indent)
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def children
- @day
- end
-
- def _tags
- @day.compact.collect do
- [nil, "day"]
- end
+ install_have_children_element(name, "", occurs)
end
class Day < Element
@@ -267,9 +138,13 @@ module RSS
content_setup
- def initialize(content=nil)
- super()
- self.content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
end
end
@@ -282,29 +157,7 @@ module RSS
[
["hour", "*"]
].each do |name, occurs|
- install_have_children_element(name)
- install_model(name, occurs)
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- hour_elements(false, next_indent)
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def children
- @hour
- end
-
- def _tags
- @hour.compact.collect do
- [nil, "hour"]
- end
+ install_have_children_element(name, "", occurs)
end
class Hour < Element
@@ -312,9 +165,13 @@ module RSS
content_setup(:integer)
- def initialize(content=nil)
- super()
- self.content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
end
end
@@ -325,54 +182,31 @@ module RSS
include RSS09
%w(url title link).each do |name|
- install_text_element(name)
- install_model(name, nil)
+ install_text_element(name, "", nil)
end
[
["width", :integer],
["height", :integer],
["description"],
].each do |name, type|
- install_text_element(name, type)
- install_model(name, "?")
- end
-
- def initialize(url=nil, title=nil, link=nil, width=nil, height=nil,
- description=nil)
- super()
- self.url = url
- self.title = title
- self.link = link
- self.width = width
- self.height = height
- self.description = description
+ install_text_element(name, "", "?", name, type)
end
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- url_element(false, next_indent),
- title_element(false, next_indent),
- link_element(false, next_indent),
- width_element(false, next_indent),
- height_element(false, next_indent),
- description_element(false, next_indent),
- other_element(false, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.url = args[0]
+ self.title = args[1]
+ self.link = args[2]
+ self.width = args[3]
+ self.height = args[4]
+ self.description = args[5]
end
- rv = convert(rv) if need_convert
- rv
end
private
- def _tags
- %w(url title link width height description).delete_if do |name|
- __send__(name).nil?
- end.collect do |elem|
- [nil, elem]
- end
- end
-
def maker_target(maker)
maker.image
end
@@ -381,106 +215,47 @@ module RSS
class Cloud < Element
include RSS09
-
+
[
- ["domain", nil, true],
- ["port", nil, true, :integer],
- ["path", nil, true],
- ["registerProcedure", nil, true],
- ["protocol", nil, true],
+ ["domain", "", true],
+ ["port", "", true, :integer],
+ ["path", "", true],
+ ["registerProcedure", "", true],
+ ["protocol", "", true],
].each do |name, uri, required, type|
install_get_attribute(name, uri, required, type)
end
- def initialize(domain=nil, port=nil, path=nil, rp=nil, protocol=nil)
- super()
- self.domain = domain
- self.port = port
- self.path = path
- self.registerProcedure = rp
- self.protocol = protocol
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def _attrs
- %w(domain port path registerProcedure protocol).collect do |attr|
- [attr, true]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.domain = args[0]
+ self.port = args[1]
+ self.path = args[2]
+ self.registerProcedure = args[3]
+ self.protocol = args[4]
end
end
-
end
class Item < Element
include RSS09
- %w(title link description).each do |name|
- install_text_element(name)
- end
-
- %w(source enclosure).each do |name|
- install_have_child_element(name)
- end
-
[
- %w(category categories),
- ].each do |name, plural_name|
- install_have_children_element(name, plural_name)
- end
-
- [
- ["title", '?'],
- ["link", '?'],
- ["description", '?'],
- ["category", '*'],
- ["source", '?'],
- ["enclosure", '?'],
- ].each do |tag, occurs|
- install_model(tag, occurs)
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- link_element(false, next_indent),
- description_element(false, next_indent),
- category_elements(false, next_indent),
- source_element(false, next_indent),
- enclosure_element(false, next_indent),
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
+ ["title", '?', :text],
+ ["link", '?', :text],
+ ["description", '?', :text],
+ ["category", '*', :have_children, "categories"],
+ ["source", '?', :have_child],
+ ["enclosure", '?', :have_child],
+ ].each do |tag, occurs, type, *args|
+ __send__("install_#{type}_element", tag, "", occurs, tag, *args)
end
private
- def children
- [@source, @enclosure, *@category].compact
- end
-
- def _tags
- rv = %w(title link description author comments
- source enclosure).delete_if do |name|
- __send__(name).nil?
- end.collect do |name|
- [nil, name]
- end
-
- @category.each do
- rv << [nil, "category"]
- end
-
- rv
- end
-
def maker_target(items)
if items.respond_to?("items")
# For backward compatibility
@@ -500,31 +275,24 @@ module RSS
include RSS09
[
- ["url", nil, true]
+ ["url", "", true]
].each do |name, uri, required|
install_get_attribute(name, uri, required)
end
content_setup
- def initialize(url=nil, content=nil)
- super()
- self.url = url
- self.content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.url = args[0]
+ self.content = args[1]
+ end
end
private
- def _tags
- []
- end
-
- def _attrs
- [
- ["url", true]
- ]
- end
-
-
def maker_target(item)
item.source
end
@@ -540,35 +308,25 @@ module RSS
include RSS09
[
- ["url", nil, true],
- ["length", nil, true, :integer],
- ["type", nil, true],
+ ["url", "", true],
+ ["length", "", true, :integer],
+ ["type", "", true],
].each do |name, uri, required, type|
install_get_attribute(name, uri, required, type)
end
- def initialize(url=nil, length=nil, type=nil)
- super()
- self.url = url
- self.length = length
- self.type = type
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.url = args[0]
+ self.length = args[1]
+ self.type = args[2]
+ end
end
private
- def _attrs
- [
- ["url", true],
- ["length", true],
- ["type", true],
- ]
- end
-
def maker_target(item)
item.enclosure
end
@@ -585,26 +343,24 @@ module RSS
include RSS09
[
- ["domain", nil, false]
+ ["domain", "", false]
].each do |name, uri, required|
install_get_attribute(name, uri, required)
end
content_setup
- def initialize(domain=nil, content=nil)
- super()
- self.domain = domain
- self.content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.domain = args[0]
+ self.content = args[1]
+ end
end
private
- def _attrs
- [
- ["domain", false]
- ]
- end
-
def maker_target(item)
item.new_category
end
@@ -623,41 +379,22 @@ module RSS
include RSS09
%w(title description name link).each do |name|
- install_text_element(name)
- install_model(name, nil)
+ install_text_element(name, "", nil)
end
- def initialize(title=nil, description=nil, name=nil, link=nil)
- super()
- self.title = title
- self.description = description
- self.name = name
- self.link = link
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- description_element(false, next_indent),
- name_element(false, next_indent),
- link_element(false, next_indent),
- other_element(false, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.title = args[0]
+ self.description = args[1]
+ self.name = args[2]
+ self.link = args[3]
end
- rv = convert(rv) if need_convert
- rv
end
private
- def _tags
- %w(title description name link).each do |name|
- __send__(name).nil?
- end.collect do |elem|
- [nil, elem]
- end
- end
-
def maker_target(maker)
maker.textinput
end
@@ -668,21 +405,22 @@ module RSS
end
RSS09::ELEMENTS.each do |name|
- BaseListener.install_get_text_element(nil, name, "#{name}=")
+ BaseListener.install_get_text_element("", name, name)
end
module ListenerMixin
private
- def start_rss(tag_name, prefix, attrs, ns)
- check_ns(tag_name, prefix, ns, nil)
+ def initial_start_rss(tag_name, prefix, attrs, ns)
+ check_ns(tag_name, prefix, ns, "")
@rss = Rss.new(attrs['version'], @version, @encoding, @standalone)
@rss.do_validate = @do_validate
@rss.xml_stylesheets = @xml_stylesheets
@last_element = @rss
- @proc_stack.push Proc.new { |text, tags|
- @rss.validate_for_stream(tags) if @do_validate
- }
+ pr = Proc.new do |text, tags|
+ @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
+ end
+ @proc_stack.push(pr)
end
end
diff --git a/lib/rss/1.0.rb b/lib/rss/1.0.rb
index 36d6f5df874..f04e61c5ebf 100644
--- a/lib/rss/1.0.rb
+++ b/lib/rss/1.0.rb
@@ -38,62 +38,22 @@ module RSS
[
["channel", nil],
["image", "?"],
- ["item", "+"],
+ ["item", "+", :children],
["textinput", "?"],
- ].each do |tag, occurs|
- install_model(tag, occurs)
+ ].each do |tag, occurs, type|
+ type ||= :child
+ __send__("install_have_#{type}_element", tag, ::RSS::URI, occurs)
end
- %w(channel image textinput).each do |name|
- install_have_child_element(name)
- end
-
- install_have_children_element("item")
-
- attr_accessor :rss_version, :version, :encoding, :standalone
-
+ alias_method(:rss_version, :feed_version)
def initialize(version=nil, encoding=nil, standalone=nil)
super('1.0', version, encoding, standalone)
+ @feed_type = "rss"
end
def full_name
tag_name_with_prefix(PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent, ns_declarations) do |next_indent|
- [
- channel_element(false, next_indent),
- image_element(false, next_indent),
- item_elements(false, next_indent),
- textinput_element(false, next_indent),
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def rdf_validate(tags)
- _validate(tags, [])
- end
-
- def children
- [@channel, @image, @textinput, *@item]
- end
-
- def _tags
- rv = [
- [::RSS::URI, "channel"],
- [::RSS::URI, "image"],
- ].delete_if {|uri, name| __send__(name).nil?}
- @item.each do |item|
- rv << [::RSS::URI, "item"]
- end
- rv << [::RSS::URI, "textinput"] if @textinput
- rv
- end
class Li < Element
@@ -106,32 +66,23 @@ module RSS
end
[
- ["resource", [URI, nil], true]
+ ["resource", [URI, ""], true]
].each do |name, uri, required|
install_get_attribute(name, uri, required)
end
- def initialize(resource=nil)
- super()
- self.resource = resource
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
end
def full_name
tag_name_with_prefix(PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def _attrs
- [
- ["resource", true]
- ]
- end
end
class Seq < Element
@@ -148,21 +99,15 @@ module RSS
@tag_name = 'Seq'
- install_have_children_element("li")
-
+ install_have_children_element("li", URI, "*")
install_must_call_validator('rdf', ::RSS::RDF::URI)
- def initialize(li=[])
- super()
- @li = li
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- tag(indent) do |next_indent|
- [
- li_elements(need_convert, next_indent),
- other_element(need_convert, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ @li = args[0] if args[0]
end
end
@@ -175,23 +120,6 @@ module RSS
target << li.resource
end
end
-
- private
- def children
- @li
- end
-
- def rdf_validate(tags)
- _validate(tags, [["li", '*']])
- end
-
- def _tags
- rv = []
- @li.each do |li|
- rv << [URI, "li"]
- end
- rv
- end
end
class Bag < Element
@@ -208,21 +136,15 @@ module RSS
@tag_name = 'Bag'
- install_have_children_element("li")
-
- install_must_call_validator('rdf', ::RSS::RDF::URI)
-
- def initialize(li=[])
- super()
- @li = li
- end
+ install_have_children_element("li", URI, "*")
+ install_must_call_validator('rdf', URI)
- def to_s(need_convert=true, indent=calc_indent)
- tag(indent) do |next_indent|
- [
- li_elements(need_convert, next_indent),
- other_element(need_convert, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ @li = args[0] if args[0]
end
end
@@ -235,23 +157,6 @@ module RSS
target << li.resource
end
end
-
- private
- def children
- @li
- end
-
- def rdf_validate(tags)
- _validate(tags, [["li", '*']])
- end
-
- def _tags
- rv = []
- @li.each do |li|
- rv << [URI, "li"]
- end
- rv
- end
end
class Channel < Element
@@ -269,73 +174,31 @@ module RSS
[
["about", URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- %w(title link description).each do |name|
- install_text_element(name)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
end
- %w(image items textinput).each do |name|
- install_have_child_element(name)
- end
-
[
- ['title', nil],
- ['link', nil],
- ['description', nil],
- ['image', '?'],
- ['items', nil],
- ['textinput', '?'],
- ].each do |tag, occurs|
- install_model(tag, occurs)
- end
-
- def initialize(about=nil)
- super()
- self.about = about
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- link_element(false, next_indent),
- description_element(false, next_indent),
- image_element(false, next_indent),
- items_element(false, next_indent),
- textinput_element(false, next_indent),
- other_element(false, next_indent),
- ]
+ ['title', nil, :text],
+ ['link', nil, :text],
+ ['description', nil, :text],
+ ['image', '?', :have_child],
+ ['items', nil, :have_child],
+ ['textinput', '?', :have_child],
+ ].each do |tag, occurs, type|
+ __send__("install_#{type}_element", tag, ::RSS::URI, occurs)
+ end
+
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
end
- rv = convert(rv) if need_convert
- rv
end
private
- def children
- [@image, @items, @textinput]
- end
-
- def _tags
- [
- [::RSS::URI, 'title'],
- [::RSS::URI, 'link'],
- [::RSS::URI, 'description'],
- [::RSS::URI, 'image'],
- [::RSS::URI, 'items'],
- [::RSS::URI, 'textinput'],
- ].delete_if do |uri, name|
- __send__(name).nil?
- end
- end
-
- def _attrs
- [
- ["#{PREFIX}:about", true, "about"]
- ]
- end
-
def maker_target(maker)
maker.channel
end
@@ -359,25 +222,17 @@ module RSS
[
["resource", URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
end
- def initialize(resource=nil)
- super()
- self.resource = resource
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def _attrs
- [
- ["#{PREFIX}:resource", true, "resource"]
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
end
end
@@ -396,25 +251,17 @@ module RSS
[
["resource", URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
end
- def initialize(resource=nil)
- super()
- self.resource = resource
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def _attrs
- [
- ["#{PREFIX}:resource", true, "resource"]
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
end
end
@@ -432,22 +279,17 @@ module RSS
end
- install_have_child_element("Seq")
-
- install_must_call_validator('rdf', ::RSS::RDF::URI)
+ install_have_child_element("Seq", URI, nil)
+ install_must_call_validator('rdf', URI)
- def initialize(seq=Seq.new)
- super()
- @Seq = seq
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- Seq_element(need_convert, next_indent),
- other_element(need_convert, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.Seq = args[0]
end
+ self.Seq ||= Seq.new
end
def resources
@@ -459,21 +301,6 @@ module RSS
[]
end
end
-
- private
- def children
- [@Seq]
- end
-
- def _tags
- rv = []
- rv << [URI, 'Seq'] unless @Seq.nil?
- rv
- end
-
- def rdf_validate(tags)
- _validate(tags, [["Seq", nil]])
- end
end
end
@@ -488,60 +315,28 @@ module RSS
end
end
-
+
[
["about", URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
end
%w(title url link).each do |name|
- install_text_element(name)
- end
-
- [
- ['title', nil],
- ['url', nil],
- ['link', nil],
- ].each do |tag, occurs|
- install_model(tag, occurs)
+ install_text_element(name, ::RSS::URI, nil)
end
- def initialize(about=nil)
- super()
- self.about = about
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- url_element(false, next_indent),
- link_element(false, next_indent),
- other_element(false, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
end
- rv = convert(rv) if need_convert
- rv
end
private
- def _tags
- [
- [::RSS::URI, 'title'],
- [::RSS::URI, 'url'],
- [::RSS::URI, 'link'],
- ].delete_if do |uri, name|
- __send__(name).nil?
- end
- end
-
- def _attrs
- [
- ["#{PREFIX}:about", true, "about"]
- ]
- end
-
def maker_target(maker)
maker.image
end
@@ -559,14 +354,12 @@ module RSS
end
+
[
["about", URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
- end
-
- %w(title link description).each do |name|
- install_text_element(name)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
end
[
@@ -574,44 +367,19 @@ module RSS
["link", nil],
["description", "?"],
].each do |tag, occurs|
- install_model(tag, occurs)
+ install_text_element(tag, ::RSS::URI, occurs)
end
- def initialize(about=nil)
- super()
- self.about = about
- end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- link_element(false, next_indent),
- description_element(false, next_indent),
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def _tags
- [
- [::RSS::URI, 'title'],
- [::RSS::URI, 'link'],
- [::RSS::URI, 'description'],
- ].delete_if do |uri, name|
- __send__(name).nil?
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
end
end
- def _attrs
- [
- ["#{PREFIX}:about", true, "about"]
- ]
- end
-
+ private
def maker_target(items)
if items.respond_to?("items")
# For backward compatibility
@@ -636,59 +404,24 @@ module RSS
[
["about", URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{PREFIX}:#{name}")
end
%w(title description name link).each do |name|
- install_text_element(name)
- end
-
- [
- ["title", nil],
- ["description", nil],
- ["name", nil],
- ["link", nil],
- ].each do |tag, occurs|
- install_model(tag, occurs)
- end
-
- def initialize(about=nil)
- super()
- self.about = about
+ install_text_element(name, ::RSS::URI, nil)
end
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- title_element(false, next_indent),
- description_element(false, next_indent),
- name_element(false, next_indent),
- link_element(false, next_indent),
- other_element(false, next_indent),
- ]
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
end
- rv = convert(rv) if need_convert
- rv
end
private
- def _tags
- [
- [::RSS::URI, 'title'],
- [::RSS::URI, 'description'],
- [::RSS::URI, 'name'],
- [::RSS::URI, 'link'],
- ].delete_if do |uri, name|
- __send__(name).nil?
- end
- end
-
- def _attrs
- [
- ["#{PREFIX}:about", true, "about"]
- ]
- end
-
def maker_target(maker)
maker.textinput
end
@@ -697,21 +430,22 @@ module RSS
end
RSS10::ELEMENTS.each do |name|
- BaseListener.install_get_text_element(URI, name, "#{name}=")
+ BaseListener.install_get_text_element(URI, name, name)
end
module ListenerMixin
private
- def start_RDF(tag_name, prefix, attrs, ns)
+ def initial_start_RDF(tag_name, prefix, attrs, ns)
check_ns(tag_name, prefix, ns, RDF::URI)
@rss = RDF.new(@version, @encoding, @standalone)
@rss.do_validate = @do_validate
@rss.xml_stylesheets = @xml_stylesheets
@last_element = @rss
- @proc_stack.push Proc.new { |text, tags|
- @rss.validate_for_stream(tags) if @do_validate
- }
+ pr = Proc.new do |text, tags|
+ @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate
+ end
+ @proc_stack.push(pr)
end
end
diff --git a/lib/rss/2.0.rb b/lib/rss/2.0.rb
index 1c3c22ee70d..3798da4eb7c 100644
--- a/lib/rss/2.0.rb
+++ b/lib/rss/2.0.rb
@@ -10,52 +10,20 @@ module RSS
["generator"],
["ttl", :integer],
].each do |name, type|
- install_text_element(name, type)
- install_model(name, '?')
+ install_text_element(name, "", "?", name, type)
end
[
%w(category categories),
].each do |name, plural_name|
- install_have_children_element(name, plural_name)
- install_model(name, '*')
+ install_have_children_element(name, "", "*", name, plural_name)
end
-
+
[
["image", "?"],
["language", "?"],
].each do |name, occurs|
- install_model(name, occurs)
- end
-
- def other_element(need_convert, indent)
- rv = <<-EOT
-#{category_elements(need_convert, indent)}
-#{generator_element(need_convert, indent)}
-#{ttl_element(need_convert, indent)}
-EOT
- rv << super
- end
-
- private
- alias children09 children
- def children
- children09 + @category.compact
- end
-
- alias _tags09 _tags
- def _tags
- rv = %w(generator ttl).delete_if do |name|
- __send__(name).nil?
- end.collect do |elem|
- [nil, elem]
- end + _tags09
-
- @category.each do
- rv << [nil, "category"]
- end
-
- rv
+ install_model(name, "", occurs)
end
Category = Item::Category
@@ -66,15 +34,13 @@ EOT
["comments", "?"],
["author", "?"],
].each do |name, occurs|
- install_text_element(name)
- install_model(name, occurs)
+ install_text_element(name, "", occurs)
end
[
["pubDate", '?'],
].each do |name, occurs|
- install_date_element(name, 'rfc822')
- install_model(name, occurs)
+ install_date_element(name, "", occurs, name, 'rfc822')
end
alias date pubDate
alias date= pubDate=
@@ -82,37 +48,10 @@ EOT
[
["guid", '?'],
].each do |name, occurs|
- install_have_child_element(name)
- install_model(name, occurs)
- end
-
- def other_element(need_convert, indent)
- rv = [
- super,
- *%w(author comments pubDate guid).collect do |name|
- __send__("#{name}_element", false, indent)
- end
- ].reject do |value|
- /\A\s*\z/.match(value)
- end
- rv.join("\n")
+ install_have_child_element(name, "", occurs)
end
private
- alias children09 children
- def children
- children09 + [@guid].compact
- end
-
- alias _tags09 _tags
- def _tags
- %w(comments author pubDate guid).delete_if do |name|
- __send__(name).nil?
- end.collect do |elem|
- [nil, elem]
- end + _tags09
- end
-
alias _setup_maker_element setup_maker_element
def setup_maker_element(item)
_setup_maker_element(item)
@@ -124,17 +63,21 @@ EOT
include RSS09
[
- ["isPermaLink", nil, false, :boolean]
+ ["isPermaLink", "", false, :boolean]
].each do |name, uri, required, type|
install_get_attribute(name, uri, required, type)
end
content_setup
- def initialize(isPermaLink=nil, content=nil)
- super()
- self.isPermaLink = isPermaLink
- self.content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.isPermaLink = args[0]
+ self.content = args[1]
+ end
end
alias_method :_PermaLink?, :PermaLink?
@@ -145,12 +88,6 @@ EOT
end
private
- def _attrs
- [
- ["isPermaLink", false]
- ]
- end
-
def maker_target(item)
item.guid
end
@@ -168,7 +105,7 @@ EOT
end
RSS09::ELEMENTS.each do |name|
- BaseListener.install_get_text_element(nil, name, "#{name}=")
+ BaseListener.install_get_text_element("", name, name)
end
end
diff --git a/lib/rss/atom.rb b/lib/rss/atom.rb
new file mode 100644
index 00000000000..901e69a4b0b
--- /dev/null
+++ b/lib/rss/atom.rb
@@ -0,0 +1,749 @@
+require 'base64'
+require 'rss/parser'
+
+module RSS
+ module Atom
+ URI = "http://www.w3.org/2005/Atom"
+ XHTML_URI = "http://www.w3.org/1999/xhtml"
+
+ module CommonModel
+ NSPOOL = {}
+ ELEMENTS = []
+
+ def self.append_features(klass)
+ super
+ klass.install_must_call_validator("atom", URI)
+ [
+ ["lang", :xml],
+ ["base", :xml],
+ ].each do |name, uri, required|
+ klass.install_get_attribute(name, uri, required, [nil, :inherit])
+ end
+ klass.class_eval do
+ class << self
+ def required_uri
+ URI
+ end
+
+ def need_parent?
+ true
+ end
+ end
+ end
+ end
+ end
+
+ module ContentModel
+ module ClassMethods
+ def content_type
+ @content_type ||= nil
+ end
+ end
+
+ class << self
+ def append_features(klass)
+ super
+ klass.extend(ClassMethods)
+ klass.content_setup(klass.content_type, klass.tag_name)
+ end
+ end
+
+ def maker_target(target)
+ target
+ end
+
+ private
+ def setup_maker_element_writer
+ "#{self.class.name.split(/::/).last.downcase}="
+ end
+
+ def setup_maker_element(target)
+ target.__send__(setup_maker_element_writer, content)
+ super
+ end
+ end
+
+ module URIContentModel
+ class << self
+ def append_features(klass)
+ super
+ klass.class_eval do
+ @content_type = [nil, :uri]
+ include(ContentModel)
+ end
+ end
+ end
+ end
+
+ module TextConstruct
+ def self.append_features(klass)
+ super
+ klass.class_eval do
+ [
+ ["type", ""],
+ ].each do |name, uri, required|
+ install_get_attribute(name, uri, required, :text_type)
+ end
+
+ content_setup
+ add_need_initialize_variable("xhtml")
+
+ class << self
+ def xml_getter
+ "xhtml"
+ end
+
+ def xml_setter
+ "xhtml="
+ end
+ end
+ end
+ end
+
+ attr_writer :xhtml
+ def xhtml
+ return @xhtml if @xhtml.nil?
+ if @xhtml.is_a?(XML::Element) and
+ [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
+ return @xhtml
+ end
+
+ children = @xhtml
+ children = [children] unless children.is_a?(Array)
+ XML::Element.new("div", nil, XHTML_URI,
+ {"xmlns" => XHTML_URI}, children)
+ end
+
+ def have_xml_content?
+ @type == "xhtml"
+ end
+
+ def atom_validate(ignore_unknown_element, tags, uri)
+ if have_xml_content?
+ if @xhtml.nil?
+ raise MissingTagError.new("div", tag_name)
+ end
+ unless [@xhtml.name, @xhtml.uri] == ["div", XHTML_URI]
+ raise NotExpectedTagError.new(@xhtml.name, @xhtml.uri, tag_name)
+ end
+ end
+ end
+
+ private
+ def maker_target(target)
+ target.__send__(self.class.name.split(/::/).last.downcase)
+ end
+
+ def setup_maker_attributes(target)
+ target.type = type
+ target.content = content
+ target.xml_content = @xhtml
+ end
+ end
+
+ module PersonConstruct
+ def self.append_features(klass)
+ super
+ klass.class_eval do
+ [
+ ["name", nil],
+ ["uri", "?"],
+ ["email", "?"],
+ ].each do |tag, occurs|
+ install_have_attribute_element(tag, URI, occurs, nil, :content)
+ end
+ end
+ end
+
+ def maker_target(target)
+ target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
+ end
+
+ class Name < RSS::Element
+ include CommonModel
+ include ContentModel
+ end
+
+ class Uri < RSS::Element
+ include CommonModel
+ include URIContentModel
+ end
+
+ class Email < RSS::Element
+ include CommonModel
+ include ContentModel
+ end
+ end
+
+ module DateConstruct
+ def self.append_features(klass)
+ super
+ klass.class_eval do
+ @content_type = :w3cdtf
+ include(ContentModel)
+ end
+ end
+
+ def atom_validate(ignore_unknown_element, tags, uri)
+ raise NotAvailableValueError.new(tag_name, "") if content.nil?
+ end
+ end
+
+ module DuplicateLinkChecker
+ def validate_duplicate_links(links)
+ link_infos = {}
+ links.each do |link|
+ rel = link.rel || "alternate"
+ next unless rel == "alternate"
+ key = [link.hreflang, link.type]
+ if link_infos.has_key?(key)
+ raise TooMuchTagError.new("link", tag_name)
+ end
+ link_infos[key] = true
+ end
+ end
+ end
+
+ class Feed < RSS::Element
+ include RootElementMixin
+ include CommonModel
+ include DuplicateLinkChecker
+
+ install_ns('', URI)
+
+ [
+ ["author", "*", :children],
+ ["category", "*", :children, "categories"],
+ ["contributor", "*", :children],
+ ["generator", "?"],
+ ["icon", "?", nil, :content],
+ ["id", nil, nil, :content],
+ ["link", "*", :children],
+ ["logo", "?"],
+ ["rights", "?"],
+ ["subtitle", "?", nil, :content],
+ ["title", nil, nil, :content],
+ ["updated", nil, nil, :content],
+ ["entry", "*", :children, "entries"],
+ ].each do |tag, occurs, type, *args|
+ type ||= :child
+ __send__("install_have_#{type}_element",
+ tag, URI, occurs, tag, *args)
+ end
+
+ def initialize(version=nil, encoding=nil, standalone=nil)
+ super("1.0", version, encoding, standalone)
+ @feed_type = "atom"
+ @feed_subtype = "feed"
+ end
+
+ alias_method :items, :entries
+
+ private
+ def atom_validate(ignore_unknown_element, tags, uri)
+ unless have_author?
+ raise MissingTagError.new("author", tag_name)
+ end
+ validate_duplicate_links(links)
+ end
+
+ def have_required_elements?
+ super and have_author?
+ end
+
+ def have_author?
+ authors.any? {|author| !author.to_s.empty?} or
+ entries.any? {|entry| entry.__send!(:have_author?, false)}
+ end
+
+ def maker_target(maker)
+ maker.channel
+ end
+
+ def setup_maker_element(channel)
+ prev_dc_dates = channel.dc_dates.to_a.dup
+ super
+ channel.about = id.content if id
+ channel.dc_dates.replace(prev_dc_dates)
+ end
+
+ def setup_maker_elements(channel)
+ super
+ items = channel.maker.items
+ entries.each do |entry|
+ entry.setup_maker(items)
+ end
+ end
+
+ class Author < RSS::Element
+ include CommonModel
+ include PersonConstruct
+ end
+
+ class Category < RSS::Element
+ include CommonModel
+
+ [
+ ["term", "", true],
+ ["scheme", "", false, [nil, :uri]],
+ ["label", ""],
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ private
+ def maker_target(target)
+ target.new_category
+ end
+ end
+
+ class Contributor < RSS::Element
+ include CommonModel
+ include PersonConstruct
+ end
+
+ class Generator < RSS::Element
+ include CommonModel
+ include ContentModel
+
+ [
+ ["uri", "", false, [nil, :uri]],
+ ["version", ""],
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ private
+ def setup_maker_attributes(target)
+ generator = target.generator
+ generator.uri = uri if uri
+ generator.version = version if version
+ end
+ end
+
+ class Icon < RSS::Element
+ include CommonModel
+ include URIContentModel
+ end
+
+ class Id < RSS::Element
+ include CommonModel
+ include URIContentModel
+ end
+
+ class Link < RSS::Element
+ include CommonModel
+
+ [
+ ["href", "", true, [nil, :uri]],
+ ["rel", ""],
+ ["type", ""],
+ ["hreflang", ""],
+ ["title", ""],
+ ["length", ""],
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ private
+ def maker_target(target)
+ target.new_link
+ end
+ end
+
+ class Logo < RSS::Element
+ include CommonModel
+ include URIContentModel
+
+ def maker_target(target)
+ target.maker.image
+ end
+
+ private
+ def setup_maker_element_writer
+ "url="
+ end
+ end
+
+ class Rights < RSS::Element
+ include CommonModel
+ include TextConstruct
+ end
+
+ class Subtitle < RSS::Element
+ include CommonModel
+ include TextConstruct
+ end
+
+ class Title < RSS::Element
+ include CommonModel
+ include TextConstruct
+ end
+
+ class Updated < RSS::Element
+ include CommonModel
+ include DateConstruct
+ end
+
+ class Entry < RSS::Element
+ include CommonModel
+ include DuplicateLinkChecker
+
+ [
+ ["author", "*", :children],
+ ["category", "*", :children, "categories"],
+ ["content", "?", :child],
+ ["contributor", "*", :children],
+ ["id", nil, nil, :content],
+ ["link", "*", :children],
+ ["published", "?", :child, :content],
+ ["rights", "?", :child],
+ ["source", "?"],
+ ["summary", "?", :child],
+ ["title", nil],
+ ["updated", nil, :child, :content],
+ ].each do |tag, occurs, type, *args|
+ type ||= :attribute
+ __send__("install_have_#{type}_element",
+ tag, URI, occurs, tag, *args)
+ end
+
+ private
+ def atom_validate(ignore_unknown_element, tags, uri)
+ unless have_author?
+ raise MissingTagError.new("author", tag_name)
+ end
+ validate_duplicate_links(links)
+ end
+
+ def have_required_elements?
+ super and have_author?
+ end
+
+ def have_author?(check_parent=true)
+ authors.any? {|author| !author.to_s.empty?} or
+ (check_parent and @parent and @parent.__send!(:have_author?)) or
+ (source and source.__send!(:have_author?))
+ end
+
+ def maker_target(items)
+ if items.respond_to?("items")
+ # For backward compatibility
+ items = items.items
+ end
+ items.new_item
+ end
+
+ Author = Feed::Author
+ Category = Feed::Category
+
+ class Content < RSS::Element
+ include CommonModel
+
+ class << self
+ def xml_setter
+ "xml="
+ end
+
+ def xml_getter
+ "xml"
+ end
+ end
+
+ [
+ ["type", ""],
+ ["src", "", false, [nil, :uri]],
+ ].each do |name, uri, required, type|
+ install_get_attribute(name, uri, required, type)
+ end
+
+ content_setup
+ add_need_initialize_variable("xml")
+
+ attr_writer :xml
+ def have_xml_content?
+ inline_xhtml? or inline_other_xml?
+ end
+
+ def xml
+ return @xml unless inline_xhtml?
+ return @xml if @xml.nil?
+ if @xml.is_a?(XML::Element) and
+ [@xml.name, @xml.uri] == ["div", XHTML_URI]
+ return @xml
+ end
+
+ children = @xml
+ children = [children] unless children.is_a?(Array)
+ XML::Element.new("div", nil, XHTML_URI,
+ {"xmlns" => XHTML_URI}, children)
+ end
+
+ def xhtml
+ if inline_xhtml?
+ xml
+ else
+ nil
+ end
+ end
+
+ def atom_validate(ignore_unknown_element, tags, uri)
+ if out_of_line?
+ raise MissingAttributeError.new(tag_name, "type") if @type.nil?
+ unless (content.nil? or content.empty?)
+ raise NotAvailableValueError.new(tag_name, content)
+ end
+ elsif inline_xhtml?
+ if @xml.nil?
+ raise MissingTagError.new("div", tag_name)
+ end
+ unless @xml.name == "div" and @xml.uri == XHTML_URI
+ raise NotExpectedTagError.new(@xml.name, @xml.uri, tag_name)
+ end
+ end
+ end
+
+ def inline_text?
+ !out_of_line? and [nil, "text", "html"].include?(@type)
+ end
+
+ def inline_html?
+ return false if out_of_line?
+ @type == "html" or mime_split == ["text", "html"]
+ end
+
+ def inline_xhtml?
+ !out_of_line? and @type == "xhtml"
+ end
+
+ def inline_other?
+ return false if out_of_line?
+ media_type, subtype = mime_split
+ return false if media_type.nil? or subtype.nil?
+ true
+ end
+
+ def inline_other_text?
+ return false unless inline_other?
+ return false if inline_other_xml?
+
+ media_type, subtype = mime_split
+ return true if "text" == media_type.downcase
+ false
+ end
+
+ def inline_other_xml?
+ return false unless inline_other?
+
+ media_type, subtype = mime_split
+ normalized_mime_type = "#{media_type}/#{subtype}".downcase
+ if /(?:\+xml|^xml)$/ =~ subtype or
+ %w(text/xml-external-parsed-entity
+ application/xml-external-parsed-entity
+ application/xml-dtd).find {|x| x == normalized_mime_type}
+ return true
+ end
+ false
+ end
+
+ def inline_other_base64?
+ inline_other? and !inline_other_text? and !inline_other_xml?
+ end
+
+ def out_of_line?
+ not @src.nil?
+ end
+
+ def mime_split
+ media_type = subtype = nil
+ if /\A\s*([a-z]+)\/([a-z\+]+)\s*(?:;.*)?\z/i =~ @type.to_s
+ media_type = $1.downcase
+ subtype = $2.downcase
+ end
+ [media_type, subtype]
+ end
+
+ def need_base64_encode?
+ inline_other_base64?
+ end
+
+ private
+ def empty_content?
+ out_of_line? or super
+ end
+ end
+
+ Contributor = Feed::Contributor
+ Id = Feed::Id
+ Link = Feed::Link
+
+ class Published < RSS::Element
+ include CommonModel
+ include DateConstruct
+ end
+
+ Rights = Feed::Rights
+
+ class Source < RSS::Element
+ include CommonModel
+
+ [
+ ["author", "*", :children],
+ ["category", "*", :children, "categories"],
+ ["contributor", "*", :children],
+ ["generator", "?"],
+ ["icon", "?"],
+ ["id", "?", nil, :content],
+ ["link", "*", :children],
+ ["logo", "?"],
+ ["rights", "?"],
+ ["subtitle", "?"],
+ ["title", "?"],
+ ["updated", "?", nil, :content],
+ ].each do |tag, occurs, type, *args|
+ type ||= :attribute
+ __send__("install_have_#{type}_element",
+ tag, URI, occurs, tag, *args)
+ end
+
+ private
+ def have_author?
+ !author.to_s.empty?
+ end
+
+ Author = Feed::Author
+ Category = Feed::Category
+ Contributor = Feed::Contributor
+ Generator = Feed::Generator
+ Icon = Feed::Icon
+ Id = Feed::Id
+ Link = Feed::Link
+ Logo = Feed::Logo
+ Rights = Feed::Rights
+ Subtitle = Feed::Subtitle
+ Title = Feed::Title
+ Updated = Feed::Updated
+ end
+
+ class Summary < RSS::Element
+ include CommonModel
+ include TextConstruct
+ end
+
+ Title = Feed::Title
+ Updated = Feed::Updated
+ end
+ end
+
+ class Entry < RSS::Element
+ include RootElementMixin
+ include CommonModel
+ include DuplicateLinkChecker
+
+ [
+ ["author", "*", :children],
+ ["category", "*", :children, "categories"],
+ ["content", "?"],
+ ["contributor", "*", :children],
+ ["id", nil, nil, :content],
+ ["link", "*", :children],
+ ["published", "?", :child, :content],
+ ["rights", "?"],
+ ["source", "?"],
+ ["summary", "?"],
+ ["title", nil],
+ ["updated", nil, nil, :content],
+ ].each do |tag, occurs, type, *args|
+ type ||= :attribute
+ __send__("install_have_#{type}_element",
+ tag, URI, occurs, tag, *args)
+ end
+
+ def initialize(version=nil, encoding=nil, standalone=nil)
+ super("1.0", version, encoding, standalone)
+ @feed_type = "atom"
+ @feed_subtype = "entry"
+ end
+
+ def items
+ [self]
+ end
+
+ def setup_maker(maker)
+ maker = maker.maker if maker.respond_to?("maker")
+ super(maker)
+ end
+
+ private
+ def atom_validate(ignore_unknown_element, tags, uri)
+ unless have_author?
+ raise MissingTagError.new("author", tag_name)
+ end
+ validate_duplicate_links(links)
+ end
+
+ def have_required_elements?
+ super and have_author?
+ end
+
+ def have_author?
+ authors.any? {|author| !author.to_s.empty?} or
+ (source and source.__send!(:have_author?))
+ end
+
+ def maker_target(maker)
+ maker.items.new_item
+ end
+
+ Author = Feed::Entry::Author
+ Category = Feed::Entry::Category
+ Content = Feed::Entry::Content
+ Contributor = Feed::Entry::Contributor
+ Id = Feed::Entry::Id
+ Link = Feed::Entry::Link
+ Published = Feed::Entry::Published
+ Rights = Feed::Entry::Rights
+ Source = Feed::Entry::Source
+ Summary = Feed::Entry::Summary
+ Title = Feed::Entry::Title
+ Updated = Feed::Entry::Updated
+ end
+ end
+
+ Atom::CommonModel::ELEMENTS.each do |name|
+ BaseListener.install_get_text_element(Atom::URI, name, "#{name}=")
+ end
+
+ module ListenerMixin
+ private
+ def initial_start_feed(tag_name, prefix, attrs, ns)
+ check_ns(tag_name, prefix, ns, Atom::URI)
+
+ @rss = Atom::Feed.new(@version, @encoding, @standalone)
+ @rss.do_validate = @do_validate
+ @rss.xml_stylesheets = @xml_stylesheets
+ @rss.lang = attrs["xml:lang"]
+ @rss.base = attrs["xml:base"]
+ @last_element = @rss
+ pr = Proc.new do |text, tags|
+ @rss.validate_for_stream(tags) if @do_validate
+ end
+ @proc_stack.push(pr)
+ end
+
+ def initial_start_entry(tag_name, prefix, attrs, ns)
+ check_ns(tag_name, prefix, ns, Atom::URI)
+
+ @rss = Atom::Entry.new(@version, @encoding, @standalone)
+ @rss.do_validate = @do_validate
+ @rss.xml_stylesheets = @xml_stylesheets
+ @rss.lang = attrs["xml:lang"]
+ @rss.base = attrs["xml:base"]
+ @last_element = @rss
+ pr = Proc.new do |text, tags|
+ @rss.validate_for_stream(tags) if @do_validate
+ end
+ @proc_stack.push(pr)
+ end
+ end
+end
diff --git a/lib/rss/content.rb b/lib/rss/content.rb
index a732cec9730..bb61d9ebc5a 100644
--- a/lib/rss/content.rb
+++ b/lib/rss/content.rb
@@ -15,28 +15,13 @@ module RSS
def self.append_features(klass)
super
-
- klass.module_eval(<<-EOC, *get_file_and_line_from_caller(1))
- %w(encoded).each do |name|
- install_text_element("\#{CONTENT_PREFIX}_\#{name}")
- end
- EOC
- end
-
- def content_validate(tags)
- counter = {}
- ELEMENTS.each do |name|
- counter[name] = 0
- end
- tags.each do |tag|
- key = "#{CONTENT_PREFIX}_#{tag}"
- raise UnknownTagError.new(tag, CONTENT_URI) unless counter.has_key?(key)
- counter[key] += 1
- raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1
+ klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
+ %w(encoded).each do |name|
+ klass.install_text_element(name, CONTENT_URI, "?",
+ "#{CONTENT_PREFIX}_#{name}")
end
end
-
end
class RDF
@@ -47,7 +32,7 @@ module RSS
ContentModel::ELEMENTS.uniq!
ContentModel::ELEMENTS.each do |full_name|
name = full_name[prefix_size..-1]
- BaseListener.install_get_text_element(CONTENT_URI, name, "#{full_name}=")
+ BaseListener.install_get_text_element(CONTENT_URI, name, full_name)
end
end
diff --git a/lib/rss/converter.rb b/lib/rss/converter.rb
index 7ad79db318c..415a319188a 100644
--- a/lib/rss/converter.rb
+++ b/lib/rss/converter.rb
@@ -66,7 +66,7 @@ module RSS
end
end
- def def_uconv_convert_if_can(meth, to_enc, from_enc)
+ def def_uconv_convert_if_can(meth, to_enc, from_enc, nkf_arg)
begin
require "uconv"
def_convert(1) do |value|
@@ -79,24 +79,31 @@ module RSS
EOC
end
rescue LoadError
- def_iconv_convert(to_enc, from_enc, 1)
+ require 'nkf'
+ if NKF.const_defined?(:UTF8)
+ def_convert(1) do |value|
+ "NKF.nkf(#{nkf_arg.dump}, #{value})"
+ end
+ else
+ def_iconv_convert(to_enc, from_enc, 1)
+ end
end
end
def def_to_euc_jp_from_utf_8
- def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8')
+ def_uconv_convert_if_can('u8toeuc', 'EUC-JP', 'UTF-8', '-We')
end
def def_to_utf_8_from_euc_jp
- def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP')
+ def_uconv_convert_if_can('euctou8', 'UTF-8', 'EUC-JP', '-Ew')
end
def def_to_shift_jis_from_utf_8
- def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8')
+ def_uconv_convert_if_can('u8tosjis', 'Shift_JIS', 'UTF-8', '-Ws')
end
def def_to_utf_8_from_shift_jis
- def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS')
+ def_uconv_convert_if_can('sjistou8', 'UTF-8', 'Shift_JIS', '-Sw')
end
def def_to_euc_jp_from_shift_jis
diff --git a/lib/rss/dublincore.rb b/lib/rss/dublincore.rb
index 79d2ca561c1..7ba239f8f19 100644
--- a/lib/rss/dublincore.rb
+++ b/lib/rss/dublincore.rb
@@ -1,11 +1,8 @@
-require "rss/1.0"
+require "rss/rss"
module RSS
-
DC_PREFIX = 'dc'
DC_URI = "http://purl.org/dc/elements/1.1/"
-
- RDF.install_ns(DC_PREFIX, DC_URI)
module BaseDublinCoreModel
def append_features(klass)
@@ -17,10 +14,10 @@ module RSS
full_name = "#{DC_PREFIX}_#{name}"
full_plural_name = "#{DC_PREFIX}_#{plural}"
klass_name = "DublinCore#{Utils.to_class_name(name)}"
+ klass.install_must_call_validator(DC_PREFIX, DC_URI)
+ klass.install_have_children_element(name, DC_URI, "*",
+ full_name, full_plural_name)
klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
- install_have_children_element(#{full_name.dump},
- #{full_plural_name.dump})
-
remove_method :#{full_name}
remove_method :#{full_name}=
remove_method :set_#{full_name}
@@ -36,8 +33,17 @@ module RSS
EOC
end
klass.module_eval(<<-EOC, *get_file_and_line_from_caller(0))
- alias date #{DC_PREFIX}_date
- alias date= #{DC_PREFIX}_date=
+ if method_defined?(:date)
+ alias date_without_#{DC_PREFIX}_date= date=
+
+ def date=(value)
+ self.date_without_#{DC_PREFIX}_date = value
+ self.#{DC_PREFIX}_date = value
+ end
+ else
+ alias date #{DC_PREFIX}_date
+ alias date= #{DC_PREFIX}_date=
+ end
# For backward compatibility
alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
@@ -72,7 +78,7 @@ module RSS
}
ELEMENT_NAME_INFOS = DublinCoreModel::TEXT_ELEMENTS.to_a
- DublinCoreModel::DATE_ELEMENTS.each do |name, _|
+ DublinCoreModel::DATE_ELEMENTS.each do |name, |
ELEMENT_NAME_INFOS << [name, nil]
end
@@ -100,9 +106,13 @@ module RSS
alias_method(:value, :content)
alias_method(:value=, :content=)
- def initialize(content=nil)
- super()
- self.content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
end
def full_name
@@ -121,39 +131,23 @@ module RSS
end
DATE_ELEMENTS.each do |name, type|
+ tag_name = "#{DC_PREFIX}:#{name}"
module_eval(<<-EOC, *get_file_and_line_from_caller(0))
class DublinCore#{Utils.to_class_name(name)} < Element
remove_method(:content=)
remove_method(:value=)
- date_writer("content", #{type.dump}, #{name.dump})
-
+ date_writer("content", #{type.dump}, #{tag_name.dump})
+
alias_method(:value=, :content=)
end
EOC
end
-
- def dc_validate(tags)
- tags.each do |tag|
- key = "#{DC_PREFIX}_#{tag}"
- unless DublinCoreModel::ELEMENTS.include?(key)
- raise UnknownTagError.new(tag, DC_URI)
- end
- end
- end
-
end
# For backward compatibility
DublincoreModel = DublinCoreModel
- class RDF
- class Channel; include DublinCoreModel; end
- class Image; include DublinCoreModel; end
- class Item; include DublinCoreModel; end
- class Textinput; include DublinCoreModel; end
- end
-
DublinCoreModel::ELEMENTS.each do |name|
class_name = Utils.to_class_name(name)
BaseListener.install_class_name(DC_URI, name, "DublinCore#{class_name}")
@@ -161,3 +155,7 @@ module RSS
DublinCoreModel::ELEMENTS.collect! {|name| "#{DC_PREFIX}_#{name}"}
end
+
+require 'rss/dublincore/1.0'
+require 'rss/dublincore/2.0'
+require 'rss/dublincore/atom'
diff --git a/lib/rss/dublincore/1.0.rb b/lib/rss/dublincore/1.0.rb
new file mode 100644
index 00000000000..e193c6d2c23
--- /dev/null
+++ b/lib/rss/dublincore/1.0.rb
@@ -0,0 +1,13 @@
+require "rss/1.0"
+require "rss/dublincore"
+
+module RSS
+ RDF.install_ns(DC_PREFIX, DC_URI)
+
+ class RDF
+ class Channel; include DublinCoreModel; end
+ class Image; include DublinCoreModel; end
+ class Item; include DublinCoreModel; end
+ class Textinput; include DublinCoreModel; end
+ end
+end
diff --git a/lib/rss/dublincore/2.0.rb b/lib/rss/dublincore/2.0.rb
new file mode 100644
index 00000000000..82ed1888c57
--- /dev/null
+++ b/lib/rss/dublincore/2.0.rb
@@ -0,0 +1,13 @@
+require "rss/2.0"
+require "rss/dublincore"
+
+module RSS
+ Rss.install_ns(DC_PREFIX, DC_URI)
+
+ class Rss
+ class Channel
+ include DublinCoreModel
+ class Item; include DublinCoreModel; end
+ end
+ end
+end
diff --git a/lib/rss/dublincore/atom.rb b/lib/rss/dublincore/atom.rb
new file mode 100644
index 00000000000..e78df4821b4
--- /dev/null
+++ b/lib/rss/dublincore/atom.rb
@@ -0,0 +1,17 @@
+require "rss/atom"
+require "rss/dublincore"
+
+module RSS
+ module Atom
+ Feed.install_ns(DC_PREFIX, DC_URI)
+
+ class Feed
+ include DublinCoreModel
+ class Entry; include DublinCoreModel; end
+ end
+
+ class Entry
+ include DublinCoreModel
+ end
+ end
+end
diff --git a/lib/rss/image.rb b/lib/rss/image.rb
index 9d3326efca4..44ee3dd41b6 100644
--- a/lib/rss/image.rb
+++ b/lib/rss/image.rb
@@ -17,9 +17,11 @@ module RSS
end
module ImageModelUtils
- def validate_one_tag_name(name, tags)
- invalid = tags.find {|tag| tag != name}
- raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
+ def validate_one_tag_name(ignore_unknown_element, name, tags)
+ if !ignore_unknown_element
+ invalid = tags.find {|tag| tag != name}
+ raise UnknownTagError.new(invalid, IMAGE_URI) if invalid
+ end
raise TooMuchTagError.new(name, tag_name) if tags.size > 1
end
end
@@ -31,13 +33,11 @@ module RSS
def self.append_features(klass)
super
- klass.install_have_child_element("#{IMAGE_PREFIX}_item")
+ klass.install_have_child_element("item", IMAGE_URI, "?",
+ "#{IMAGE_PREFIX}_item")
+ klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
end
- def image_validate(tags)
- validate_one_tag_name("item", tags)
- end
-
class ImageItem < Element
include RSS10
include DublinCoreModel
@@ -53,19 +53,23 @@ module RSS
IMAGE_URI
end
end
-
+
+ install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
+
[
["about", ::RSS::RDF::URI, true],
["resource", ::RSS::RDF::URI, false],
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{::RSS::RDF::PREFIX}:#{name}")
end
%w(width height).each do |tag|
full_name = "#{IMAGE_PREFIX}_#{tag}"
disp_name = "#{IMAGE_PREFIX}:#{tag}"
- install_text_element(full_name, :integer, disp_name)
- BaseListener.install_get_text_element(IMAGE_URI, tag, "#{full_name}=")
+ install_text_element(tag, IMAGE_URI, "?",
+ full_name, :integer, disp_name)
+ BaseListener.install_get_text_element(IMAGE_URI, tag, full_name)
end
alias width= image_width=
@@ -73,43 +77,21 @@ module RSS
alias height= image_height=
alias height image_height
- def initialize(about=nil, resource=nil)
- super()
- self.about = about
- self.resource = resource
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ self.resource = args[1]
+ end
end
def full_name
tag_name_with_prefix(IMAGE_PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
private
- def _tags
- [
- [IMAGE_URI, 'width'],
- [IMAGE_URI, 'height'],
- ].delete_if do |uri, name|
- __send__(name).nil?
- end
- end
-
- def _attrs
- [
- ["#{::RSS::RDF::PREFIX}:about", true, "about"],
- ["#{::RSS::RDF::PREFIX}:resource", false, "resource"],
- ]
- end
-
def maker_target(target)
target.image_item
end
@@ -129,14 +111,12 @@ module RSS
super
unless klass.class == Module
- klass.install_have_child_element("#{IMAGE_PREFIX}_favicon")
+ klass.install_have_child_element("favicon", IMAGE_URI, "?",
+ "#{IMAGE_PREFIX}_favicon")
+ klass.install_must_call_validator(IMAGE_PREFIX, IMAGE_URI)
end
end
- def image_validate(tags)
- validate_one_tag_name("favicon", tags)
- end
-
class ImageFavicon < Element
include RSS10
include DublinCoreModel
@@ -152,12 +132,13 @@ module RSS
IMAGE_URI
end
end
-
+
[
- ["about", ::RSS::RDF::URI, true],
- ["size", IMAGE_URI, true],
- ].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ ["about", ::RSS::RDF::URI, true, ::RSS::RDF::PREFIX],
+ ["size", IMAGE_URI, true, IMAGE_PREFIX],
+ ].each do |name, uri, required, prefix|
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{prefix}:#{name}")
end
AVAILABLE_SIZES = %w(small medium large)
@@ -171,40 +152,27 @@ module RSS
raise NotAvailableValueError.new(full_name, new_value, attr_name)
end
end
- funcall(:_size=, new_value)
+ __send!(:_size=, new_value)
end
alias image_size= size=
alias image_size size
- def initialize(about=nil, size=nil)
- super()
- self.about = about
- self.size = size
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ self.size = args[1]
+ end
end
def full_name
tag_name_with_prefix(IMAGE_PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- other_element(false, next_indent),
- ]
- end
- rv = convert(rv) if need_convert
- rv
- end
private
- def _attrs
- [
- ["#{::RSS::RDF::PREFIX}:about", true, "about"],
- ["#{IMAGE_PREFIX}:size", true, "size"],
- ]
- end
-
def maker_target(target)
target.image_favicon
end
diff --git a/lib/rss/maker.rb b/lib/rss/maker.rb
index 9ed799ac7f6..a47b55b6700 100644
--- a/lib/rss/maker.rb
+++ b/lib/rss/maker.rb
@@ -1,14 +1,14 @@
require "rss/rss"
module RSS
-
module Maker
-
MAKERS = {}
-
+
class << self
def make(version, &block)
- maker(version).make(&block)
+ m = maker(version)
+ raise UnsupportedMakerVersionError.new(version) if m.nil?
+ m.make(&block)
end
def maker(version)
@@ -19,16 +19,21 @@ module RSS
MAKERS[version] = maker
end
- def filename_to_version(filename)
- File.basename(filename, ".*")
+ def versions
+ MAKERS.keys.uniq.sort
+ end
+
+ def makers
+ MAKERS.values.uniq
end
end
end
-
end
require "rss/maker/1.0"
require "rss/maker/2.0"
+require "rss/maker/feed"
+require "rss/maker/entry"
require "rss/maker/content"
require "rss/maker/dublincore"
require "rss/maker/syndication"
diff --git a/lib/rss/maker/0.9.rb b/lib/rss/maker/0.9.rb
index b82585fb96e..dd75c9289b8 100644
--- a/lib/rss/maker/0.9.rb
+++ b/lib/rss/maker/0.9.rb
@@ -7,13 +7,14 @@ module RSS
class RSS09 < RSSBase
- def initialize(rss_version="0.91")
+ def initialize(feed_version="0.91")
super
+ @feed_type = "rss"
end
private
- def make_rss
- Rss.new(@rss_version, @version, @encoding, @standalone)
+ def make_feed
+ Rss.new(@feed_version, @version, @encoding, @standalone)
end
def setup_elements(rss)
@@ -22,40 +23,34 @@ module RSS
class Channel < ChannelBase
- def to_rss(rss)
+ def to_feed(rss)
channel = Rss::Channel.new
set = setup_values(channel)
- if set
+ _not_set_required_variables = not_set_required_variables
+ if _not_set_required_variables.empty?
rss.channel = channel
+ set_parent(channel, rss)
setup_items(rss)
setup_image(rss)
setup_textinput(rss)
- setup_other_elements(rss)
- if rss.channel.image
- rss
- else
- nil
- end
- elsif variable_is_set?
- raise NotSetError.new("maker.channel", not_set_required_variables)
+ setup_other_elements(rss, channel)
+ rss
+ else
+ raise NotSetError.new("maker.channel", _not_set_required_variables)
end
end
- def have_required_values?
- @title and @link and @description and @language
- end
-
private
def setup_items(rss)
- @maker.items.to_rss(rss)
+ @maker.items.to_feed(rss)
end
def setup_image(rss)
- @maker.image.to_rss(rss)
+ @maker.image.to_feed(rss)
end
def setup_textinput(rss)
- @maker.textinput.to_rss(rss)
+ @maker.textinput.to_feed(rss)
end
def variables
@@ -63,162 +58,409 @@ module RSS
end
def required_variable_names
- %w(title link description language)
+ %w(link language)
end
-
+
+ def not_set_required_variables
+ vars = super
+ vars << "description" unless description.have_required_values?
+ vars << "title" unless title.have_required_values?
+ vars
+ end
+
class SkipDays < SkipDaysBase
- def to_rss(rss, channel)
+ def to_feed(rss, channel)
unless @days.empty?
skipDays = Rss::Channel::SkipDays.new
channel.skipDays = skipDays
+ set_parent(skipDays, channel)
@days.each do |day|
- day.to_rss(rss, skipDays.days)
+ day.to_feed(rss, skipDays.days)
end
end
end
class Day < DayBase
- def to_rss(rss, days)
+ def to_feed(rss, days)
day = Rss::Channel::SkipDays::Day.new
set = setup_values(day)
if set
days << day
- setup_other_elements(rss)
+ set_parent(day, days)
+ setup_other_elements(rss, day)
end
end
- def have_required_values?
- @content
+ private
+ def required_variable_names
+ %w(content)
end
end
end
class SkipHours < SkipHoursBase
- def to_rss(rss, channel)
+ def to_feed(rss, channel)
unless @hours.empty?
skipHours = Rss::Channel::SkipHours.new
channel.skipHours = skipHours
+ set_parent(skipHours, channel)
@hours.each do |hour|
- hour.to_rss(rss, skipHours.hours)
+ hour.to_feed(rss, skipHours.hours)
end
end
end
class Hour < HourBase
- def to_rss(rss, hours)
+ def to_feed(rss, hours)
hour = Rss::Channel::SkipHours::Hour.new
set = setup_values(hour)
if set
hours << hour
- setup_other_elements(rss)
+ set_parent(hour, hours)
+ setup_other_elements(rss, hour)
end
end
- def have_required_values?
- @content
+ private
+ def required_variable_names
+ %w(content)
end
end
end
class Cloud < CloudBase
- def to_rss(*args)
+ def to_feed(*args)
end
end
class Categories < CategoriesBase
- def to_rss(*args)
+ def to_feed(*args)
end
class Category < CategoryBase
end
end
+
+ class Links < LinksBase
+ def to_feed(rss, channel)
+ return if @links.empty?
+ @links.first.to_feed(rss, channel)
+ end
+
+ class Link < LinkBase
+ def to_feed(rss, channel)
+ if have_required_values?
+ channel.link = href
+ else
+ raise NotSetError.new("maker.channel.link",
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(href)
+ end
+ end
+ end
+
+ class Authors < AuthorsBase
+ def to_feed(rss, channel)
+ end
+
+ class Author < AuthorBase
+ def to_feed(rss, channel)
+ end
+ end
+ end
+
+ class Contributors < ContributorsBase
+ def to_feed(rss, channel)
+ end
+
+ class Contributor < ContributorBase
+ end
+ end
+
+ class Generator < GeneratorBase
+ def to_feed(rss, channel)
+ end
+ end
+
+ class Copyright < CopyrightBase
+ def to_feed(rss, channel)
+ channel.copyright = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+
+ class Description < DescriptionBase
+ def to_feed(rss, channel)
+ channel.description = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+
+ class Title < TitleBase
+ def to_feed(rss, channel)
+ channel.title = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
end
-
+
class Image < ImageBase
- def to_rss(rss)
+ def to_feed(rss)
image = Rss::Channel::Image.new
set = setup_values(image)
if set
image.link = link
rss.channel.image = image
- setup_other_elements(rss)
+ set_parent(image, rss.channel)
+ setup_other_elements(rss, image)
+ elsif required_element?
+ raise NotSetError.new("maker.image", not_set_required_variables)
end
end
-
- def have_required_values?
- @url and @title and link
+
+ private
+ def required_variable_names
+ %w(url title link)
+ end
+
+ def required_element?
+ true
end
end
class Items < ItemsBase
- def to_rss(rss)
+ def to_feed(rss)
if rss.channel
normalize.each do |item|
- item.to_rss(rss)
+ item.to_feed(rss)
end
- setup_other_elements(rss)
+ setup_other_elements(rss, rss.items)
end
end
class Item < ItemBase
- def to_rss(rss)
+ def to_feed(rss)
item = Rss::Channel::Item.new
set = setup_values(item)
- if set
+ if set or title.have_required_values?
rss.items << item
- setup_other_elements(rss)
+ set_parent(item, rss.channel)
+ setup_other_elements(rss, item)
+ elsif variable_is_set?
+ raise NotSetError.new("maker.items", not_set_required_variables)
end
end
-
- private
+
def have_required_values?
- @title and @link
+ super and title.have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(link)
+ end
+
+ def not_set_required_variables
+ vars = super
+ vars << "title" unless title.have_required_values?
+ vars
end
class Guid < GuidBase
- def to_rss(*args)
+ def to_feed(*args)
end
end
-
+
class Enclosure < EnclosureBase
- def to_rss(*args)
+ def to_feed(*args)
end
end
-
+
class Source < SourceBase
- def to_rss(*args)
+ def to_feed(*args)
+ end
+
+ class Authors < AuthorsBase
+ def to_feed(*args)
+ end
+
+ class Author < AuthorBase
+ end
+ end
+
+ class Categories < CategoriesBase
+ def to_feed(*args)
+ end
+
+ class Category < CategoryBase
+ end
+ end
+
+ class Contributors < ContributorsBase
+ def to_feed(*args)
+ end
+
+ class Contributor < ContributorBase
+ end
+ end
+
+ class Generator < GeneratorBase
+ def to_feed(*args)
+ end
+ end
+
+ class Icon < IconBase
+ def to_feed(*args)
+ end
+ end
+
+ class Links < LinksBase
+ def to_feed(*args)
+ end
+
+ class Link < LinkBase
+ end
+ end
+
+ class Logo < LogoBase
+ def to_feed(*args)
+ end
+ end
+
+ class Rights < RightsBase
+ def to_feed(*args)
+ end
+ end
+
+ class Subtitle < SubtitleBase
+ def to_feed(*args)
+ end
+ end
+
+ class Title < TitleBase
+ def to_feed(*args)
+ end
end
end
-
+
class Categories < CategoriesBase
- def to_rss(*args)
+ def to_feed(*args)
end
class Category < CategoryBase
end
end
-
+
+ class Authors < AuthorsBase
+ def to_feed(*args)
+ end
+
+ class Author < AuthorBase
+ end
+ end
+
+ class Links < LinksBase
+ def to_feed(rss, item)
+ return if @links.empty?
+ @links.first.to_feed(rss, item)
+ end
+
+ class Link < LinkBase
+ def to_feed(rss, item)
+ if have_required_values?
+ item.link = href
+ else
+ raise NotSetError.new("maker.link",
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(href)
+ end
+ end
+ end
+
+ class Contributors < ContributorsBase
+ def to_feed(rss, item)
+ end
+
+ class Contributor < ContributorBase
+ end
+ end
+
+ class Rights < RightsBase
+ def to_feed(rss, item)
+ end
+ end
+
+ class Description < DescriptionBase
+ def to_feed(rss, item)
+ item.description = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+
+ class Content < ContentBase
+ def to_feed(rss, item)
+ end
+ end
+
+ class Title < TitleBase
+ def to_feed(rss, item)
+ item.title = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
end
end
class Textinput < TextinputBase
- def to_rss(rss)
+ def to_feed(rss)
textInput = Rss::Channel::TextInput.new
set = setup_values(textInput)
if set
rss.channel.textInput = textInput
- setup_other_elements(rss)
+ set_parent(textInput, rss.channel)
+ setup_other_elements(rss, textInput)
end
end
private
- def have_required_values?
- @title and @description and @name and @link
+ def required_variable_names
+ %w(title description name link)
end
end
end
- add_maker(filename_to_version(__FILE__), RSS09)
- add_maker(filename_to_version(__FILE__) + "1", RSS09)
+ add_maker("0.9", RSS09)
+ add_maker("0.91", RSS09)
+ add_maker("rss0.91", RSS09)
end
end
diff --git a/lib/rss/maker/1.0.rb b/lib/rss/maker/1.0.rb
index 3e6542a0078..12608ad94af 100644
--- a/lib/rss/maker/1.0.rb
+++ b/lib/rss/maker/1.0.rb
@@ -9,10 +9,11 @@ module RSS
def initialize
super("1.0")
+ @feed_type = "rss"
end
private
- def make_rss
+ def make_feed
RDF.new(@version, @encoding, @standalone)
end
@@ -25,43 +26,46 @@ module RSS
class Channel < ChannelBase
- def to_rss(rss)
- set = false
- if @about
- channel = RDF::Channel.new(@about)
- set = setup_values(channel)
- if set
+ def to_feed(rss)
+ set_default_values do
+ _not_set_required_variables = not_set_required_variables
+ if _not_set_required_variables.empty?
+ channel = RDF::Channel.new(@about)
+ set = setup_values(channel)
channel.dc_dates.clear
rss.channel = channel
+ set_parent(channel, rss)
setup_items(rss)
setup_image(rss)
setup_textinput(rss)
- setup_other_elements(rss)
+ setup_other_elements(rss, channel)
+ else
+ raise NotSetError.new("maker.channel", _not_set_required_variables)
end
end
-
- if (!@about or !set) and variable_is_set?
- raise NotSetError.new("maker.channel", not_set_required_variables)
- end
- end
-
- def have_required_values?
- @about and @title and @link and @description
end
private
def setup_items(rss)
items = RDF::Channel::Items.new
seq = items.Seq
- @maker.items.normalize.each do |item|
- seq.lis << RDF::Channel::Items::Seq::Li.new(item.link)
+ set_parent(items, seq)
+ target_items = @maker.items.normalize
+ raise NotSetError.new("maker", ["items"]) if target_items.empty?
+ target_items.each do |item|
+ li = RDF::Channel::Items::Seq::Li.new(item.link)
+ seq.lis << li
+ set_parent(li, seq)
end
rss.channel.items = items
+ set_parent(rss.channel, items)
end
def setup_image(rss)
if @maker.image.have_required_values?
- rss.channel.image = RDF::Channel::Image.new(@maker.image.url)
+ image = RDF::Channel::Image.new(@maker.image.url)
+ rss.channel.image = image
+ set_parent(image, rss.channel)
end
end
@@ -69,15 +73,23 @@ module RSS
if @maker.textinput.have_required_values?
textinput = RDF::Channel::Textinput.new(@maker.textinput.link)
rss.channel.textinput = textinput
+ set_parent(textinput, rss.channel)
end
end
def required_variable_names
- %w(about title link description)
+ %w(about link)
end
-
+
+ def not_set_required_variables
+ vars = super
+ vars << "description" unless description.have_required_values?
+ vars << "title" unless title.have_required_values?
+ vars
+ end
+
class SkipDays < SkipDaysBase
- def to_rss(*args)
+ def to_feed(*args)
end
class Day < DayBase
@@ -85,7 +97,7 @@ module RSS
end
class SkipHours < SkipHoursBase
- def to_rss(*args)
+ def to_feed(*args)
end
class Hour < HourBase
@@ -93,112 +105,330 @@ module RSS
end
class Cloud < CloudBase
- def to_rss(*args)
+ def to_feed(*args)
end
end
class Categories < CategoriesBase
- def to_rss(*args)
+ def to_feed(*args)
end
class Category < CategoryBase
end
end
+
+ class Links < LinksBase
+ def to_feed(rss, channel)
+ return if @links.empty?
+ @links.first.to_feed(rss, channel)
+ end
+
+ class Link < LinkBase
+ def to_feed(rss, channel)
+ if have_required_values?
+ channel.link = href
+ else
+ raise NotSetError.new("maker.channel.link",
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(href)
+ end
+ end
+ end
+
+ class Authors < AuthorsBase
+ def to_feed(rss, channel)
+ end
+
+ class Author < AuthorBase
+ def to_feed(rss, channel)
+ end
+ end
+ end
+
+ class Contributors < ContributorsBase
+ def to_feed(rss, channel)
+ end
+
+ class Contributor < ContributorBase
+ end
+ end
+
+ class Generator < GeneratorBase
+ def to_feed(rss, channel)
+ end
+ end
+
+ class Copyright < CopyrightBase
+ def to_feed(rss, channel)
+ end
+ end
+
+ class Description < DescriptionBase
+ def to_feed(rss, channel)
+ channel.description = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+
+ class Title < TitleBase
+ def to_feed(rss, channel)
+ channel.title = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
end
class Image < ImageBase
- def to_rss(rss)
+ def to_feed(rss)
if @url
image = RDF::Image.new(@url)
set = setup_values(image)
if set
rss.image = image
- setup_other_elements(rss)
+ set_parent(image, rss)
+ setup_other_elements(rss, image)
end
end
end
def have_required_values?
- @url and @title and link and @maker.channel.have_required_values?
+ super and @maker.channel.have_required_values?
end
private
def variables
super + ["link"]
end
+
+ def required_variable_names
+ %w(url title link)
+ end
end
class Items < ItemsBase
- def to_rss(rss)
+ def to_feed(rss)
if rss.channel
normalize.each do |item|
- item.to_rss(rss)
+ item.to_feed(rss)
end
- setup_other_elements(rss)
+ setup_other_elements(rss, rss.items)
end
end
class Item < ItemBase
- def to_rss(rss)
- if @link
- item = RDF::Item.new(@link)
+ def to_feed(rss)
+ set_default_values do
+ item = RDF::Item.new(link)
set = setup_values(item)
if set
item.dc_dates.clear
rss.items << item
- setup_other_elements(rss)
+ set_parent(item, rss)
+ setup_other_elements(rss, item)
+ elsif !have_required_values?
+ raise NotSetError.new("maker.item", not_set_required_variables)
end
end
end
- def have_required_values?
- @title and @link
+ private
+ def required_variable_names
+ %w(link)
+ end
+
+ def variables
+ super + %w(link)
+ end
+
+ def not_set_required_variables
+ set_default_values do
+ vars = super
+ vars << "title" unless title.have_required_values?
+ vars
+ end
end
class Guid < GuidBase
- def to_rss(*args)
+ def to_feed(*args)
end
end
-
+
class Enclosure < EnclosureBase
- def to_rss(*args)
+ def to_feed(*args)
end
end
-
+
class Source < SourceBase
- def to_rss(*args)
+ def to_feed(*args)
+ end
+
+ class Authors < AuthorsBase
+ def to_feed(*args)
+ end
+
+ class Author < AuthorBase
+ end
+ end
+
+ class Categories < CategoriesBase
+ def to_feed(*args)
+ end
+
+ class Category < CategoryBase
+ end
+ end
+
+ class Contributors < ContributorsBase
+ def to_feed(*args)
+ end
+
+ class Contributor < ContributorBase
+ end
+ end
+
+ class Generator < GeneratorBase
+ def to_feed(*args)
+ end
+ end
+
+ class Icon < IconBase
+ def to_feed(*args)
+ end
+ end
+
+ class Links < LinksBase
+ def to_feed(*args)
+ end
+
+ class Link < LinkBase
+ end
+ end
+
+ class Logo < LogoBase
+ def to_feed(*args)
+ end
+ end
+
+ class Rights < RightsBase
+ def to_feed(*args)
+ end
+ end
+
+ class Subtitle < SubtitleBase
+ def to_feed(*args)
+ end
+ end
+
+ class Title < TitleBase
+ def to_feed(*args)
+ end
end
end
-
+
class Categories < CategoriesBase
- def to_rss(*args)
+ def to_feed(*args)
end
class Category < CategoryBase
end
end
+
+ class Authors < AuthorsBase
+ def to_feed(*args)
+ end
+
+ class Author < AuthorBase
+ end
+ end
+
+ class Links < LinksBase
+ def to_feed(*args)
+ end
+
+ class Link < LinkBase
+ end
+ end
+
+ class Contributors < ContributorsBase
+ def to_feed(rss, item)
+ end
+
+ class Contributor < ContributorBase
+ end
+ end
+
+ class Rights < RightsBase
+ def to_feed(rss, item)
+ end
+ end
+
+ class Description < DescriptionBase
+ def to_feed(rss, item)
+ item.description = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+
+ class Content < ContentBase
+ def to_feed(rss, item)
+ end
+ end
+
+ class Title < TitleBase
+ def to_feed(rss, item)
+ item.title = content if have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
end
end
class Textinput < TextinputBase
- def to_rss(rss)
+ def to_feed(rss)
if @link
textinput = RDF::Textinput.new(@link)
set = setup_values(textinput)
if set
rss.textinput = textinput
- setup_other_elements(rss)
+ set_parent(textinput, rss)
+ setup_other_elements(rss, textinput)
end
end
end
def have_required_values?
- @title and @description and @name and @link and
- @maker.channel.have_required_values?
+ super and @maker.channel.have_required_values?
+ end
+
+ private
+ def required_variable_names
+ %w(title description name link)
end
end
end
- add_maker(filename_to_version(__FILE__), RSS10)
+ add_maker("1.0", RSS10)
+ add_maker("rss1.0", RSS10)
end
end
diff --git a/lib/rss/maker/2.0.rb b/lib/rss/maker/2.0.rb
index a958661614c..d93ba94d4a3 100644
--- a/lib/rss/maker/2.0.rb
+++ b/lib/rss/maker/2.0.rb
@@ -7,16 +7,13 @@ module RSS
class RSS20 < RSS09
- def initialize(rss_version="2.0")
+ def initialize(feed_version="2.0")
super
end
class Channel < RSS09::Channel
- def have_required_values?
- @title and @link and @description
- end
-
+ private
def required_variable_names
%w(title link description)
end
@@ -32,47 +29,64 @@ module RSS
end
class Cloud < RSS09::Channel::Cloud
- def to_rss(rss, channel)
+ def to_feed(rss, channel)
cloud = Rss::Channel::Cloud.new
set = setup_values(cloud)
if set
channel.cloud = cloud
- setup_other_elements(rss)
+ set_parent(cloud, channel)
+ setup_other_elements(rss, cloud)
end
end
- def have_required_values?
- @domain and @port and @path and
- @registerProcedure and @protocol
+ private
+ def required_variable_names
+ %w(domain port path registerProcedure protocol)
end
end
class Categories < RSS09::Channel::Categories
- def to_rss(rss, channel)
+ def to_feed(rss, channel)
@categories.each do |category|
- category.to_rss(rss, channel)
+ category.to_feed(rss, channel)
end
end
class Category < RSS09::Channel::Categories::Category
- def to_rss(rss, channel)
+ def to_feed(rss, channel)
category = Rss::Channel::Category.new
set = setup_values(category)
if set
channel.categories << category
- setup_other_elements(rss)
+ set_parent(category, channel)
+ setup_other_elements(rss, category)
end
end
-
- def have_required_values?
- @content
+
+ private
+ def required_variable_names
+ %w(content)
end
end
end
-
+
+ class Generator < GeneratorBase
+ def to_feed(rss, channel)
+ channel.generator = content
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
end
class Image < RSS09::Image
+ private
+ def required_element?
+ false
+ end
end
class Items < RSS09::Items
@@ -84,85 +98,123 @@ module RSS
end
private
+ def required_variable_names
+ %w(title description)
+ end
+
def variables
super + ["pubDate"]
end
class Guid < RSS09::Items::Item::Guid
- def to_rss(rss, item)
+ def to_feed(rss, item)
guid = Rss::Channel::Item::Guid.new
set = setup_values(guid)
if set
item.guid = guid
- setup_other_elements(rss)
+ set_parent(guid, item)
+ setup_other_elements(rss, guid)
end
end
-
- def have_required_values?
- @content
+
+ private
+ def required_variable_names
+ %w(content)
end
end
class Enclosure < RSS09::Items::Item::Enclosure
- def to_rss(rss, item)
+ def to_feed(rss, item)
enclosure = Rss::Channel::Item::Enclosure.new
set = setup_values(enclosure)
if set
item.enclosure = enclosure
- setup_other_elements(rss)
+ set_parent(enclosure, item)
+ setup_other_elements(rss, enclosure)
end
end
-
- def have_required_values?
- @url and @length and @type
+
+ private
+ def required_variable_names
+ %w(url length type)
end
end
class Source < RSS09::Items::Item::Source
- def to_rss(rss, item)
+ def to_feed(rss, item)
source = Rss::Channel::Item::Source.new
set = setup_values(source)
if set
item.source = source
- setup_other_elements(rss)
+ set_parent(source, item)
+ setup_other_elements(rss, source)
end
end
-
- def have_required_values?
- @url and @content
+
+ private
+ def required_variable_names
+ %w(url content)
+ end
+
+ class Links < RSS09::Items::Item::Source::Links
+ def to_feed(rss, source)
+ return if @links.empty?
+ @links.first.to_feed(rss, source)
+ end
+
+ class Link < RSS09::Items::Item::Source::Links::Link
+ def to_feed(rss, source)
+ source.url = href
+ end
+ end
end
end
class Categories < RSS09::Items::Item::Categories
- def to_rss(rss, item)
+ def to_feed(rss, item)
@categories.each do |category|
- category.to_rss(rss, item)
+ category.to_feed(rss, item)
end
end
class Category < RSS09::Items::Item::Categories::Category
- def to_rss(rss, item)
+ def to_feed(rss, item)
category = Rss::Channel::Item::Category.new
set = setup_values(category)
if set
item.categories << category
+ set_parent(category, item)
setup_other_elements(rss)
end
end
-
- def have_required_values?
- @content
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+ end
+
+ class Authors < RSS09::Items::Item::Authors
+ def to_feed(rss, item)
+ return if @authors.empty?
+ @authors.first.to_feed(rss, item)
+ end
+
+ class Author < RSS09::Items::Item::Authors::Author
+ def to_feed(rss, item)
+ item.author = name
end
end
end
end
-
end
class Textinput < RSS09::Textinput
end
end
- add_maker(filename_to_version(__FILE__), RSS20)
+ add_maker("2.0", RSS20)
+ add_maker("rss2.0", RSS20)
end
end
diff --git a/lib/rss/maker/atom.rb b/lib/rss/maker/atom.rb
new file mode 100644
index 00000000000..27d30c6d896
--- /dev/null
+++ b/lib/rss/maker/atom.rb
@@ -0,0 +1,172 @@
+require "rss/atom"
+
+require "rss/maker/base"
+
+module RSS
+ module Maker
+ module AtomPersons
+ module_function
+ def def_atom_persons(klass, name, maker_name, plural=nil)
+ plural ||= "#{name}s"
+ klass_name = Utils.to_class_name(name)
+ plural_klass_name = Utils.to_class_name(plural)
+
+ klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class #{plural_klass_name} < #{plural_klass_name}Base
+ class #{klass_name} < #{klass_name}Base
+ def to_feed(feed, current)
+ #{name} = feed.class::#{klass_name}.new
+ set = setup_values(#{name})
+ unless set
+ raise NotSetError.new(#{maker_name.dump},
+ not_set_required_variables)
+ end
+ current.#{plural} << #{name}
+ set_parent(#{name}, current)
+ setup_other_elements(#{name})
+ end
+
+ private
+ def required_variable_names
+ %w(name)
+ end
+ end
+ end
+EOC
+ end
+ end
+
+ module AtomTextConstruct
+ class << self
+ def def_atom_text_construct(klass, name, maker_name, klass_name=nil,
+ atom_klass_name=nil)
+ klass_name ||= Utils.to_class_name(name)
+ atom_klass_name ||= Utils.to_class_name(name)
+
+ klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class #{klass_name} < #{klass_name}Base
+ include #{self.name}
+ def to_feed(feed, current)
+ #{name} = current.class::#{atom_klass_name}.new
+ if setup_values(#{name})
+ current.#{name} = #{name}
+ set_parent(#{name}, current)
+ setup_other_elements(feed)
+ elsif variable_is_set?
+ raise NotSetError.new(#{maker_name.dump},
+ not_set_required_variables)
+ end
+ end
+ end
+ EOC
+ end
+ end
+
+ private
+ def required_variable_names
+ if type == "xhtml"
+ %w(xml_content)
+ else
+ %w(content)
+ end
+ end
+
+ def variables
+ if type == "xhtml"
+ super + %w(xhtml)
+ else
+ super
+ end
+ end
+ end
+
+ module AtomCategory
+ def to_feed(feed, current)
+ category = feed.class::Category.new
+ set = setup_values(category)
+ if set
+ current.categories << category
+ set_parent(category, current)
+ setup_other_elements(feed)
+ else
+ raise NotSetError.new(self.class.not_set_name,
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(term)
+ end
+
+ def variables
+ super + ["term", "scheme"]
+ end
+ end
+
+ module AtomLink
+ def to_feed(feed, current)
+ link = feed.class::Link.new
+ set = setup_values(link)
+ if set
+ current.links << link
+ set_parent(link, current)
+ setup_other_elements(feed)
+ else
+ raise NotSetError.new(self.class.not_set_name,
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(href)
+ end
+ end
+
+ module AtomGenerator
+ def to_feed(feed, current)
+ generator = current.class::Generator.new
+ if setup_values(generator)
+ current.generator = generator
+ set_parent(generator, current)
+ setup_other_elements(feed)
+ elsif variable_is_set?
+ raise NotSetError.new(self.class.not_set_name,
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(content)
+ end
+ end
+
+ module AtomLogo
+ def to_feed(feed, current)
+ logo = current.class::Logo.new
+ class << logo
+ alias uri= content=
+ end
+ set = setup_values(logo)
+ class << logo
+ undef uri=
+ end
+ if set
+ current.logo = logo
+ set_parent(logo, current)
+ setup_other_elements(feed)
+ elsif variable_is_set?
+ raise NotSetError.new(self.class.not_set_name,
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(uri)
+ end
+ end
+ end
+end
diff --git a/lib/rss/maker/base.rb b/lib/rss/maker/base.rb
index 6d7dd557bf6..ad47ff29cc6 100644
--- a/lib/rss/maker/base.rb
+++ b/lib/rss/maker/base.rb
@@ -4,9 +4,7 @@ require 'rss/rss'
module RSS
module Maker
-
module Base
-
def self.append_features(klass)
super
@@ -46,28 +44,60 @@ module RSS
NEED_INITIALIZE_VARIABLES
end
- def self.def_array_element(name)
+ def self.def_array_element(name, plural=nil, klass=nil)
include Enumerable
extend Forwardable
- def_delegators("@\#{name}", :<<, :[], :[]=, :first, :last)
- def_delegators("@\#{name}", :push, :pop, :shift, :unshift)
- def_delegators("@\#{name}", :each, :size)
-
- add_need_initialize_variable(name, "[]")
+ plural ||= "\#{name}s"
+ klass ||= "self.class::\#{Utils.to_class_name(name)}"
+
+ def_delegators("@\#{plural}", :<<, :[], :[]=, :first, :last)
+ def_delegators("@\#{plural}", :push, :pop, :shift, :unshift)
+ def_delegators("@\#{plural}", :each, :size, :empty?, :clear)
+
+ add_need_initialize_variable(plural, "[]")
+
+ module_eval(<<-EOM, __FILE__, __LINE__ + 1)
+ def new_\#{name}
+ \#{name} = \#{klass}.new(@maker)
+ @\#{plural} << \#{name}
+ if block_given?
+ yield \#{name}
+ else
+ \#{name}
+ end
+ end
+ alias new_child new_\#{name}
+
+ def to_feed(*args)
+ @\#{plural}.each do |\#{name}|
+ \#{name}.to_feed(*args)
+ end
+ end
+
+ def replace(elements)
+ @\#{plural}.replace(elements.to_a)
+ end
+EOM
end
EOC
end
+ attr_reader :maker
def initialize(maker)
@maker = maker
+ @default_values_are_set = false
initialize_variables
end
def have_required_values?
- true
+ not_set_required_variables.empty?
end
-
+
+ def variable_is_set?
+ variables.any? {|var| not __send__(var).nil?}
+ end
+
private
def initialize_variables
self.class.need_initialize_variables.each do |variable_name, init_value|
@@ -75,16 +105,32 @@ module RSS
end
end
- def setup_other_elements(rss)
+ def setup_other_elements(feed, current=nil)
+ current ||= current_element(feed)
self.class.other_elements.each do |element|
- __send__("setup_#{element}", rss, current_element(rss))
+ __send__("setup_#{element}", feed, current)
end
end
- def current_element(rss)
- rss
+ def current_element(feed)
+ feed
end
-
+
+ def set_default_values(&block)
+ return yield if @default_values_are_set
+
+ begin
+ @default_values_are_set = true
+ _set_default_values(&block)
+ ensure
+ @default_values_are_set = false
+ end
+ end
+
+ def _set_default_values(&block)
+ yield
+ end
+
def setup_values(target)
set = false
if have_required_values?
@@ -102,6 +148,10 @@ module RSS
set
end
+ def set_parent(target, parent)
+ target.parent = parent if target.class.need_parent?
+ end
+
def variables
self.class.need_initialize_variables.find_all do |name, init|
"nil" == init
@@ -110,10 +160,6 @@ module RSS
end
end
- def variable_is_set?
- variables.find {|var| !__send__(var).nil?}
- end
-
def not_set_required_variables
required_variable_names.find_all do |var|
__send__(var).nil?
@@ -126,7 +172,92 @@ module RSS
end
true
end
-
+ end
+
+ module AtomPersonConstructBase
+ def self.append_features(klass)
+ super
+
+ klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ %w(name uri email).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+EOC
+ end
+ end
+
+ module AtomTextConstructBase
+ module EnsureXMLContent
+ def ensure_xml_content(content)
+ xhtml_uri = ::RSS::Atom::XHTML_URI
+ unless content.is_a?(RSS::XML::Element) and
+ ["div", xhtml_uri] == [content.name, content.uri]
+ children = content
+ children = [children] unless content.is_a?(Array)
+ children = set_xhtml_uri_as_default_uri(children)
+ content = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ children)
+ end
+ content
+ end
+
+ private
+ def set_xhtml_uri_as_default_uri(children)
+ children.collect do |child|
+ if child.is_a?(RSS::XML::Element) and
+ child.prefix.nil? and child.uri.nil?
+ RSS::XML::Element.new(child.name, nil, ::RSS::Atom::XHTML_URI,
+ child.attributes.dup,
+ set_xhtml_uri_as_default_uri(child.children))
+ else
+ child
+ end
+ end
+ end
+ end
+
+ def self.append_features(klass)
+ super
+
+ klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ include EnsureXMLContent
+
+ %w(type content xml_content).each do |element|
+ attr element, element != "xml_content"
+ add_need_initialize_variable(element)
+ end
+
+ def xml_content=(content)
+ @xml_content = ensure_xml_content(content)
+ end
+
+ alias_method(:xhtml, :xml_content)
+ alias_method(:xhtml=, :xml_content=)
+EOC
+ end
+ end
+
+ module SetupDefaultDate
+ private
+ def _set_default_values(&block)
+ keep = {
+ :date => date,
+ :dc_dates => dc_dates.to_a.dup,
+ }
+ _date = date
+ if _date and !dc_dates.any? {|dc_date| dc_date.value == _date}
+ dc_date = self.class::DublinCoreDates::Date.new(self)
+ dc_date.value = _date.dup
+ dc_dates.unshift(dc_date)
+ end
+ self.date ||= self.dc_date
+ super(&block)
+ ensure
+ date = keep[:date]
+ dc_dates.replace(keep[:dc_dates])
+ end
end
class RSSBase
@@ -143,8 +274,8 @@ module RSS
add_need_initialize_variable(element, "make_#{element}")
module_eval(<<-EOC, __FILE__, __LINE__)
private
- def setup_#{element}(rss)
- @#{element}.to_rss(rss)
+ def setup_#{element}(feed)
+ @#{element}.to_feed(feed)
end
def make_#{element}
@@ -153,12 +284,15 @@ module RSS
EOC
end
- attr_reader :rss_version
+ attr_reader :feed_version
+ alias_method(:rss_version, :feed_version)
attr_accessor :version, :encoding, :standalone
-
- def initialize(rss_version)
+
+ def initialize(feed_version)
super(self)
- @rss_version = rss_version
+ @feed_type = nil
+ @feed_subtype = nil
+ @feed_version = feed_version
@version = "1.0"
@encoding = "UTF-8"
@standalone = nil
@@ -167,19 +301,19 @@ EOC
def make
if block_given?
yield(self)
- to_rss
+ to_feed
else
nil
end
end
- def to_rss
- rss = make_rss
- setup_xml_stylesheets(rss)
- setup_elements(rss)
- setup_other_elements(rss)
- if rss.channel
- rss
+ def to_feed
+ feed = make_feed
+ setup_xml_stylesheets(feed)
+ setup_elements(feed)
+ setup_other_elements(feed)
+ if feed.valid?
+ feed
else
nil
end
@@ -190,25 +324,12 @@ EOC
def make_xml_stylesheets
XMLStyleSheets.new(self)
end
-
end
class XMLStyleSheets
include Base
- def_array_element("xml_stylesheets")
-
- def to_rss(rss)
- @xml_stylesheets.each do |xss|
- xss.to_rss(rss)
- end
- end
-
- def new_xml_stylesheet
- xss = XMLStyleSheet.new(@maker)
- @xml_stylesheets << xss
- xss
- end
+ def_array_element("xml_stylesheet", nil, "XMLStyleSheet")
class XMLStyleSheet
include Base
@@ -218,19 +339,15 @@ EOC
add_need_initialize_variable(attribute)
end
- def to_rss(rss)
+ def to_feed(feed)
xss = ::RSS::XMLStyleSheet.new
guess_type_if_need(xss)
set = setup_values(xss)
if set
- rss.xml_stylesheets << xss
+ feed.xml_stylesheets << xss
end
end
- def have_required_values?
- @href and @type
- end
-
private
def guess_type_if_need(xss)
if @type.nil?
@@ -238,20 +355,27 @@ EOC
@type = xss.type
end
end
+
+ def required_variable_names
+ %w(href type)
+ end
end
end
class ChannelBase
include Base
+ include SetupDefaultDate
- %w(cloud categories skipDays skipHours).each do |element|
+ %w(cloud categories skipDays skipHours links authors
+ contributors generator copyright description
+ title).each do |element|
attr_reader element
add_other_element(element)
add_need_initialize_variable(element, "make_#{element}")
module_eval(<<-EOC, __FILE__, __LINE__)
private
- def setup_#{element}(rss, current)
- @#{element}.to_rss(rss, current)
+ def setup_#{element}(feed, current)
+ @#{element}.to_feed(feed, current)
end
def make_#{element}
@@ -260,34 +384,102 @@ EOC
EOC
end
- %w(about title link description language copyright
+ %w(id about language
managingEditor webMaster rating docs date
- lastBuildDate generator ttl).each do |element|
+ lastBuildDate ttl).each do |element|
attr_accessor element
add_need_initialize_variable(element)
end
- alias_method(:pubDate, :date)
- alias_method(:pubDate=, :date=)
+ def pubDate
+ date
+ end
+
+ def pubDate=(date)
+ self.date = date
+ end
+
+ def updated
+ date
+ end
+
+ def updated=(date)
+ self.date = date
+ end
+
+ def link
+ _link = links.first
+ _link ? _link.href : nil
+ end
+
+ def link=(href)
+ _link = links.first || links.new_link
+ _link.rel = "self"
+ _link.href = href
+ end
+
+ def author
+ _author = authors.first
+ _author ? _author.name : nil
+ end
+
+ def author=(name)
+ _author = authors.first || authors.new_author
+ _author.name = name
+ end
+
+ def contributor
+ _contributor = contributors.first
+ _contributor ? _contributor.name : nil
+ end
+
+ def contributor=(name)
+ _contributor = contributors.first || contributors.new_contributor
+ _contributor.name = name
+ end
+
+ def generator=(content)
+ @generator.content = content
+ end
+
+ def copyright=(content)
+ @copyright.content = content
+ end
+
+ alias_method(:rights, :copyright)
+ alias_method(:rights=, :copyright=)
+
+ def description=(content)
+ @description.content = content
+ end
+
+ alias_method(:subtitle, :description)
+ alias_method(:subtitle=, :description=)
+
+ def title=(content)
+ @title.content = content
+ end
- def current_element(rss)
- rss.channel
+ def icon
+ image_favicon.about
+ end
+
+ def icon=(url)
+ image_favicon.about = url
+ end
+
+ def logo
+ maker.image.url
+ end
+
+ def logo=(url)
+ maker.image.url = url
end
class SkipDaysBase
include Base
- def_array_element("days")
-
- def new_day
- day = self.class::Day.new(@maker)
- @days << day
- day
- end
-
- def current_element(rss)
- rss.channel.skipDays
- end
+ def_array_element("day")
class DayBase
include Base
@@ -296,28 +488,13 @@ EOC
attr_accessor element
add_need_initialize_variable(element)
end
-
- def current_element(rss)
- rss.channel.skipDays.last
- end
-
end
end
class SkipHoursBase
include Base
- def_array_element("hours")
-
- def new_hour
- hour = self.class::Hour.new(@maker)
- @hours << hour
- hour
- end
-
- def current_element(rss)
- rss.channel.skipHours
- end
+ def_array_element("hour")
class HourBase
include Base
@@ -326,11 +503,6 @@ EOC
attr_accessor element
add_need_initialize_variable(element)
end
-
- def current_element(rss)
- rss.channel.skipHours.last
- end
-
end
end
@@ -341,33 +513,88 @@ EOC
attr_accessor element
add_need_initialize_variable(element)
end
-
- def current_element(rss)
- rss.channel.cloud
- end
-
end
class CategoriesBase
include Base
-
- def_array_element("categories")
- def new_category
- category = self.class::Category.new(@maker)
- @categories << category
- category
- end
+ def_array_element("category", "categories")
class CategoryBase
include Base
- %w(domain content).each do |element|
+ %w(domain content label).each do |element|
attr_accessor element
add_need_initialize_variable(element)
end
+
+ alias_method(:term, :domain)
+ alias_method(:term=, :domain=)
+ alias_method(:scheme, :content)
+ alias_method(:scheme=, :content=)
end
end
+
+ class LinksBase
+ include Base
+
+ def_array_element("link")
+
+ class LinkBase
+ include Base
+
+ %w(href rel type hreflang title length).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+ end
+
+ class AuthorsBase
+ include Base
+
+ def_array_element("author")
+
+ class AuthorBase
+ include Base
+ include AtomPersonConstructBase
+ end
+ end
+
+ class ContributorsBase
+ include Base
+
+ def_array_element("contributor")
+
+ class ContributorBase
+ include Base
+ include AtomPersonConstructBase
+ end
+ end
+
+ class GeneratorBase
+ include Base
+
+ %w(uri version content).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+
+ class CopyrightBase
+ include Base
+ include AtomTextConstructBase
+ end
+
+ class DescriptionBase
+ include Base
+ include AtomTextConstructBase
+ end
+
+ class TitleBase
+ include Base
+ include AtomTextConstructBase
+ end
end
class ImageBase
@@ -377,21 +604,17 @@ EOC
attr_accessor element
add_need_initialize_variable(element)
end
-
+
def link
@maker.channel.link
end
-
- def current_element(rss)
- rss.image
- end
end
class ItemsBase
include Base
- def_array_element("items")
-
+ def_array_element("item")
+
attr_accessor :do_sort, :max_size
def initialize(maker)
@@ -407,17 +630,7 @@ EOC
sort_if_need[0..@max_size]
end
end
-
- def current_element(rss)
- rss.items
- end
- def new_item
- item = self.class::Item.new(@maker)
- @items << item
- item
- end
-
private
def sort_if_need
if @do_sort.respond_to?(:call)
@@ -435,15 +648,17 @@ EOC
class ItemBase
include Base
-
- %w(guid enclosure source categories).each do |element|
+ include SetupDefaultDate
+
+ %w(guid enclosure source categories authors links
+ contributors rights description content title).each do |element|
attr_reader element
add_other_element(element)
add_need_initialize_variable(element, "make_#{element}")
module_eval(<<-EOC, __FILE__, __LINE__)
private
- def setup_#{element}(rss, current)
- @#{element}.to_rss(rss, current)
+ def setup_#{element}(feed, current)
+ @#{element}.to_feed(feed, current)
end
def make_#{element}
@@ -451,30 +666,77 @@ EOC
end
EOC
end
-
- %w(title link description date author comments).each do |element|
+
+ %w(date comments id published).each do |element|
attr_accessor element
add_need_initialize_variable(element)
end
- alias_method(:pubDate, :date)
- alias_method(:pubDate=, :date=)
+ def pubDate
+ date
+ end
+
+ def pubDate=(date)
+ self.date = date
+ end
+
+ def updated
+ date
+ end
+
+ def updated=(date)
+ self.date = date
+ end
+
+ def author
+ _link = authors.first
+ _link ? _author.name : nil
+ end
+
+ def author=(name)
+ _author = authors.first || authors.new_author
+ _author.name = name
+ end
+
+ def link
+ _link = links.first
+ _link ? _link.href : nil
+ end
+
+ def link=(href)
+ _link = links.first || links.new_link
+ _link.rel = "alternate"
+ _link.href = href
+ end
+
+ def rights=(content)
+ @rights.content = content
+ end
+
+ def description=(content)
+ @description.content = content
+ end
+
+ alias_method(:summary, :description)
+ alias_method(:summary=, :description=)
+
+ def title=(content)
+ @title.content = content
+ end
def <=>(other)
- if date and other.date
- date <=> other.date
- elsif date
+ _date = date || dc_date
+ _other_date = other.date || other.dc_date
+ if _date and _other_date
+ _date <=> _other_date
+ elsif _date
1
- elsif other.date
+ elsif _other_date
-1
else
0
end
end
-
- def current_element(rss)
- rss.items.last
- end
class GuidBase
include Base
@@ -484,7 +746,7 @@ EOC
add_need_initialize_variable(element)
end
end
-
+
class EnclosureBase
include Base
@@ -493,18 +755,168 @@ EOC
add_need_initialize_variable(element)
end
end
-
+
class SourceBase
include Base
- %w(url content).each do |element|
+ %w(authors categories contributors generator icon
+ links logo rights subtitle title).each do |element|
+ attr_reader element
+ add_other_element(element)
+ add_need_initialize_variable(element, "make_#{element}")
+ module_eval(<<-EOC, __FILE__, __LINE__)
+ private
+ def setup_#{element}(feed, current)
+ @#{element}.to_feed(feed, current)
+ end
+
+ def make_#{element}
+ self.class::#{Utils.to_class_name(element)}.new(@maker)
+ end
+ EOC
+ end
+
+ %w(id content date).each do |element|
attr_accessor element
add_need_initialize_variable(element)
end
+
+ def url
+ link = links.first
+ link ? link.href : nil
+ end
+
+ def url=(value)
+ link = links.first || links.new_link
+ link.href = value
+ end
+
+ def updated
+ date
+ end
+
+ def updated=(date)
+ self.date = date
+ end
+
+ private
+ AuthorsBase = ChannelBase::AuthorsBase
+ CategoriesBase = ChannelBase::CategoriesBase
+ ContributorsBase = ChannelBase::ContributorsBase
+ GeneratorBase = ChannelBase::GeneratorBase
+
+ class IconBase
+ include Base
+
+ %w(url).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+
+ LinksBase = ChannelBase::LinksBase
+
+ class LogoBase
+ include Base
+
+ %w(uri).each do |element|
+ attr_accessor element
+ add_need_initialize_variable(element)
+ end
+ end
+
+ class RightsBase
+ include Base
+ include AtomTextConstructBase
+ end
+
+ class SubtitleBase
+ include Base
+ include AtomTextConstructBase
+ end
+
+ class TitleBase
+ include Base
+ include AtomTextConstructBase
+ end
end
-
+
CategoriesBase = ChannelBase::CategoriesBase
-
+ AuthorsBase = ChannelBase::AuthorsBase
+ LinksBase = ChannelBase::LinksBase
+ ContributorsBase = ChannelBase::ContributorsBase
+
+ class RightsBase
+ include Base
+ include AtomTextConstructBase
+ end
+
+ class DescriptionBase
+ include Base
+ include AtomTextConstructBase
+ end
+
+ class ContentBase
+ include Base
+ include AtomTextConstructBase::EnsureXMLContent
+
+ %w(type src content xml_content).each do |element|
+ attr element, element != "xml_content"
+ add_need_initialize_variable(element)
+ end
+
+ def xml_content=(content)
+ content = ensure_xml_content(content) if inline_xhtml?
+ @xml_content = content
+ end
+
+ alias_method(:xhtml, :xml_content)
+ alias_method(:xhtml=, :xml_content=)
+
+ alias_method(:xml, :xml_content)
+ alias_method(:xml=, :xml_content=)
+
+ private
+ def inline_text?
+ [nil, "text", "html"].include?(@type)
+ end
+
+ def inline_html?
+ @type == "html"
+ end
+
+ def inline_xhtml?
+ @type == "xhtml"
+ end
+
+ def inline_other?
+ !out_of_line? and ![nil, "text", "html", "xhtml"].include?(@type)
+ end
+
+ def inline_other_text?
+ return false if @type.nil? or out_of_line?
+ /\Atext\//i.match(@type) ? true : false
+ end
+
+ def inline_other_xml?
+ return false if @type.nil? or out_of_line?
+ /[\+\/]xml\z/i.match(@type) ? true : false
+ end
+
+ def inline_other_base64?
+ return false if @type.nil? or out_of_line?
+ @type.include?("/") and !inline_other_text? and !inline_other_xml?
+ end
+
+ def out_of_line?
+ not @src.nil? and @content.nil?
+ end
+ end
+
+ class TitleBase
+ include Base
+ include AtomTextConstructBase
+ end
end
end
@@ -515,12 +927,6 @@ EOC
attr_accessor element
add_need_initialize_variable(element)
end
-
- def current_element(rss)
- rss.textinput
- end
-
end
-
end
end
diff --git a/lib/rss/maker/dublincore.rb b/lib/rss/maker/dublincore.rb
index b208d5fcb2b..088ae60942e 100644
--- a/lib/rss/maker/dublincore.rb
+++ b/lib/rss/maker/dublincore.rb
@@ -24,8 +24,8 @@ module RSS
#{full_plural_klass_name}.new(@maker)
end
- def setup_#{full_plural_name}(rss, current)
- @#{full_plural_name}.to_rss(rss, current)
+ def setup_#{full_plural_name}(feed, current)
+ @#{full_plural_name}.to_feed(feed, current)
end
def #{full_name}
@@ -36,6 +36,17 @@ module RSS
@#{full_plural_name}[0] = #{full_klass_name}.new(self)
@#{full_plural_name}[0].value = new_value
end
+
+ def new_#{full_name}(value=nil)
+ #{full_name} = #{full_klass_name}.new(self)
+ #{full_name}.value = value
+ @#{full_plural_name} << #{full_name}
+ if block_given?
+ yield #{full_name}
+ else
+ #{full_name}
+ end
+ end
EOC
end
@@ -48,25 +59,14 @@ EOC
::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
plural_name ||= "#{name}s"
klass_name = Utils.to_class_name(name)
+ full_klass_name = "DublinCore#{klass_name}"
plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
module_eval(<<-EOC, __FILE__, __LINE__)
class #{plural_klass_name}Base
include Base
- def_array_element(#{plural_name.dump})
-
- def new_#{name}
- #{name} = self.class::#{klass_name}.new(self)
- @#{plural_name} << #{name}
- #{name}
- end
+ def_array_element(#{name.dump}, #{plural_name.dump})
- def to_rss(rss, current)
- @#{plural_name}.each do |#{name}|
- #{name}.to_rss(rss, current)
- end
- end
-
class #{klass_name}Base
include Base
@@ -78,6 +78,13 @@ EOC
def have_required_values?
@value
end
+
+ def to_feed(feed, current)
+ if value and current.respond_to?(:dc_#{name})
+ new_item = current.class::#{full_klass_name}.new(value)
+ current.dc_#{plural_name} << new_item
+ end
+ end
end
end
EOC
@@ -88,16 +95,9 @@ EOC
plural_name ||= "#{name}s"
klass_name = Utils.to_class_name(name)
plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
- full_klass_name = "DublinCore#{klass_name}"
- klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1))
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
class #{plural_klass_name} < #{plural_klass_name}Base
class #{klass_name} < #{klass_name}Base
- def to_rss(rss, current)
- if value and current.respond_to?(:dc_#{name})
- new_item = current.class::#{full_klass_name}.new(value)
- current.dc_#{plural_name} << new_item
- end
- end
end
end
EOC
@@ -107,64 +107,36 @@ EOC
class ChannelBase
include DublinCoreModel
-
- remove_method(:date)
- remove_method(:date=)
- alias_method(:date, :dc_date)
- alias_method(:date=, :dc_date=)
end
class ImageBase; include DublinCoreModel; end
class ItemsBase
class ItemBase
include DublinCoreModel
-
- remove_method(:date)
- remove_method(:date=)
- alias_method(:date, :dc_date)
- alias_method(:date=, :dc_date=)
end
end
class TextinputBase; include DublinCoreModel; end
- class RSS10
- class Channel
- DublinCoreModel.install_dublin_core(self)
- end
-
- class Image
- DublinCoreModel.install_dublin_core(self)
- end
-
- class Items
- class Item
+ makers.each do |maker|
+ maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class Channel
DublinCoreModel.install_dublin_core(self)
end
- end
- class Textinput
- DublinCoreModel.install_dublin_core(self)
- end
- end
-
- class RSS09
- class Channel
- DublinCoreModel.install_dublin_core(self)
- end
+ class Image
+ DublinCoreModel.install_dublin_core(self)
+ end
- class Image
- DublinCoreModel.install_dublin_core(self)
- end
+ class Items
+ class Item
+ DublinCoreModel.install_dublin_core(self)
+ end
+ end
- class Items
- class Item
+ class Textinput
DublinCoreModel.install_dublin_core(self)
end
- end
-
- class Textinput
- DublinCoreModel.install_dublin_core(self)
- end
+ EOC
end
end
end
diff --git a/lib/rss/maker/entry.rb b/lib/rss/maker/entry.rb
new file mode 100644
index 00000000000..baa22c5bf17
--- /dev/null
+++ b/lib/rss/maker/entry.rb
@@ -0,0 +1,167 @@
+require "rss/maker/atom"
+require "rss/maker/feed"
+
+module RSS
+ module Maker
+ module Atom
+ class Entry < RSSBase
+ def initialize
+ super("1.0")
+ @feed_type = "atom"
+ @feed_subtype = "entry"
+ end
+
+ private
+ def make_feed
+ ::RSS::Atom::Entry.new(@version, @encoding, @standalone)
+ end
+
+ def setup_elements(entry)
+ setup_items(entry)
+ end
+
+ class Channel < ChannelBase
+ class SkipDays < SkipDaysBase
+ class Day < DayBase
+ end
+ end
+
+ class SkipHours < SkipHoursBase
+ class Hour < HourBase
+ end
+ end
+
+ class Cloud < CloudBase
+ end
+
+ Categories = Feed::Channel::Categories
+ Links = Feed::Channel::Links
+ Authors = Feed::Channel::Authors
+ Contributors = Feed::Channel::Contributors
+
+ class Generator < GeneratorBase
+ include AtomGenerator
+
+ def self.not_set_name
+ "maker.channel.generator"
+ end
+ end
+
+ Copyright = Feed::Channel::Copyright
+
+ class Description < DescriptionBase
+ end
+
+ Title = Feed::Channel::Title
+ end
+
+ class Image < ImageBase
+ end
+
+ class Items < ItemsBase
+ def to_feed(entry)
+ (normalize.first || Item.new(@maker)).to_feed(entry)
+ end
+
+ class Item < ItemBase
+ def to_feed(entry)
+ set_default_values do
+ setup_values(entry)
+ entry.dc_dates.clear
+ setup_other_elements(entry)
+ unless have_required_values?
+ raise NotSetError.new("maker.item", not_set_required_variables)
+ end
+ end
+ end
+
+ def have_required_values?
+ set_default_values do
+ super and title.have_required_values?
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(id updated)
+ end
+
+ def variables
+ super + ["updated"]
+ end
+
+ def variable_is_set?
+ super or !authors.empty?
+ end
+
+ def not_set_required_variables
+ set_default_values do
+ vars = super
+ if authors.all? {|author| !author.have_required_values?}
+ vars << "author"
+ end
+ vars << "title" unless title.have_required_values?
+ vars
+ end
+ end
+
+ def _set_default_values(&block)
+ keep = {
+ :authors => authors.to_a.dup,
+ :contributors => contributors.to_a.dup,
+ :categories => categories.to_a.dup,
+ :id => id,
+ :links => links.to_a.dup,
+ :rights => @rights,
+ :title => @title,
+ :updated => updated,
+ }
+ authors.replace(@maker.channel.authors) if keep[:authors].empty?
+ if keep[:contributors].empty?
+ contributors.replace(@maker.channel.contributors)
+ end
+ if keep[:categories].empty?
+ categories.replace(@maker.channel.categories)
+ end
+ self.id ||= link || @maker.channel.id
+ links.replace(@maker.channel.links) if keep[:links].empty?
+ unless keep[:rights].variable_is_set?
+ @rights = @maker.channel.rights
+ end
+ @title = @maker.channel.title unless keep[:title].variable_is_set?
+ self.updated ||= @maker.channel.updated
+ super(&block)
+ ensure
+ authors.replace(keep[:authors])
+ contributors.replace(keep[:contributors])
+ categories.replace(keep[:categories])
+ links.replace(keep[:links])
+ self.id = keep[:id]
+ @rights = keep[:rights]
+ @title = keep[:title]
+ self.updated = keep[:prev_updated]
+ end
+
+ Guid = Feed::Items::Item::Guid
+ Enclosure = Feed::Items::Item::Enclosure
+ Source = Feed::Items::Item::Source
+ Categories = Feed::Items::Item::Categories
+ Authors = Feed::Items::Item::Authors
+ Contributors = Feed::Items::Item::Contributors
+ Links = Feed::Items::Item::Links
+ Rights = Feed::Items::Item::Rights
+ Description = Feed::Items::Item::Description
+ Title = Feed::Items::Item::Title
+ Content = Feed::Items::Item::Content
+ end
+ end
+
+ class Textinput < TextinputBase
+ end
+ end
+ end
+
+ add_maker("atom:entry", Atom::Entry)
+ add_maker("atom1.0:entry", Atom::Entry)
+ end
+end
diff --git a/lib/rss/maker/feed.rb b/lib/rss/maker/feed.rb
new file mode 100644
index 00000000000..ac26788102d
--- /dev/null
+++ b/lib/rss/maker/feed.rb
@@ -0,0 +1,429 @@
+require "rss/maker/atom"
+
+module RSS
+ module Maker
+ module Atom
+ class Feed < RSSBase
+ def initialize
+ super("1.0")
+ @feed_type = "atom"
+ @feed_subtype = "feed"
+ end
+
+ private
+ def make_feed
+ ::RSS::Atom::Feed.new(@version, @encoding, @standalone)
+ end
+
+ def setup_elements(feed)
+ setup_channel(feed)
+ setup_image(feed)
+ setup_items(feed)
+ end
+
+ class Channel < ChannelBase
+ def to_feed(feed)
+ set_default_values do
+ setup_values(feed)
+ feed.dc_dates.clear
+ setup_other_elements(feed)
+ if image_favicon.about
+ icon = feed.class::Icon.new
+ icon.content = image_favicon.about
+ feed.icon = icon
+ end
+ unless have_required_values?
+ raise NotSetError.new("maker.channel",
+ not_set_required_variables)
+ end
+ end
+ end
+
+ def have_required_values?
+ super and
+ (!authors.empty? or
+ @maker.items.any? {|item| !item.authors.empty?})
+ end
+
+ private
+ def required_variable_names
+ %w(id updated)
+ end
+
+ def variables
+ super + %w(id updated)
+ end
+
+ def variable_is_set?
+ super or !authors.empty?
+ end
+
+ def not_set_required_variables
+ vars = super
+ if authors.empty? and
+ @maker.items.all? {|item| item.author.to_s.empty?}
+ vars << "author"
+ end
+ vars << "title" unless title.have_required_values?
+ vars
+ end
+
+ def _set_default_values(&block)
+ keep = {
+ :id => id,
+ :updated => updated,
+ }
+ self.id ||= about
+ self.updated ||= dc_date
+ super(&block)
+ ensure
+ self.id = keep[:id]
+ self.updated = keep[:updated]
+ end
+
+ class SkipDays < SkipDaysBase
+ def to_feed(*args)
+ end
+
+ class Day < DayBase
+ end
+ end
+
+ class SkipHours < SkipHoursBase
+ def to_feed(*args)
+ end
+
+ class Hour < HourBase
+ end
+ end
+
+ class Cloud < CloudBase
+ def to_feed(*args)
+ end
+ end
+
+ class Categories < CategoriesBase
+ class Category < CategoryBase
+ include AtomCategory
+
+ def self.not_set_name
+ "maker.channel.category"
+ end
+ end
+ end
+
+ class Links < LinksBase
+ class Link < LinkBase
+ include AtomLink
+
+ def self.not_set_name
+ "maker.channel.link"
+ end
+ end
+ end
+
+ AtomPersons.def_atom_persons(self, "author", "maker.channel.author")
+ AtomPersons.def_atom_persons(self, "contributor",
+ "maker.channel.contributor")
+
+ class Generator < GeneratorBase
+ include AtomGenerator
+
+ def self.not_set_name
+ "maker.channel.generator"
+ end
+ end
+
+ AtomTextConstruct.def_atom_text_construct(self, "rights",
+ "maker.channel.copyright",
+ "Copyright")
+ AtomTextConstruct.def_atom_text_construct(self, "subtitle",
+ "maker.channel.description",
+ "Description")
+ AtomTextConstruct.def_atom_text_construct(self, "title",
+ "maker.channel.title")
+ end
+
+ class Image < ImageBase
+ def to_feed(feed)
+ logo = feed.class::Logo.new
+ class << logo
+ alias url= content=
+ end
+ set = setup_values(logo)
+ class << logo
+ undef url=
+ end
+ if set
+ feed.logo = logo
+ set_parent(logo, feed)
+ setup_other_elements(feed, logo)
+ elsif variable_is_set?
+ raise NotSetError.new("maker.image", not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(url)
+ end
+ end
+
+ class Items < ItemsBase
+ def to_feed(feed)
+ normalize.each do |item|
+ item.to_feed(feed)
+ end
+ setup_other_elements(feed, feed.entries)
+ end
+
+ class Item < ItemBase
+ def to_feed(feed)
+ set_default_values do
+ entry = feed.class::Entry.new
+ set = setup_values(entry)
+ setup_other_elements(feed, entry)
+ if set
+ feed.entries << entry
+ set_parent(entry, feed)
+ elsif variable_is_set?
+ raise NotSetError.new("maker.item", not_set_required_variables)
+ end
+ end
+ end
+
+ def have_required_values?
+ set_default_values do
+ super and title.have_required_values?
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(id updated)
+ end
+
+ def variables
+ super + ["updated"]
+ end
+
+ def not_set_required_variables
+ vars = super
+ vars << "title" unless title.have_required_values?
+ vars
+ end
+
+ def _set_default_values(&block)
+ keep = {
+ :id => id,
+ :updated => updated,
+ }
+ self.id ||= link
+ self.updated ||= dc_date
+ super(&block)
+ ensure
+ self.id = keep[:id]
+ self.updated = keep[:updated]
+ end
+
+ class Guid < GuidBase
+ def to_feed(feed, current)
+ end
+ end
+
+ class Enclosure < EnclosureBase
+ def to_feed(feed, current)
+ end
+ end
+
+ class Source < SourceBase
+ def to_feed(feed, current)
+ source = current.class::Source.new
+ setup_values(source)
+ current.source = source
+ set_parent(source, current)
+ setup_other_elements(feed, source)
+ current.source = nil if source.to_s == "<source/>"
+ end
+
+ private
+ def required_variable_names
+ []
+ end
+
+ def variables
+ super + ["updated"]
+ end
+
+ AtomPersons.def_atom_persons(self, "author",
+ "maker.item.source.author")
+ AtomPersons.def_atom_persons(self, "contributor",
+ "maker.item.source.contributor")
+
+ class Categories < CategoriesBase
+ class Category < CategoryBase
+ include AtomCategory
+
+ def self.not_set_name
+ "maker.item.source.category"
+ end
+ end
+ end
+
+ class Generator < GeneratorBase
+ include AtomGenerator
+
+ def self.not_set_name
+ "maker.item.source.generator"
+ end
+ end
+
+ class Icon < IconBase
+ def to_feed(feed, current)
+ icon = current.class::Icon.new
+ class << icon
+ alias url= content=
+ end
+ set = setup_values(icon)
+ class << icon
+ undef url=
+ end
+ if set
+ current.icon = icon
+ set_parent(icon, current)
+ setup_other_elements(feed, icon)
+ elsif variable_is_set?
+ raise NotSetError.new("maker.item.source.icon",
+ not_set_required_variables)
+ end
+ end
+
+ private
+ def required_variable_names
+ %w(url)
+ end
+ end
+
+ class Links < LinksBase
+ class Link < LinkBase
+ include AtomLink
+
+ def self.not_set_name
+ "maker.item.source.link"
+ end
+ end
+ end
+
+ class Logo < LogoBase
+ include AtomLogo
+
+ def self.not_set_name
+ "maker.item.source.logo"
+ end
+ end
+
+ maker_name_base = "maker.item.source."
+ maker_name = "#{maker_name_base}rights"
+ AtomTextConstruct.def_atom_text_construct(self, "rights",
+ maker_name)
+ maker_name = "#{maker_name_base}subtitle"
+ AtomTextConstruct.def_atom_text_construct(self, "subtitle",
+ maker_name)
+ maker_name = "#{maker_name_base}title"
+ AtomTextConstruct.def_atom_text_construct(self, "title",
+ maker_name)
+ end
+
+ class Categories < CategoriesBase
+ class Category < CategoryBase
+ include AtomCategory
+
+ def self.not_set_name
+ "maker.item.category"
+ end
+ end
+ end
+
+ AtomPersons.def_atom_persons(self, "author", "maker.item.author")
+ AtomPersons.def_atom_persons(self, "contributor",
+ "maker.item.contributor")
+
+ class Links < LinksBase
+ class Link < LinkBase
+ include AtomLink
+
+ def self.not_set_name
+ "maker.item.link"
+ end
+ end
+ end
+
+ AtomTextConstruct.def_atom_text_construct(self, "rights",
+ "maker.item.rights")
+ AtomTextConstruct.def_atom_text_construct(self, "summary",
+ "maker.item.description",
+ "Description")
+ AtomTextConstruct.def_atom_text_construct(self, "title",
+ "maker.item.title")
+
+ class Content < ContentBase
+ def to_feed(feed, current)
+ content = current.class::Content.new
+ if setup_values(content)
+ content.src = nil if content.src and content.content
+ current.content = content
+ set_parent(content, current)
+ setup_other_elements(feed, content)
+ elsif variable_is_set?
+ raise NotSetError.new("maker.item.content",
+ not_set_required_variables)
+ end
+ end
+
+ alias_method(:xml, :xml_content)
+
+ private
+ def required_variable_names
+ if out_of_line?
+ %w(type)
+ elsif xml_type?
+ %w(xml_content)
+ else
+ %w(content)
+ end
+ end
+
+ def variables
+ if out_of_line?
+ super
+ elsif xml_type?
+ super + %w(xml)
+ else
+ super
+ end
+ end
+
+ def xml_type?
+ _type = type
+ return false if _type.nil?
+ _type == "xhtml" or
+ /(?:\+xml|\/xml)$/i =~ _type or
+ %w(text/xml-external-parsed-entity
+ application/xml-external-parsed-entity
+ application/xml-dtd).include?(_type.downcase)
+ end
+ end
+ end
+ end
+
+ class Textinput < TextinputBase
+ end
+ end
+ end
+
+ add_maker("atom", Atom::Feed)
+ add_maker("atom:feed", Atom::Feed)
+ add_maker("atom1.0", Atom::Feed)
+ add_maker("atom1.0:feed", Atom::Feed)
+ end
+end
diff --git a/lib/rss/maker/image.rb b/lib/rss/maker/image.rb
index ed51c8ecba1..e3469d05971 100644
--- a/lib/rss/maker/image.rb
+++ b/lib/rss/maker/image.rb
@@ -11,11 +11,11 @@ module RSS
name = "#{RSS::IMAGE_PREFIX}_item"
klass.add_need_initialize_variable(name, "make_#{name}")
klass.add_other_element(name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
attr_reader :#{name}
- def setup_#{name}(rss, current)
+ def setup_#{name}(feed, current)
if @#{name}
- @#{name}.to_rss(rss, current)
+ @#{name}.to_feed(feed, current)
end
end
@@ -25,6 +25,14 @@ module RSS
EOC
end
+ def self.install_image_item(klass)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class ImageItem < ImageItemBase
+ DublinCoreModel.install_dublin_core(self)
+ end
+EOC
+ end
+
class ImageItemBase
include Base
include Maker::DublinCoreModel
@@ -42,6 +50,15 @@ EOC
def have_required_values?
@about
end
+
+ def to_feed(feed, current)
+ if current.respond_to?(:image_item=) and have_required_values?
+ item = current.class::ImageItem.new
+ setup_values(item)
+ setup_other_elements(item)
+ current.image_item = item
+ end
+ end
end
end
@@ -54,9 +71,9 @@ EOC
klass.add_other_element(name)
klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
attr_reader :#{name}
- def setup_#{name}(rss, current)
+ def setup_#{name}(feed, current)
if @#{name}
- @#{name}.to_rss(rss, current)
+ @#{name}.to_feed(feed, current)
end
end
@@ -66,6 +83,14 @@ EOC
EOC
end
+ def self.install_image_favicon(klass)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class ImageFavicon < ImageFaviconBase
+ DublinCoreModel.install_dublin_core(self)
+ end
+EOC
+ end
+
class ImageFaviconBase
include Base
include Maker::DublinCoreModel
@@ -79,6 +104,15 @@ EOC
def have_required_values?
@about and @image_size
end
+
+ def to_feed(feed, current)
+ if current.respond_to?(:image_favicon=) and have_required_values?
+ favicon = current.class::ImageFavicon.new
+ setup_values(favicon)
+ setup_other_elements(favicon)
+ current.image_favicon = favicon
+ end
+ end
end
end
@@ -88,58 +122,18 @@ EOC
class ItemBase; include Maker::ImageItemModel; end
end
- class RSS10
- class Items
- class Item
- class ImageItem < ImageItemBase
- DublinCoreModel.install_dublin_core(self)
- def to_rss(rss, current)
- if @about
- item = ::RSS::ImageItemModel::ImageItem.new(@about, @resource)
- setup_values(item)
- setup_other_elements(item)
- current.image_item = item
- end
- end
- end
+ makers.each do |maker|
+ maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class Channel
+ ImageFaviconModel.install_image_favicon(self)
end
- end
-
- class Channel
- class ImageFavicon < ImageFaviconBase
- DublinCoreModel.install_dublin_core(self)
- def to_rss(rss, current)
- if @about and @image_size
- args = [@about, @image_size]
- favicon = ::RSS::ImageFaviconModel::ImageFavicon.new(*args)
- setup_values(favicon)
- setup_other_elements(favicon)
- current.image_favicon = favicon
- end
- end
- end
- end
- end
- class RSS09
- class Items
- class Item
- class ImageItem < ImageItemBase
- DublinCoreModel.install_dublin_core(self)
- def to_rss(*args)
- end
+ class Items
+ class Item
+ ImageItemModel.install_image_item(self)
end
end
- end
-
- class Channel
- class ImageFavicon < ImageFaviconBase
- DublinCoreModel.install_dublin_core(self)
- def to_rss(*args)
- end
- end
- end
+ EOC
end
-
end
end
diff --git a/lib/rss/maker/taxonomy.rb b/lib/rss/maker/taxonomy.rb
index 2e54ea66ebb..2e53a4e1f48 100644
--- a/lib/rss/maker/taxonomy.rb
+++ b/lib/rss/maker/taxonomy.rb
@@ -15,17 +15,17 @@ module RSS
def make_taxo_topics
self.class::TaxonomyTopics.new(@maker)
end
-
- def setup_taxo_topics(rss, current)
- @taxo_topics.to_rss(rss, current)
+
+ def setup_taxo_topics(feed, current)
+ @taxo_topics.to_feed(feed, current)
end
EOC
end
def self.install_taxo_topics(klass)
- klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1))
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
class TaxonomyTopics < TaxonomyTopicsBase
- def to_rss(rss, current)
+ def to_feed(feed, current)
if current.respond_to?(:taxo_topics)
topics = current.class::TaxonomyTopics.new
bag = topics.Bag
@@ -43,7 +43,8 @@ EOC
include Base
attr_reader :resources
- def_array_element("resources")
+ def_array_element("resource")
+ remove_method :new_resource
end
end
@@ -59,8 +60,8 @@ EOC
self.class::TaxonomyTopics.new(@maker)
end
- def setup_taxo_topics(rss, current)
- @taxo_topics.to_rss(rss, current)
+ def setup_taxo_topics(feed, current)
+ @taxo_topics.to_feed(feed, current)
end
def taxo_topic
@@ -75,25 +76,21 @@ EOC
end
def self.install_taxo_topic(klass)
- klass.module_eval(<<-EOC, *Utils.get_file_and_line_from_caller(1))
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
class TaxonomyTopics < TaxonomyTopicsBase
class TaxonomyTopic < TaxonomyTopicBase
DublinCoreModel.install_dublin_core(self)
TaxonomyTopicsModel.install_taxo_topics(self)
- def to_rss(rss, current)
+ def to_feed(feed, current)
if current.respond_to?(:taxo_topics)
topic = current.class::TaxonomyTopic.new(value)
topic.taxo_link = value
- taxo_topics.to_rss(rss, topic) if taxo_topics
+ taxo_topics.to_feed(feed, topic) if taxo_topics
current.taxo_topics << topic
- setup_other_elements(rss)
+ setup_other_elements(feed, topic)
end
end
-
- def current_element(rss)
- super.taxo_topics.last
- end
end
end
EOC
@@ -102,20 +99,8 @@ EOC
class TaxonomyTopicsBase
include Base
- def_array_element("taxo_topics")
-
- def new_taxo_topic
- taxo_topic = self.class::TaxonomyTopic.new(self)
- @taxo_topics << taxo_topic
- taxo_topic
- end
+ def_array_element("taxo_topic", nil, "self.class::TaxonomyTopic")
- def to_rss(rss, current)
- @taxo_topics.each do |taxo_topic|
- taxo_topic.to_rss(rss, current)
- end
- end
-
class TaxonomyTopicBase
include Base
include DublinCoreModel
@@ -147,32 +132,20 @@ EOC
end
end
- class RSS10
- TaxonomyTopicModel.install_taxo_topic(self)
-
- class Channel
- TaxonomyTopicsModel.install_taxo_topics(self)
- end
+ makers.each do |maker|
+ maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ TaxonomyTopicModel.install_taxo_topic(self)
- class Items
- class Item
+ class Channel
TaxonomyTopicsModel.install_taxo_topics(self)
end
- end
- end
-
- class RSS09
- TaxonomyTopicModel.install_taxo_topic(self)
-
- class Channel
- TaxonomyTopicsModel.install_taxo_topics(self)
- end
- class Items
- class Item
- TaxonomyTopicsModel.install_taxo_topics(self)
+ class Items
+ class Item
+ TaxonomyTopicsModel.install_taxo_topics(self)
+ end
end
- end
+ EOC
end
end
end
diff --git a/lib/rss/maker/trackback.rb b/lib/rss/maker/trackback.rb
index 32254a040ce..09a2fceb2d2 100644
--- a/lib/rss/maker/trackback.rb
+++ b/lib/rss/maker/trackback.rb
@@ -11,9 +11,9 @@ module RSS
name = "#{RSS::TRACKBACK_PREFIX}_ping"
klass.add_need_initialize_variable(name)
klass.add_other_element(name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
attr_accessor :#{name}
- def setup_#{name}(rss, current)
+ def setup_#{name}(feed, current)
if #{name} and current.respond_to?(:#{name}=)
current.#{name} = #{name}
end
@@ -23,14 +23,14 @@ module RSS
name = "#{RSS::TRACKBACK_PREFIX}_abouts"
klass.add_need_initialize_variable(name, "make_#{name}")
klass.add_other_element(name)
- klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
attr_accessor :#{name}
def make_#{name}
self.class::TrackBackAbouts.new(self)
end
- def setup_#{name}(rss, current)
- @#{name}.to_rss(rss, current)
+ def setup_#{name}(feed, current)
+ @#{name}.to_feed(feed, current)
end
EOC
end
@@ -38,20 +38,8 @@ module RSS
class TrackBackAboutsBase
include Base
- def_array_element("abouts")
-
- def new_about
- about = self.class::TrackBackAbout.new(@maker)
- @abouts << about
- about
- end
+ def_array_element("about", nil, "self.class::TrackBackAbout")
- def to_rss(rss, current)
- @abouts.each do |about|
- about.to_rss(rss, current)
- end
- end
-
class TrackBackAboutBase
include Base
@@ -62,65 +50,38 @@ module RSS
alias_method(:resource=, :value=)
alias_method(:content, :value)
alias_method(:content=, :value=)
-
+
def have_required_values?
@value
end
-
- end
- end
- end
-
- class ItemsBase
- class ItemBase; include TrackBackModel; end
- end
- class RSS10
- class Items
- class Item
- class TrackBackAbouts < TrackBackAboutsBase
- class TrackBackAbout < TrackBackAboutBase
- def to_rss(rss, current)
- if resource
- about = ::RSS::TrackBackModel10::TrackBackAbout.new(resource)
- current.trackback_abouts << about
- end
- end
+ def to_feed(feed, current)
+ if current.respond_to?(:trackback_abouts) and have_required_values?
+ about = current.class::TrackBackAbout.new
+ setup_values(about)
+ setup_other_elements(about)
+ current.trackback_abouts << about
end
end
end
end
end
- class RSS09
- class Items
- class Item
- class TrackBackAbouts < TrackBackAboutsBase
- def to_rss(*args)
- end
- class TrackBackAbout < TrackBackAboutBase
- end
- end
- end
- end
+ class ItemsBase
+ class ItemBase; include TrackBackModel; end
end
-
- class RSS20
- class Items
- class Item
- class TrackBackAbouts < TrackBackAboutsBase
- class TrackBackAbout < TrackBackAboutBase
- def to_rss(rss, current)
- if content
- about = ::RSS::TrackBackModel20::TrackBackAbout.new(content)
- current.trackback_abouts << about
- end
+
+ makers.each do |maker|
+ maker.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ class Items
+ class Item
+ class TrackBackAbouts < TrackBackAboutsBase
+ class TrackBackAbout < TrackBackAboutBase
end
end
end
end
- end
+ EOC
end
-
end
end
diff --git a/lib/rss/parser.rb b/lib/rss/parser.rb
index babf15f52c6..f5ea2bbc03e 100644
--- a/lib/rss/parser.rb
+++ b/lib/rss/parser.rb
@@ -2,6 +2,7 @@ require "forwardable"
require "open-uri"
require "rss/rss"
+require "rss/xml"
module RSS
@@ -63,7 +64,8 @@ module RSS
end
end
- def parse(rss, do_validate=true, ignore_unknown_element=true, parser_class=default_parser)
+ def parse(rss, do_validate=true, ignore_unknown_element=true,
+ parser_class=default_parser)
parser = new(rss, parser_class)
parser.do_validate = do_validate
parser.ignore_unknown_element = ignore_unknown_element
@@ -103,7 +105,7 @@ module RSS
return rss if rss.is_a?(::URI::Generic)
begin
- URI(rss)
+ ::URI.parse(rss)
rescue ::URI::Error
rss
end
@@ -158,26 +160,26 @@ module RSS
class << self
- @@setters = {}
+ @@accessor_bases = {}
@@registered_uris = {}
@@class_names = {}
- def install_setter(uri, tag_name, setter)
- @@setters[uri] ||= {}
- @@setters[uri][tag_name] = setter
- end
-
def setter(uri, tag_name)
- begin
- @@setters[uri][tag_name]
- rescue NameError
+ _getter = getter(uri, tag_name)
+ if _getter
+ "#{_getter}="
+ else
nil
end
end
+ def getter(uri, tag_name)
+ (@@accessor_bases[uri] || {})[tag_name]
+ end
+
def available_tags(uri)
begin
- @@setters[uri].keys
+ @@accessor_bases[uri].keys
rescue NameError
[]
end
@@ -205,8 +207,8 @@ module RSS
end
end
- def install_get_text_element(uri, name, setter)
- install_setter(uri, name, setter)
+ def install_get_text_element(uri, name, accessor_base)
+ install_accessor_base(uri, name, accessor_base)
def_get_text_element(uri, name, *get_file_and_line_from_caller(1))
end
@@ -215,20 +217,18 @@ module RSS
end
private
+ def install_accessor_base(uri, tag_name, accessor_base)
+ @@accessor_bases[uri] ||= {}
+ @@accessor_bases[uri][tag_name] = accessor_base.chomp("=")
+ end
def def_get_text_element(uri, name, file, line)
register_uri(uri, name)
unless private_instance_methods(false).include?("start_#{name}".to_sym)
module_eval(<<-EOT, file, line)
def start_#{name}(name, prefix, attrs, ns)
- uri = ns[prefix]
+ uri = _ns(ns, prefix)
if self.class.uri_registered?(uri, #{name.inspect})
- if @do_validate
- tags = self.class.available_tags(uri)
- unless tags.include?(name)
- raise UnknownTagError.new(name, uri)
- end
- end
start_get_text_element(name, prefix, ns, uri)
else
start_else_element(name, prefix, attrs, ns)
@@ -244,7 +244,6 @@ module RSS
end
module ListenerMixin
-
attr_reader :rss
attr_accessor :ignore_unknown_element
@@ -254,13 +253,16 @@ module RSS
@rss = nil
@ignore_unknown_element = true
@do_validate = true
- @ns_stack = [{}]
+ @ns_stack = [{"xml" => :xml}]
@tag_stack = [[]]
@text_stack = ['']
@proc_stack = []
@last_element = nil
@version = @encoding = @standalone = nil
@xml_stylesheets = []
+ @xml_child_mode = false
+ @xml_element = nil
+ @last_xml_element = nil
end
def xmldecl(version, encoding, standalone)
@@ -271,7 +273,7 @@ module RSS
if name == "xml-stylesheet"
params = parse_pi_content(content)
if params.has_key?("href")
- @xml_stylesheets << XMLStyleSheet.new(*params)
+ @xml_stylesheets << XMLStyleSheet.new(params)
end
end
end
@@ -291,12 +293,41 @@ module RSS
@ns_stack.push(ns)
prefix, local = split_name(name)
- @tag_stack.last.push([ns[prefix], local])
+ @tag_stack.last.push([_ns(ns, prefix), local])
@tag_stack.push([])
- if respond_to?("start_#{local}", true)
- __send__("start_#{local}", local, prefix, attrs, ns.dup)
+ if @xml_child_mode
+ previous = @last_xml_element
+ element_attrs = attributes.dup
+ unless previous
+ ns.each do |ns_prefix, value|
+ next if ns_prefix == "xml"
+ key = ns_prefix.empty? ? "xmlns" : "xmlns:#{ns_prefix}"
+ element_attrs[key] ||= value
+ end
+ end
+ next_element = XML::Element.new(local,
+ prefix.empty? ? nil : prefix,
+ _ns(ns, prefix),
+ element_attrs)
+ previous << next_element if previous
+ @last_xml_element = next_element
+ pr = Proc.new do |text, tags|
+ if previous
+ @last_xml_element = previous
+ else
+ @xml_element = @last_xml_element
+ @last_xml_element = nil
+ end
+ end
+ @proc_stack.push(pr)
else
- start_else_element(local, prefix, attrs, ns.dup)
+ if @rss.nil? and respond_to?("initial_start_#{local}", true)
+ __send__("initial_start_#{local}", local, prefix, attrs, ns.dup)
+ elsif respond_to?("start_#{local}", true)
+ __send__("start_#{local}", local, prefix, attrs, ns.dup)
+ else
+ start_else_element(local, prefix, attrs, ns.dup)
+ end
end
end
@@ -313,10 +344,17 @@ module RSS
end
def text(data)
- @text_stack.last << data
+ if @xml_child_mode
+ @last_xml_element << data if @last_xml_element
+ else
+ @text_stack.last << data
+ end
end
private
+ def _ns(ns, prefix)
+ ns.fetch(prefix, "")
+ end
CONTENT_PATTERN = /\s*([^=]+)=(["'])([^\2]+?)\2/
def parse_pi_content(content)
@@ -328,20 +366,20 @@ module RSS
end
def start_else_element(local, prefix, attrs, ns)
- class_name = self.class.class_name(ns[prefix], local)
+ class_name = self.class.class_name(_ns(ns, prefix), local)
current_class = @last_element.class
if current_class.const_defined?(class_name)
next_class = current_class.const_get(class_name)
start_have_something_element(local, prefix, attrs, ns, next_class)
else
- if @ignore_unknown_element
+ if !@do_validate or @ignore_unknown_element
@proc_stack.push(nil)
else
parent = "ROOT ELEMENT???"
if current_class.tag_name
parent = current_class.tag_name
end
- raise NotExceptedTagError.new(local, parent)
+ raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)
end
end
end
@@ -353,41 +391,48 @@ module RSS
end
def check_ns(tag_name, prefix, ns, require_uri)
- if @do_validate
- if ns[prefix] == require_uri
- #ns.delete(prefix)
- else
+ unless _ns(ns, prefix) == require_uri
+ if @do_validate
raise NSError.new(tag_name, prefix, require_uri)
+ else
+ # Force bind required URI with prefix
+ @ns_stack.last[prefix] = require_uri
end
end
end
def start_get_text_element(tag_name, prefix, ns, required_uri)
- @proc_stack.push Proc.new {|text, tags|
+ pr = Proc.new do |text, tags|
setter = self.class.setter(required_uri, tag_name)
- setter ||= "#{tag_name}="
if @last_element.respond_to?(setter)
+ if @do_validate
+ getter = self.class.getter(required_uri, tag_name)
+ if @last_element.__send__(getter)
+ raise TooMuchTagError.new(tag_name, @last_element.tag_name)
+ end
+ end
@last_element.__send__(setter, text.to_s)
else
- if @do_validate and not @ignore_unknown_element
- raise NotExceptedTagError.new(tag_name, @last_element.tag_name)
+ if @do_validate and !@ignore_unknown_element
+ raise NotExpectedTagError.new(tag_name, _ns(ns, prefix),
+ @last_element.tag_name)
end
end
- }
+ end
+ @proc_stack.push(pr)
end
def start_have_something_element(tag_name, prefix, attrs, ns, klass)
check_ns(tag_name, prefix, ns, klass.required_uri)
- args = []
-
- klass.get_attributes.each do |a_name, a_uri, required|
+ attributes = {}
+ klass.get_attributes.each do |a_name, a_uri, required, element_name|
if a_uri.is_a?(String) or !a_uri.respond_to?(:include?)
a_uri = [a_uri]
end
- unless a_uri == [nil]
+ unless a_uri == [""]
for prefix, uri in ns
if a_uri.include?(uri)
val = attrs["#{prefix}:#{a_name}"]
@@ -395,12 +440,12 @@ module RSS
end
end
end
- if val.nil? and a_uri.include?(nil)
+ if val.nil? and a_uri.include?("")
val = attrs[a_name]
end
if @do_validate and required and val.nil?
- unless a_uri.include?(nil)
+ unless a_uri.include?("")
for prefix, uri in ns
if a_uri.include?(uri)
a_name = "#{prefix}:#{a_name}"
@@ -410,20 +455,37 @@ module RSS
raise MissingAttributeError.new(tag_name, a_name)
end
- args << val
+ attributes[a_name] = val
end
previous = @last_element
- next_element = klass.new(*args)
- next_element.do_validate = @do_validate
- previous.funcall(:set_next_element, tag_name, next_element)
+ next_element = klass.new(@do_validate, attributes)
+ previous.__send!(:set_next_element, tag_name, next_element)
@last_element = next_element
- @proc_stack.push Proc.new { |text, tags|
+ @last_element.parent = previous if klass.need_parent?
+ @xml_child_mode = @last_element.have_xml_content?
+ pr = Proc.new do |text, tags|
p(@last_element.class) if DEBUG
- @last_element.content = text if klass.have_content?
- @last_element.validate_for_stream(tags) if @do_validate
+ if @xml_child_mode
+ @last_element.content = @xml_element.to_s
+ xml_setter = @last_element.class.xml_setter
+ @last_element.__send__(xml_setter, @xml_element)
+ @xml_element = nil
+ @xml_child_mode = false
+ else
+ if klass.have_content?
+ if @last_element.need_base64_encode?
+ text = Base64.decode64(text.lstrip)
+ end
+ @last_element.content = text
+ end
+ end
+ if @do_validate
+ @last_element.validate_for_stream(tags, @ignore_unknown_element)
+ end
@last_element = previous
- }
+ end
+ @proc_stack.push(pr)
end
end
diff --git a/lib/rss/rss.rb b/lib/rss/rss.rb
index 52ca4db890c..c0ce96d6bf6 100644
--- a/lib/rss/rss.rb
+++ b/lib/rss/rss.rb
@@ -11,11 +11,19 @@ class Time
(\.\d+)?
(Z|[+-]\d\d:\d\d)?)?
\s*\z/ix =~ date and (($5 and $8) or (!$5 and !$8))
- datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
- datetime << $7.to_f * 1000000 if $7
- if $8
- Time.utc(*datetime) - zone_offset($8)
+ datetime = [$1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i]
+ usec = 0
+ usec = $7.to_f * 1000000 if $7
+ zone = $8
+ if zone
+ off = zone_offset(zone, datetime[0])
+ datetime = apply_offset(*(datetime + [off]))
+ datetime << usec
+ time = Time.utc(*datetime)
+ time.localtime unless zone_utc?(zone)
+ time
else
+ datetime << usec
Time.local(*datetime)
end
else
@@ -26,7 +34,14 @@ class Time
end
unless method_defined?(:w3cdtf)
- alias w3cdtf iso8601
+ def w3cdtf
+ if usec.zero?
+ fraction_digits = 0
+ else
+ fraction_digits = Math.log10(usec.to_s.sub(/0*$/, '').to_i).floor + 1
+ end
+ xmlschema(fraction_digits)
+ end
end
end
@@ -38,7 +53,7 @@ require "rss/xml-stylesheet"
module RSS
- VERSION = "0.1.6"
+ VERSION = "0.1.7"
URI = "http://purl.org/rss/1.0/"
@@ -87,13 +102,15 @@ module RSS
end
end
- class NotExceptedTagError < InvalidRSSError
- attr_reader :tag, :parent
- def initialize(tag, parent)
- @tag, @parent = tag, parent
- super("tag <#{tag}> is not expected in tag <#{parent}>")
+ class NotExpectedTagError < InvalidRSSError
+ attr_reader :tag, :uri, :parent
+ def initialize(tag, uri, parent)
+ @tag, @uri, @parent = tag, uri, parent
+ super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>")
end
end
+ # For backward compatibility :X
+ NotExceptedTagError = NotExpectedTagError
class NotAvailableValueError < InvalidRSSError
attr_reader :tag, :value, :attribute
@@ -135,15 +152,27 @@ module RSS
super("required variables of #{@name} are not set: #{@variables.join(', ')}")
end
end
-
+
+ class UnsupportedMakerVersionError < Error
+ attr_reader :version
+ def initialize(version)
+ @version = version
+ super("Maker doesn't support version: #{@version}")
+ end
+ end
+
module BaseModel
include Utils
- def install_have_child_element(name)
+ def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil)
+ name ||= tag_name
add_need_initialize_variable(name)
+ install_model(tag_name, uri, occurs, name)
- attr_accessor name
+ writer_type, reader_type = type
+ def_corresponded_attr_writer name, writer_type
+ def_corresponded_attr_reader name, reader_type
install_element(name) do |n, elem_name|
<<-EOC
if @#{n}
@@ -156,11 +185,13 @@ EOC
end
alias_method(:install_have_attribute_element, :install_have_child_element)
- def install_have_children_element(name, plural_name=nil)
+ def install_have_children_element(tag_name, uri, occurs, name=nil, plural_name=nil)
+ name ||= tag_name
plural_name ||= "#{name}s"
add_have_children_element(name, plural_name)
add_plural_form(name, plural_name)
-
+ install_model(tag_name, uri, occurs, plural_name)
+
def_children_accessor(name, plural_name)
install_element(name, "s") do |n, elem_name|
<<-EOC
@@ -174,9 +205,12 @@ EOC
end
end
- def install_text_element(name, type=nil, disp_name=name)
+ def install_text_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
+ name ||= tag_name
+ disp_name ||= name
self::ELEMENTS << name
add_need_initialize_variable(name)
+ install_model(tag_name, uri, occurs, name)
def_corresponded_attr_writer name, type, disp_name
convert_attr_reader name
@@ -199,9 +233,13 @@ EOC
end
end
- def install_date_element(name, type, disp_name=name)
+ def install_date_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
+ name ||= tag_name
+ type ||= :w3cdtf
+ disp_name ||= name
self::ELEMENTS << name
add_need_initialize_variable(name)
+ install_model(tag_name, uri, occurs, name)
# accessor
convert_attr_reader name
@@ -230,34 +268,76 @@ EOC
private
def install_element(name, postfix="")
elem_name = name.sub('_', ':')
+ method_name = "#{name}_element#{postfix}"
+ add_to_element_method(method_name)
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def #{name}_element#{postfix}(need_convert=true, indent='')
+ def #{method_name}(need_convert=true, indent='')
#{yield(name, elem_name)}
end
- private :#{name}_element#{postfix}
+ private :#{method_name}
EOC
end
- def convert_attr_reader(*attrs)
+ def inherit_convert_attr_reader(*attrs)
+ attrs.each do |attr|
+ attr = attr.id2name if attr.kind_of?(Integer)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{attr}_without_inherit
+ convert(@#{attr})
+ end
+
+ def #{attr}
+ if @#{attr}
+ #{attr}_without_inherit
+ elsif @parent
+ @parent.#{attr}
+ else
+ nil
+ end
+ end
+EOC
+ end
+ end
+
+ def uri_convert_attr_reader(*attrs)
attrs.each do |attr|
attr = attr.id2name if attr.kind_of?(Integer)
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{attr}_without_base
+ convert(@#{attr})
+ end
+
def #{attr}
- if @converter
- @converter.convert(@#{attr})
+ value = #{attr}_without_base
+ return nil if value.nil?
+ if /\\A[a-z][a-z0-9+.\\-]*:/i =~ value
+ value
else
- @#{attr}
+ "\#{base}\#{value}"
end
end
EOC
end
end
+ def convert_attr_reader(*attrs)
+ attrs.each do |attr|
+ attr = attr.id2name if attr.kind_of?(Integer)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{attr}
+ convert(@#{attr})
+ end
+EOC
+ end
+ end
+
def date_writer(name, type, disp_name=name)
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
def #{name}=(new_value)
- if new_value.nil? or new_value.kind_of?(Time)
+ if new_value.nil?
@#{name} = new_value
+ elsif new_value.kind_of?(Time)
+ @#{name} = new_value.dup
else
if @do_validate
begin
@@ -269,7 +349,9 @@ EOC
@#{name} = nil
if /\\A\\s*\\z/ !~ new_value.to_s
begin
- @#{name} = Time.parse(new_value)
+ unless Date._parse(new_value, false).empty?
+ @#{name} = Time.parse(new_value)
+ end
rescue ArgumentError
end
end
@@ -350,6 +432,32 @@ EOC
EOC
end
+ def text_type_writer(name, disp_name=name)
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{name}=(new_value)
+ if @do_validate and
+ !["text", "html", "xhtml", nil].include?(new_value)
+ raise NotAvailableValueError.new('#{disp_name}', new_value)
+ end
+ @#{name} = new_value
+ end
+EOC
+ end
+
+ def content_writer(name, disp_name=name)
+ klass_name = "self.class::#{Utils.to_class_name(name)}"
+ module_eval(<<-EOC, *get_file_and_line_from_caller(2))
+ def #{name}=(new_value)
+ if new_value.is_a?(#{klass_name})
+ @#{name} = new_value
+ else
+ @#{name} = #{klass_name}.new
+ @#{name}.content = new_value
+ end
+ end
+EOC
+ end
+
def def_children_accessor(accessor_name, plural_name)
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
def #{plural_name}
@@ -365,10 +473,12 @@ EOC
end
def #{accessor_name}=(*args)
+ receiver = self.class.name
warn("Warning:\#{caller.first.sub(/:in `.*'\z/, '')}: " \
- "Don't use `#{accessor_name} = XXX'/`set_#{accessor_name}(XXX)'. " \
+ "Don't use `\#{receiver}\##{accessor_name} = XXX'/" \
+ "`\#{receiver}\#set_#{accessor_name}(XXX)'. " \
"Those APIs are not sense of Ruby. " \
- "Use `#{plural_name} << XXX' instead of them.")
+ "Use `\#{receiver}\##{plural_name} << XXX' instead of them.")
if args.size == 1
@#{accessor_name}.push(args[0])
else
@@ -378,36 +488,70 @@ EOC
alias_method(:set_#{accessor_name}, :#{accessor_name}=)
EOC
end
+ end
- def def_content_only_to_s
- module_eval(<<-EOC, *get_file_and_line_from_caller(2))
- def to_s(need_convert=true, indent=calc_indent)
- if @content
- rv = tag(indent) do |next_indent|
- h(@content)
- end
- rv = convert(rv) if need_convert
- rv
+ module SetupMaker
+ def setup_maker(maker)
+ target = maker_target(maker)
+ unless target.nil?
+ setup_maker_attributes(target)
+ setup_maker_element(target)
+ setup_maker_elements(target)
+ end
+ end
+
+ private
+ def maker_target(maker)
+ nil
+ end
+
+ def setup_maker_attributes(target)
+ end
+
+ def setup_maker_element(target)
+ self.class.need_initialize_variables.each do |var|
+ value = __send__(var)
+ if value.respond_to?("setup_maker") and
+ !not_need_to_call_setup_maker_variables.include?(var)
+ value.setup_maker(target)
else
- ""
+ setter = "#{var}="
+ if target.respond_to?(setter)
+ target.__send__(setter, value)
+ end
+ end
+ end
+ end
+
+ def not_need_to_call_setup_maker_variables
+ []
+ end
+
+ def setup_maker_elements(parent)
+ self.class.have_children_elements.each do |name, plural_name|
+ if parent.respond_to?(plural_name)
+ target = parent.__send__(plural_name)
+ __send__(plural_name).each do |elem|
+ elem.setup_maker(target)
+ end
end
end
-EOC
end
-
end
class Element
extend BaseModel
include Utils
+ include SetupMaker
INDENT = " "
MUST_CALL_VALIDATORS = {}
- MODEL = []
+ MODELS = []
GET_ATTRIBUTES = []
HAVE_CHILDREN_ELEMENTS = []
+ TO_ELEMENT_METHODS = []
NEED_INITIALIZE_VARIABLES = []
PLURAL_FORMS = {}
@@ -416,8 +560,8 @@ EOC
def must_call_validators
MUST_CALL_VALIDATORS
end
- def model
- MODEL
+ def models
+ MODELS
end
def get_attributes
GET_ATTRIBUTES
@@ -425,6 +569,9 @@ EOC
def have_children_elements
HAVE_CHILDREN_ELEMENTS
end
+ def to_element_methods
+ TO_ELEMENT_METHODS
+ end
def need_initialize_variables
NEED_INITIALIZE_VARIABLES
end
@@ -435,9 +582,10 @@ EOC
def inherited(klass)
klass.const_set("MUST_CALL_VALIDATORS", {})
- klass.const_set("MODEL", [])
+ klass.const_set("MODELS", [])
klass.const_set("GET_ATTRIBUTES", [])
klass.const_set("HAVE_CHILDREN_ELEMENTS", [])
+ klass.const_set("TO_ELEMENT_METHODS", [])
klass.const_set("NEED_INITIALIZE_VARIABLES", [])
klass.const_set("PLURAL_FORMS", {})
@@ -446,14 +594,13 @@ EOC
@tag_name = name.split(/::/).last
@tag_name[0,1] = @tag_name[0,1].downcase
- @indent_size = name.split(/::/).size - 2
@have_content = false
def self.must_call_validators
super.merge(MUST_CALL_VALIDATORS)
end
- def self.model
- MODEL + super
+ def self.models
+ MODELS + super
end
def self.get_attributes
GET_ATTRIBUTES + super
@@ -461,6 +608,9 @@ EOC
def self.have_children_elements
HAVE_CHILDREN_ELEMENTS + super
end
+ def self.to_element_methods
+ TO_ELEMENT_METHODS + super
+ end
def self.need_initialize_variables
NEED_INITIALIZE_VARIABLES + super
end
@@ -473,25 +623,32 @@ EOC
MUST_CALL_VALIDATORS[uri] = prefix
end
- def self.install_model(tag, occurs=nil)
- if m = MODEL.find {|t, o| t == tag}
- m[1] = occurs
+ def self.install_model(tag, uri, occurs=nil, getter=nil)
+ getter ||= tag
+ if m = MODELS.find {|t, u, o, g| t == tag and u == uri}
+ m[2] = occurs
else
- MODEL << [tag, occurs]
+ MODELS << [tag, uri, occurs, getter]
end
end
def self.install_get_attribute(name, uri, required=true,
- type=nil, disp_name=name)
- def_corresponded_attr_writer name, type, disp_name
- convert_attr_reader name
+ type=nil, disp_name=nil,
+ element_name=nil)
+ disp_name ||= name
+ element_name ||= name
+ writer_type, reader_type = type
+ def_corresponded_attr_writer name, writer_type, disp_name
+ def_corresponded_attr_reader name, reader_type
if type == :boolean and /^is/ =~ name
alias_method "\#{$POSTMATCH}?", name
end
- GET_ATTRIBUTES << [name, uri, required]
+ GET_ATTRIBUTES << [name, uri, required, element_name]
+ add_need_initialize_variable(disp_name)
end
- def self.def_corresponded_attr_writer(name, type=nil, disp_name=name)
+ def self.def_corresponded_attr_writer(name, type=nil, disp_name=nil)
+ disp_name ||= name
case type
when :integer
integer_writer name, disp_name
@@ -499,15 +656,32 @@ EOC
positive_integer_writer name, disp_name
when :boolean
boolean_writer name, disp_name
+ when :w3cdtf, :rfc822, :rfc2822
+ date_writer name, type, disp_name
+ when :text_type
+ text_type_writer name, disp_name
+ when :content
+ content_writer name, disp_name
else
attr_writer name
end
end
- def self.content_setup(type=nil)
- def_corresponded_attr_writer "content", type
- convert_attr_reader :content
- def_content_only_to_s
+ def self.def_corresponded_attr_reader(name, type=nil)
+ case type
+ when :inherit
+ inherit_convert_attr_reader name
+ when :uri
+ uri_convert_attr_reader name
+ else
+ convert_attr_reader name
+ end
+ end
+
+ def self.content_setup(type=nil, disp_name=nil)
+ writer_type, reader_type = type
+ def_corresponded_attr_writer :content, writer_type, disp_name
+ def_corresponded_attr_reader :content, reader_type
@have_content = true
end
@@ -519,6 +693,10 @@ EOC
HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
end
+ def self.add_to_element_method(method_name)
+ TO_ELEMENT_METHODS << method_name
+ end
+
def self.add_need_initialize_variable(variable_name)
NEED_INITIALIZE_VARIABLES << variable_name
end
@@ -535,7 +713,11 @@ EOC
end
def required_uri
- nil
+ ""
+ end
+
+ def need_parent?
+ false
end
def install_ns(prefix, uri)
@@ -548,19 +730,18 @@ EOC
def tag_name
@tag_name
end
-
- def indent_size
- @indent_size
- end
-
end
- attr_accessor :do_validate
+ attr_accessor :parent, :do_validate
- def initialize(do_validate=true)
+ def initialize(do_validate=true, attrs=nil)
+ @parent = nil
@converter = nil
+ if attrs.nil? and (do_validate.is_a?(Hash) or do_validate.is_a?(Array))
+ do_validate, attrs = true, do_validate
+ end
@do_validate = do_validate
- initialize_variables
+ initialize_variables(attrs || {})
end
def tag_name
@@ -571,10 +752,6 @@ EOC
tag_name
end
- def indent_size
- self.class.indent_size
- end
-
def converter=(converter)
@converter = converter
targets = children.dup
@@ -593,33 +770,73 @@ EOC
value
end
end
-
- def validate
+
+ def valid?(ignore_unknown_element=true)
+ validate(ignore_unknown_element)
+ true
+ rescue RSS::Error
+ false
+ end
+
+ def validate(ignore_unknown_element=true)
+ do_validate = @do_validate
+ @do_validate = true
validate_attribute
- __validate
+ __validate(ignore_unknown_element)
+ ensure
+ @do_validate = do_validate
end
- def validate_for_stream(tags)
+ def validate_for_stream(tags, ignore_unknown_element=true)
validate_attribute
- __validate(tags, false)
+ __validate(ignore_unknown_element, tags, false)
end
- def setup_maker(maker)
- target = maker_target(maker)
- unless target.nil?
- setup_maker_attributes(target)
- setup_maker_element(target)
- setup_maker_elements(target)
+ def to_s(need_convert=true, indent='')
+ if self.class.have_content?
+ return "" if !empty_content? and !content_is_set?
+ rv = tag(indent) do |next_indent|
+ if empty_content?
+ ""
+ else
+ xmled_content
+ end
+ end
+ else
+ rv = tag(indent) do |next_indent|
+ self.class.to_element_methods.collect do |method_name|
+ __send__(method_name, false, next_indent)
+ end
+ end
end
+ rv = convert(rv) if need_convert
+ rv
end
-
+
+ def have_xml_content?
+ false
+ end
+
+ def need_base64_encode?
+ false
+ end
+
private
- def initialize_variables
+ def initialize_variables(attrs)
+ normalized_attrs = {}
+ attrs.each do |key, value|
+ normalized_attrs[key.to_s] = value
+ end
self.class.need_initialize_variables.each do |variable_name|
- instance_eval("@#{variable_name} = nil")
+ value = normalized_attrs[variable_name.to_s]
+ if value
+ __send__("#{variable_name}=", value)
+ else
+ instance_eval("@#{variable_name} = nil")
+ end
end
initialize_have_children_elements
- @content = "" if self.class.have_content?
+ @content = normalized_attrs["content"] if self.class.have_content?
end
def initialize_have_children_elements
@@ -628,14 +845,16 @@ EOC
end
end
- def tag(indent, additional_attrs=[], &block)
+ def tag(indent, additional_attrs={}, &block)
next_indent = indent + INDENT
attrs = collect_attrs
return "" if attrs.nil?
- attrs += additional_attrs
- start_tag = make_start_tag(indent, next_indent, attrs)
+ return "" unless have_required_elements?
+
+ attrs.update(additional_attrs)
+ start_tag = make_start_tag(indent, next_indent, attrs.dup)
if block
content = block.call(next_indent)
@@ -650,6 +869,7 @@ EOC
else
content = content.reject{|x| x.empty?}
if content.empty?
+ return "" if attrs.empty?
end_tag = "/>"
else
start_tag << ">\n"
@@ -671,58 +891,24 @@ EOC
end
def collect_attrs
- _attrs.collect do |name, required, alias_name|
+ attrs = {}
+ _attrs.each do |name, required, alias_name|
value = __send__(alias_name || name)
return nil if required and value.nil?
- [name, value]
- end.reject do |name, value|
- value.nil?
+ next if value.nil?
+ return nil if attrs.has_key?(name)
+ attrs[name] = value
end
+ attrs
end
def tag_name_with_prefix(prefix)
"#{prefix}:#{tag_name}"
end
-
- def calc_indent
- INDENT * (self.class.indent_size)
- end
- def maker_target(maker)
- nil
- end
-
- def setup_maker_attributes(target)
- end
-
- def setup_maker_element(target)
- self.class.need_initialize_variables.each do |var|
- value = __send__(var)
- if value.respond_to?("setup_maker") and
- !not_need_to_call_setup_maker_variables.include?(var)
- value.setup_maker(target)
- else
- setter = "#{var}="
- if target.respond_to?(setter)
- target.__send__(setter, value)
- end
- end
- end
- end
-
- def not_need_to_call_setup_maker_variables
- []
- end
-
- def setup_maker_elements(parent)
- self.class.have_children_elements.each do |name, plural_name|
- if parent.respond_to?(plural_name)
- target = parent.__send__(plural_name)
- __send__(plural_name).each do |elem|
- elem.setup_maker(target)
- end
- end
- end
+ # For backward compatibility
+ def calc_indent
+ ''
end
def set_next_element(tag_name, next_element)
@@ -737,22 +923,41 @@ EOC
__send__("#{prefix}#{tag_name}=", next_element)
end
end
-
- # not String class children.
+
def children
- []
+ rv = []
+ self.class.models.each do |name, uri, occurs, getter|
+ value = __send__(getter)
+ next if value.nil?
+ value = [value] unless value.is_a?(Array)
+ value.each do |v|
+ rv << v if v.is_a?(Element)
+ end
+ end
+ rv
end
- # default #validate() argument.
def _tags
- []
+ rv = []
+ self.class.models.each do |name, uri, occurs, getter|
+ value = __send__(getter)
+ next if value.nil?
+ if value.is_a?(Array)
+ rv.concat([[uri, name]] * value.size)
+ else
+ rv << [uri, name]
+ end
+ end
+ rv
end
def _attrs
- []
+ self.class.get_attributes.collect do |name, uri, required, element_name|
+ [element_name, required, name]
+ end
end
- def __validate(tags=_tags, recursive=true)
+ def __validate(ignore_unknown_element, tags=_tags, recursive=true)
if recursive
children.compact.each do |child|
child.validate
@@ -761,54 +966,44 @@ EOC
must_call_validators = self.class.must_call_validators
tags = tag_filter(tags.dup)
p tags if DEBUG
- self.class::NSPOOL.each do |prefix, uri|
- if tags.has_key?(uri) and !must_call_validators.has_key?(uri)
- meth = "#{prefix}_validate"
- __send__(meth, tags[uri]) if respond_to?(meth, true)
- end
- end
must_call_validators.each do |uri, prefix|
- __send__("#{prefix}_validate", tags[uri])
+ _validate(ignore_unknown_element, tags[uri], uri)
+ meth = "#{prefix}_validate"
+ if !prefix.empty? and respond_to?(meth, true)
+ __send__(meth, ignore_unknown_element, tags[uri], uri)
+ end
end
end
def validate_attribute
_attrs.each do |a_name, required, alias_name|
- if required and __send__(alias_name || a_name).nil?
+ value = instance_variable_get("@#{alias_name || a_name}")
+ if required and value.nil?
raise MissingAttributeError.new(tag_name, a_name)
end
+ __send__("#{alias_name || a_name}=", value)
end
end
- def other_element(need_convert, indent='')
- rv = []
- private_methods.each do |meth|
- if /\A([^_]+)_[^_]+_elements?\z/ =~ meth.to_s and
- self.class::NSPOOL.has_key?($1)
- res = __send__(meth, need_convert, indent)
- rv << res if /\A\s*\z/ !~ res
- end
- end
- rv.join("\n")
- end
-
- def _validate(tags, model=self.class.model)
+ def _validate(ignore_unknown_element, tags, uri, models=self.class.models)
count = 1
do_redo = false
not_shift = false
tag = nil
- element_names = model.collect {|elem| elem[0]}
+ models = models.find_all {|model| model[1] == uri}
+ element_names = models.collect {|model| model[0]}
if tags
tags_size = tags.size
tags = tags.sort_by {|x| element_names.index(x) || tags_size}
end
- model.each_with_index do |elem, i|
+ models.each_with_index do |model, i|
+ name, model_uri, occurs, getter = model
if DEBUG
p "before"
p tags
- p elem
+ p model
end
if not_shift
@@ -822,41 +1017,41 @@ EOC
p count
end
- case elem[1]
+ case occurs
when '?'
if count > 2
- raise TooMuchTagError.new(elem[0], tag_name)
+ raise TooMuchTagError.new(name, tag_name)
else
- if elem[0] == tag
+ if name == tag
do_redo = true
else
not_shift = true
end
end
when '*'
- if elem[0] == tag
+ if name == tag
do_redo = true
else
not_shift = true
end
when '+'
- if elem[0] == tag
+ if name == tag
do_redo = true
else
if count > 1
not_shift = true
else
- raise MissingTagError.new(elem[0], tag_name)
+ raise MissingTagError.new(name, tag_name)
end
end
else
- if elem[0] == tag
- if model[i+1] and model[i+1][0] != elem[0] and
- tags and tags.first == elem[0]
- raise TooMuchTagError.new(elem[0], tag_name)
+ if name == tag
+ if models[i+1] and models[i+1][0] != name and
+ tags and tags.first == name
+ raise TooMuchTagError.new(name, tag_name)
end
else
- raise MissingTagError.new(elem[0], tag_name)
+ raise MissingTagError.new(name, tag_name)
end
end
@@ -877,8 +1072,8 @@ EOC
end
- if !tags.nil? and !tags.empty?
- raise NotExceptedTagError.new(tag, tag_name)
+ if !ignore_unknown_element and !tags.nil? and !tags.empty?
+ raise NotExpectedTagError.new(tags.first, uri, tag_name)
end
end
@@ -892,6 +1087,43 @@ EOC
rv
end
+ def empty_content?
+ false
+ end
+
+ def content_is_set?
+ if have_xml_content?
+ __send__(self.class.xml_getter)
+ else
+ @content
+ end
+ end
+
+ def xmled_content
+ if have_xml_content?
+ __send__(self.class.xml_getter).to_s
+ else
+ content = @content
+ content = Base64.encode64(content) if need_base64_encode?
+ h(content)
+ end
+ end
+
+ def have_required_elements?
+ self.class::MODELS.all? do |tag, uri, occurs, getter|
+ if occurs.nil? or occurs == "+"
+ child = __send__(getter)
+ if child.is_a?(Array)
+ children = child
+ children.any? {|child| child.__send!(:have_required_elements?)}
+ else
+ !child.to_s.empty?
+ end
+ else
+ true
+ end
+ end
+ end
end
module RootElementMixin
@@ -899,16 +1131,23 @@ EOC
include XMLStyleSheetMixin
attr_reader :output_encoding
-
- def initialize(rss_version, version=nil, encoding=nil, standalone=nil)
+ attr_reader :feed_type, :feed_subtype, :feed_version
+ attr_accessor :version, :encoding, :standalone
+ def initialize(feed_version, version=nil, encoding=nil, standalone=nil)
super()
- @rss_version = rss_version
+ @feed_type = nil
+ @feed_subtype = nil
+ @feed_version = feed_version
@version = version || '1.0'
@encoding = encoding
@standalone = standalone
@output_encoding = nil
end
+ def feed_info
+ [@feed_type, @feed_version, @feed_subtype]
+ end
+
def output_encoding=(enc)
@output_encoding = enc
self.converter = Converter.new(@output_encoding, @encoding)
@@ -923,14 +1162,48 @@ EOC
xss.setup_maker(maker)
end
- setup_maker_elements(maker)
+ super
end
-
+
+ def to_feed(type, &block)
+ Maker.make(type) do |maker|
+ setup_maker(maker)
+ block.call(maker) if block
+ end
+ end
+
+ def to_rss(type, &block)
+ to_feed("rss#{type}", &block)
+ end
+
+ def to_atom(type, &block)
+ to_feed("atom:#{type}", &block)
+ end
+
+ def to_xml(type=nil, &block)
+ if type.nil? or same_feed_type?(type)
+ to_s
+ else
+ to_feed(type, &block).to_s
+ end
+ end
+
private
- def tag(indent, attrs, &block)
- rv = xmldecl + xml_stylesheet_pi
- rv << super(indent, attrs, &block)
- rv
+ def same_feed_type?(type)
+ if /^(atom|rss)?(\d+\.\d+)?(?::(.+))?$/i =~ type
+ feed_type = ($1 || @feed_type).downcase
+ feed_version = $2 || @feed_version
+ feed_subtype = $3 || @feed_subtype
+ [feed_type, feed_version, feed_subtype] == feed_info
+ else
+ false
+ end
+ end
+
+ def tag(indent, attrs={}, &block)
+ rv = super(indent, ns_declarations.merge(attrs), &block)
+ return rv if rv.empty?
+ "#{xmldecl}#{xml_stylesheet_pi}#{rv}"
end
def xmldecl
@@ -944,18 +1217,16 @@ EOC
end
def ns_declarations
+ decls = {}
self.class::NSPOOL.collect do |prefix, uri|
prefix = ":#{prefix}" unless prefix.empty?
- ["xmlns#{prefix}", uri]
+ decls["xmlns#{prefix}"] = uri
end
+ decls
end
-
- def setup_maker_elements(maker)
- channel.setup_maker(maker) if channel
- image.setup_maker(maker) if image
- textinput.setup_maker(maker) if textinput
- super(maker)
+
+ def maker_target(target)
+ target
end
end
-
end
diff --git a/lib/rss/syndication.rb b/lib/rss/syndication.rb
index 8791ec24fc2..3eb15429f66 100644
--- a/lib/rss/syndication.rb
+++ b/lib/rss/syndication.rb
@@ -15,20 +15,26 @@ module RSS
def self.append_features(klass)
super
-
- klass.module_eval(<<-EOC, *get_file_and_line_from_caller(1))
+
+ klass.install_must_call_validator(SY_PREFIX, SY_URI)
+ klass.module_eval do
[
["updatePeriod"],
["updateFrequency", :positive_integer]
].each do |name, type|
- install_text_element("\#{SY_PREFIX}_\#{name}", type,
- "\#{SY_PREFIX}:\#{name}")
+ install_text_element(name, SY_URI, "?",
+ "#{SY_PREFIX}_#{name}", type,
+ "#{SY_PREFIX}:#{name}")
end
%w(updateBase).each do |name|
- install_date_element("\#{SY_PREFIX}_\#{name}", 'w3cdtf', name)
+ install_date_element(name, SY_URI, "?",
+ "#{SY_PREFIX}_#{name}", 'w3cdtf',
+ "#{SY_PREFIX}:#{name}")
end
+ end
+ klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
alias_method(:_sy_updatePeriod=, :sy_updatePeriod=)
def sy_updatePeriod=(new_value)
new_value = new_value.strip
@@ -38,20 +44,6 @@ module RSS
EOC
end
- def sy_validate(tags)
- counter = {}
- ELEMENTS.each do |name|
- counter[name] = 0
- end
-
- tags.each do |tag|
- key = "#{SY_PREFIX}_#{tag}"
- raise UnknownTagError.new(tag, SY_URI) unless counter.has_key?(key)
- counter[key] += 1
- raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1
- end
- end
-
private
SY_UPDATEPERIOD_AVAILABLE_VALUES = %w(hourly daily weekly monthly yearly)
def validate_sy_updatePeriod(value)
@@ -69,7 +61,7 @@ module RSS
SyndicationModel::ELEMENTS.uniq!
SyndicationModel::ELEMENTS.each do |full_name|
name = full_name[prefix_size..-1]
- BaseListener.install_get_text_element(SY_URI, name, "#{full_name}=")
+ BaseListener.install_get_text_element(SY_URI, name, full_name)
end
end
diff --git a/lib/rss/taxonomy.rb b/lib/rss/taxonomy.rb
index 52267133ff6..276f63b05dc 100644
--- a/lib/rss/taxonomy.rb
+++ b/lib/rss/taxonomy.rb
@@ -12,7 +12,7 @@ module RSS
%w(link).each do |name|
full_name = "#{TAXO_PREFIX}_#{name}"
- BaseListener.install_get_text_element(TAXO_URI, name, "#{full_name}=")
+ BaseListener.install_get_text_element(TAXO_URI, name, full_name)
TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
end
@@ -28,22 +28,10 @@ module RSS
def self.append_features(klass)
super
- var_name = "#{TAXO_PREFIX}_topics"
- klass.install_have_child_element(var_name)
- end
-
- def taxo_validate(tags)
- found_topics = false
- tags.each do |tag|
- if tag == "topics"
- if found_topics
- raise TooMuchTagError.new(tag, tag_name)
- else
- found_topics = true
- end
- else
- raise UnknownTagError.new(tag, TAXO_URI)
- end
+ klass.install_must_call_validator(TAXO_PREFIX, TAXO_URI)
+ %w(topics).each do |name|
+ klass.install_have_child_element(name, TAXO_URI, "?",
+ "#{TAXO_PREFIX}_#{name}")
end
end
@@ -64,13 +52,17 @@ module RSS
@tag_name = "topics"
- install_have_child_element("Bag")
-
- install_must_call_validator('rdf', ::RSS::RDF::URI)
+ install_have_child_element("Bag", RDF::URI, nil)
+ install_must_call_validator('rdf', RDF::URI)
- def initialize(bag=Bag.new)
- super()
- @Bag = bag
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.Bag = args[0]
+ end
+ self.Bag ||= Bag.new
end
def full_name
@@ -80,15 +72,6 @@ module RSS
def maker_target(target)
target.taxo_topics
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- Bag_element(need_convert, next_indent),
- other_element(need_convert, next_indent),
- ]
- end
- end
def resources
if @Bag
@@ -99,21 +82,6 @@ module RSS
[]
end
end
-
- private
- def children
- [@Bag]
- end
-
- def _tags
- rv = []
- rv << [::RSS::RDF::URI, 'Bag'] unless @Bag.nil?
- rv
- end
-
- def rdf_validate(tags)
- _validate(tags, [["Bag", nil]])
- end
end
end
@@ -123,15 +91,7 @@ module RSS
def self.append_features(klass)
super
var_name = "#{TAXO_PREFIX}_topic"
- klass.install_have_children_element(var_name)
- end
-
- def taxo_validate(tags)
- tags.each do |tag|
- if tag != "topic"
- raise UnknownTagError.new(tag, TAXO_URI)
- end
- end
+ klass.install_have_children_element("topic", TAXO_URI, "*", var_name)
end
class TaxonomyTopic < Element
@@ -152,62 +112,26 @@ module RSS
@tag_name = "topic"
- install_get_attribute("about", ::RSS::RDF::URI, true)
- install_text_element("#{TAXO_PREFIX}_link")
+ install_get_attribute("about", ::RSS::RDF::URI, true, nil, nil,
+ "#{RDF::PREFIX}:about")
+ install_text_element("link", TAXO_URI, "?", "#{TAXO_PREFIX}_link")
- def initialize(about=nil)
- super()
- @about = about
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.about = args[0]
+ end
end
def full_name
tag_name_with_prefix(TAXO_PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent) do |next_indent|
- [
- other_element(need_convert, next_indent),
- ]
- end
- end
-
- def taxo_validate(tags)
- elements = %w(link topics)
- counter = {}
-
- tags.each do |tag|
- if elements.include?(tag)
- counter[tag] ||= 0
- counter[tag] += 1
- raise TooMuchTagError.new(tag, tag_name) if counter[tag] > 1
- else
- raise UnknownTagError.new(tag, TAXO_URI)
- end
- end
- end
def maker_target(target)
target.new_taxo_topic
end
-
- private
- def children
- [@taxo_link, @taxo_topics]
- end
-
- def _attrs
- [
- ["#{RDF::PREFIX}:about", true, "about"]
- ]
- end
-
- def _tags
- rv = []
- rv << [TAXO_URI, "link"] unless @taxo_link.nil?
- rv << [TAXO_URI, "topics"] unless @taxo_topics.nil?
- rv
- end
end
end
diff --git a/lib/rss/trackback.rb b/lib/rss/trackback.rb
index ad6954f3f51..ee2491f332a 100644
--- a/lib/rss/trackback.rb
+++ b/lib/rss/trackback.rb
@@ -11,28 +11,15 @@ module RSS
module TrackBackUtils
private
- def trackback_validate(tags)
- counter = {}
- %w(ping about).each do |name|
- counter["#{TRACKBACK_PREFIX}_#{name}"] = 0
- end
-
- tags.each do |tag|
- key = "#{TRACKBACK_PREFIX}_#{tag}"
- raise UnknownTagError.new(tag, TRACKBACK_URI) unless counter.has_key?(key)
- counter[key] += 1
- if tag != "about" and counter[key] > 1
- raise TooMuchTagError.new(tag, tag_name)
- end
- end
-
- if counter["#{TRACKBACK_PREFIX}_ping"].zero? and
- counter["#{TRACKBACK_PREFIX}_about"].nonzero?
+ def trackback_validate(ignore_unknown_element, tags, uri)
+ return if tags.nil?
+ if tags.find {|tag| tag == "about"} and
+ !tags.find {|tag| tag == "ping"}
raise MissingTagError.new("#{TRACKBACK_PREFIX}:ping", tag_name)
end
end
end
-
+
module BaseTrackBackModel
ELEMENTS = %w(ping about)
@@ -43,10 +30,11 @@ module RSS
unless klass.class == Module
klass.module_eval {include TrackBackUtils}
+ klass.install_must_call_validator(TRACKBACK_PREFIX, TRACKBACK_URI)
%w(ping).each do |name|
var_name = "#{TRACKBACK_PREFIX}_#{name}"
klass_name = "TrackBack#{Utils.to_class_name(name)}"
- klass.install_have_child_element(var_name)
+ klass.install_have_child_element(name, TRACKBACK_URI, "?", var_name)
klass.module_eval(<<-EOC, __FILE__, __LINE__)
remove_method :#{var_name}
def #{var_name}
@@ -63,7 +51,8 @@ module RSS
[%w(about s)].each do |name, postfix|
var_name = "#{TRACKBACK_PREFIX}_#{name}"
klass_name = "TrackBack#{Utils.to_class_name(name)}"
- klass.install_have_children_element(var_name)
+ klass.install_have_children_element(name, TRACKBACK_URI, "*",
+ var_name)
klass.module_eval(<<-EOC, __FILE__, __LINE__)
remove_method :#{var_name}
def #{var_name}(*args)
@@ -124,38 +113,28 @@ module RSS
end
@tag_name = "ping"
-
+
[
["resource", ::RSS::RDF::URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{::RSS::RDF::PREFIX}:#{name}")
end
alias_method(:value, :resource)
alias_method(:value=, :resource=)
-
- def initialize(resource=nil)
- super()
- @resource = resource
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
end
def full_name
tag_name_with_prefix(TRACKBACK_PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
- end
-
- private
- def _attrs
- [
- ["#{::RSS::RDF::PREFIX}:resource", true, "resource"],
- ]
- end
-
end
class TrackBackAbout < Element
@@ -174,38 +153,31 @@ module RSS
end
@tag_name = "about"
-
+
[
["resource", ::RSS::RDF::URI, true]
].each do |name, uri, required|
- install_get_attribute(name, uri, required)
+ install_get_attribute(name, uri, required, nil, nil,
+ "#{::RSS::RDF::PREFIX}:#{name}")
end
alias_method(:value, :resource)
alias_method(:value=, :resource=)
- def initialize(resource=nil)
- super()
- @resource = resource
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.resource = args[0]
+ end
end
def full_name
tag_name_with_prefix(TRACKBACK_PREFIX)
end
-
- def to_s(need_convert=true, indent=calc_indent)
- rv = tag(indent)
- rv = convert(rv) if need_convert
- rv
- end
private
- def _attrs
- [
- ["#{::RSS::RDF::PREFIX}:resource", true, "resource"],
- ]
- end
-
def maker_target(abouts)
abouts.new_about
end
@@ -243,9 +215,13 @@ module RSS
alias_method(:value, :content)
alias_method(:value=, :content=)
- def initialize(content=nil)
- super()
- @content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
end
def full_name
@@ -276,9 +252,13 @@ module RSS
alias_method(:value, :content)
alias_method(:value=, :content=)
- def initialize(content=nil)
- super()
- @content = content
+ def initialize(*args)
+ if Utils.element_initialize_arguments?(args)
+ super
+ else
+ super()
+ self.content = args[0]
+ end
end
def full_name
diff --git a/lib/rss/utils.rb b/lib/rss/utils.rb
index 0286becf00d..031ff3072be 100644
--- a/lib/rss/utils.rb
+++ b/lib/rss/utils.rb
@@ -1,7 +1,5 @@
module RSS
-
module Utils
-
module_function
def to_class_name(name)
name.split(/_/).collect do |part|
@@ -26,6 +24,9 @@ module RSS
klass.new(value)
end
end
- end
+ def element_initialize_arguments?(args)
+ [true, false].include?(args[0]) and args[1].is_a?(Hash)
+ end
+ end
end
diff --git a/lib/rss/xml.rb b/lib/rss/xml.rb
new file mode 100644
index 00000000000..1ae878b7721
--- /dev/null
+++ b/lib/rss/xml.rb
@@ -0,0 +1,71 @@
+require "rss/utils"
+
+module RSS
+ module XML
+ class Element
+ include Enumerable
+
+ attr_reader :name, :prefix, :uri, :attributes, :children
+ def initialize(name, prefix=nil, uri=nil, attributes={}, children=[])
+ @name = name
+ @prefix = prefix
+ @uri = uri
+ @attributes = attributes
+ if children.is_a?(String) or !children.respond_to?(:each)
+ @children = [children]
+ else
+ @children = children
+ end
+ end
+
+ def [](name)
+ @attributes[name]
+ end
+
+ def []=(name, value)
+ @attributes[name] = value
+ end
+
+ def <<(child)
+ @children << child
+ end
+
+ def each(&block)
+ @children.each(&block)
+ end
+
+ def ==(other)
+ other.kind_of?(self.class) and
+ @name == other.name and
+ @uri == other.uri and
+ @attributes == other.attributes and
+ @children == other.children
+ end
+
+ def to_s
+ rv = "<#{full_name}"
+ attributes.each do |key, value|
+ rv << " #{Utils.html_escape(key)}=\"#{Utils.html_escape(value)}\""
+ end
+ if children.empty?
+ rv << "/>"
+ else
+ rv << ">"
+ children.each do |child|
+ rv << child.to_s
+ end
+ rv << "</#{full_name}>"
+ end
+ rv
+ end
+
+ def full_name
+ if @prefix
+ "#{@prefix}:#{@name}"
+ else
+ @name
+ end
+ end
+ end
+ end
+end
diff --git a/sample/rss/blend.rb b/sample/rss/blend.rb
index 2fbd6efed63..7d6b239613f 100755
--- a/sample/rss/blend.rb
+++ b/sample/rss/blend.rb
@@ -64,6 +64,12 @@ rss = RSS::Maker.make("1.0") do |maker|
item.setup_maker(maker.items)
end
end
+
+ maker.items.each do |item|
+ item.title.content ||= "UNKNOWN"
+ item.link ||= "UNKNOWN"
+ end
+
maker.items.do_sort = true
maker.items.max_size = 15
end
diff --git a/sample/rss/convert.rb b/sample/rss/convert.rb
new file mode 100755
index 00000000000..e6bff4c623d
--- /dev/null
+++ b/sample/rss/convert.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+
+require "rss"
+
+feeds = []
+verbose = false
+encoding = "UTF-8"
+to_version = "1.0"
+
+def error(exception)
+ mark = "=" * 20
+ mark = "#{mark} error #{mark}"
+ STDERR.puts mark
+ STDERR.puts exception.class
+ STDERR.puts exception.message
+ STDERR.puts exception.backtrace
+ STDERR.puts mark
+end
+
+before_time = Time.now
+ARGV.each do |fname|
+ case fname
+ when '-v'
+ verbose = true
+ next
+ when /^-t(0\.91|1\.0|2\.0|atom)$/
+ to_version = $1
+ next
+ end
+ rss = nil
+ f = File.read(fname)
+ begin
+ ## do validate parse
+ rss = RSS::Parser.parse(f)
+ rescue RSS::InvalidRSSError
+ error($!) if verbose
+ ## do non validate parse for invalid RSS 1.0
+ begin
+ rss = RSS::Parser.parse(f, false)
+ rescue RSS::Error
+ ## invalid RSS.
+ error($!) if verbose
+ end
+ rescue RSS::Error
+ error($!) if verbose
+ end
+ if rss.nil?
+ STDERR.puts "#{fname} does not include RSS 1.0 or 0.9x/2.0"
+ else
+ begin
+ rss.output_encoding = encoding
+ rescue RSS::UnknownConversionMethodError
+ error($!) if verbose
+ end
+ feeds << [fname, rss]
+ end
+end
+processing_time = Time.now - before_time
+
+feeds.each do |fname, rss|
+ converted_rss = rss.to_xml(to_version)
+ output_name = fname.sub(/(\.[^\.]+)$/, "-#{to_version}\\1")
+ File.open(output_name, "w") do |output|
+ output.print(converted_rss)
+ end
+end
+
+STDERR.puts "Used XML parser: #{RSS::Parser.default_parser}"
+STDERR.puts "Processing time: #{processing_time}s"
diff --git a/sample/rss/list_description.rb b/sample/rss/list_description.rb
index bb1f9636e22..5f7069f3dbc 100644..100755
--- a/sample/rss/list_description.rb
+++ b/sample/rss/list_description.rb
@@ -56,9 +56,18 @@ ARGV.each do |fname|
rescue RSS::UnknownConversionMethodError
error($!) if verbose
end
- rss.channel.title ||= "Unknown"
+
+ rss = rss.to_rss("1.0") do |maker|
+ maker.channel.about ||= maker.channel.link
+ maker.channel.description.content ||= "No description"
+ maker.items.each do |item|
+ item.title.content ||= "No title"
+ item.link ||= "UNKNOWN"
+ end
+ end
+ next if rss.nil?
+
rss.items.each do |item|
- item.title ||= "Unknown"
channels[rss.channel.title] ||= []
channels[rss.channel.title] << item if item.description
end
diff --git a/sample/rss/re_read.rb b/sample/rss/re_read.rb
index c19a5099bb2..ee54a18a88c 100755
--- a/sample/rss/re_read.rb
+++ b/sample/rss/re_read.rb
@@ -29,16 +29,16 @@ ARGV.each do |fname|
read = false
begin
rss = RSS::Parser.parse(source)
- puts "Re-read valid RSS: #{fname}"
+ puts "Re-read valid feed: #{fname}"
RSS::Parser.parse(rss.to_s)
read = true
rescue RSS::InvalidRSSError
error($!) if verbose
- ## do non validate parse for invalid RSS 1.0
+ ## do non validate parse for invalid feed
begin
rss = RSS::Parser.parse(source, false)
rescue RSS::Error
- ## invalid RSS.
+ ## invalid feed
error($!) if verbose
end
rescue RSS::Error
@@ -46,9 +46,9 @@ ARGV.each do |fname|
end
if rss.nil?
- puts "Invalid RSS: #{fname}"
+ puts "Invalid feed: #{fname}"
elsif !read
- puts "Re-read invalid RSS: #{fname}"
+ puts "Re-read invalid feed: #{fname}"
begin
RSS::Parser.parse(rss.to_s)
rescue RSS::Error
diff --git a/sample/rss/rss_recent.rb b/sample/rss/rss_recent.rb
index 7821df5c7ba..1b02835ad11 100644..100755
--- a/sample/rss/rss_recent.rb
+++ b/sample/rss/rss_recent.rb
@@ -55,16 +55,19 @@ ARGV.each do |fname|
rescue RSS::UnknownConversionMethodError
error($!) if verbose
end
- rss.items.each do |item|
- if item.respond_to?(:pubDate) and item.pubDate
- class << item
- alias_method(:dc_date, :pubDate)
- end
- end
- if item.respond_to?(:dc_date) and item.dc_date
- items << [rss.channel, item]
+
+ rss = rss.to_rss("1.0") do |maker|
+ maker.channel.about ||= maker.channel.link
+ maker.channel.description.content ||= "No description"
+ maker.items.each do |item|
+ item.link ||= "UNKNOWN"
end
end
+ next if rss.nil?
+
+ rss.items.each do |item|
+ items << [rss.channel, item] if item.dc_date
+ end
end
end
processing_time = Time.now - before_time
diff --git a/test/rss/rss-assertions.rb b/test/rss/rss-assertions.rb
index c61f74b1366..01f68678f0d 100644
--- a/test/rss/rss-assertions.rb
+++ b/test/rss/rss-assertions.rb
@@ -1,6 +1,5 @@
module RSS
module Assertions
-
def assert_parse(rss, assert_method, *args)
__send__("assert_#{assert_method}", *args) do
::RSS::Parser.parse(rss)
@@ -58,13 +57,14 @@ module RSS
end
end
- def assert_not_excepted_tag(tag, parent)
+ def assert_not_expected_tag(tag, uri, parent)
_wrap_assertion do
begin
yield
- flunk("Not raise NotExceptedTagError")
- rescue ::RSS::NotExceptedTagError => e
+ flunk("Not raise NotExpectedTagError")
+ rescue ::RSS::NotExpectedTagError => e
assert_equal(tag, e.tag)
+ assert_equal(uri, e.uri)
assert_equal(parent, e.parent)
end
end
@@ -129,10 +129,13 @@ module RSS
def assert_xml_stylesheet_pis(attrs_ary, rss=nil)
_wrap_assertion do
- rss ||= ::RSS::RDF.new()
+ if rss.nil?
+ rss = ::RSS::RDF.new
+ setup_rss10(rss)
+ end
xss_strs = []
attrs_ary.each do |attrs|
- xss = ::RSS::XMLStyleSheet.new(*attrs)
+ xss = ::RSS::XMLStyleSheet.new(attrs)
xss_strs.push(xss.to_s)
rss.xml_stylesheets.push(xss)
end
@@ -381,6 +384,648 @@ module RSS
end
end
+ def assert_atom_person(tag_name, generator)
+ _wrap_assertion do
+ name = "Mark Pilgrim"
+ uri = "http://example.org/"
+ email = "f8dy@example.com"
+
+ assert_parse(generator.call(<<-EOA), :missing_tag, "name", tag_name)
+ <#{tag_name}/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :missing_tag, "name", tag_name)
+ <#{tag_name}>
+ <uri>#{uri}</uri>
+ <email>#{email}</email>
+ </#{tag_name}>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <#{tag_name}>
+ <name>#{name}</name>
+ </#{tag_name}>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <#{tag_name}>
+ <name>#{name}</name>
+ <uri>#{uri}</uri>
+ <email>#{email}</email>
+ </#{tag_name}>
+EOA
+
+ person = yield(feed)
+ assert_not_nil(person)
+ assert_equal(name, person.name.content)
+ assert_equal(uri, person.uri.content)
+ assert_equal(email, person.email.content)
+ end
+ end
+
+ def assert_atom_category(generator)
+ _wrap_assertion do
+ term = "Music"
+ scheme = "http://xmlns.com/wordnet/1.6/"
+ label = "music"
+
+ missing_args = [:missing_attribute, "category", "term"]
+ assert_parse(generator.call(<<-EOA), *missing_args)
+ <category/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), *missing_args)
+ <category scheme="#{scheme}" label="#{label}"/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <category term="#{term}"/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <category term="#{term}" scheme="#{scheme}" label="#{label}"/>
+EOA
+
+ category = yield(feed)
+ assert_not_nil(category)
+ assert_equal(term, category.term)
+ assert_equal(scheme, category.scheme)
+ assert_equal(label, category.label)
+ end
+ end
+
+ def assert_atom_link(generator)
+ _wrap_assertion do
+ href = "http://example.org/feed.atom"
+ rel = "self"
+ type = "application/atom+xml"
+ hreflang = "en"
+ title = "Atom"
+ length = "1024"
+
+ assert_parse(generator.call(<<-EOA), :missing_attribute, "link", "href")
+ <link/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :missing_attribute, "link", "href")
+ <link rel="#{rel}" type="#{type}" hreflang="#{hreflang}"
+ title="#{title}" length="#{length}"/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <link href="#{href}"/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <link href="#{href}" rel="#{rel}" type="#{type}" hreflang="#{hreflang}"
+ title="#{title}" length="#{length}"/>
+EOA
+
+ link = yield(feed)
+ assert_not_nil(link)
+ assert_equal(href, link.href)
+ assert_equal(rel, link.rel)
+ assert_equal(type, link.type)
+ assert_equal(hreflang, link.hreflang)
+ assert_equal(title, link.title)
+ assert_equal(length, link.length)
+
+
+ href = "http://example.org/index.html.ja"
+ parent = link.parent.tag_name
+ return if parent == "source"
+
+ optional_attributes = %w(hreflang="ja" type="text/html")
+ 0.upto(optional_attributes.size) do |i|
+ combination(optional_attributes, i).each do |attributes|
+ attrs = attributes.join(" ")
+ assert_parse(generator.call(<<-EOA), :too_much_tag, "link", parent)
+ <link rel="alternate" #{attrs} href="#{href}"/>
+ <link rel="alternate" #{attrs} href="#{href}"/>
+EOA
+ end
+ end
+ end
+ end
+
+ def assert_atom_generator(generator)
+ _wrap_assertion do
+ uri = "http://www.example.com/"
+ version = "1.0"
+ content = "Example Toolkit"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <generator/>
+EOA
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <generator uri="#{uri}" version="#{version}"/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <generator uri="#{uri}" version="#{version}">#{content}</generator>
+EOA
+
+ gen = yield(feed)
+ assert_not_nil(gen)
+ assert_equal(uri, gen.uri)
+ assert_equal(version, gen.version)
+ assert_equal(content, gen.content)
+ end
+ end
+
+ def assert_atom_icon(generator)
+ _wrap_assertion do
+ content = "http://www.example.com/example.png"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <icon/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <icon>#{content}</icon>
+EOA
+
+ icon = yield(feed)
+ assert_not_nil(icon)
+ assert_equal(content, icon.content)
+ end
+ end
+
+ def assert_atom_text_construct(tag_name, generator)
+ _wrap_assertion do
+ [nil, "text", "html"].each do |type|
+ attr = ""
+ attr = " type=\"#{type}\""if type
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <#{tag_name}#{attr}/>
+EOA
+ end
+
+ assert_parse(generator.call(<<-EOA), :missing_tag, "div", tag_name)
+ <#{tag_name} type="xhtml"/>
+EOA
+
+ args = ["x", Atom::URI, tag_name]
+ assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)
+ <#{tag_name} type="xhtml"><x/></#{tag_name}>
+EOA
+
+ invalid_value = "invalid"
+ args = ["type", invalid_value]
+ assert_parse(generator.call(<<-EOA), :not_available_value, *args)
+ <#{tag_name} type="#{invalid_value}"/>
+EOA
+
+ [
+ [nil, "A lot of effort went into making this effortless"],
+ ["text", "A lot of effort went into making this effortless"],
+ ["html", "A <em>lot</em> of effort went into making this effortless"],
+ ].each do |type, content|
+ attr = ""
+ attr = " type=\"#{type}\"" if type
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <#{tag_name}#{attr}>#{h content}</#{tag_name}>
+EOA
+
+ element = yield(feed)
+ assert_not_nil(element)
+ assert_equal(type, element.type)
+ assert_equal(content, element.content)
+ end
+
+ [false, true].each do |with_space|
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ xhtml_content = "<div xmlns=\"#{xhtml_uri}\">abc</div>"
+ xhtml_element = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ ["abc"])
+ content = xhtml_content
+ content = " #{content} " if with_space
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <#{tag_name} type="xhtml">#{content}</#{tag_name}>
+EOA
+
+ element = yield(feed)
+ assert_not_nil(element)
+ assert_equal("xhtml", element.type)
+ assert_equal(xhtml_content, element.content)
+ assert_equal(xhtml_element, element.xhtml)
+ end
+ end
+ end
+
+ def assert_atom_date_construct(tag_name, generator)
+ _wrap_assertion do
+ args = [tag_name, ""]
+ assert_parse(generator.call(<<-EOR), :not_available_value, *args)
+ <#{tag_name}/>
+EOR
+
+ [
+ ["xxx", false],
+ ["2007", false],
+ ["2007/02/09", true],
+ ].each do |invalid_value, can_parse|
+ assert_not_available_value(tag_name, invalid_value) do
+ RSS::Parser.parse(generator.call(<<-EOR))
+ <#{tag_name}>#{invalid_value}</#{tag_name}>
+EOR
+ end
+
+ feed = RSS::Parser.parse(generator.call(<<-EOR), false)
+ <#{tag_name}>#{invalid_value}</#{tag_name}>
+EOR
+ value = yield(feed).content
+ if can_parse
+ assert_equal(Time.parse(invalid_value), value)
+ else
+ assert_nil(value)
+ end
+ end
+
+ [
+ "2003-12-13T18:30:02Z",
+ "2003-12-13T18:30:02.25Z",
+ "2003-12-13T18:30:02+01:00",
+ "2003-12-13T18:30:02.25+01:00",
+ ].each do |valid_value|
+ assert_parse(generator.call(<<-EOR), :nothing_raised)
+ <#{tag_name}>#{valid_value}</#{tag_name}>
+EOR
+
+ feed = RSS::Parser.parse(generator.call(<<-EOR))
+ <#{tag_name}>#{valid_value}</#{tag_name}>
+EOR
+ assert_equal(Time.parse(valid_value), yield(feed).content)
+ end
+ end
+ end
+
+ def assert_atom_logo(generator)
+ _wrap_assertion do
+ content = "http://www.example.com/example.png"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <logo/>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <logo>#{content}</logo>
+EOA
+
+ logo = yield(feed)
+ assert_not_nil(logo)
+ assert_equal(content, logo.content)
+ end
+ end
+
+ def assert_atom_content(generator, &getter)
+ _wrap_assertion do
+ assert_atom_content_inline_text(generator, &getter)
+ assert_atom_content_inline_xhtml(generator, &getter)
+ assert_atom_content_inline_other(generator, &getter)
+ assert_atom_content_out_of_line(generator, &getter)
+ end
+ end
+
+ def assert_atom_content_inline_text(generator)
+ _wrap_assertion do
+ [nil, "text", "html"].each do |type|
+ content = "<content"
+ content << " type='#{type}'" if type
+
+ suffix = "/>"
+ assert_parse(generator.call(content + suffix), :nothing_raised)
+ suffix = ">xxx</content>"
+ assert_parse(generator.call(content + suffix), :nothing_raised)
+ end
+
+ [
+ ["text", "sample content"],
+ ["text/plain", "sample content"],
+ ["html", "<em>sample</em> content"]
+ ].each do |type, content_content|
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{type}">#{h content_content}</content>
+EOA
+ content = yield(feed)
+ assert_equal(type, content.type)
+ if %w(text html).include?(type)
+ assert(content.inline_text?)
+ else
+ assert(!content.inline_text?)
+ end
+ if type == "html"
+ assert(content.inline_html?)
+ else
+ assert(!content.inline_html?)
+ end
+ assert(!content.inline_xhtml?)
+ if type == "text/plain"
+ assert(content.inline_other?)
+ assert(content.inline_other_text?)
+ else
+ assert(!content.inline_other?)
+ assert(!content.inline_other_text?)
+ end
+ assert(!content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(!content.have_xml_content?)
+ assert_equal(content_content, content.content)
+ end
+ end
+ end
+
+ def assert_atom_content_inline_xhtml(generator)
+ _wrap_assertion do
+ args = ["div", "content"]
+ assert_parse(generator.call(<<-EOA), :missing_tag, *args)
+ <content type="xhtml"/>
+EOA
+
+ args = ["x", Atom::URI, "content"]
+ assert_parse(generator.call(<<-EOA), :not_expected_tag, *args)
+ <content type="xhtml"><x/></content>
+EOA
+
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ xhtml_content = "<div xmlns=\"#{xhtml_uri}\">abc</div>"
+ xhtml_element = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ ["abc"])
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="xhtml">#{xhtml_content}</content>
+EOA
+
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal("xhtml", content.type)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(content.inline_xhtml?)
+ assert(!content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(!content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(content.have_xml_content?)
+ assert_equal(xhtml_content, content.content)
+ assert_equal(xhtml_element, content.xhtml)
+ end
+ end
+
+ def assert_atom_content_inline_other(generator, &getter)
+ _wrap_assertion do
+ assert_atom_content_inline_other_text(generator, &getter)
+ assert_atom_content_inline_other_xml(generator, &getter)
+ end
+ end
+
+ def assert_atom_content_inline_other_text(generator)
+ _wrap_assertion do
+ require "zlib"
+
+ type = "application/zip"
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <content type="#{type}"/>
+EOA
+
+ text = ""
+ char = "a"
+ 100.times do |i|
+ text << char
+ char.succ!
+ end
+ base64_content = Base64.encode64(Zlib::Deflate.deflate(text))
+
+ [false, true].each do |with_space|
+ xml_content = base64_content
+ xml_content = " #{base64_content}" if with_space
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{type}">#{xml_content}</content>
+EOA
+
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal(type, content.type)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(!content.inline_xhtml?)
+ assert(content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(!content.inline_other_xml?)
+ assert(content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(!content.have_xml_content?)
+ assert_equal(text, Zlib::Inflate.inflate(content.content))
+
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => type}, base64_content, xml)
+ end
+ end
+ end
+
+ def assert_atom_content_inline_other_xml(generator)
+ _wrap_assertion do
+ type = "image/svg+xml"
+
+ assert_parse(generator.call(<<-EOA), :nothing_raised)
+ <content type="#{type}"/>
+EOA
+
+ svg_uri = "http://www.w3.org/2000/svg"
+ svg_width = "50pt"
+ svg_height = "20pt"
+ svg_version = "1.0"
+ text_x = "15"
+ text_y = "15"
+ text = "text"
+ svg_content = <<-EOS
+<svg
+ xmlns="#{svg_uri}"
+ width="#{svg_width}"
+ height="#{svg_height}"
+ version="#{svg_version}"
+><text x="#{text_x}" y="#{text_y}">#{text}</text
+></svg>
+EOS
+
+ text_element = RSS::XML::Element.new("text", nil, svg_uri,
+ {
+ "x" => text_x,
+ "y" => text_y,
+ },
+ [text])
+ svg_element = RSS::XML::Element.new("svg", nil, svg_uri,
+ {
+ "xmlns" => svg_uri,
+ "width" => svg_width,
+ "height" => svg_height,
+ "version" => svg_version,
+ },
+ [text_element])
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{type}">#{svg_content}</content>
+EOA
+
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal(type, content.type)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(!content.inline_xhtml?)
+ assert(content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(!content.out_of_line?)
+ assert(content.have_xml_content?)
+ assert_equal(REXML::Document.new(svg_content).to_s.chomp,
+ REXML::Document.new(content.content).to_s.chomp)
+ assert_equal(svg_element, content.xml)
+ assert_nil(content.xhtml)
+ end
+ end
+
+ def assert_atom_content_out_of_line(generator)
+ _wrap_assertion do
+ text_type = "text/plain"
+ text_src = "http://example.com/README.txt"
+
+ missing_args = [:missing_attribute, "content", "type"]
+ # RSS Parser raises error even if this is "should" not "must".
+ assert_parse(generator.call(<<-EOA), *missing_args)
+ <content src="#{text_src}"/>
+EOA
+
+ content_content = "xxx"
+ not_available_value_args = [:not_available_value,
+ "content", content_content]
+ assert_parse(generator.call(<<-EOA), *not_available_value_args)
+ <content type="#{text_type}" src="#{text_src}">#{content_content}</content>
+EOA
+
+ feed = RSS::Parser.parse(generator.call(<<-EOA))
+ <content type="#{text_type}" src="#{text_src}"/>
+EOA
+ content = yield(feed)
+ assert_not_nil(content)
+ assert_equal(text_type, content.type)
+ assert_equal(text_src, content.src)
+ assert(!content.inline_text?)
+ assert(!content.inline_html?)
+ assert(!content.inline_xhtml?)
+ assert(!content.inline_other?)
+ assert(!content.inline_other_text?)
+ assert(!content.inline_other_xml?)
+ assert(!content.inline_other_base64?)
+ assert(content.out_of_line?)
+ assert(!content.have_xml_content?)
+ assert_nil(content.xml)
+ assert_nil(content.xhtml)
+ assert_equal("", content.content)
+ end
+ end
+
+ def assert_atom_source(generator, &getter)
+ _wrap_assertion do
+ assert_atom_source_author(generator, &getter)
+ assert_atom_source_category(generator, &getter)
+ assert_atom_source_contributor(generator, &getter)
+ assert_atom_source_generator(generator, &getter)
+ assert_atom_source_icon(generator, &getter)
+ assert_atom_source_id(generator, &getter)
+ assert_atom_source_link(generator, &getter)
+ assert_atom_source_logo(generator, &getter)
+ assert_atom_source_rights(generator, &getter)
+ assert_atom_source_subtitle(generator, &getter)
+ assert_atom_source_title(generator, &getter)
+ assert_atom_source_updated(generator, &getter)
+ end
+ end
+
+ def assert_atom_source_author(generator)
+ assert_atom_person("author", generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.authors.size)
+ source.author
+ end
+ end
+
+ def assert_atom_source_category(generator)
+ assert_atom_category(generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.categories.size)
+ source.category
+ end
+ end
+
+ def assert_atom_source_contributor(generator)
+ assert_atom_person("contributor", generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.contributors.size)
+ source.contributor
+ end
+ end
+
+ def assert_atom_source_generator(generator)
+ assert_atom_generator(generator) do |feed|
+ yield(feed).generator
+ end
+ end
+
+ def assert_atom_source_icon(generator)
+ assert_atom_icon(generator) do |feed|
+ yield(feed).icon
+ end
+ end
+
+ def assert_atom_source_id(generator)
+ id_content = "urn:uuid:a2fb588b-5674-4898-b420-265a734fea69"
+ id = "<id>#{id_content}</id>"
+ feed = RSS::Parser.parse(generator.call(id))
+ assert_equal(id_content, yield(feed).id.content)
+ end
+
+ def assert_atom_source_link(generator)
+ assert_atom_link(generator) do |feed|
+ source = yield(feed)
+ assert_equal(1, source.links.size)
+ source.link
+ end
+ end
+
+ def assert_atom_source_logo(generator)
+ assert_atom_logo(generator) do |feed|
+ yield(feed).logo
+ end
+ end
+
+ def assert_atom_source_rights(generator)
+ assert_atom_text_construct("rights", generator) do |feed|
+ yield(feed).rights
+ end
+ end
+
+ def assert_atom_source_subtitle(generator)
+ assert_atom_text_construct("subtitle", generator) do |feed|
+ yield(feed).subtitle
+ end
+ end
+
+ def assert_atom_source_title(generator)
+ assert_atom_text_construct("title", generator) do |feed|
+ yield(feed).title
+ end
+ end
+
+ def assert_atom_source_updated(generator)
+ assert_atom_date_construct("updated", generator) do |feed|
+ yield(feed).updated
+ end
+ end
def assert_dublin_core(elems, target)
_wrap_assertion do
@@ -479,7 +1124,1531 @@ module RSS
end
end
end
-
+
+ def assert_rexml_element(children, attrs, text, element, text_type=nil)
+ _wrap_assertion do
+ if children
+ children_info = element.elements.collect {|e| [e.namespace, e.name]}
+ assert_equal(children.collect {|uri, name| [uri, name]}.sort,
+ children_info.sort)
+ end
+ if attrs
+ assert_equal(attrs.collect {|k, v| [k, v]}.sort,
+ element.attributes.collect {|k, v| [k, v]}.sort)
+ end
+ case text_type
+ when :time
+ assert_not_nil(element.text)
+ assert_equal(Time.parse(text).to_s, Time.parse(element.text).to_s)
+ else
+ assert_equal(text, element.text)
+ end
+ end
+ end
+
+
+ def assert_atom_person_to_s(target_class)
+ _wrap_assertion do
+ name = "A person"
+ uri = "http://example.com/person/"
+ email = "person@example.com"
+
+ target = target_class.new
+ assert_equal("", target.to_s)
+
+ target = target_class.new
+ person_name = target_class::Name.new
+ person_name.content = name
+ target.name = person_name
+ xml_target = REXML::Document.new(target.to_s).root
+ assert_equal(["name"], xml_target.elements.collect {|e| e.name})
+ assert_equal([name], xml_target.elements.collect {|e| e.text})
+
+ person_uri = target_class::Uri.new
+ person_uri.content = uri
+ target.uri = person_uri
+ xml_target = REXML::Document.new(target.to_s).root
+ assert_equal(["name", "uri"], xml_target.elements.collect {|e| e.name})
+ assert_equal([name, uri], xml_target.elements.collect {|e| e.text})
+
+ person_email = target_class::Email.new
+ person_email.content = email
+ target.email = person_email
+ xml_target = REXML::Document.new(target.to_s).root
+ assert_equal(["name", "uri", "email"],
+ xml_target.elements.collect {|e| e.name})
+ assert_equal([name, uri, email],
+ xml_target.elements.collect {|e| e.text})
+ end
+ end
+
+ def assert_atom_category_to_s(target_class)
+ _wrap_assertion do
+ term = "music"
+ scheme = "http://example.com/music"
+ label = "Music"
+
+ category = target_class.new
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.scheme = scheme
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.label = label
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.scheme = scheme
+ category.label = label
+ assert_equal("", category.to_s)
+
+ category = target_class.new
+ category.term = term
+ xml = REXML::Document.new(category.to_s).root
+ assert_rexml_element([], {"term" => term}, nil, xml)
+
+ category = target_class.new
+ category.term = term
+ category.scheme = scheme
+ xml = REXML::Document.new(category.to_s).root
+ assert_rexml_element([], {"term" => term, "scheme" => scheme}, nil, xml)
+
+ category = target_class.new
+ category.term = term
+ category.label = label
+ xml = REXML::Document.new(category.to_s).root
+ assert_rexml_element([], {"term" => term, "label" => label}, nil, xml)
+
+ category = target_class.new
+ category.term = term
+ category.scheme = scheme
+ category.label = label
+ xml = REXML::Document.new(category.to_s).root
+ attrs = {"term" => term, "scheme" => scheme, "label" => label}
+ assert_rexml_element([], attrs, nil, xml)
+ end
+ end
+
+ def assert_atom_generator_to_s(target_class)
+ _wrap_assertion do
+ content = "Feed generator"
+ uri = "http://example.com/generator"
+ version = "0.0.1"
+
+ generator = target_class.new
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.uri = uri
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.version = version
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.uri = uri
+ generator.version = version
+ assert_equal("", generator.to_s)
+
+ generator = target_class.new
+ generator.content = content
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {}, content, xml)
+
+ generator = target_class.new
+ generator.content = content
+ generator.uri = uri
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {"uri" => uri}, content, xml)
+
+ generator = target_class.new
+ generator.content = content
+ generator.version = version
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {"version" => version}, content, xml)
+
+ generator = target_class.new
+ generator.content = content
+ generator.uri = uri
+ generator.version = version
+ xml = REXML::Document.new(generator.to_s).root
+ assert_rexml_element([], {"uri" => uri, "version" => version},
+ content, xml)
+ end
+ end
+
+ def assert_atom_icon_to_s(target_class)
+ _wrap_assertion do
+ content = "http://example.com/icon.png"
+
+ icon = target_class.new
+ assert_equal("", icon.to_s)
+
+ icon = target_class.new
+ icon.content = content
+ xml = REXML::Document.new(icon.to_s).root
+ assert_rexml_element([], {}, content, xml)
+ end
+ end
+
+ def assert_atom_id_to_s(target_class)
+ _wrap_assertion do
+ content = "http://example.com/1"
+
+ id = target_class.new
+ assert_equal("", id.to_s)
+
+ id = target_class.new
+ id.content = content
+ xml = REXML::Document.new(id.to_s).root
+ assert_rexml_element([], {}, content, xml)
+ end
+ end
+
+ def assert_atom_link_to_s(target_class)
+ _wrap_assertion do
+ href = "http://example.com/atom.xml"
+ rel = "self"
+ type = "application/atom+xml"
+ hreflang = "ja"
+ title = "Atom Feed"
+ length = "801"
+
+ link = target_class.new
+ assert_equal("", link.to_s)
+
+ link = target_class.new
+ link.href = href
+ xml = REXML::Document.new(link.to_s).root
+ assert_rexml_element([], {"href" => href}, nil, xml)
+
+ optional_arguments = %w(rel type hreflang title length)
+ optional_arguments.each do |name|
+ rest = optional_arguments.reject {|x| x == name}
+
+ link = target_class.new
+ link.__send__("#{name}=", eval(name))
+ assert_equal("", link.to_s)
+
+ rest.each do |n|
+ link.__send__("#{n}=", eval(n))
+ assert_equal("", link.to_s)
+ end
+
+ link = target_class.new
+ link.href = href
+ link.__send__("#{name}=", eval(name))
+ attrs = [["href", href], [name, eval(name)]]
+ xml = REXML::Document.new(link.to_s).root
+ assert_rexml_element([], attrs, nil, xml)
+
+ rest.each do |n|
+ link.__send__("#{n}=", eval(n))
+ attrs << [n, eval(n)]
+ xml = REXML::Document.new(link.to_s).root
+ assert_rexml_element([], attrs, nil, xml)
+ end
+ end
+ end
+ end
+
+ def assert_atom_logo_to_s(target_class)
+ _wrap_assertion do
+ content = "http://example.com/logo.png"
+
+ logo = target_class.new
+ assert_equal("", logo.to_s)
+
+ logo = target_class.new
+ logo.content = content
+ xml = REXML::Document.new(logo.to_s).root
+ assert_rexml_element([], {}, content, xml)
+ end
+ end
+
+ def assert_atom_text_construct_to_s(target_class)
+ _wrap_assertion do
+ text_content = "plain text"
+ html_content = "<em>#{text_content}</em>"
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ xhtml_em = RSS::XML::Element.new("em", nil, xhtml_uri, {}, text_content)
+ xhtml_content = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ [xhtml_em])
+
+ text = target_class.new
+ assert_equal("", text.to_s)
+
+ text = target_class.new
+ text.type = "text"
+ assert_equal("", text.to_s)
+
+ text = target_class.new
+ text.content = text_content
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([], {}, text_content, xml)
+
+ text = target_class.new
+ text.type = "text"
+ text.content = text_content
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([], {"type" => "text"}, text_content, xml)
+
+ text = target_class.new
+ text.type = "html"
+ text.content = html_content
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([], {"type" => "html"}, html_content, xml)
+
+ text = target_class.new
+ text.type = "xhtml"
+ text.content = xhtml_content
+ assert_equal("", text.to_s)
+
+ text = target_class.new
+ text.type = "xhtml"
+ text.__send__(target_class.xml_setter, xhtml_content)
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([[xhtml_uri, "div"]], {"type" => "xhtml"},
+ nil, xml)
+ assert_rexml_element([[xhtml_uri, "em"]], nil, nil, xml.elements[1])
+ assert_rexml_element([], {}, text_content, xml.elements[1].elements[1])
+
+ text = target_class.new
+ text.type = "xhtml"
+ text.__send__(target_class.xml_setter, xhtml_em)
+ xml = REXML::Document.new(text.to_s).root
+ assert_rexml_element([[xhtml_uri, "div"]], {"type" => "xhtml"},
+ nil, xml)
+ assert_rexml_element([[xhtml_uri, "em"]], nil, nil, xml.elements[1])
+ assert_rexml_element([], {}, text_content, xml.elements[1].elements[1])
+ end
+ end
+
+ def assert_atom_date_construct_to_s(target_class)
+ _wrap_assertion do
+ date = target_class.new
+ assert_equal("", date.to_s)
+
+ [
+ "2003-12-13T18:30:02Z",
+ "2003-12-13T18:30:02.25Z",
+ "2003-12-13T18:30:02+01:00",
+ "2003-12-13T18:30:02.25+01:00",
+ ].each do |content|
+ date = target_class.new
+ date.content = content
+ xml = REXML::Document.new(date.to_s).root
+ assert_rexml_element([], {}, content, xml, :time)
+
+ date = target_class.new
+ date.content = Time.parse(content)
+ xml = REXML::Document.new(date.to_s).root
+ assert_rexml_element([], {}, content, xml, :time)
+ end
+ end
+ end
+
+ def assert_atom_content_to_s(target_class)
+ _wrap_assertion do
+ assert_atom_text_construct_to_s(target_class)
+ assert_atom_content_inline_other_xml_to_s(target_class)
+ assert_atom_content_inline_other_text_to_s(target_class)
+ assert_atom_content_inline_other_base64_to_s(target_class)
+ assert_atom_content_out_of_line_to_s(target_class)
+ end
+ end
+
+ def assert_atom_content_inline_other_xml_to_s(target_class)
+ _wrap_assertion do
+ content = target_class.new
+ content.type = "text/xml"
+ assert_equal("", content.to_s)
+
+ content = target_class.new
+ content.type = "text/xml"
+ content.xml = RSS::XML::Element.new("em")
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([["", "em"]], {"type" => "text/xml"}, nil, xml)
+ end
+ end
+
+ def assert_atom_content_inline_other_text_to_s(target_class)
+ _wrap_assertion do
+ content = target_class.new
+ content.type = "text/plain"
+ assert_equal("", content.to_s)
+
+ content = target_class.new
+ content.type = "text/plain"
+ content.xml = RSS::XML::Element.new("em")
+ assert_equal("", content.to_s)
+
+ content = target_class.new
+ content.type = "text/plain"
+ content.content = "content"
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => "text/plain"}, "content", xml)
+ end
+ end
+
+ def assert_atom_content_inline_other_base64_to_s(target_class)
+ _wrap_assertion do
+ require "zlib"
+
+ text = ""
+ char = "a"
+ 100.times do |i|
+ text << char
+ char.succ!
+ end
+
+ type = "application/zip"
+ original_content = Zlib::Deflate.deflate(text)
+
+ content = target_class.new
+ content.type = type
+ content.content = original_content
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => type},
+ Base64.encode64(original_content), xml)
+ end
+ end
+
+ def assert_atom_content_out_of_line_to_s(target_class)
+ _wrap_assertion do
+ type = "application/zip"
+ src = "http://example.com/xxx.zip"
+
+ content = target_class.new
+ assert(!content.out_of_line?)
+ content.src = src
+ assert(content.out_of_line?)
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"src" => src}, nil, xml)
+
+ content = target_class.new
+ assert(!content.out_of_line?)
+ content.type = type
+ assert(!content.out_of_line?)
+ content.src = src
+ assert(content.out_of_line?)
+ xml = REXML::Document.new(content.to_s).root
+ assert_rexml_element([], {"type" => type, "src" => src}, nil, xml)
+ end
+ end
+
+ def _assert_maker_atom_persons(feed_type, maker_readers, feed_readers)
+ _wrap_assertion do
+ persons = []
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ targets.each do |target|
+ person = {
+ :name => target.name,
+ :uri => target.uri,
+ :email => target.email,
+ }
+ persons << person if person[:name]
+ end
+ end
+
+ actual_persons = chain_reader(feed, feed_readers) || []
+ actual_persons = actual_persons.collect do |person|
+ {
+ :name => person.name ? person.name.content : nil,
+ :uri => person.uri ? person.uri.content : nil,
+ :email => person.email ? person.email.content : nil,
+ }
+ end
+ p [feed_readers, feed.source.authors] unless persons == actual_persons
+ assert_equal(persons, actual_persons)
+ end
+ end
+
+ def assert_maker_atom_persons(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil,
+ parent_not_set_error_name=nil,
+ parent_not_set_variable=nil)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ args = [feed_type, maker_readers, feed_readers]
+ if parent_not_set_error_name or parent_not_set_variable
+ assert_not_set_error(parent_not_set_error_name,
+ parent_not_set_variable) do
+ _assert_maker_atom_persons(*args) do |maker|
+ yield maker
+ end
+ end
+ else
+ _assert_maker_atom_persons(*args) do |maker|
+ yield maker
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.uri = "http://example.com/~me/"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.email = "me@example.com"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.uri = "http://example.com/~me/"
+ target.email = "me@example.com"
+ end
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ target.email = "me@example.com"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ target.email = "me@example.com"
+ end
+
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ target.email = "me@example.com"
+
+ target = targets.new_child
+ target.name = "you"
+ target.uri = "http://example.com/~you/"
+ target.email = "you@example.com"
+ end
+
+ assert_not_set_error(not_set_error_name, %w(name)) do
+ _assert_maker_atom_persons(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+
+ target = targets.new_child
+ target.name = "me"
+ target.uri = "http://example.com/~me/"
+ target.email = "me@example.com"
+
+ target = targets.new_child
+ end
+ end
+ end
+ end
+
+ def _assert_maker_atom_text_construct(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ text = {
+ :type => target.type,
+ :content => target.content,
+ :xml_content => target.xml_content,
+ }
+ if text[:type] == "xhtml"
+ if text[:xml_content]
+ xml_content = text[:xml_content]
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ unless xml_content.is_a?(RSS::XML::Element) and
+ ["div", xhtml_uri] == [xml_content.name, xml_content.uri]
+ children = xml_content
+ children = [children] unless children.is_a?(Array)
+ xml_content = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ children)
+ text[:xml_content] = xml_content
+ end
+ text
+ else
+ nil
+ end
+ else
+ text[:content] ? text : nil
+ end
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :type => target.type,
+ :content => target.content,
+ :xml_content => target.xhtml,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_text_construct(feed_type, maker_readers, feed_readers,
+ parent_not_set_error_name=nil,
+ parent_not_set_variable=nil,
+ not_set_error_name=nil)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ args = [feed_type, maker_readers, feed_readers]
+ if parent_not_set_error_name or parent_not_set_variable
+ assert_not_set_error(parent_not_set_error_name,
+ parent_not_set_variable) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ end
+ end
+ else
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "html"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.content = "Content"
+ end
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text"
+ target.content = "Content"
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "html"
+ target.content = "<em>Content</em>"
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml_content = "text only"
+ end
+
+ _assert_maker_atom_text_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml_content = RSS::XML::Element.new("unknown")
+ end
+ end
+ end
+
+ def _assert_maker_atom_date_construct(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ date = {
+ :content => target,
+ }
+ date[:content] ? date : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :content => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_date_construct(feed_type, maker_readers, feed_readers,
+ parent_not_set_error_name=nil,
+ parent_not_set_variable=nil)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ if parent_not_set_error_name or parent_not_set_variable
+ assert_not_set_error(parent_not_set_error_name,
+ parent_not_set_variable) do
+ _assert_maker_atom_date_construct(*args) do |maker|
+ yield maker
+ end
+ end
+ else
+ _assert_maker_atom_date_construct(*args) do |maker|
+ yield maker
+ end
+ end
+
+ maker_readers = maker_readers.dup
+ writer = "#{maker_readers.pop}="
+ _assert_maker_atom_date_construct(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.__send__(writer, Time.now)
+ end
+ end
+ end
+
+ def _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor)
+ _wrap_assertion do
+ element = nil
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ element = maker_extractor.call(target)
+ end
+
+ target = chain_reader(feed, feed_readers)
+ if target
+ actual_element = feed_extractor.call(target)
+ else
+ actual_element = nil
+ end
+ assert_equal(element, actual_element)
+ end
+ end
+
+ def _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ invalid_feed_checker=nil)
+ _wrap_assertion do
+ elements = []
+ invalid_feed = false
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ targets.each do |target|
+ element = maker_extractor.call(target)
+ elements << element if element
+ end
+ if invalid_feed_checker
+ invalid_feed = invalid_feed_checker.call(targets)
+ end
+ end
+
+ if invalid_feed
+ assert_nil(feed)
+ else
+ actual_elements = chain_reader(feed, feed_readers) || []
+ actual_elements = actual_elements.collect do |target|
+ feed_extractor.call(target)
+ end
+ assert_equal(elements, actual_elements)
+ end
+ end
+ end
+
+ def assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ required_variable, assert_method_name,
+ not_set_error_name=nil,
+ *additional_args)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ 0.upto(optional_variables.size) do |i|
+ combination(optional_variables, i).each do |names|
+ have = {}
+ names.each do |name|
+ have[name.intern] = true
+ end
+ have_required_variable_too =
+ have.merge({required_variable.intern => true})
+
+ assert_not_set_error(not_set_error_name, [required_variable]) do
+ __send__(assert_method_name, feed_type, maker_readers,
+ feed_readers, *additional_args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ setup_target.call(target, have)
+ end
+ end
+
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ setup_target.call(target, have_required_variable_too)
+ end
+ end
+ end
+ end
+ end
+
+ def assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ required_variable, assert_method_name,
+ not_set_error_name=nil,
+ *additional_args)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ 0.upto(optional_variables.size) do |i|
+ combination(optional_variables, i).each do |names|
+ have = {}
+ names.each do |name|
+ have[name.intern] = true
+ end
+ have_required_variable_too =
+ have.merge({required_variable.intern => true})
+
+ assert_not_set_error(not_set_error_name, [required_variable]) do
+ __send__(assert_method_name, feed_type, maker_readers,
+ feed_readers, *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have)
+ end
+ end
+
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have_required_variable_too)
+ end
+
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have_required_variable_too)
+ setup_target.call(targets, have_required_variable_too)
+ end
+
+ assert_not_set_error(not_set_error_name, [required_variable]) do
+ __send__(assert_method_name, feed_type, maker_readers, feed_readers,
+ *additional_args) do |maker|
+ yield maker
+ targets = chain_reader(maker, maker_readers)
+ setup_target.call(targets, have_required_variable_too)
+ setup_target.call(targets, have)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def _assert_maker_atom_categories(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ category = {
+ :term => target.term,
+ :scheme => target.scheme,
+ :label => target.label,
+ }
+ category[:term] ? category : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :term => target.term,
+ :scheme => target.scheme,
+ :label => target.label,
+ }
+ end
+ _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor, &block)
+ end
+
+ def assert_maker_atom_categories(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, &block)
+ _wrap_assertion do
+ _assert_maker_atom_categories(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ end
+
+ setup_target = Proc.new do |targets, have|
+ target = targets.new_child
+ target.term = "music" if have[:term]
+ target.scheme = "http://example.com/category/music" if have[:scheme]
+ target.label = "Music" if have[:label]
+ end
+
+ optional_variables = %w(scheme label)
+
+ assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ "term", :_assert_maker_atom_categories,
+ not_set_error_name, &block)
+ end
+ end
+
+ def _assert_maker_atom_generator(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ generator = {
+ :uri => target.uri,
+ :version => target.version,
+ :content => target.content,
+ }
+ generator[:content] ? generator : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :uri => target.uri,
+ :version => target.version,
+ :content => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_generator(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, &block)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ _assert_maker_atom_generator(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ end
+
+ setup_target = Proc.new do |target, have|
+ target.content = "RSS Maker" if have[:content]
+ target.uri = "http://example.com/rss/maker" if have[:uri]
+ target.version = "0.0.1" if have[:version]
+ end
+
+ optional_variables = %w(uri version)
+
+ assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ "content", :_assert_maker_atom_generator,
+ not_set_error_name, &block)
+ end
+ end
+
+ def _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base, &block)
+ maker_extractor = Proc.new do |target|
+ icon = {
+ :content => target.__send__(accessor_base),
+ }
+ icon[:content] ? icon : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :content => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base=nil, not_set_error_name=nil)
+ _wrap_assertion do
+ accessor_base ||= "url"
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ end
+
+ _assert_maker_atom_icon(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.__send__("#{accessor_base}=", "http://example.com/icon.png")
+ end
+ end
+ end
+
+ def _assert_maker_atom_links(feed_type, maker_readers, feed_readers,
+ allow_duplication=false, &block)
+ maker_extractor = Proc.new do |target|
+ link = {
+ :href => target.href,
+ :rel => target.rel,
+ :type => target.type,
+ :hreflang => target.hreflang,
+ :title => target.title,
+ :length => target.length,
+ }
+ link[:href] ? link : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :href => target.href,
+ :rel => target.rel,
+ :type => target.type,
+ :hreflang => target.hreflang,
+ :title => target.title,
+ :length => target.length,
+ }
+ end
+ invalid_feed_checker = Proc.new do |targets|
+ infos = {}
+ invalid = false
+ targets.each do |target|
+ key = [target.hreflang, target.type]
+ if infos.has_key?(key)
+ invalid = true
+ break
+ end
+ infos[key] = true if target.rel.nil? or target.rel == "alternate"
+ end
+ invalid
+ end
+ invalid_feed_checker = nil if allow_duplication
+ _assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ invalid_feed_checker,
+ &block)
+ end
+
+ def assert_maker_atom_links(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, allow_duplication=false,
+ &block)
+ _wrap_assertion do
+ _assert_maker_atom_links(feed_type, maker_readers,
+ feed_readers) do |maker|
+ yield maker
+ end
+
+ langs = %(ja en fr zh po)
+ setup_target = Proc.new do |targets, have|
+ target = targets.new_child
+ lang = langs[targets.size % langs.size]
+ target.href = "http://example.com/index.html.#{lang}" if have[:href]
+ target.rel = "alternate" if have[:rel]
+ target.type = "text/xhtml" if have[:type]
+ target.hreflang = lang if have[:hreflang]
+ target.title = "FrontPage(#{lang})" if have[:title]
+ target.length = 1024 if have[:length]
+ end
+
+ optional_variables = %w(rel type hreflang title length)
+
+ assert_maker_atom_elements(feed_type, maker_readers, feed_readers,
+ setup_target, optional_variables,
+ "href", :_assert_maker_atom_links,
+ not_set_error_name, allow_duplication,
+ &block)
+ end
+ end
+
+ def _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base, &block)
+ maker_extractor = Proc.new do |target|
+ logo = {
+ :uri => target.__send__(accessor_base),
+ }
+ logo[:uri] ? logo : nil
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :uri => target.content,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base=nil, not_set_error_name=nil)
+ _wrap_assertion do
+ accessor_base ||= "uri"
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ end
+
+ _assert_maker_atom_logo(feed_type, maker_readers, feed_readers,
+ accessor_base) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.__send__("#{accessor_base}=", "http://example.com/logo.png")
+ end
+ end
+ end
+
+ def _assert_maker_atom_id(feed_type, maker_readers, feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ id = {
+ :uri => target.id,
+ }
+ id[:uri] ? id : nil
+ end
+ feed_extractor = Proc.new do |target|
+ if target.id
+ {
+ :uri => target.id.content,
+ }
+ else
+ nil
+ end
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_id(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+
+ args = [feed_type, maker_readers, feed_readers]
+ _assert_maker_atom_id(*args) do |maker|
+ yield maker
+ end
+
+ _assert_maker_atom_id(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.id = "http://example.com/id/1"
+ end
+ end
+ end
+
+ def _assert_maker_atom_content(feed_type, maker_readers,
+ feed_readers, &block)
+ maker_extractor = Proc.new do |target|
+ content = {
+ :type => target.type,
+ :src => target.src,
+ :content => target.content,
+ :xml => target.xml,
+ :inline_text => target.__send!(:inline_text?),
+ :inline_html => target.__send!(:inline_html?),
+ :inline_xhtml => target.__send!(:inline_xhtml?),
+ :inline_other => target.__send!(:inline_other?),
+ :inline_other_text => target.__send!(:inline_other_text?),
+ :inline_other_xml => target.__send!(:inline_other_xml?),
+ :inline_other_base64 => target.__send!(:inline_other_base64?),
+ :out_of_line => target.__send!(:out_of_line?),
+ }
+ content[:src] = nil if content[:src] and content[:content]
+ if content[:type] or content[:content]
+ content
+ else
+ nil
+ end
+ end
+ feed_extractor = Proc.new do |target|
+ {
+ :type => target.type,
+ :src => target.src,
+ :content => target.content,
+ :xml => target.xml,
+ :inline_text => target.inline_text?,
+ :inline_html => target.inline_html?,
+ :inline_xhtml => target.inline_xhtml?,
+ :inline_other => target.inline_other?,
+ :inline_other_text => target.inline_other_text?,
+ :inline_other_xml => target.inline_other_xml?,
+ :inline_other_base64 => target.inline_other_base64?,
+ :out_of_line => target.out_of_line?,
+ }
+ end
+ _assert_maker_atom_element(feed_type, maker_readers, feed_readers,
+ maker_extractor, feed_extractor,
+ &block)
+ end
+
+ def assert_maker_atom_content(feed_type, maker_readers, feed_readers,
+ not_set_error_name=nil, &block)
+ _wrap_assertion do
+ not_set_error_name ||= "maker.#{maker_readers.join('.')}"
+ args = [feed_type, maker_readers, feed_readers, not_set_error_name]
+ assert_maker_atom_content_inline_text(*args, &block)
+ assert_maker_atom_content_inline_xhtml(*args, &block)
+ assert_maker_atom_content_inline_other(*args, &block)
+ assert_maker_atom_content_out_of_line(*args, &block)
+ end
+ end
+
+ def assert_maker_atom_content_inline_text(feed_type, maker_readers,
+ feed_readers, not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "html"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.content = ""
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text"
+ target.content = "example content"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "html"
+ target.content = "<em>text</em>"
+ end
+ end
+ end
+
+ def assert_maker_atom_content_inline_xhtml(feed_type, maker_readers,
+ feed_readers, not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.content = "dummy"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml_content = "text"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = "text"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml_content =
+ RSS::XML::Element.new("em", nil, nil, {}, ["text"])
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = RSS::XML::Element.new("em", nil, nil, {}, ["text"])
+ end
+
+
+ xhtml_uri = "http://www.w3.org/1999/xhtml"
+ em = RSS::XML::Element.new("em", nil, nil, {}, ["text"])
+ em_with_xhtml_uri =
+ RSS::XML::Element.new("em", nil, xhtml_uri, {}, ["text"])
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = em
+ end
+ assert_equal(RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri},
+ [em_with_xhtml_uri]),
+ chain_reader(feed, feed_readers).xml)
+
+ div = RSS::XML::Element.new("div", nil, xhtml_uri,
+ {"xmlns" => xhtml_uri,
+ "class" => "sample"},
+ ["text"])
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "xhtml"
+ target.xml = div
+ end
+ assert_equal(div, chain_reader(feed, feed_readers).xml)
+ end
+ end
+
+ def assert_maker_atom_content_inline_other(*args, &block)
+ _wrap_assertion do
+ assert_maker_atom_content_inline_other_xml(*args, &block)
+ assert_maker_atom_content_inline_other_text(*args, &block)
+ assert_maker_atom_content_inline_other_base64(*args, &block)
+ end
+ end
+
+ def assert_maker_atom_content_inline_other_xml(feed_type, maker_readers,
+ feed_readers,
+ not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "application/xml"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(xml_content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "svg/image+xml"
+ end
+ end
+
+ svg_uri = "http://www.w3.org/2000/svg"
+ rect = RSS::XML::Element.new("rect", nil, svg_uri,
+ {"x" => "0.5cm",
+ "y" => "0.5cm",
+ "width" => "2cm",
+ "height" => "1cm"})
+ svg = RSS::XML::Element.new("svg", nil, svg_uri,
+ {"xmlns" => svg_uri,
+ "version" => "1.1",
+ "width" => "5cm",
+ "height" => "4cm"},
+ [rect])
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/svg+xml"
+ target.xml = svg
+ end
+
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/svg+xml"
+ target.xml = svg
+ end
+ assert_equal(svg, chain_reader(feed, feed_readers).xml)
+ end
+ end
+
+ def assert_maker_atom_content_inline_other_text(feed_type, maker_readers,
+ feed_readers,
+ not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text/plain"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text/plain"
+ target.content = "text"
+ end
+ end
+ end
+
+ def assert_maker_atom_content_inline_other_base64(feed_type, maker_readers,
+ feed_readers,
+ not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ content = "\211PNG\r\n\032\n"
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.content = content
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.src = "http://example.com/logo.png"
+ target.content = content
+ end
+
+ feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.src = "http://example.com/logo.png"
+ target.content = content
+ end
+ target = chain_reader(feed, feed_readers)
+ assert_nil(target.src)
+ assert_equal(content, target.content)
+ end
+ end
+
+ def assert_maker_atom_content_out_of_line(feed_type, maker_readers,
+ feed_readers, not_set_error_name)
+ _wrap_assertion do
+ args = [feed_type, maker_readers, feed_readers]
+ assert_not_set_error(not_set_error_name, %w(content)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ end
+ end
+
+ assert_not_set_error(not_set_error_name, %w(type)) do
+ RSS::Maker.make("atom:#{feed_type}") do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.src = "http://example.com/logo.png"
+ end
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.src = "http://example.com/logo.png"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "image/png"
+ target.content = "\211PNG\r\n\032\n"
+ end
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "application/xml"
+ target.src = "http://example.com/sample.xml"
+ end
+
+
+ _assert_maker_atom_content(*args) do |maker|
+ yield maker
+ target = chain_reader(maker, maker_readers)
+ target.type = "text/plain"
+ target.src = "http://example.com/README.txt"
+ end
+ end
+ end
+
+ def chain_reader(target, readers)
+ readers.inject(target) do |result, reader|
+ return nil if result.nil?
+ result.__send__(reader)
+ end
+ end
+
def normalized_attrs(attrs)
n_attrs = {}
attrs.each do |name, value|
@@ -487,6 +2656,18 @@ module RSS
end
n_attrs
end
-
+
+ def combination(elements, n)
+ if n <= 0 or elements.size < n
+ []
+ elsif n == 1
+ elements.collect {|element| [element]}
+ else
+ first, *rest = elements
+ combination(rest, n - 1).collect do |sub_elements|
+ [first, *sub_elements]
+ end + combination(rest, n)
+ end
+ end
end
end
diff --git a/test/rss/rss-testcase.rb b/test/rss/rss-testcase.rb
index 0612abcccdb..baac597c00b 100644
--- a/test/rss/rss-testcase.rb
+++ b/test/rss/rss-testcase.rb
@@ -3,6 +3,8 @@ require "erb"
require "test/unit"
require 'rss-assertions'
+require "rss"
+
module RSS
class TestCase < Test::Unit::TestCase
include ERB::Util
@@ -22,7 +24,7 @@ module RSS
NAME_VALUE = "hogehoge"
LANGUAGE_VALUE = "ja"
DESCRIPTION_VALUE = "
- XML.com features a rich mix of information and services
+ XML.com features a rich mix of information and services
for the XML community.
"
RESOURCES = [
@@ -42,6 +44,45 @@ module RSS
CATEGORY_DOMAIN = "http://www.superopendirectory.com/"
+ FEED_TITLE = "dive into mark"
+ FEED_UPDATED = "2003-12-13T18:30:02Z"
+ FEED_AUTHOR_NAME = "John Doe"
+ FEED_ID = "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6"
+
+ ENTRY_TITLE = "Atom-Powered Robots Run Amok"
+ ENTRY_LINK = "http://example.org/2003/12/13/atom03"
+ ENTRY_ID = "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a"
+ ENTRY_UPDATED = "2003-12-13T18:30:02Z"
+ ENTRY_SUMMARY = "Some text."
+
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ DC_ELEMENTS = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael@oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly &amp; Associates, Inc.",
+ :date => t,
+ }
+
+ DC_NODES = DC_ELEMENTS.collect do |name, value|
+ "<#{DC_PREFIX}:#{name}>#{value}</#{DC_PREFIX}:#{name}>"
+ end.join("\n")
+
def default_test
# This class isn't tested
end
@@ -140,6 +181,15 @@ EOR
EORSS
end
+ def make_sample_items20
+ RESOURCES.collect do |res|
+ elems = ["<link>#{res}</link>"]
+ elems << "<title>title of #{res}</title>"
+ elems = elems.join("\n")
+ item = "<item>\n#{elems}\n</item>"
+ end.join("\n")
+ end
+
def make_channel20(content=nil)
<<-EOC
<channel>
@@ -154,7 +204,7 @@ EORSS
<link>#{LINK_VALUE}</link>
</image>
-#{RESOURCES.collect do |res| '<item><link>' + res + '</link></item>' end.join("\n")}
+#{make_sample_items20}
<textInput>
<title>#{TITLE_VALUE}</title>
@@ -190,6 +240,88 @@ EOI
EOC
end
+ def make_sample_rss20
+ make_rss20(<<-EOR)
+#{make_channel20}
+EOR
+ end
+
+ def make_feed_without_entry(content=nil, xmlns=[])
+ <<-EOA
+<feed xmlns="#{Atom::URI}"
+#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
+ <id>#{FEED_ID}</id>
+ <title>#{FEED_TITLE}</title>
+ <updated>#{FEED_UPDATED}</updated>
+ <author>
+ <name>#{FEED_AUTHOR_NAME}</name>
+ </author>
+#{block_given? ? yield : content}
+</feed>
+EOA
+ end
+
+ def make_entry(content=nil)
+ <<-EOA
+ <entry>
+ <title>#{ENTRY_TITLE}</title>
+ <id>#{ENTRY_ID}</id>
+ <updated>#{ENTRY_UPDATED}</updated>
+#{block_given? ? yield : content}
+ </entry>
+EOA
+ end
+
+ def make_feed_with_open_entry(content=nil, xmlns=[], &block)
+ make_feed_without_entry(<<-EOA, xmlns)
+#{make_entry(content, &block)}
+EOA
+ end
+
+ def make_feed_with_open_entry_source(content=nil, xmlns=[])
+ make_feed_with_open_entry(<<-EOA, xmlns)
+ <source>
+#{block_given? ? yield : content}
+ </source>
+EOA
+ end
+
+ def make_feed(content=nil, xmlns=[])
+ make_feed_without_entry(<<-EOA, xmlns)
+ <entry>
+ <title>#{ENTRY_TITLE}</title>
+ <link href="#{ENTRY_LINK}"/>
+ <id>#{ENTRY_ID}</id>
+ <updated>#{ENTRY_UPDATED}</updated>
+ <summary>#{ENTRY_SUMMARY}</summary>
+ </entry>
+#{block_given? ? yield : content}
+EOA
+ end
+
+ def make_entry_document(content=nil, xmlns=[])
+ <<-EOA
+<entry xmlns="#{Atom::URI}"
+#{xmlns.collect {|pre, uri| "xmlns:#{pre}='#{uri}'"}.join(' ')}>
+ <id>#{ENTRY_ID}</id>
+ <title>#{ENTRY_TITLE}</title>
+ <updated>#{ENTRY_UPDATED}</updated>
+ <author>
+ <name>#{FEED_AUTHOR_NAME}</name>
+ </author>
+#{block_given? ? yield : content}
+</entry>
+EOA
+ end
+
+ def make_entry_document_with_open_source(content=nil, xmlns=[])
+ make_entry_document(<<-EOA, xmlns)
+ <source>
+#{block_given? ? yield : content}
+ </source>
+EOA
+ end
+
def make_element(elem_name, attrs, contents)
attrs_str = attrs.collect do |name, value|
"#{h name}='#{h value}'"
@@ -202,10 +334,52 @@ EOC
end
private
+ def setup_rss10(rdf)
+ assert_equal("", rdf.to_s)
+
+ channel = RDF::Channel.new
+ assert_equal("", channel.to_s)
+ channel.about = "http://example.com/index.rdf"
+ channel.title = "title"
+ channel.link = "http://example.com/"
+ channel.description = "description"
+ assert_equal("", channel.to_s)
+
+ item_title = "item title"
+ item_link = "http://example.com/item"
+ channel.items = RDF::Channel::Items.new
+ channel.items.Seq.lis << RDF::Channel::Items::Seq::Li.new(item_link)
+ assert_not_equal("", channel.to_s)
+
+ rdf.channel = channel
+ assert_equal("", rdf.to_s)
+
+ item = RDF::Item.new
+ item.title = item_title
+ item.link = item_link
+ item.about = item_link
+ rdf.items << item
+ assert_not_equal("", rdf.to_s)
+ end
+
+ def setup_rss20(rss)
+ assert_equal("", rss.to_s)
+
+ channel = Rss::Channel.new
+ assert_equal("", channel.to_s)
+ channel.title = "title"
+ channel.link = "http://example.com/"
+ channel.description = "description"
+ assert_not_equal("", channel.to_s)
+
+ rss.channel = channel
+ assert_not_equal("", rss.to_s)
+ end
+
def setup_dummy_channel(maker)
about = "http://hoge.com"
title = "fugafuga"
- link = "http://hoge.com"
+ link = "http://hoge.com/feed.xml"
description = "fugafugafugafuga"
language = "ja"
@@ -216,6 +390,17 @@ EOC
maker.channel.language = language
end
+ def setup_dummy_channel_atom(maker)
+ updated = Time.now
+ author = "Foo"
+
+ setup_dummy_channel(maker)
+ maker.channel.links.first.rel = "self"
+ maker.channel.links.first.type = "application/atom+xml"
+ maker.channel.updated = updated
+ maker.channel.author = author
+ end
+
def setup_dummy_image(maker)
title = "fugafuga"
link = "http://hoge.com"
@@ -247,7 +432,15 @@ EOC
item.title = title
item.link = link
end
-
+
+ def setup_dummy_item_atom(maker)
+ setup_dummy_item(maker)
+
+ item = maker.items.first
+ item.id = "http://example.net/xxx"
+ item.updated = Time.now
+ end
+
def setup_taxo_topic(target, topics)
topics.each do |topic|
taxo_topic = target.taxo_topics.new_taxo_topic
diff --git a/test/rss/test_1.0.rb b/test/rss/test_1.0.rb
index b905ba6e94a..9cb76075904 100644
--- a/test/rss/test_1.0.rb
+++ b/test/rss/test_1.0.rb
@@ -19,8 +19,8 @@ module RSS
standalone = false
rdf = RDF.new(version, encoding, standalone)
-
- doc = REXML::Document.new(rdf.to_s(false))
+ setup_rss10(rdf)
+ doc = REXML::Document.new(rdf.to_s)
xmldecl = doc.xml_decl
@@ -59,16 +59,31 @@ module RSS
link = "http://hoge.com"
description = "fugafugafugafuga"
resource = "http://hoge.com/hoge.png"
+
+ item_title = "item title"
+ item_link = "http://hoge.com/item"
+
image = RDF::Channel::Image.new(resource)
items = RDF::Channel::Items.new
+ items.Seq.lis << items.class::Seq::Li.new(item_link)
textinput = RDF::Channel::Textinput.new(resource)
-
+
+ rss_item = RDF::Item.new
+ rss_item.title = item_title
+ rss_item.link = item_link
+ rss_item.about = item_link
+
channel = RDF::Channel.new(about)
%w(title link description image items textinput).each do |x|
channel.__send__("#{x}=", instance_eval(x))
end
- doc = REXML::Document.new(make_RDF(channel.to_s))
+ doc = REXML::Document.new(make_RDF(<<-EOR))
+#{channel}
+<items>
+#{rss_item}
+</items>
+EOR
c = doc.root.elements[1]
assert_equal(about, c.attributes["about"])
@@ -123,8 +138,12 @@ module RSS
assert_equal(resource, res.value)
end
- def test_items
+ def test_channel_items
+ item_link = "http://example.com/item"
+
items = RDF::Channel::Items.new
+ li = items.Seq.class::Li.new(item_link)
+ items.Seq.lis << li
doc = REXML::Document.new(make_RDF(items.to_s))
i = doc.root.elements[1]
@@ -133,18 +152,34 @@ module RSS
assert_equal(@uri, i.namespace)
assert_equal(1, i.elements.size)
- assert_equal("Seq", i.elements[1].name)
- assert_equal(@rdf_uri, i.elements[1].namespace)
+ seq = i.elements[1]
+ assert_equal("Seq", seq.name)
+ assert_equal(@rdf_uri, seq.namespace)
+
+ assert_equal(1, seq.elements.size)
+ l = seq.elements[1]
+ assert_equal("li", l.name)
+ assert_equal(@rdf_uri, l.namespace)
+ assert_equal(item_link, l.attributes["resource"])
end
def test_seq
+ item_link = "http://example.com/item"
seq = RDF::Seq.new
+ li = seq.class::Li.new(item_link)
+ seq.lis << li
doc = REXML::Document.new(make_RDF(seq.to_s))
s = doc.root.elements[1]
assert_equal("Seq", s.name)
assert_equal(@rdf_uri, s.namespace)
+
+ assert_equal(1, s.elements.size)
+ l = s.elements[1]
+ assert_equal("li", l.name)
+ assert_equal(@rdf_uri, l.namespace)
+ assert_equal(item_link, l.attributes["resource"])
end
def test_li
@@ -233,15 +268,29 @@ module RSS
end
end
- def test_indent_size
- assert_equal(0, RDF.indent_size)
- assert_equal(1, RDF::Channel.indent_size)
- assert_equal(2, RDF::Channel::Image.indent_size)
- assert_equal(2, RDF::Channel::Textinput.indent_size)
- assert_equal(2, RDF::Channel::Items.indent_size)
- assert_equal(1, RDF::Image.indent_size)
- assert_equal(1, RDF::Item.indent_size)
- assert_equal(1, RDF::Textinput.indent_size)
+ def test_to_xml
+ rss = RSS::Parser.parse(make_sample_RDF)
+ assert_equal(rss.to_s, rss.to_xml)
+ assert_equal(rss.to_s, rss.to_xml("1.0"))
+ rss09 = rss.to_xml("0.91") do |maker|
+ maker.channel.language = "en-us"
+ end
+ rss09 = RSS::Parser.parse(rss09)
+ assert_equal("0.91", rss09.rss_version)
+ assert_equal(["rss", "0.91", nil], rss09.feed_info)
+ rss20 = RSS::Parser.parse(rss.to_xml("2.0"))
+ assert_equal("2.0", rss20.rss_version)
+ assert_equal(["rss", "2.0", nil], rss20.feed_info)
+
+ atom_xml = rss.to_xml("atom") do |maker|
+ maker.channel.author = "Alice"
+ maker.channel.updated ||= Time.now
+ maker.items.each do |item|
+ item.updated ||= Time.now
+ end
+ end
+ atom = RSS::Parser.parse(atom_xml)
+ assert_equal(["atom", "1.0", "feed"], atom.feed_info)
end
end
end
diff --git a/test/rss/test_2.0.rb b/test/rss/test_2.0.rb
index 2027e5344ad..5a63efbcb95 100644
--- a/test/rss/test_2.0.rb
+++ b/test/rss/test_2.0.rb
@@ -2,8 +2,6 @@ require "rexml/document"
require "rss-testcase"
-require "rss/2.0"
-
module RSS
class TestRSS20Core < TestCase
@@ -17,6 +15,7 @@ module RSS
standalone = false
rss = Rss.new(@rss_version, version, encoding, standalone)
+ setup_rss20(rss)
doc = REXML::Document.new(rss.to_s(false))
@@ -48,7 +47,9 @@ module RSS
{:href => "a.css", :type => "text/css"},
],
].each do |attrs_ary|
- assert_xml_stylesheet_pis(attrs_ary, Rss.new(@rss_version))
+ rss = Rss.new(@rss_version)
+ setup_rss20(rss)
+ assert_xml_stylesheet_pis(attrs_ary, rss)
end
end
@@ -253,6 +254,10 @@ module RSS
pubDate = Time.parse("Sat, 07 Sep 2002 00:00:01 GMT")
channel = Rss::Channel.new
+ channel.title = "title"
+ channel.link = "http://example.com/"
+ channel.description = "description"
+
item = Rss::Channel::Item.new
channel.items << item
@@ -373,22 +378,33 @@ module RSS
end
assert_equal(source_params, actual)
end
-
- def test_indent_size
- assert_equal(0, Rss.indent_size)
- assert_equal(1, Rss::Channel.indent_size)
- assert_equal(2, Rss::Channel::SkipDays.indent_size)
- assert_equal(3, Rss::Channel::SkipDays::Day.indent_size)
- assert_equal(2, Rss::Channel::SkipHours.indent_size)
- assert_equal(3, Rss::Channel::SkipHours::Hour.indent_size)
- assert_equal(2, Rss::Channel::Image.indent_size)
- assert_equal(2, Rss::Channel::Cloud.indent_size)
- assert_equal(2, Rss::Channel::Item.indent_size)
- assert_equal(3, Rss::Channel::Item::Source.indent_size)
- assert_equal(3, Rss::Channel::Item::Enclosure.indent_size)
- assert_equal(3, Rss::Channel::Item::Category.indent_size)
- assert_equal(3, Rss::Channel::Item::Guid.indent_size)
- assert_equal(2, Rss::Channel::TextInput.indent_size)
+
+ def test_to_xml
+ rss = RSS::Parser.parse(make_sample_rss20)
+ assert_equal(rss.to_s, rss.to_xml)
+ assert_equal(rss.to_s, rss.to_xml("2.0"))
+ rss09_xml = rss.to_xml("0.91") do |maker|
+ setup_dummy_image(maker)
+ end
+ rss09 = RSS::Parser.parse(rss09_xml)
+ assert_equal("0.91", rss09.rss_version)
+ rss10 = rss.to_xml("1.0") do |maker|
+ maker.channel.about = "http://www.example.com/index.rdf"
+ end
+ rss10 = RSS::Parser.parse(rss10)
+ assert_equal("1.0", rss10.rss_version)
+
+ atom_xml = rss.to_xml("atom1.0") do |maker|
+ maker.channel.id = "http://www.example.com/atom.xml"
+ maker.channel.author = "Alice"
+ maker.channel.updated = Time.now
+ maker.items.each do |item|
+ item.author = "Bob"
+ item.updated = Time.now
+ end
+ end
+ atom = RSS::Parser.parse(atom_xml)
+ assert_equal(["atom", "1.0", "feed"], atom.feed_info)
end
end
end
diff --git a/test/rss/test_atom.rb b/test/rss/test_atom.rb
new file mode 100644
index 00000000000..aea05bebbef
--- /dev/null
+++ b/test/rss/test_atom.rb
@@ -0,0 +1,281 @@
+require "rexml/document"
+
+require "rss-testcase"
+
+require "rss/atom"
+
+module RSS
+ class TestAtomCore < TestCase
+ def setup
+ @uri = "http://www.w3.org/2005/Atom"
+ @xhtml_uri = "http://www.w3.org/1999/xhtml"
+ end
+
+ def test_feed
+ version = "1.0"
+ encoding = "UTF-8"
+ standalone = false
+
+ feed = Atom::Feed.new(version, encoding, standalone)
+ assert_equal("", feed.to_s)
+
+ author = feed.class::Author.new
+ name = feed.class::Author::Name.new
+ name.content = "an author"
+ author.name = name
+ assert_not_equal("", author.to_s)
+ feed.authors << author
+ assert_equal("", feed.to_s)
+
+ id = feed.class::Id.new
+ id.content = "http://example.com/atom.xml"
+ assert_not_equal("", id.to_s)
+ feed.id = id
+ assert_equal("", feed.to_s)
+
+ title = feed.class::Title.new
+ title.content = "a title"
+ assert_not_equal("", title.to_s)
+ feed.title = title
+ assert_equal("", feed.to_s)
+
+ updated = feed.class::Updated.new
+ updated.content = Time.now
+ assert_not_equal("", updated.to_s)
+ feed.updated = updated
+ assert_not_equal("", feed.to_s)
+
+
+ feed.authors.clear
+ assert_equal("", feed.to_s)
+ entry = Atom::Feed::Entry.new
+ setup_entry(entry)
+ assert_not_equal("", entry.to_s)
+
+ author = entry.authors.first
+ entry.authors.clear
+ assert_equal("", entry.to_s)
+ entry.parent = feed
+ assert_equal("", entry.to_s)
+ feed.authors << author
+ assert_not_equal("", entry.to_s)
+ feed.authors.clear
+ feed.entries << entry
+ assert_equal("", feed.to_s)
+ entry.authors << author
+ assert_not_equal("", entry.to_s)
+ assert_not_equal("", feed.to_s)
+
+ doc = REXML::Document.new(feed.to_s)
+ xmldecl = doc.xml_decl
+
+ %w(version encoding).each do |x|
+ assert_equal(instance_eval(x), xmldecl.__send__(x))
+ end
+ assert_equal(standalone, !xmldecl.standalone.nil?)
+
+ assert_equal(@uri, doc.root.namespace)
+ end
+
+ def test_entry
+ version = "1.0"
+ encoding = "UTF-8"
+ standalone = false
+
+ entry = Atom::Entry.new(version, encoding, standalone)
+ setup_entry(entry)
+
+ author = entry.authors.first
+ entry.authors.clear
+ assert_equal("", entry.to_s)
+ source = Atom::Entry::Source.new
+ source.authors << author
+ entry.source = source
+ assert_not_equal("", entry.to_s)
+
+ doc = REXML::Document.new(entry.to_s)
+ xmldecl = doc.xml_decl
+
+ %w(version encoding).each do |x|
+ assert_equal(instance_eval(x), xmldecl.__send__(x))
+ end
+ assert_equal(standalone, !xmldecl.standalone.nil?)
+
+ assert_equal(@uri, doc.root.namespace)
+ end
+
+ def test_not_displayed_xml_stylesheets
+ feed = Atom::Feed.new
+ plain_feed = feed.to_s
+ 3.times do
+ feed.xml_stylesheets.push(XMLStyleSheet.new)
+ assert_equal(plain_feed, feed.to_s)
+ end
+ end
+
+ def test_atom_author
+ assert_atom_person_to_s(Atom::Feed::Author)
+ assert_atom_person_to_s(Atom::Feed::Entry::Author)
+ assert_atom_person_to_s(Atom::Entry::Author)
+ assert_atom_person_to_s(Atom::Feed::Entry::Source::Author)
+ assert_atom_person_to_s(Atom::Entry::Source::Author)
+ end
+
+ def test_atom_category
+ assert_atom_category_to_s(Atom::Feed::Category)
+ assert_atom_category_to_s(Atom::Feed::Entry::Category)
+ assert_atom_category_to_s(Atom::Entry::Category)
+ assert_atom_category_to_s(Atom::Feed::Entry::Source::Category)
+ assert_atom_category_to_s(Atom::Entry::Source::Category)
+ end
+
+ def test_atom_contributor
+ assert_atom_person_to_s(Atom::Feed::Contributor)
+ assert_atom_person_to_s(Atom::Feed::Entry::Contributor)
+ assert_atom_person_to_s(Atom::Entry::Contributor)
+ assert_atom_person_to_s(Atom::Feed::Entry::Source::Contributor)
+ assert_atom_person_to_s(Atom::Entry::Source::Contributor)
+ end
+
+ def test_atom_generator
+ assert_atom_generator_to_s(Atom::Feed::Generator)
+ assert_atom_generator_to_s(Atom::Feed::Entry::Source::Generator)
+ assert_atom_generator_to_s(Atom::Entry::Source::Generator)
+ end
+
+ def test_atom_icon
+ assert_atom_icon_to_s(Atom::Feed::Icon)
+ assert_atom_icon_to_s(Atom::Feed::Entry::Source::Icon)
+ assert_atom_icon_to_s(Atom::Entry::Source::Icon)
+ end
+
+ def test_atom_id
+ assert_atom_id_to_s(Atom::Feed::Id)
+ assert_atom_id_to_s(Atom::Feed::Entry::Id)
+ assert_atom_id_to_s(Atom::Entry::Id)
+ assert_atom_id_to_s(Atom::Feed::Entry::Source::Id)
+ assert_atom_id_to_s(Atom::Entry::Source::Id)
+ end
+
+ def test_atom_link
+ assert_atom_link_to_s(Atom::Feed::Link)
+ assert_atom_link_to_s(Atom::Feed::Entry::Link)
+ assert_atom_link_to_s(Atom::Entry::Link)
+ assert_atom_link_to_s(Atom::Feed::Entry::Source::Link)
+ assert_atom_link_to_s(Atom::Entry::Source::Link)
+ end
+
+ def test_atom_logo
+ assert_atom_logo_to_s(Atom::Feed::Logo)
+ assert_atom_logo_to_s(Atom::Feed::Entry::Source::Logo)
+ assert_atom_logo_to_s(Atom::Entry::Source::Logo)
+ end
+
+ def test_atom_rights
+ assert_atom_text_construct_to_s(Atom::Feed::Rights)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Rights)
+ assert_atom_text_construct_to_s(Atom::Entry::Rights)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Rights)
+ assert_atom_text_construct_to_s(Atom::Entry::Source::Rights)
+ end
+
+ def test_atom_subtitle
+ assert_atom_text_construct_to_s(Atom::Feed::Subtitle)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Subtitle)
+ assert_atom_text_construct_to_s(Atom::Entry::Source::Subtitle)
+ end
+
+ def test_atom_title
+ assert_atom_text_construct_to_s(Atom::Feed::Title)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Title)
+ assert_atom_text_construct_to_s(Atom::Entry::Title)
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Source::Title)
+ assert_atom_text_construct_to_s(Atom::Entry::Source::Title)
+ end
+
+ def test_atom_updated
+ assert_atom_date_construct_to_s(Atom::Feed::Updated)
+ assert_atom_date_construct_to_s(Atom::Feed::Entry::Updated)
+ assert_atom_date_construct_to_s(Atom::Entry::Updated)
+ assert_atom_date_construct_to_s(Atom::Feed::Entry::Source::Updated)
+ assert_atom_date_construct_to_s(Atom::Entry::Source::Updated)
+ end
+
+ def test_atom_content
+ assert_atom_content_to_s(Atom::Feed::Entry::Content)
+ assert_atom_content_to_s(Atom::Entry::Content)
+ end
+
+ def test_atom_published
+ assert_atom_date_construct_to_s(Atom::Feed::Entry::Published)
+ assert_atom_date_construct_to_s(Atom::Entry::Published)
+ end
+
+ def test_atom_summary
+ assert_atom_text_construct_to_s(Atom::Feed::Entry::Summary)
+ assert_atom_text_construct_to_s(Atom::Entry::Summary)
+ end
+
+
+ def test_to_xml
+ atom = RSS::Parser.parse(make_feed)
+ assert_equal(atom.to_s, atom.to_xml)
+ assert_equal(atom.to_s, atom.to_xml("atom"))
+ assert_equal(atom.to_s, atom.to_xml("atom1.0"))
+ assert_equal(atom.to_s, atom.to_xml("atom1.0:feed"))
+ assert_equal(atom.to_s, atom.to_xml("atom:feed"))
+
+ rss09_xml = atom.to_xml("0.91") do |maker|
+ maker.channel.language = "en-us"
+ maker.channel.link = "http://example.com/"
+ maker.channel.description.content = atom.title.content
+
+ maker.image.url = "http://example.com/logo.png"
+ maker.image.title = "Logo"
+ end
+ rss09 = RSS::Parser.parse(rss09_xml)
+ assert_equal(["rss", "0.91", nil], rss09.feed_info)
+
+ rss20_xml = atom.to_xml("2.0") do |maker|
+ maker.channel.link = "http://example.com/"
+ maker.channel.description.content = atom.title.content
+ end
+ rss20 = RSS::Parser.parse(rss20_xml)
+ assert_equal("2.0", rss20.rss_version)
+ assert_equal(["rss", "2.0", nil], rss20.feed_info)
+ end
+
+ private
+ def setup_entry(entry)
+ _wrap_assertion do
+ assert_equal("", entry.to_s)
+
+ author = entry.class::Author.new
+ name = entry.class::Author::Name.new
+ name.content = "an author"
+ author.name = name
+ assert_not_equal("", author.to_s)
+ entry.authors << author
+ assert_equal("", entry.to_s)
+
+ id = entry.class::Id.new
+ id.content = "http://example.com/atom.xml"
+ assert_not_equal("", id.to_s)
+ entry.id = id
+ assert_equal("", entry.to_s)
+
+ title = entry.class::Title.new
+ title.content = "a title"
+ assert_not_equal("", title.to_s)
+ entry.title = title
+ assert_equal("", entry.to_s)
+
+ updated = entry.class::Updated.new
+ updated.content = Time.now
+ assert_not_equal("", updated.to_s)
+ entry.updated = updated
+ assert_not_equal("", entry.to_s)
+ end
+ end
+ end
+end
diff --git a/test/rss/test_content.rb b/test/rss/test_content.rb
index 0622625e26c..aef930caa16 100644
--- a/test/rss/test_content.rb
+++ b/test/rss/test_content.rb
@@ -74,7 +74,7 @@ EOR
excepted = "<#{@prefix}:#{name}>#{CGI.escapeHTML(value)}</#{@prefix}:#{name}>"
@parents.each do |parent|
meth = "#{RSS::CONTENT_PREFIX}_#{name}_element"
- assert_equal(excepted, @rss.__send__(parent).funcall(meth))
+ assert_equal(excepted, @rss.__send__(parent).__send!(meth))
end
end
diff --git a/test/rss/test_dublincore.rb b/test/rss/test_dublincore.rb
index 36c7f14ec94..0e049e7910c 100644
--- a/test/rss/test_dublincore.rb
+++ b/test/rss/test_dublincore.rb
@@ -8,86 +8,168 @@ require "rss/dublincore"
module RSS
class TestDublinCore < TestCase
-
def setup
- @prefix = "dc"
- @uri = "http://purl.org/dc/elements/1.1/"
-
- @parents = %w(channel image item textinput)
-
- t = Time.iso8601("2000-01-01T12:00:05+00:00")
- class << t
- alias_method(:to_s, :iso8601)
- end
-
- @elems = {
- :title => "hoge",
- :description =>
- " XML is placing increasingly heavy loads on
- the existing technical infrastructure of the Internet.",
- :creator => "Rael Dornfest (mailto:rael@oreilly.com)",
- :subject => "XML",
- :publisher => "The O'Reilly Network",
- :contributor => "hogehoge",
- :type => "fugafuga",
- :format => "hohoho",
- :identifier => "fufufu",
- :source => "barbar",
- :language => "ja",
- :relation => "cococo",
- :rights => "Copyright (c) 2000 O'Reilly &amp; Associates, Inc.",
- :date => t,
- }
-
- @dc_nodes = @elems.collect do |name, value|
- "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
- end.join("\n")
-
- @rss_source = make_RDF(<<-EOR, {@prefix => @uri})
-#{make_channel(@dc_nodes)}
-#{make_image(@dc_nodes)}
-#{make_item(@dc_nodes)}
-#{make_textinput(@dc_nodes)}
+ @rss10_parents = [%w(channel), %w(image), %w(item), %w(textinput)]
+
+ @rss10_source = make_RDF(<<-EOR, {DC_PREFIX => DC_URI})
+#{make_channel(DC_NODES)}
+#{make_image(DC_NODES)}
+#{make_item(DC_NODES)}
+#{make_textinput(DC_NODES)}
+EOR
+
+ @rss20_parents = [%w(channel), %w(items last)]
+
+ @rss20_source = make_rss20(<<-EOR, {DC_PREFIX => DC_URI})
+#{make_channel20(DC_NODES + make_item20(DC_NODES))}
+EOR
+
+ @atom_feed_parents = [[], %w(entries last)]
+
+ @atom_feed_source = make_feed(<<-EOR, {DC_PREFIX => DC_URI})
+#{DC_NODES}
+#{make_entry(DC_NODES)}
EOR
- @rss = Parser.parse(@rss_source)
+ @atom_entry_parents = [[]]
+
+ @atom_entry_source = make_entry_document(<<-EOR, {DC_PREFIX => DC_URI})
+#{DC_NODES}
+EOR
end
-
+
def test_parser
- assert_nothing_raised do
- Parser.parse(@rss_source)
+ rss10_maker = Proc.new do |content, xmlns|
+ make_RDF(<<-EOR, xmlns)
+#{make_channel(content)}
+#{make_image(content)}
+#{make_item(content)}
+#{make_textinput(content)}
+EOR
+ end
+ assert_dc_parse(@rss10_source, @rss10_parents, false, &rss10_maker)
+ assert_dc_parse(@rss10_source, @rss10_parents, true, &rss10_maker)
+
+ rss20_maker = Proc.new do |content, xmlns|
+ make_rss20(<<-EOR, xmlns)
+#{make_channel20(content + make_item20(content))}
+EOR
+ end
+ assert_dc_parse(@rss20_source, @rss20_parents, false, &rss20_maker)
+ assert_dc_parse(@rss20_source, @rss20_parents, true, &rss20_maker)
+
+ atom_feed_maker = Proc.new do |content, xmlns|
+ make_feed(<<-EOR, xmlns)
+#{content}
+#{make_entry(content)}
+EOR
end
-
- @elems.each do |tag, value|
- rss = nil
- assert_nothing_raised do
- rss = Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
-#{make_channel(("<" + @prefix + ":" + tag.to_s + ">" +
- value.to_s +
- "</" + @prefix + ":" + tag.to_s + ">") * 2)}
-#{make_item}
+ assert_dc_parse(@atom_feed_source, @atom_feed_parents, false,
+ &atom_feed_maker)
+ assert_dc_parse(@atom_feed_source, @atom_feed_parents, true,
+ &atom_feed_maker)
+
+ atom_entry_maker = Proc.new do |content, xmlns|
+ make_entry_document(<<-EOR, xmlns)
+#{content}
EOR
+ end
+ assert_dc_parse(@atom_entry_source, @atom_entry_parents, false,
+ &atom_entry_maker)
+ assert_dc_parse(@atom_entry_source, @atom_entry_parents, true,
+ &atom_entry_maker)
+ end
+
+ def test_singular_accessor
+ assert_dc_singular_accessor(@rss10_source, @rss10_parents)
+ assert_dc_singular_accessor(@rss20_source, @rss20_parents)
+ assert_dc_singular_accessor(@atom_feed_source, @atom_feed_parents)
+ assert_dc_singular_accessor(@atom_entry_source, @atom_entry_parents)
+ end
+
+ def test_plural_accessor
+ assert_dc_plural_accessor(@rss10_source, @rss10_parents, false)
+ assert_dc_plural_accessor(@rss10_source, @rss10_parents, true)
+
+ assert_dc_plural_accessor(@rss20_source, @rss20_parents, false)
+ assert_dc_plural_accessor(@rss20_source, @rss20_parents, true)
+
+ assert_dc_plural_accessor(@atom_feed_source, @atom_feed_parents, false)
+ assert_dc_plural_accessor(@atom_feed_source, @atom_feed_parents, true)
+
+ assert_dc_plural_accessor(@atom_entry_source, @atom_entry_parents, false)
+ assert_dc_plural_accessor(@atom_entry_source, @atom_entry_parents, true)
+ end
+
+ def test_to_s
+ assert_dc_to_s(@rss10_source, @rss10_parents, false)
+ assert_dc_to_s(@rss10_source, @rss10_parents, true)
+
+ targets = ["channel", "channel/item[3]"]
+ assert_dc_to_s(@rss20_source, @rss20_parents, false, targets)
+ assert_dc_to_s(@rss20_source, @rss20_parents, true, targets)
+
+ targets = [".", "entry"]
+ assert_dc_to_s(@atom_feed_source, @atom_feed_parents, false, targets)
+ assert_dc_to_s(@atom_feed_source, @atom_feed_parents, true, targets)
+
+ targets = ["."]
+ assert_dc_to_s(@atom_entry_source, @atom_entry_parents, false, targets)
+ assert_dc_to_s(@atom_entry_source, @atom_entry_parents, true, targets)
+ end
+
+ private
+ def dc_plural_suffix(name, check_backward_compatibility)
+ if name == :rights
+ if check_backward_compatibility
+ "es"
+ else
+ "_list"
end
- plural_reader = "dc_#{tag}" + (tag == :rights ? "es" : "s")
- values = rss.channel.__send__(plural_reader).collect do |x|
- val = x.value
- if val.kind_of?(String)
- CGI.escapeHTML(val)
- else
- val
+ else
+ "s"
+ end
+ end
+
+ def assert_dc_parse(source, parents, check_backward_compatibility, &maker)
+ assert_nothing_raised do
+ Parser.parse(source)
+ end
+
+ DC_ELEMENTS.each do |name, value|
+ parents.each do |parent_readers|
+ feed = nil
+ assert_nothing_raised do
+ tag = "#{DC_PREFIX}:#{name}"
+ dc_content = "<#{tag}>#{value}</#{tag}>\n"
+ dc_content *= 2
+ feed = Parser.parse(maker.call(dc_content, {DC_PREFIX => DC_URI}))
end
+ parent = chain_reader(feed, parent_readers)
+
+ plural_suffix = dc_plural_suffix(name, check_backward_compatibility)
+ plural_reader = "dc_#{name}#{plural_suffix}"
+ values = parent.__send__(plural_reader).collect do |x|
+ val = x.value
+ if val.kind_of?(String)
+ CGI.escapeHTML(val)
+ else
+ val
+ end
+ end
+ assert_equal([value, value], values)
end
- assert_equal([value, value], values)
end
-
end
- def test_singular_accessor
+ def assert_dc_singular_accessor(source, parents)
+ feed = Parser.parse(source)
new_value = "hoge"
- @elems.each do |name, value|
- @parents.each do |parent|
- parsed_value = @rss.__send__(parent).__send__("dc_#{name}")
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ DC_ELEMENTS.each do |name, value|
+ parsed_value = parent.__send__("dc_#{name}")
if parsed_value.kind_of?(String)
parsed_value = CGI.escapeHTML(parsed_value)
end
@@ -97,34 +179,40 @@ EOR
class << t
alias_method(:to_s, :iso8601)
end
- @rss.__send__(parent).__send__("dc_#{name}=", t.iso8601)
- assert_equal(t, @rss.__send__(parent).__send__("dc_#{name}"))
- assert_equal(t, @rss.__send__(parent).date)
-
- @rss.__send__(parent).date = value
- assert_equal(value, @rss.__send__(parent).date)
- assert_equal(value, @rss.__send__(parent).__send__("dc_#{name}"))
+ parent.__send__("dc_#{name}=", t.iso8601)
+ assert_equal(t, parent.__send__("dc_#{name}"))
+ if parent.class.method_defined?(:date_without_dc_date=)
+ assert_nil(parent.date)
+ else
+ assert_equal(t, parent.date)
+ end
+
+ parent.date = value
+ assert_equal(value, parent.date)
+ assert_equal(value, parent.__send__("dc_#{name}"))
else
- @rss.__send__(parent).__send__("dc_#{name}=", new_value)
- assert_equal(new_value,
- @rss.__send__(parent).__send__("dc_#{name}"))
+ parent.__send__("dc_#{name}=", new_value)
+ assert_equal(new_value, parent.__send__("dc_#{name}"))
end
end
end
end
- def test_plural_accessor
+ def assert_dc_plural_accessor(source, parents, check_backward_compatibility)
+ feed = Parser.parse(source)
new_value = "hoge"
-
- @elems.each do |name, value|
- @parents.each do |parent|
- parsed_value = @rss.__send__(parent).__send__("dc_#{name}")
+
+ DC_ELEMENTS.each do |name, value|
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ parsed_value = parent.__send__("dc_#{name}")
if parsed_value.kind_of?(String)
parsed_value = CGI.escapeHTML(parsed_value)
end
assert_equal(value, parsed_value)
- plural_reader = "dc_#{name}" + (name == :rights ? "es" : "s")
+ plural_suffix = dc_plural_suffix(name, check_backward_compatibility)
+ plural_reader = "dc_#{name}#{plural_suffix}"
klass_name = "DublinCore#{Utils.to_class_name(name.to_s)}"
klass = DublinCoreModel.const_get(klass_name)
if name == :date
@@ -132,58 +220,60 @@ EOR
class << t
alias_method(:to_s, :iso8601)
end
- elems = @rss.__send__(parent).__send__(plural_reader)
+ elems = parent.__send__(plural_reader)
elems << klass.new(t.iso8601)
- new_elems = @rss.__send__(parent).__send__(plural_reader)
+ new_elems = parent.__send__(plural_reader)
values = new_elems.collect{|x| x.value}
- assert_equal([@rss.__send__(parent).__send__("dc_#{name}"), t],
- values)
+ assert_equal([parent.__send__("dc_#{name}"), t], values)
else
- elems = @rss.__send__(parent).__send__(plural_reader)
+ elems = parent.__send__(plural_reader)
elems << klass.new(new_value)
- new_elems = @rss.__send__(parent).__send__(plural_reader)
+ new_elems = parent.__send__(plural_reader)
values = new_elems.collect{|x| x.value}
- assert_equal([
- @rss.__send__(parent).__send__("dc_#{name}"),
- new_value
- ],
+ assert_equal([parent.__send__("dc_#{name}"), new_value],
values)
end
end
end
end
- def test_to_s
- @elems.each do |name, value|
- excepted = "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
- @parents.each do |parent|
- assert_equal(excepted,
- @rss.__send__(parent).funcall("dc_#{name}_elements"))
+ def assert_dc_to_s(source, parents, check_backward_compatibility,
+ targets=nil)
+ feed = Parser.parse(source)
+
+ DC_ELEMENTS.each do |name, value|
+ excepted = "<#{DC_PREFIX}:#{name}>#{value}</#{DC_PREFIX}:#{name}>"
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ assert_equal(excepted, parent.__send!("dc_#{name}_elements"))
end
-
+
+ plural_suffix = dc_plural_suffix(name, check_backward_compatibility)
+ reader = "dc_#{name}#{plural_suffix}"
excepted = Array.new(2, excepted).join("\n")
- @parents.each do |parent|
- reader = "dc_#{name}" + (name == :rights ? "es" : "s")
- elems = @rss.__send__(parent).__send__(reader)
+ parents.each do |parent_readers|
+ parent = chain_reader(feed, parent_readers)
+ elems = parent.__send__(reader)
klass_name = "DublinCore#{Utils.to_class_name(name.to_s)}"
klass = DublinCoreModel.const_get(klass_name)
- elems << klass.new(@rss.__send__(parent).__send__("dc_#{name}"))
- assert_equal(excepted,
- @rss.__send__(parent).funcall("dc_#{name}_elements"))
+ elems << klass.new(parent.__send__("dc_#{name}"))
+ assert_equal(excepted, parent.__send!("dc_#{name}_elements"))
end
end
-
- REXML::Document.new(@rss_source).root.each_element do |parent|
- if @parents.include?(parent.name)
- parent.each_element do |elem|
- if elem.namespace == @uri
- assert_equal(CGI.escapeHTML(elem.text),
- @elems[elem.name.intern].to_s)
- end
+
+ targets ||= parents.collect do |parent_readers|
+ parent_readers.first
+ end
+ feed_root = REXML::Document.new(source).root
+ targets.each do |target_xpath|
+ parent = feed_root.elements[target_xpath]
+ parent.each_element do |elem|
+ if elem.namespace == DC_URI
+ assert_equal(CGI.escapeHTML(elem.text),
+ DC_ELEMENTS[elem.name.intern].to_s)
end
end
end
end
-
end
end
diff --git a/test/rss/test_image.rb b/test/rss/test_image.rb
index 0fb9fce276f..8bb73232067 100644
--- a/test/rss/test_image.rb
+++ b/test/rss/test_image.rb
@@ -52,11 +52,11 @@ module RSS
items << make_item(image_item)
end
- ns = {
+ @ns = {
@prefix => @uri,
DC_PREFIX => DC_URI,
}
- @rss_source = make_RDF(<<-EOR, ns)
+ @rss_source = make_RDF(<<-EOR, @ns)
#{make_channel(@channel_nodes)}
#{make_image}
#{items}
@@ -70,13 +70,23 @@ EOR
assert_nothing_raised do
Parser.parse(@rss_source)
end
-
+
assert_too_much_tag("favicon", "channel") do
- Parser.parse(make_RDF(<<-EOR, {@prefix => @uri}))
+ Parser.parse(make_RDF(<<-EOR, @ns))
#{make_channel(@channel_nodes * 2)}
#{make_item}
EOR
end
+
+ attrs = {"rdf:about" => "http://www.example.org/item.png"}
+ contents = [["#{@prefix}:width", "80"]] * 5
+ image_item = make_element("#{@prefix}:item", attrs, contents)
+ assert_too_much_tag("width", "item") do
+ Parser.parse(make_RDF(<<-EOR, @ns))
+#{make_channel}
+#{make_item(image_item)}
+EOR
+ end
end
def test_favicon_accessor
diff --git a/test/rss/test_maker_0.9.rb b/test/rss/test_maker_0.9.rb
index d8556887e18..0551dc28006 100644
--- a/test/rss/test_maker_0.9.rb
+++ b/test/rss/test_maker_0.9.rb
@@ -11,18 +11,21 @@ module RSS
rss = RSS::Maker.make("0.9") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
end
assert_equal("0.91", rss.rss_version)
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
end
assert_equal("0.91", rss.rss_version)
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
-
+ setup_dummy_image(maker)
+
maker.encoding = "EUC-JP"
end
assert_equal("0.91", rss.rss_version)
@@ -30,7 +33,8 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
-
+ setup_dummy_image(maker)
+
maker.standalone = "yes"
end
assert_equal("0.91", rss.rss_version)
@@ -38,7 +42,8 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
-
+ setup_dummy_image(maker)
+
maker.encoding = "EUC-JP"
maker.standalone = "yes"
end
@@ -67,7 +72,10 @@ module RSS
]
pubDate = Time.now
lastBuildDate = Time.now
-
+
+ image_url = "http://example.com/logo.png"
+ image_title = "Logo"
+
rss = RSS::Maker.make("0.91") do |maker|
maker.channel.title = title
maker.channel.link = link
@@ -82,13 +90,18 @@ module RSS
maker.channel.lastBuildDate = lastBuildDate
skipDays.each do |day|
- new_day = maker.channel.skipDays.new_day
- new_day.content = day
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
end
skipHours.each do |hour|
- new_hour = maker.channel.skipHours.new_hour
- new_hour.content = hour
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
end
+
+ maker.image.url = image_url
+ maker.image.title = image_title
end
channel = rss.channel
@@ -113,7 +126,11 @@ module RSS
end
assert(channel.items.empty?)
- assert_nil(channel.image)
+
+ assert_equal(image_url, channel.image.url)
+ assert_equal(image_title, channel.image.title)
+ assert_equal(link, channel.image.link)
+
assert_nil(channel.textInput)
end
@@ -209,17 +226,18 @@ module RSS
height = "400"
description = "an image"
- rss = RSS::Maker.make("0.91") do |maker|
- setup_dummy_channel(maker)
- maker.channel.link = link
-
- # maker.image.title = title
- maker.image.url = url
- maker.image.width = width
- maker.image.height = height
- maker.image.description = description
+ assert_not_set_error("maker.image", %w(title)) do
+ RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ # maker.image.title = title
+ maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
end
- assert_nil(rss.channel.image)
assert_not_set_error("maker.channel", %w(link)) do
RSS::Maker.make("0.91") do |maker|
@@ -235,17 +253,18 @@ module RSS
end
end
- rss = RSS::Maker.make("0.91") do |maker|
- setup_dummy_channel(maker)
- maker.channel.link = link
-
- maker.image.title = title
- # maker.image.url = url
- maker.image.width = width
- maker.image.height = height
- maker.image.description = description
+ assert_not_set_error("maker.image", %w(url)) do
+ RSS::Maker.make("0.91") do |maker|
+ setup_dummy_channel(maker)
+ maker.channel.link = link
+
+ maker.image.title = title
+ # maker.image.url = url
+ maker.image.width = width
+ maker.image.height = height
+ maker.image.description = description
+ end
end
- assert_nil(rss.channel.image)
end
def test_items
@@ -255,16 +274,20 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
end
assert(rss.channel.items.empty?)
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
- item = maker.items.new_item
- item.title = title
- item.link = link
- # item.description = description
+ maker.items.new_item do |item|
+ item.title = title
+ item.link = link
+ # item.description = description
+ end
+
+ setup_dummy_image(maker)
end
assert_equal(1, rss.channel.items.size)
item = rss.channel.items.first
@@ -278,12 +301,15 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
maker.items.do_sort = true
+
+ setup_dummy_image(maker)
end
assert_equal(item_size, rss.items.size)
rss.channel.items.each_with_index do |item, i|
@@ -296,14 +322,17 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
maker.items.do_sort = Proc.new do |x, y|
- y.title[-1] <=> x.title[-1]
+ y.title.content[-1] <=> x.title.content[-1]
end
+
+ setup_dummy_image(maker)
end
assert_equal(item_size, rss.items.size)
rss.channel.items.reverse.each_with_index do |item, i|
@@ -321,6 +350,7 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
maker.textinput.title = title
maker.textinput.description = description
@@ -333,15 +363,17 @@ module RSS
assert_equal(name, textInput.name)
assert_equal(link, textInput.link)
- rss = RSS::Maker.make("0.91") do |maker|
- # setup_dummy_channel(maker)
+ assert_not_set_error("maker.channel",
+ %w(link language description title)) do
+ RSS::Maker.make("0.91") do |maker|
+ # setup_dummy_channel(maker)
- maker.textinput.title = title
- maker.textinput.description = description
- maker.textinput.name = name
- maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
end
- assert_nil(rss)
end
def test_not_valid_textInput
@@ -352,6 +384,7 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
# maker.textinput.title = title
maker.textinput.description = description
@@ -362,7 +395,8 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
-
+ setup_dummy_image(maker)
+
maker.textinput.title = title
# maker.textinput.description = description
maker.textinput.name = name
@@ -372,7 +406,8 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
-
+ setup_dummy_image(maker)
+
maker.textinput.title = title
maker.textinput.description = description
# maker.textinput.name = name
@@ -382,7 +417,8 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
-
+ setup_dummy_image(maker)
+
maker.textinput.title = title
maker.textinput.description = description
maker.textinput.name = name
diff --git a/test/rss/test_maker_1.0.rb b/test/rss/test_maker_1.0.rb
index 9d90f3bedd7..cc1e58c1a20 100644
--- a/test/rss/test_maker_1.0.rb
+++ b/test/rss/test_maker_1.0.rb
@@ -8,12 +8,15 @@ module RSS
def test_rdf
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_item(maker)
end
assert_equal("1.0", rss.rss_version)
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
maker.encoding = "EUC-JP"
+
+ setup_dummy_item(maker)
end
assert_equal("1.0", rss.rss_version)
assert_equal("EUC-JP", rss.encoding)
@@ -21,6 +24,8 @@ module RSS
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
maker.standalone = "yes"
+
+ setup_dummy_item(maker)
end
assert_equal("1.0", rss.rss_version)
assert_equal("yes", rss.standalone)
@@ -29,6 +34,8 @@ module RSS
setup_dummy_channel(maker)
maker.encoding = "EUC-JP"
maker.standalone = "yes"
+
+ setup_dummy_item(maker)
end
assert_equal("1.0", rss.rss_version)
assert_equal("EUC-JP", rss.encoding)
@@ -49,13 +56,15 @@ module RSS
maker.channel.title = title
maker.channel.link = link
maker.channel.description = description
+
+ setup_dummy_item(maker)
end
channel = rss.channel
assert_equal(about, channel.about)
assert_equal(title, channel.title)
assert_equal(link, channel.link)
assert_equal(description, channel.description)
- assert(channel.items.Seq.lis.empty?)
+ assert_equal(1, channel.items.Seq.lis.size)
assert_nil(channel.image)
assert_nil(channel.textinput)
@@ -68,13 +77,15 @@ module RSS
setup_dummy_image(maker)
setup_dummy_textinput(maker)
+
+ setup_dummy_item(maker)
end
channel = rss.channel
assert_equal(about, channel.about)
assert_equal(title, channel.title)
assert_equal(link, channel.link)
assert_equal(description, channel.description)
- assert(channel.items.Seq.lis.empty?)
+ assert_equal(1, channel.items.Seq.lis.size)
assert_equal(rss.image.about, channel.image.resource)
assert_equal(rss.textinput.about, channel.textinput.resource)
end
@@ -134,6 +145,8 @@ module RSS
maker.image.title = title
maker.image.url = url
+
+ setup_dummy_item(maker)
end
image = rss.image
assert_equal(url, image.about)
@@ -164,6 +177,8 @@ module RSS
# maker.image.url = url
maker.image.title = title
+
+ setup_dummy_item(maker)
end
assert_nil(rss.channel.image)
assert_nil(rss.image)
@@ -174,6 +189,8 @@ module RSS
maker.image.url = url
# maker.image.title = title
+
+ setup_dummy_item(maker)
end
assert_nil(rss.channel.image)
assert_nil(rss.image)
@@ -186,27 +203,31 @@ module RSS
maker.image.url = url
maker.image.title = title
+
+ setup_dummy_item(maker)
end
end
end
-
+
def test_items
title = "TITLE"
link = "http://hoge.com/"
description = "text hoge fuga"
- rss = RSS::Maker.make("1.0") do |maker|
- setup_dummy_channel(maker)
+ assert_not_set_error("maker", %w(items)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+ end
end
- assert(rss.items.empty?)
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
- item = maker.items.new_item
- item.title = title
- item.link = link
- # item.description = description
+ maker.items.new_item do |item|
+ item.title = title
+ item.link = link
+ # item.description = description
+ end
end
assert_equal(1, rss.items.size)
item = rss.items.first
@@ -221,10 +242,11 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
maker.items.do_sort = true
end
@@ -240,13 +262,14 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
maker.items.do_sort = Proc.new do |x, y|
- y.title[-1] <=> x.title[-1]
+ y.title.content[-1] <=> x.title.content[-1]
end
end
assert_equal(item_size, rss.items.size)
@@ -262,10 +285,11 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
maker.items.max_size = max_size
end
@@ -278,28 +302,31 @@ module RSS
end
max_size = 0
- rss = RSS::Maker.make("1.0") do |maker|
- setup_dummy_channel(maker)
-
- item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ assert_not_set_error("maker", %w(items)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
+ end
+ maker.items.max_size = max_size
end
- maker.items.max_size = max_size
end
- assert_equal(max_size, rss.items.size)
max_size = -2
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
maker.items.max_size = max_size
end
@@ -316,25 +343,40 @@ module RSS
title = "TITLE"
link = "http://hoge.com/"
- rss = RSS::Maker.make("1.0") do |maker|
- setup_dummy_channel(maker)
-
- item = maker.items.new_item
- # item.title = title
- item.link = link
+ assert_not_set_error("maker.item", %w(title)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ # item.title = title
+ item.link = link
+ end
+ end
end
- assert(rss.items.empty?)
- rss = RSS::Maker.make("1.0") do |maker|
- setup_dummy_channel(maker)
-
- item = maker.items.new_item
- item.title = title
- # item.link = link
+ assert_not_set_error("maker.item", %w(link)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ item.title = title
+ # item.link = link
+ end
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(title link)) do
+ RSS::Maker.make("1.0") do |maker|
+ setup_dummy_channel(maker)
+
+ maker.items.new_item do |item|
+ # item.title = title
+ # item.link = link
+ end
+ end
end
- assert(rss.items.empty?)
end
-
+
def test_textinput
title = "fugafuga"
description = "text hoge fuga"
@@ -348,6 +390,8 @@ module RSS
maker.textinput.title = title
maker.textinput.description = description
maker.textinput.name = name
+
+ setup_dummy_item(maker)
end
textinput = rss.textinput
assert_equal(link, textinput.about)
@@ -357,15 +401,16 @@ module RSS
assert_equal(description, textinput.description)
assert_equal(link, textinput.link)
- rss = RSS::Maker.make("1.0") do |maker|
- # setup_dummy_channel(maker)
+ assert_not_set_error("maker.channel", %w(about link description title)) do
+ RSS::Maker.make("1.0") do |maker|
+ # setup_dummy_channel(maker)
- maker.textinput.link = link
- maker.textinput.title = title
- maker.textinput.description = description
- maker.textinput.name = name
+ maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ end
end
- assert_nil(rss)
end
def test_not_valid_textinput
@@ -381,6 +426,8 @@ module RSS
maker.textinput.title = title
maker.textinput.description = description
maker.textinput.name = name
+
+ setup_dummy_item(maker)
end
assert_nil(rss.channel.textinput)
assert_nil(rss.textinput)
@@ -392,6 +439,8 @@ module RSS
# maker.textinput.title = title
maker.textinput.description = description
maker.textinput.name = name
+
+ setup_dummy_item(maker)
end
assert_nil(rss.channel.textinput)
assert_nil(rss.textinput)
@@ -403,6 +452,8 @@ module RSS
maker.textinput.title = title
# maker.textinput.description = description
maker.textinput.name = name
+
+ setup_dummy_item(maker)
end
assert_nil(rss.channel.textinput)
assert_nil(rss.textinput)
@@ -414,6 +465,8 @@ module RSS
maker.textinput.title = title
maker.textinput.description = description
# maker.textinput.name = name
+
+ setup_dummy_item(maker)
end
assert_nil(rss.channel.textinput)
assert_nil(rss.textinput)
diff --git a/test/rss/test_maker_2.0.rb b/test/rss/test_maker_2.0.rb
index 2c581f75ea3..605d439a680 100644
--- a/test/rss/test_maker_2.0.rb
+++ b/test/rss/test_maker_2.0.rb
@@ -82,17 +82,20 @@ module RSS
maker.channel.lastBuildDate = lastBuildDate
skipDays.each do |day|
- new_day = maker.channel.skipDays.new_day
- new_day.content = day
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
end
skipHours.each do |hour|
- new_hour = maker.channel.skipHours.new_hour
- new_hour.content = hour
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
end
categories.each do |category|
- new_category = maker.channel.categories.new_category
- new_category.content = category
+ maker.channel.categories.new_category do |new_category|
+ new_category.content = category
+ end
end
maker.channel.generator = generator
@@ -368,13 +371,14 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
- item.author = "#{author}#{i}"
- item.comments = "#{comments}#{i}"
- item.date = pubDate
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.author = "#{author}#{i}"
+ item.comments = "#{comments}#{i}"
+ item.date = pubDate
+ end
end
maker.items.do_sort = true
end
@@ -393,16 +397,17 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
- item.author = "#{author}#{i}"
- item.comments = "#{comments}#{i}"
- item.date = pubDate
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.author = "#{author}#{i}"
+ item.comments = "#{comments}#{i}"
+ item.date = pubDate
+ end
end
maker.items.do_sort = Proc.new do |x, y|
- y.title[-1] <=> x.title[-1]
+ y.title.content[-1] <=> x.title.content[-1]
end
end
assert_equal(item_size, rss.items.size)
@@ -557,9 +562,10 @@ module RSS
setup_dummy_channel(maker)
setup_dummy_item(maker)
- category = maker.items.last.categories.new_category
- category.domain = domain
- category.content = content
+ maker.items.last.categories.new_category do |category|
+ category.domain = domain
+ category.content = content
+ end
end
category = rss.channel.items.last.categories.last
assert_equal(domain, category.domain)
@@ -573,8 +579,9 @@ module RSS
setup_dummy_channel(maker)
setup_dummy_item(maker)
- category = maker.items.last.categories.new_category
- # category.content = content
+ maker.items.last.categories.new_category do |category|
+ # category.content = content
+ end
end
assert(rss.channel.items.last.categories.empty?)
end
@@ -599,15 +606,16 @@ module RSS
assert_equal(name, textInput.name)
assert_equal(link, textInput.link)
- rss = RSS::Maker.make("2.0") do |maker|
- # setup_dummy_channel(maker)
+ assert_not_set_error("maker.channel", %w(link description title)) do
+ RSS::Maker.make("2.0") do |maker|
+ # setup_dummy_channel(maker)
- maker.textinput.title = title
- maker.textinput.description = description
- maker.textinput.name = name
- maker.textinput.link = link
+ maker.textinput.title = title
+ maker.textinput.description = description
+ maker.textinput.name = name
+ maker.textinput.link = link
+ end
end
- assert_nil(rss)
end
def test_not_valid_textInput
diff --git a/test/rss/test_maker_atom_entry.rb b/test/rss/test_maker_atom_entry.rb
new file mode 100644
index 00000000000..ae0ab2d09f9
--- /dev/null
+++ b/test/rss/test_maker_atom_entry.rb
@@ -0,0 +1,367 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerAtomEntry < TestCase
+ def test_root_element
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.encoding = "EUC-JP"
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+ assert_equal("EUC-JP", entry.encoding)
+
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+ assert_equal("yes", entry.standalone)
+
+ entry = Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "entry"], entry.feed_info)
+ assert_equal("EUC-JP", entry.encoding)
+ assert_equal("yes", entry.standalone)
+ end
+
+ def test_invalid_feed
+ assert_not_set_error("maker.item", %w(id title author updated)) do
+ Maker.make("atom:entry") do |maker|
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(id title updated)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.author = "foo"
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(title updated)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(updated)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ end
+ end
+
+ assert_not_set_error("maker.item", %w(author)) do
+ Maker.make("atom:entry") do |maker|
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ end
+
+ entry = Maker.make("atom:entry") do |maker|
+ maker.channel.author = "Foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ assert_not_nil(entry)
+ end
+
+ def test_author
+ assert_maker_atom_persons("entry",
+ ["channel", "authors"],
+ ["authors"],
+ "maker.channel.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "authors"],
+ ["authors"],
+ "maker.item.author",
+ "maker.item", ["author"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.authors.clear
+ maker.items.first.authors.clear
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "source", "authors"],
+ ["source", "authors"],
+ "maker.item.source.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_category
+ assert_maker_atom_categories("entry",
+ ["channel", "categories"],
+ ["categories"],
+ "maker.channel.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_categories("entry",
+ ["items", "first", "categories"],
+ ["categories"],
+ "maker.item.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_categories("entry",
+ ["items", "first", "source", "categories"],
+ ["source", "categories"],
+ "maker.item.source.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_content
+ assert_maker_atom_content("entry",
+ ["items", "first", "content"],
+ ["content"],
+ "maker.item.content") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_contributor
+ assert_maker_atom_persons("entry",
+ ["channel", "contributors"],
+ ["contributors"],
+ "maker.channel.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "contributors"],
+ ["contributors"],
+ "maker.item.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("entry",
+ ["items", "first", "source", "contributors"],
+ ["source", "contributors"],
+ "maker.item.source.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_link
+ assert_maker_atom_links("entry",
+ ["channel", "links"],
+ ["links"],
+ "maker.channel.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.links.clear
+ maker.items.first.links.clear
+ end
+
+ assert_maker_atom_links("entry",
+ ["items", "first", "links"],
+ ["links"],
+ "maker.item.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.links.clear
+ maker.items.first.links.clear
+ end
+
+ assert_maker_atom_links("entry",
+ ["items", "first", "source", "links"],
+ ["source", "links"],
+ "maker.item.source.link", true) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_published
+ assert_maker_atom_date_construct("entry",
+ ["items", "first", "published"],
+ ["published"]
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_rights
+ assert_maker_atom_text_construct("entry",
+ ["channel", "copyright"],
+ ["rights"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "rights"],
+ ["rights"],
+ nil, nil, "maker.item.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "source", "rights"],
+ ["source", "rights"],
+ nil, nil, "maker.item.source.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+
+ def test_source_generator
+ assert_maker_atom_generator("entry",
+ ["items", "first", "source", "generator"],
+ ["source", "generator"],
+ "maker.item.source.generator") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_icon
+ assert_maker_atom_icon("entry",
+ ["items", "first", "source", "icon"],
+ ["source", "icon"],
+ nil, "maker.item.source.icon") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_id
+ assert_maker_atom_id("entry",
+ ["items", "first", "source"],
+ ["source"],
+ "maker.item.source") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_logo
+ assert_maker_atom_logo("entry",
+ ["items", "first", "source", "logo"],
+ ["source", "logo"],
+ nil,
+ "maker.item.source.logo") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_source_subtitle
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "source", "subtitle"],
+ ["source", "subtitle"],
+ nil, nil,
+ "maker.item.source.subtitle") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_summary
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "description"],
+ ["summary"],
+ nil, nil, "maker.item.description"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_title
+ assert_maker_atom_text_construct("entry",
+ ["channel", "title"], ["title"],
+ "maker.item", ["title"],
+ "maker.channel.title") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.title = nil
+ maker.items.first.title = nil
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "title"],
+ ["title"],
+ "maker.item", ["title"],
+ "maker.item.title") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.title = nil
+ maker.items.first.title = nil
+ end
+
+ assert_maker_atom_text_construct("entry",
+ ["items", "first", "source", "title"],
+ ["source", "title"],
+ nil, nil, "maker.item.source.title"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_updated
+ assert_maker_atom_date_construct("entry",
+ ["channel", "updated"], ["updated"],
+ "maker.item", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.updated = nil
+ maker.items.first.updated = nil
+ end
+
+ assert_maker_atom_date_construct("entry",
+ ["items", "first", "updated"],
+ ["updated"],
+ "maker.item", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.updated = nil
+ maker.items.first.updated = nil
+ end
+
+ assert_maker_atom_date_construct("entry",
+ ["items", "first", "source", "updated"],
+ ["source", "updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+ end
+end
diff --git a/test/rss/test_maker_atom_feed.rb b/test/rss/test_maker_atom_feed.rb
new file mode 100644
index 00000000000..f4c5cc2a3da
--- /dev/null
+++ b/test/rss/test_maker_atom_feed.rb
@@ -0,0 +1,380 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestMakerAtomFeed < TestCase
+ def test_root_element
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.encoding = "EUC-JP"
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+ assert_equal("EUC-JP", feed.encoding)
+
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+ assert_equal("yes", feed.standalone)
+
+ feed = Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.encoding = "EUC-JP"
+ maker.standalone = "yes"
+ end
+ assert_equal(["atom", "1.0", "feed"], feed.feed_info)
+ assert_equal("EUC-JP", feed.encoding)
+ assert_equal("yes", feed.standalone)
+ end
+
+ def test_invalid_feed
+ assert_not_set_error("maker.channel", %w(id title author updated)) do
+ Maker.make("atom") do |maker|
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(id title updated)) do
+ Maker.make("atom") do |maker|
+ maker.channel.author = "foo"
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(title updated)) do
+ Maker.make("atom") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(updated)) do
+ Maker.make("atom") do |maker|
+ maker.channel.author = "foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ end
+ end
+
+ assert_not_set_error("maker.channel", %w(author)) do
+ Maker.make("atom") do |maker|
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ end
+
+ feed = Maker.make("atom") do |maker|
+ maker.channel.author = "Foo"
+ maker.channel.id = "http://example.com"
+ maker.channel.title = "Atom Feed"
+ maker.channel.updated = Time.now
+ end
+ assert_not_nil(feed)
+ end
+
+ def test_author
+ assert_maker_atom_persons("feed",
+ ["channel", "authors"],
+ ["authors"],
+ "maker.channel.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_not_set_error("maker.channel", %w(author)) do
+ RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.channel.authors.clear
+ end
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "authors"],
+ ["entries", "first", "authors"],
+ "maker.item.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "source", "authors"],
+ ["entries", "first", "source", "authors"],
+ "maker.item.source.author") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_category
+ assert_maker_atom_categories("feed",
+ ["channel", "categories"],
+ ["categories"],
+ "maker.channel.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_categories("feed",
+ ["items", "first", "categories"],
+ ["entries", "first", "categories"],
+ "maker.item.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_categories("feed",
+ ["items", "first", "source", "categories"],
+ ["entries", "first", "source", "categories"],
+ "maker.item.source.category") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_contributor
+ assert_maker_atom_persons("feed",
+ ["channel", "contributors"],
+ ["contributors"],
+ "maker.channel.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "contributors"],
+ ["entries", "first", "contributors"],
+ "maker.item.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_persons("feed",
+ ["items", "first", "source", "contributors"],
+ ["entries", "first", "source", "contributors"],
+ "maker.item.source.contributor") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_generator
+ assert_maker_atom_generator("feed",
+ ["channel", "generator"],
+ ["generator"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_generator("feed",
+ ["items", "first", "source", "generator"],
+ ["entries", "first", "source", "generator"],
+ "maker.item.source.generator") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_icon
+ assert_maker_atom_icon("feed", ["channel"], ["icon"], "icon") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_icon("feed",
+ ["items", "first", "source", "icon"],
+ ["entries", "first", "source", "icon"],
+ nil, "maker.item.source.icon") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_link
+ assert_maker_atom_links("feed",
+ ["channel", "links"],
+ ["links"],
+ "maker.channel.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_links("feed",
+ ["items", "first", "links"],
+ ["entries", "first", "links"],
+ "maker.item.link") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_links("feed",
+ ["items", "first", "source", "links"],
+ ["entries", "first", "source", "links"],
+ "maker.item.source.link", true) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_logo
+ assert_maker_atom_logo("feed", ["channel"], ["logo"], "logo") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_logo("feed", ["image"], ["logo"], "url") do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_logo("feed",
+ ["items", "first", "source", "logo"],
+ ["entries", "first", "source", "logo"],
+ nil, "maker.item.source.logo") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_rights
+ assert_maker_atom_text_construct("feed",
+ ["channel", "copyright"],
+ ["rights"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "rights"],
+ ["entries", "first", "rights"],
+ nil, nil, "maker.item.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "source", "rights"],
+ ["entries", "first", "source", "rights"],
+ nil, nil, "maker.item.source.rights"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_subtitle
+ assert_maker_atom_text_construct("feed",
+ ["channel", "subtitle"],
+ ["subtitle"],
+ nil, nil,
+ "maker.channel.description") do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.description.content = nil
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "source", "subtitle"],
+ ["entries", "first",
+ "source", "subtitle"],
+ nil, nil,
+ "maker.item.source.subtitle") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_title
+ assert_maker_atom_text_construct("feed",
+ ["channel", "title"], ["title"],
+ "maker.channel", ["title"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.title = nil
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "title"],
+ ["entries", "first", "title"],
+ "maker.item", ["title"],
+ "maker.item.title") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.items.first.title = nil
+ end
+
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "source", "title"],
+ ["entries", "first", "source", "title"],
+ nil, nil, "maker.item.source.title"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_updated
+ assert_maker_atom_date_construct("feed",
+ ["channel", "updated"], ["updated"],
+ "maker.channel", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ maker.channel.updated = nil
+ end
+
+ assert_maker_atom_date_construct("feed",
+ ["items", "first", "updated"],
+ ["entries", "first", "updated"],
+ "maker.item", ["updated"]) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ maker.items.first.updated = nil
+ end
+
+ assert_maker_atom_date_construct("feed",
+ ["items", "first", "source", "updated"],
+ ["entries", "first", "source", "updated"]
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_published
+ assert_maker_atom_date_construct("feed",
+ ["items", "first", "published"],
+ ["entries", "first", "published"]
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_summary
+ assert_maker_atom_text_construct("feed",
+ ["items", "first", "description"],
+ ["entries", "first", "summary"],
+ nil, nil, "maker.item.description"
+ ) do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_content
+ assert_maker_atom_content("feed",
+ ["items", "first", "content"],
+ ["entries", "first", "content"],
+ "maker.item.content") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+
+ def test_id
+ assert_maker_atom_id("feed",
+ ["items", "first", "source"],
+ ["entries", "first", "source"],
+ "maker.item.source") do |maker|
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ end
+ end
+end
diff --git a/test/rss/test_maker_dc.rb b/test/rss/test_maker_dc.rb
index 37a7f2bb1d3..72a967231a8 100644
--- a/test/rss/test_maker_dc.rb
+++ b/test/rss/test_maker_dc.rb
@@ -107,14 +107,16 @@ module RSS
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
maker.channel.date = t1
- date = maker.channel.dc_dates.new_date
- date.value = t2
+ maker.channel.dc_dates.new_date do |date|
+ date.value = t2
+ end
setup_dummy_item(maker)
item = maker.items.last
item.date = t2
- date = item.dc_dates.new_date
- date.value = t1
+ item.dc_dates.new_date do |date|
+ date.value = t1
+ end
end
assert_equal([t1, t2], rss.channel.dc_dates.collect{|x| x.value})
assert_equal([t2, t1], rss.items.last.dc_dates.collect{|x| x.value})
@@ -136,8 +138,9 @@ module RSS
plural ||= "#{name}s"
dc_elems = target.__send__("dc_#{plural}")
values.each do |value|
- new_dc_elem = dc_elems.__send__("new_#{name}")
- new_dc_elem.value = value
+ dc_elems.__send__("new_#{name}") do |new_dc_elem|
+ new_dc_elem.value = value
+ end
end
end
end
diff --git a/test/rss/test_maker_sy.rb b/test/rss/test_maker_sy.rb
index fd6df9a0eb5..309a3b70fd3 100644
--- a/test/rss/test_maker_sy.rb
+++ b/test/rss/test_maker_sy.rb
@@ -24,6 +24,7 @@ module RSS
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
set_elements(maker.channel)
+ setup_dummy_item(maker)
end
assert_syndication(@elements, rss.channel)
end
diff --git a/test/rss/test_maker_taxo.rb b/test/rss/test_maker_taxo.rb
index 1c7d2844ce6..8feb4e1d331 100644
--- a/test/rss/test_maker_taxo.rb
+++ b/test/rss/test_maker_taxo.rb
@@ -56,14 +56,16 @@ module RSS
rss = RSS::Maker.make("1.0") do |maker|
setup_dummy_channel(maker)
maker.channel.date = t1
- date = maker.channel.dc_dates.new_date
- date.value = t2
+ maker.channel.dc_dates.new_date do |date|
+ date.value = t2
+ end
setup_dummy_item(maker)
item = maker.items.last
item.date = t2
- date = item.dc_dates.new_date
- date.value = t1
+ item.dc_dates.new_date do |date|
+ date.value = t1
+ end
end
assert_equal([t1, t2], rss.channel.dc_dates.collect{|x| x.value})
assert_equal([t2, t1], rss.items.last.dc_dates.collect{|x| x.value})
diff --git a/test/rss/test_maker_trackback.rb b/test/rss/test_maker_trackback.rb
index e90bb600a32..58705c6f80a 100644
--- a/test/rss/test_maker_trackback.rb
+++ b/test/rss/test_maker_trackback.rb
@@ -25,8 +25,9 @@ module RSS
item = maker.items.last
item.trackback_ping = @elements[:ping]
@elements[:abouts].each do |about|
- new_about = item.trackback_abouts.new_about
- new_about.value = about
+ item.trackback_abouts.new_about do |new_about|
+ new_about.value = about
+ end
end
end
assert_trackback(@elements, rss.items.last)
diff --git a/test/rss/test_maker_xml-stylesheet.rb b/test/rss/test_maker_xml-stylesheet.rb
index bbdfdc682bc..9d45e520388 100644
--- a/test/rss/test_maker_xml-stylesheet.rb
+++ b/test/rss/test_maker_xml-stylesheet.rb
@@ -14,15 +14,17 @@ module RSS
alternate = 'yes'
rss = RSS::Maker.make("1.0") do |maker|
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
- xss.type = type
- xss.title = title
- xss.media = media
- xss.charset = charset
- xss.alternate = alternate
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
setup_dummy_channel(maker)
+ setup_dummy_item(maker)
end
xss = rss.xml_stylesheets.first
@@ -37,10 +39,12 @@ module RSS
href = 'http://example.com/index.xsl'
type = 'text/xsl'
rss = RSS::Maker.make("1.0") do |maker|
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ end
+
setup_dummy_channel(maker)
+ setup_dummy_item(maker)
end
xss = rss.xml_stylesheets.first
@@ -53,20 +57,24 @@ module RSS
type = "text/xsl"
rss = RSS::Maker.make("1.0") do |maker|
- xss = maker.xml_stylesheets.new_xml_stylesheet
- # xss.href = href
- xss.type = type
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ # xss.href = href
+ xss.type = type
+ end
+
setup_dummy_channel(maker)
+ setup_dummy_item(maker)
end
assert(rss.xml_stylesheets.empty?)
rss = RSS::Maker.make("1.0") do |maker|
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
- # xss.type = type
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ # xss.type = type
+ end
+
setup_dummy_channel(maker)
+ setup_dummy_item(maker)
end
assert(rss.xml_stylesheets.empty?)
end
diff --git a/test/rss/test_parser.rb b/test/rss/test_parser.rb
index f410b1b4f07..49b441bf96b 100644
--- a/test/rss/test_parser.rb
+++ b/test/rss/test_parser.rb
@@ -13,12 +13,10 @@ end
require "rss-testcase"
require "rss/1.0"
-require "rss/2.0"
require "rss/dublincore"
module RSS
class TestParser < TestCase
-
def setup
@_default_parser = Parser.default_parser
@rss10 = make_RDF(<<-EOR)
@@ -35,588 +33,6 @@ EOR
Parser.default_parser = @_default_parser
FileUtils.rm_f(@rss_file)
end
-
- def test_RDF
- assert_ns("", RDF::URI) do
- Parser.parse(<<-EOR)
-#{make_xmldecl}
-<RDF/>
-EOR
- end
-
- assert_ns("", RDF::URI) do
- Parser.parse(<<-EOR)
-#{make_xmldecl}
-<RDF xmlns="hoge"/>
-EOR
- end
-
- assert_ns("rdf", RDF::URI) do
- Parser.parse(<<-EOR)
-#{make_xmldecl}
-<rdf:RDF xmlns:rdf="hoge"/>
-EOR
- end
-
- assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
-#{make_xmldecl}
-<rdf:RDF xmlns:rdf="#{RSS::RDF::URI}"/>
-EOR
-
- assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
-#{make_xmldecl}
-<RDF xmlns="#{RSS::RDF::URI}"/>
-EOR
-
- assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
-#{make_xmldecl}
-<RDF xmlns="#{RSS::RDF::URI}"/>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
-#{make_channel}
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
-#{make_channel}
-#{make_image}
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
-#{make_channel}
-#{make_textinput}
-EOR
-
- assert_too_much_tag("image", "RDF") do
- Parser.parse(make_RDF(<<-EOR))
-#{make_channel}
-#{make_image}
-#{make_image}
-#{make_item}
-#{make_textinput}
-EOR
- end
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_item}
-#{make_image}
-#{make_textinput}
-EOR
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_item}
-#{make_textinput}
-#{make_image}
-EOR
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_image}
-#{make_item}
-EOR
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_image}
-#{make_item}
-#{make_textinput}
-EOR
-
- 1.step(15, 3) do |i|
- rss = make_RDF() do
- res = make_channel
- i.times { res << make_item }
- res
- end
- assert_parse(rss, :nothing_raised)
- end
- end
-
- def test_undefined_entity
- return unless RSS::Parser.default_parser.raise_for_undefined_entity?
- assert_parse(make_RDF(<<-EOR), :raises, RSS::NotWellFormedError)
-#{make_channel}
-#{make_image}
-<item rdf:about="#{RDF_ABOUT}">
- <title>#{TITLE_VALUE} &UNKNOWN_ENTITY;</title>
- <link>#{LINK_VALUE}</link>
- <description>#{DESCRIPTION_VALUE}</description>
-</item>
-#{make_textinput}
-EOR
- end
-
- def test_channel
-
- assert_parse(make_RDF(<<-EOR), :missing_attribute, "channel", "rdf:about")
-<channel />
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "channel")
-<channel rdf:about="http://example.com/"/>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "channel")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
-</channel>
-EOR
-
- assert_parse(make_RDF(<<EOR), :missing_tag, "description", "channel")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
-</channel>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
-</channel>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "rdf:resource")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image/>
-</channel>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image rdf:resource="http://example.com/hoge.png" />
-</channel>
-EOR
-
- rss = make_RDF(<<-EOR)
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image rdf:resource="http://example.com/hoge.png" />
- <items/>
-</channel>
-EOR
-
- assert_missing_tag("Seq", "items") do
- Parser.parse(rss)
- end
-
- assert_missing_tag("item", "RDF") do
- Parser.parse(rss, false).validate
- end
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image rdf:resource="http://example.com/hoge.png" />
- <items>
- <rdf:Seq>
- </rdf:Seq>
- </items>
-</channel>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "rdf:resource")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image rdf:resource="http://example.com/hoge.png" />
- <items>
- <rdf:Seq>
- </rdf:Seq>
- </items>
- <textinput/>
-</channel>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image rdf:resource="http://example.com/hoge.png" />
- <items>
- <rdf:Seq>
- </rdf:Seq>
- </items>
- <textinput rdf:resource="http://example.com/search" />
-</channel>
-EOR
-
- end
-
- def test_rdf_li
-
- rss = make_RDF(<<-EOR)
-<channel rdf:about="http://example.com/">
- <title>hoge</title>
- <link>http://example.com/</link>
- <description>hogehoge</description>
- <image rdf:resource="http://example.com/hoge.png" />
- <items>
- <rdf:Seq>
- <rdf:li \#{rdf_li_attr}/>
- </rdf:Seq>
- </items>
- <textinput rdf:resource="http://example.com/search" />
-</channel>
-#{make_item}
-EOR
-
- source = Proc.new do |rdf_li_attr|
- eval(%Q[%Q[#{rss}]], binding)
- end
-
- attr = %q[resource="http://example.com/hoge"]
- assert_parse(source.call(attr), :nothing_raised)
-
- attr = %q[rdf:resource="http://example.com/hoge"]
- assert_parse(source.call(attr), :nothing_raised)
-
- assert_parse(source.call(""), :missing_attribute, "li", "resource")
- end
-
- def test_image
-
- assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "rdf:about")
-#{make_channel}
-<image>
-</image>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "image")
-#{make_channel}
-<image rdf:about="http://example.com/hoge.png">
-</image>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "url", "image")
-#{make_channel}
-<image rdf:about="http://example.com/hoge.png">
- <title>hoge</title>
-</image>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "image")
-#{make_channel}
-<image rdf:about="http://example.com/hoge.png">
- <title>hoge</title>
- <url>http://example.com/hoge.png</url>
-</image>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
-#{make_channel}
-<image rdf:about="http://example.com/hoge.png">
- <title>hoge</title>
- <url>http://example.com/hoge.png</url>
- <link>http://example.com/</link>
-</image>
-EOR
-
- rss = make_RDF(<<-EOR)
-#{make_channel}
-<image rdf:about="http://example.com/hoge.png">
- <link>http://example.com/</link>
- <url>http://example.com/hoge.png</url>
- <title>hoge</title>
-</image>
-EOR
-
- assert_missing_tag("item", "RDF") do
- Parser.parse(rss)
- end
-
- assert_missing_tag("item", "RDF") do
- Parser.parse(rss, false).validate
- end
-
- end
-
- def test_item
-
- assert_parse(make_RDF(<<-EOR), :missing_attribute, "item", "rdf:about")
-#{make_channel}
-#{make_image}
-<item>
-</item>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "item")
-#{make_channel}
-#{make_image}
-<item rdf:about="http://example.com/hoge.html">
-</item>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "item")
-#{make_channel}
-#{make_image}
-<item rdf:about="http://example.com/hoge.html">
- <title>hoge</title>
-</item>
-EOR
-
- assert_too_much_tag("title", "item") do
- Parser.parse(make_RDF(<<-EOR))
-#{make_channel}
-#{make_image}
-<item rdf:about="http://example.com/hoge.html">
- <title>hoge</title>
- <title>hoge</title>
- <link>http://example.com/hoge.html</link>
-</item>
-EOR
- end
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_image}
-<item rdf:about="http://example.com/hoge.html">
- <title>hoge</title>
- <link>http://example.com/hoge.html</link>
-</item>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_image}
-<item rdf:about="http://example.com/hoge.html">
- <title>hoge</title>
- <link>http://example.com/hoge.html</link>
- <description>hogehoge</description>
-</item>
-EOR
-
- end
-
- def test_textinput
-
- assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "rdf:about")
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput>
-</textinput>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "textinput")
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput rdf:about="http://example.com/search.html">
-</textinput>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "description", "textinput")
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput rdf:about="http://example.com/search.html">
- <title>hoge</title>
-</textinput>
-EOR
-
- assert_too_much_tag("title", "textinput") do
- Parser.parse(make_RDF(<<-EOR))
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput rdf:about="http://example.com/search.html">
- <title>hoge</title>
- <title>hoge</title>
- <description>hogehoge</description>
-</textinput>
-EOR
- end
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "name", "textinput")
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput rdf:about="http://example.com/search.html">
- <title>hoge</title>
- <description>hogehoge</description>
-</textinput>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "textinput")
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput rdf:about="http://example.com/search.html">
- <title>hoge</title>
- <description>hogehoge</description>
- <name>key</name>
-</textinput>
-EOR
-
- assert_parse(make_RDF(<<-EOR), :nothing_raised)
-#{make_channel}
-#{make_image}
-#{make_item}
-<textinput rdf:about="http://example.com/search.html">
- <title>hoge</title>
- <description>hogehoge</description>
- <name>key</name>
- <link>http://example.com/search.html</link>
-</textinput>
-EOR
-
- end
-
- def test_rss20
-
- assert_parse(make_rss20(<<-EOR), :missing_tag, "channel", "rss")
-EOR
-
- assert_parse(make_rss20(<<-EOR), :nothing_raised)
-#{make_channel20("")}
-EOR
-
- end
-
- def test_cloud20
-
- attrs = [
- ["domain", CLOUD_DOMAIN],
- ["port", CLOUD_PORT],
- ["path", CLOUD_PATH],
- ["registerProcedure", CLOUD_REGISTER_PROCEDURE],
- ["protocol", CLOUD_PROTOCOL],
- ]
-
- (attrs.size + 1).times do |i|
- missing_attr = attrs[i]
- if missing_attr
- meth = :missing_attribute
- args = ["cloud", missing_attr[0]]
- else
- meth = :nothing_raised
- args = []
- end
-
- cloud_attrs = []
- attrs.each_with_index do |attr, j|
- unless i == j
- cloud_attrs << %Q[#{attr[0]}="#{attr[1]}"]
- end
- end
-
- assert_parse(make_rss20(<<-EOR), meth, *args)
-#{make_channel20(%Q[<cloud #{cloud_attrs.join("\n")}/>])}
-EOR
-
- end
-
- end
-
- def test_source20
-
- assert_parse(make_rss20(<<-EOR), :missing_attribute, "source", "url")
-#{make_channel20(make_item20(%Q[<source>Example</source>]))}
-EOR
-
- assert_parse(make_rss20(<<-EOR), :nothing_raised)
-#{make_channel20(make_item20(%Q[<source url="http://example.com/" />]))}
-EOR
-
- assert_parse(make_rss20(<<-EOR), :nothing_raised)
-#{make_channel20(make_item20(%Q[<source url="http://example.com/">Example</source>]))}
-EOR
- end
-
- def test_enclosure20
-
- attrs = [
- ["url", ENCLOSURE_URL],
- ["length", ENCLOSURE_LENGTH],
- ["type", ENCLOSURE_TYPE],
- ]
-
- (attrs.size + 1).times do |i|
- missing_attr = attrs[i]
- if missing_attr
- meth = :missing_attribute
- args = ["enclosure", missing_attr[0]]
- else
- meth = :nothing_raised
- args = []
- end
-
- enclosure_attrs = []
- attrs.each_with_index do |attr, j|
- unless i == j
- enclosure_attrs << %Q[#{attr[0]}="#{attr[1]}"]
- end
- end
-
- assert_parse(make_rss20(<<-EOR), meth, *args)
-#{make_channel20(%Q[
-#{make_item20(%Q[
-<enclosure
- #{enclosure_attrs.join("\n")} />
- ])}
- ])}
-EOR
-
- end
-
- end
-
- def test_category20
- values = [nil, CATEGORY_DOMAIN]
-
- values.each do |value|
- domain = ""
- domain << %Q[domain="#{value}"] if value
-
- ["", "Example Text"].each do |text|
- rss_src = make_rss20(<<-EOR)
-#{make_channel20(%Q[
-#{make_item20(%Q[
-<category #{domain}>#{text}</category>
- ])}
- ])}
-EOR
- assert_parse(rss_src, :nothing_raised)
-
- rss = RSS::Parser.parse(rss_src)
- category = rss.items.last.categories.first
- assert_equal(value, category.domain)
- assert_equal(text, category.content)
- end
- end
- end
-
- def test_ignore
-
- rss = make_RDF(<<-EOR)
-#{make_channel}
-#{make_item}
-<a/>
-EOR
-
- assert_parse(rss, :nothing_raised)
-
- assert_not_excepted_tag("a", "RDF") do
- Parser.parse(rss, true, false)
- end
-
- end
def test_default_parser
assert_nothing_raised do
@@ -640,7 +56,5 @@ EOR
assert_nil(RSS::Parser.parse(garbage_rss_file))
end
end
-
end
end
-
diff --git a/test/rss/test_parser_1.0.rb b/test/rss/test_parser_1.0.rb
new file mode 100644
index 00000000000..472602b04ab
--- /dev/null
+++ b/test/rss/test_parser_1.0.rb
@@ -0,0 +1,503 @@
+require "rss-testcase"
+
+require "rss/1.0"
+require "rss/dublincore"
+
+module RSS
+ class TestParser10 < TestCase
+ def test_RDF
+ assert_ns("", RDF::URI) do
+ Parser.parse(<<-EOR)
+#{make_xmldecl}
+<RDF/>
+EOR
+ end
+
+ assert_ns("", RDF::URI) do
+ Parser.parse(<<-EOR)
+#{make_xmldecl}
+<RDF xmlns="hoge"/>
+EOR
+ end
+
+ assert_ns("rdf", RDF::URI) do
+ Parser.parse(<<-EOR)
+#{make_xmldecl}
+<rdf:RDF xmlns:rdf="hoge"/>
+EOR
+ end
+
+ assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
+#{make_xmldecl}
+<rdf:RDF xmlns:rdf="#{RSS::RDF::URI}"/>
+EOR
+
+ assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
+#{make_xmldecl}
+<RDF xmlns="#{RSS::RDF::URI}"/>
+EOR
+
+ assert_parse(<<-EOR, :missing_tag, "channel", "RDF")
+#{make_xmldecl}
+<RDF xmlns="#{RSS::RDF::URI}"/>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+#{make_image}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+#{make_textinput}
+EOR
+
+ assert_too_much_tag("image", "RDF") do
+ Parser.parse(make_RDF(<<-EOR))
+#{make_channel}
+#{make_image}
+#{make_image}
+#{make_item}
+#{make_textinput}
+EOR
+ end
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_item}
+#{make_image}
+#{make_textinput}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_item}
+#{make_textinput}
+#{make_image}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+#{make_item}
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+#{make_item}
+#{make_textinput}
+EOR
+
+ 1.step(15, 3) do |i|
+ rss = make_RDF() do
+ res = make_channel
+ i.times { res << make_item }
+ res
+ end
+ assert_parse(rss, :nothing_raised)
+ end
+ end
+
+ def test_undefined_entity
+ return unless RSS::Parser.default_parser.raise_for_undefined_entity?
+ assert_parse(make_RDF(<<-EOR), :raises, RSS::NotWellFormedError)
+#{make_channel}
+#{make_image}
+<item rdf:about="#{RDF_ABOUT}">
+ <title>#{TITLE_VALUE} &UNKNOWN_ENTITY;</title>
+ <link>#{LINK_VALUE}</link>
+ <description>#{DESCRIPTION_VALUE}</description>
+</item>
+#{make_textinput}
+EOR
+ end
+
+ def test_channel
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "channel", "rdf:about")
+<channel />
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "channel")
+<channel rdf:about="http://example.com/"/>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<EOR), :missing_tag, "description", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "rdf:resource")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image/>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "items", "channel")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+</channel>
+EOR
+
+ rss = make_RDF(<<-EOR)
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items/>
+</channel>
+EOR
+
+ assert_missing_tag("Seq", "items") do
+ Parser.parse(rss)
+ end
+
+ assert_missing_tag("item", "RDF") do
+ Parser.parse(rss, false).validate
+ end
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ </rdf:Seq>
+ </items>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "rdf:resource")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ </rdf:Seq>
+ </items>
+ <textinput/>
+</channel>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ </rdf:Seq>
+ </items>
+ <textinput rdf:resource="http://example.com/search" />
+</channel>
+EOR
+ end
+
+ def test_rdf_li
+ rss = make_RDF(<<-EOR)
+<channel rdf:about="http://example.com/">
+ <title>hoge</title>
+ <link>http://example.com/</link>
+ <description>hogehoge</description>
+ <image rdf:resource="http://example.com/hoge.png" />
+ <items>
+ <rdf:Seq>
+ <rdf:li \#{rdf_li_attr}/>
+ </rdf:Seq>
+ </items>
+ <textinput rdf:resource="http://example.com/search" />
+</channel>
+#{make_item}
+EOR
+
+ source = Proc.new do |rdf_li_attr|
+ eval(%Q[%Q[#{rss}]], binding)
+ end
+
+ attr = %q[resource="http://example.com/hoge"]
+ assert_parse(source.call(attr), :nothing_raised)
+
+ attr = %q[rdf:resource="http://example.com/hoge"]
+ assert_parse(source.call(attr), :nothing_raised)
+
+ assert_parse(source.call(""), :missing_attribute, "li", "resource")
+ end
+
+ def test_image
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "image", "rdf:about")
+#{make_channel}
+<image>
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "image")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "url", "image")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <title>hoge</title>
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "image")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <title>hoge</title>
+ <url>http://example.com/hoge.png</url>
+</image>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "item", "RDF")
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <title>hoge</title>
+ <url>http://example.com/hoge.png</url>
+ <link>http://example.com/</link>
+</image>
+EOR
+
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+<image rdf:about="http://example.com/hoge.png">
+ <link>http://example.com/</link>
+ <url>http://example.com/hoge.png</url>
+ <title>hoge</title>
+</image>
+EOR
+
+ assert_missing_tag("item", "RDF") do
+ Parser.parse(rss)
+ end
+
+ assert_missing_tag("item", "RDF") do
+ Parser.parse(rss, false).validate
+ end
+ end
+
+ def test_item
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "item", "rdf:about")
+#{make_channel}
+#{make_image}
+<item>
+</item>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "item")
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+</item>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "item")
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+</item>
+EOR
+
+ assert_too_much_tag("title", "item") do
+ Parser.parse(make_RDF(<<-EOR))
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+ <title>hoge</title>
+ <link>http://example.com/hoge.html</link>
+</item>
+EOR
+ end
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+ <link>http://example.com/hoge.html</link>
+</item>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+<item rdf:about="http://example.com/hoge.html">
+ <title>hoge</title>
+ <link>http://example.com/hoge.html</link>
+ <description>hogehoge</description>
+</item>
+EOR
+ end
+
+ def test_textinput
+ assert_parse(make_RDF(<<-EOR), :missing_attribute, "textinput", "rdf:about")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput>
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "title", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "description", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+</textinput>
+EOR
+
+ assert_too_much_tag("title", "textinput") do
+ Parser.parse(make_RDF(<<-EOR))
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <title>hoge</title>
+ <description>hogehoge</description>
+</textinput>
+EOR
+ end
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "name", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <description>hogehoge</description>
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :missing_tag, "link", "textinput")
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <description>hogehoge</description>
+ <name>key</name>
+</textinput>
+EOR
+
+ assert_parse(make_RDF(<<-EOR), :nothing_raised)
+#{make_channel}
+#{make_image}
+#{make_item}
+<textinput rdf:about="http://example.com/search.html">
+ <title>hoge</title>
+ <description>hogehoge</description>
+ <name>key</name>
+ <link>http://example.com/search.html</link>
+</textinput>
+EOR
+ end
+
+ def test_ignore
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+<#{name}/>
+EOR
+ assert_not_expected_tag(name, ::RSS::URI, "RDF") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = ""
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+<#{name} xmlns=""/>
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "RDF") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = "http://example.com/"
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+<x:#{name} xmlns:x="#{uri}"/>
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "RDF") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = ::RSS::URI
+ name = "a"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+#{make_image("<#{name}/>")}
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "image") do
+ Parser.parse(rss, true, false)
+ end
+
+ uri = CONTENT_URI
+ name = "encoded"
+ elem = "<#{name} xmlns='#{uri}'/>"
+ rss = make_RDF(<<-EOR)
+#{make_channel}
+#{make_item}
+#{make_image(elem)}
+EOR
+ assert_parse(rss, :nothing_raised)
+ assert_not_expected_tag(name, uri, "image") do
+ Parser.parse(rss, true, false)
+ end
+ end
+ end
+end
+
diff --git a/test/rss/test_parser_2.0.rb b/test/rss/test_parser_2.0.rb
new file mode 100644
index 00000000000..249347d3dc7
--- /dev/null
+++ b/test/rss/test_parser_2.0.rb
@@ -0,0 +1,122 @@
+require "rss-testcase"
+
+require "rss/2.0"
+
+module RSS
+ class TestParser20 < TestCase
+ def test_rss20
+ assert_parse(make_rss20(<<-EOR), :missing_tag, "channel", "rss")
+EOR
+
+ assert_parse(make_rss20(<<-EOR), :nothing_raised)
+#{make_channel20("")}
+EOR
+ end
+
+ def test_cloud20
+ attrs = [
+ ["domain", CLOUD_DOMAIN],
+ ["port", CLOUD_PORT],
+ ["path", CLOUD_PATH],
+ ["registerProcedure", CLOUD_REGISTER_PROCEDURE],
+ ["protocol", CLOUD_PROTOCOL],
+ ]
+
+ (attrs.size + 1).times do |i|
+ missing_attr = attrs[i]
+ if missing_attr
+ meth = :missing_attribute
+ args = ["cloud", missing_attr[0]]
+ else
+ meth = :nothing_raised
+ args = []
+ end
+
+ cloud_attrs = []
+ attrs.each_with_index do |attr, j|
+ unless i == j
+ cloud_attrs << %Q[#{attr[0]}="#{attr[1]}"]
+ end
+ end
+
+ assert_parse(make_rss20(<<-EOR), meth, *args)
+#{make_channel20(%Q[<cloud #{cloud_attrs.join("\n")}/>])}
+EOR
+ end
+ end
+
+ def test_source20
+ assert_parse(make_rss20(<<-EOR), :missing_attribute, "source", "url")
+#{make_channel20(make_item20(%Q[<source>Example</source>]))}
+EOR
+
+ assert_parse(make_rss20(<<-EOR), :nothing_raised)
+#{make_channel20(make_item20(%Q[<source url="http://example.com/" />]))}
+EOR
+
+ assert_parse(make_rss20(<<-EOR), :nothing_raised)
+#{make_channel20(make_item20(%Q[<source url="http://example.com/">Example</source>]))}
+EOR
+ end
+
+ def test_enclosure20
+ attrs = [
+ ["url", ENCLOSURE_URL],
+ ["length", ENCLOSURE_LENGTH],
+ ["type", ENCLOSURE_TYPE],
+ ]
+
+ (attrs.size + 1).times do |i|
+ missing_attr = attrs[i]
+ if missing_attr
+ meth = :missing_attribute
+ args = ["enclosure", missing_attr[0]]
+ else
+ meth = :nothing_raised
+ args = []
+ end
+
+ enclosure_attrs = []
+ attrs.each_with_index do |attr, j|
+ unless i == j
+ enclosure_attrs << %Q[#{attr[0]}="#{attr[1]}"]
+ end
+ end
+
+ assert_parse(make_rss20(<<-EOR), meth, *args)
+#{make_channel20(%Q[
+#{make_item20(%Q[
+<enclosure
+ #{enclosure_attrs.join("\n")} />
+ ])}
+ ])}
+EOR
+ end
+ end
+
+ def test_category20
+ values = [nil, CATEGORY_DOMAIN]
+ values.each do |value|
+ domain = ""
+ domain << %Q[domain="#{value}"] if value
+
+ ["", "Example Text"].each do |text|
+ rss_src = make_rss20(<<-EOR)
+#{make_channel20(%Q[
+#{make_item20(%Q[
+<category #{domain}>#{text}</category>
+ ])}
+ ])}
+EOR
+ assert_parse(rss_src, :nothing_raised)
+
+ rss = RSS::Parser.parse(rss_src)
+ category = rss.items.last.categories.first
+ assert_equal(value, category.domain)
+ assert_equal(text, category.content)
+ end
+ end
+ end
+ end
+end
+
diff --git a/test/rss/test_parser_atom_entry.rb b/test/rss/test_parser_atom_entry.rb
new file mode 100644
index 00000000000..c2572d7a3bc
--- /dev/null
+++ b/test/rss/test_parser_atom_entry.rb
@@ -0,0 +1,163 @@
+require "rss-testcase"
+
+require "rss/atom"
+
+module RSS
+ class TestParserAtom < TestCase
+ def test_entry_validation
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<entry/>
+EOA
+ end
+
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<entry xmlns="hoge"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "id", "entry") do
+<entry xmlns="#{Atom::URI}"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "title", "entry") do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+</entry>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "updated", "entry") do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+ <title>Example Entry</title>
+</entry>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "author", "entry") do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+ <title>Example Entry</title>
+ <updated>2003-10-10T18:30:02Z</updated>
+</entry>
+EOA
+ end
+
+ assert_parse(<<-EOA, :nothing_raised) do
+<entry xmlns="#{Atom::URI}">
+ <id>urn:uuid:506e336c-a26e-4457-917b-b89dca7ae746</id>
+ <title>Example Entry</title>
+ <updated>2003-10-10T18:30:02Z</updated>
+ <author>
+ <name>A person</name>
+ </author>
+</entry>
+EOA
+ end
+ end
+
+ def test_entry
+ entry = RSS::Parser.parse(<<-EOA)
+<?xml version="1.0" encoding="utf-8"?>
+<entry xmlns="http://www.w3.org/2005/Atom">
+ <author>
+ <name>A person</name>
+ </author>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/2003/12/13/atom03"/>
+ <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <summary>Some text.</summary>
+</entry>
+EOA
+ assert_not_nil(entry)
+ assert_equal("Atom-Powered Robots Run Amok", entry.title.content)
+ assert_equal("http://example.org/2003/12/13/atom03", entry.link.href)
+ assert_equal("urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a",
+ entry.id.content)
+ assert_equal(Time.parse("2003-12-13T18:30:02Z"), entry.updated.content)
+ assert_equal("Some text.", entry.summary.content)
+ end
+
+ def test_entry_author
+ assert_atom_person("author", method(:make_entry_document)) do |entry|
+ assert_equal(2, entry.authors.size)
+ entry.authors.last
+ end
+ end
+
+ def test_entry_category
+ assert_atom_category(method(:make_entry_document)) do |entry|
+ assert_equal(1, entry.categories.size)
+ entry.category
+ end
+ end
+
+ def test_entry_content_text
+ assert_atom_content(method(:make_entry_document)) do |entry|
+ entry.content
+ end
+ end
+
+ def test_entry_contributor
+ assert_atom_person("contributor", method(:make_entry_document)) do |entry|
+ assert_equal(1, entry.contributors.size)
+ entry.contributor
+ end
+ end
+
+ def test_entry_id
+ entry = RSS::Parser.parse(make_entry_document)
+ assert_equal(ENTRY_ID, entry.id.content)
+ end
+
+ def test_entry_link
+ assert_atom_link(method(:make_entry_document)) do |entry|
+ assert_equal(1, entry.links.size)
+ entry.link
+ end
+ end
+
+ def test_published
+ generator = method(:make_entry_document)
+ assert_atom_date_construct("published", generator) do |entry|
+ entry.published
+ end
+ end
+
+ def test_entry_rights
+ generator = method(:make_entry_document)
+ assert_atom_text_construct("rights", generator) do |entry|
+ entry.rights
+ end
+ end
+
+ def test_entry_source
+ generator = method(:make_entry_document_with_open_source)
+ assert_atom_source(generator) do |entry|
+ assert_not_nil(entry.source)
+ entry.source
+ end
+ end
+
+ def test_entry_summary
+ generator = method(:make_entry_document)
+ assert_atom_text_construct("summary", generator) do |entry|
+ entry.summary
+ end
+ end
+
+ def test_entry_title
+ entry = RSS::Parser.parse(make_entry_document)
+ assert_equal(ENTRY_TITLE, entry.title.content)
+ end
+
+ def test_entry_updated
+ entry = RSS::Parser.parse(make_entry_document)
+ assert_equal(Time.parse(ENTRY_UPDATED), entry.updated.content)
+ end
+ end
+end
diff --git a/test/rss/test_parser_atom_feed.rb b/test/rss/test_parser_atom_feed.rb
new file mode 100644
index 00000000000..4358cc8898e
--- /dev/null
+++ b/test/rss/test_parser_atom_feed.rb
@@ -0,0 +1,276 @@
+require "rss-testcase"
+
+require "rss/atom"
+
+module RSS
+ class TestParserAtomFeed < TestCase
+ def test_feed_validation
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<feed/>
+EOA
+ end
+
+ assert_ns("", Atom::URI) do
+ Parser.parse(<<-EOA)
+<feed xmlns="hoge"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "id", "feed") do
+<feed xmlns="#{Atom::URI}"/>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "title", "feed") do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+</feed>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "updated", "feed") do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title>Example Feed</title>
+</feed>
+EOA
+ end
+
+ assert_parse(<<-EOA, :missing_tag, "author", "feed") do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title>Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+</feed>
+EOA
+ end
+
+ assert_parse(<<-EOA, :nothing_raised) do
+<feed xmlns="#{Atom::URI}">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title>Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author>
+ <name>A person</name>
+ </author>
+</feed>
+EOA
+ end
+ end
+
+ def test_lang
+ feed = RSS::Parser.parse(<<-EOA)
+<feed xmlns="#{Atom::URI}" xml:lang="ja">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title xml:lang="en">Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <author xml:lang="en">
+ <name>A person</name>
+ </author>
+</feed>
+EOA
+
+ assert_equal("ja", feed.lang)
+ assert_equal("ja", feed.id.lang)
+ assert_equal("en", feed.title.lang)
+ assert_equal("ja", feed.updated.lang)
+ assert_equal("en", feed.author.lang)
+ assert_equal("en", feed.author.name.lang)
+ end
+
+ def test_base
+ feed = RSS::Parser.parse(<<-EOA)
+<feed xmlns="#{Atom::URI}" xml:base="http://example.com/">
+ <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
+ <title xml:lang="en">Example Feed</title>
+ <updated>2003-12-13T18:30:02Z</updated>
+ <generator uri="generator">Generator</generator>
+ <link hreflang="ja" href="http://example.org/link1"/>
+ <link hreflang="en" href="link2"/>
+ <link hreflang="fr" xml:base="http://example.net/" href="link3"/>
+ <author>
+ <name>A person</name>
+ <uri>person</uri>
+ </author>
+</feed>
+EOA
+
+ assert_equal("http://example.com/", feed.base)
+ assert_equal("http://example.com/", feed.id.base)
+ assert_equal("http://example.com/", feed.title.base)
+ assert_equal("http://example.com/", feed.updated.base)
+ assert_equal("http://example.com/", feed.generator.base)
+ assert_equal("http://example.com/generator", feed.generator.uri)
+
+ assert_equal("http://example.com/", feed.links[0].base)
+ assert_equal("http://example.org/link1", feed.links[0].href)
+ assert_equal("http://example.com/", feed.links[1].base)
+ assert_equal("http://example.com/link2", feed.links[1].href)
+ assert_equal("http://example.net/", feed.links[2].base)
+ assert_equal("http://example.net/link3", feed.links[2].href)
+ assert_equal("http://example.com/person", feed.author.uri.content)
+ end
+
+ def test_feed_author
+ assert_atom_person("author", method(:make_feed)) do |feed|
+ assert_equal(2, feed.authors.size)
+ feed.authors[1]
+ end
+ end
+
+ def test_entry_author
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_person("author", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.authors.size)
+ feed.entry.author
+ end
+ end
+
+ def test_feed_category
+ assert_atom_category(method(:make_feed)) do |feed|
+ assert_equal(1, feed.categories.size)
+ feed.category
+ end
+ end
+
+ def test_entry_category
+ assert_atom_category(method(:make_feed_with_open_entry)) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.categories.size)
+ feed.entry.category
+ end
+ end
+
+ def test_entry_content
+ assert_atom_content(method(:make_feed_with_open_entry)) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.content
+ end
+ end
+
+ def test_feed_contributor
+ assert_atom_person("contributor", method(:make_feed)) do |feed|
+ assert_equal(1, feed.contributors.size)
+ feed.contributor
+ end
+ end
+
+ def test_entry_contributor
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_person("contributor", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.contributors.size)
+ feed.entry.contributor
+ end
+ end
+
+ def test_feed_generator
+ assert_atom_generator(method(:make_feed)) do |feed|
+ feed.generator
+ end
+ end
+
+ def test_feed_icon
+ assert_atom_icon(method(:make_feed)) do |feed|
+ feed.icon
+ end
+ end
+
+ def test_feed_id
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(FEED_ID, feed.id.content)
+ end
+
+ def test_entry_id
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(ENTRY_ID, feed.entry.id.content)
+ end
+
+ def test_feed_link
+ assert_atom_link(method(:make_feed)) do |feed|
+ assert_equal(1, feed.links.size)
+ feed.link
+ end
+ end
+
+ def test_entry_link
+ assert_atom_link(method(:make_feed_with_open_entry)) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_equal(1, feed.entry.links.size)
+ feed.entry.link
+ end
+ end
+
+ def test_feed_logo
+ assert_atom_logo(method(:make_feed)) do |feed|
+ feed.logo
+ end
+ end
+
+ def test_feed_rights
+ assert_atom_text_construct("rights", method(:make_feed)) do |feed|
+ feed.rights
+ end
+ end
+
+ def test_entry_rights
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_text_construct("rights", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.rights
+ end
+ end
+
+ def test_entry_source
+ assert_atom_source(method(:make_feed_with_open_entry_source)) do |feed|
+ assert_equal(1, feed.entries.size)
+ assert_not_nil(feed.entry.source)
+ feed.entry.source
+ end
+ end
+
+ def test_feed_subtitle
+ assert_atom_text_construct("subtitle", method(:make_feed)) do |feed|
+ feed.subtitle
+ end
+ end
+
+ def test_feed_title
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(FEED_TITLE, feed.title.content)
+ end
+
+ def test_entry_title
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(ENTRY_TITLE, feed.entry.title.content)
+ end
+
+ def test_feed_updated
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(Time.parse(FEED_UPDATED), feed.updated.content)
+ end
+
+ def test_entry_updated
+ feed = RSS::Parser.parse(make_feed(''))
+ assert_equal(Time.parse(ENTRY_UPDATED), feed.entry.updated.content)
+ end
+
+ def test_entry_published
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_date_construct("published", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.published
+ end
+ end
+
+ def test_entry_summary
+ generator = method(:make_feed_with_open_entry)
+ assert_atom_text_construct("summary", generator) do |feed|
+ assert_equal(1, feed.entries.size)
+ feed.entry.summary
+ end
+ end
+ end
+end
diff --git a/test/rss/test_setup_maker_0.9.rb b/test/rss/test_setup_maker_0.9.rb
index 086065c2bc5..c20186cc8a0 100644
--- a/test/rss/test_setup_maker_0.9.rb
+++ b/test/rss/test_setup_maker_0.9.rb
@@ -40,17 +40,28 @@ module RSS
maker.channel.lastBuildDate = lastBuildDate
skipDays.each do |day|
- new_day = maker.channel.skipDays.new_day
- new_day.content = day
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
end
skipHours.each do |hour|
- new_hour = maker.channel.skipHours.new_hour
- new_hour.content = hour
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
+ end
+
+ setup_dummy_image(maker)
+ end
+
+ assert_not_set_error("maker.image", %w(title url)) do
+ RSS::Maker.make("0.91") do |maker|
+ rss.channel.setup_maker(maker)
end
end
new_rss = RSS::Maker.make("0.91") do |maker|
rss.channel.setup_maker(maker)
+ setup_dummy_image(maker)
end
channel = new_rss.channel
@@ -72,9 +83,8 @@ module RSS
skipHours.each_with_index do |hour, i|
assert_equal(hour.to_i, channel.skipHours.hours[i].content)
end
-
+
assert(channel.items.empty?)
- assert_nil(channel.image)
assert_nil(channel.textInput)
end
@@ -119,6 +129,7 @@ module RSS
rss = RSS::Maker.make("0.91") do |maker|
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
maker.textinput.title = title
maker.textinput.description = description
@@ -128,6 +139,7 @@ module RSS
new_rss = RSS::Maker.make("0.91") do |maker|
rss.channel.setup_maker(maker)
+ rss.image.setup_maker(maker)
rss.textinput.setup_maker(maker)
end
@@ -149,11 +161,14 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ end
end
+
+ setup_dummy_image(maker)
end
new_rss = RSS::Maker.make("0.91") do |maker|
@@ -166,15 +181,16 @@ module RSS
item.setup_maker(maker.items)
end
end
+
+ rss.image.setup_maker(maker)
end
-
+
assert_equal(item_size, new_rss.items.size)
new_rss.items.each_with_index do |item, i|
assert_equal("#{title}#{i}", item.title)
assert_equal("#{link}#{i}", item.link)
assert_equal("#{description}#{i}", item.description)
end
-
end
def test_setup_maker_items_backward_compatibility
@@ -196,17 +212,19 @@ module RSS
maker.encoding = encoding
maker.standalone = standalone
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
- xss.type = type
- xss.title = title
- xss.media = media
- xss.charset = charset
- xss.alternate = alternate
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
setup_dummy_channel(maker)
+ setup_dummy_image(maker)
end
-
+
new_rss = RSS::Maker.make("0.91") do |maker|
rss.setup_maker(maker)
end
@@ -224,6 +242,5 @@ module RSS
assert_equal(charset, xss.charset)
assert_equal(alternate, xss.alternate)
end
-
end
end
diff --git a/test/rss/test_setup_maker_1.0.rb b/test/rss/test_setup_maker_1.0.rb
index 95d8b310bac..539749bf20c 100644
--- a/test/rss/test_setup_maker_1.0.rb
+++ b/test/rss/test_setup_maker_1.0.rb
@@ -87,10 +87,15 @@ module RSS
@sy_elems.each do |var, value|
maker.channel.__send__("sy_#{var}=", value)
end
+
+ setup_dummy_item(maker)
end
new_rss = RSS::Maker.make("1.0") do |maker|
rss.channel.setup_maker(maker)
+ rss.items.each do |item|
+ item.setup_maker(maker)
+ end
end
channel = new_rss.channel
@@ -98,7 +103,7 @@ module RSS
assert_equal(title, channel.title)
assert_equal(link, channel.link)
assert_equal(description, channel.description)
- assert_equal(true, channel.items.Seq.lis.empty?)
+ assert_equal(1, channel.items.Seq.lis.size)
assert_nil(channel.image)
assert_nil(channel.textinput)
@@ -128,11 +133,16 @@ module RSS
@dc_elems.each do |var, value|
maker.image.__send__("dc_#{var}=", value)
end
+
+ setup_dummy_item(maker)
end
new_rss = RSS::Maker.make("1.0") do |maker|
rss.channel.setup_maker(maker)
rss.image.setup_maker(maker)
+ rss.items.each do |item|
+ item.setup_maker(maker)
+ end
end
image = new_rss.image
@@ -164,11 +174,16 @@ module RSS
@dc_elems.each do |var, value|
maker.textinput.__send__("dc_#{var}=", value)
end
+
+ setup_dummy_item(maker)
end
new_rss = RSS::Maker.make("1.0") do |maker|
rss.channel.setup_maker(maker)
rss.textinput.setup_maker(maker)
+ rss.items.each do |item|
+ item.setup_maker(maker)
+ end
end
textinput = new_rss.textinput
@@ -195,23 +210,25 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
-
- @dc_elems.each do |var, value|
- item.__send__("dc_#{var}=", value)
- end
-
- @content_elems.each do |var, value|
- item.__send__("content_#{var}=", value)
- end
-
- item.trackback_ping = @trackback_elems[:ping]
- @trackback_elems[:about].each do |value|
- new_about = item.trackback_abouts.new_about
- new_about.value = value
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+
+ @content_elems.each do |var, value|
+ item.__send__("content_#{var}=", value)
+ end
+
+ item.trackback_ping = @trackback_elems[:ping]
+ @trackback_elems[:about].each do |value|
+ item.trackback_abouts.new_about do |new_about|
+ new_about.value = value
+ end
+ end
end
end
end
@@ -321,15 +338,17 @@ module RSS
maker.encoding = encoding
maker.standalone = standalone
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
- xss.type = type
- xss.title = title
- xss.media = media
- xss.charset = charset
- xss.alternate = alternate
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
setup_dummy_channel(maker)
+ setup_dummy_item(maker)
end
new_rss = RSS::Maker.make("1.0") do |maker|
@@ -384,14 +403,15 @@ module RSS
maker.encoding = encoding
maker.standalone = standalone
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
- xss.type = type
- xss.title = title
- xss.media = media
- xss.charset = charset
- xss.alternate = alternate
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
maker.channel.about = channel_about
maker.channel.title = channel_title
maker.channel.link = channel_link
@@ -418,23 +438,25 @@ module RSS
end
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{item_title}#{i}"
- item.link = "#{item_link}#{i}"
- item.description = "#{item_description}#{i}"
-
- @dc_elems.each do |var, value|
- item.__send__("dc_#{var}=", value)
- end
-
- @content_elems.each do |var, value|
- item.__send__("content_#{var}=", value)
- end
-
- item.trackback_ping = @trackback_elems[:ping]
- @trackback_elems[:about].each do |value|
- new_about = item.trackback_abouts.new_about
- new_about.value = value
+ maker.items.new_item do |item|
+ item.title = "#{item_title}#{i}"
+ item.link = "#{item_link}#{i}"
+ item.description = "#{item_description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+
+ @content_elems.each do |var, value|
+ item.__send__("content_#{var}=", value)
+ end
+
+ item.trackback_ping = @trackback_elems[:ping]
+ @trackback_elems[:about].each do |value|
+ item.trackback_abouts.new_about do |new_about|
+ new_about.value = value
+ end
+ end
end
end
diff --git a/test/rss/test_setup_maker_2.0.rb b/test/rss/test_setup_maker_2.0.rb
index a35096cf167..8fb727de8d5 100644
--- a/test/rss/test_setup_maker_2.0.rb
+++ b/test/rss/test_setup_maker_2.0.rb
@@ -46,18 +46,21 @@ module RSS
maker.channel.lastBuildDate = lastBuildDate
skipDays.each do |day|
- new_day = maker.channel.skipDays.new_day
- new_day.content = day
+ maker.channel.skipDays.new_day do |new_day|
+ new_day.content = day
+ end
end
skipHours.each do |hour|
- new_hour = maker.channel.skipHours.new_hour
- new_hour.content = hour
+ maker.channel.skipHours.new_hour do |new_hour|
+ new_hour.content = hour
+ end
end
categories.each do |category|
- new_category = maker.channel.categories.new_category
- new_category.content = category
+ maker.channel.categories.new_category do |new_category|
+ new_category.content = category
+ end
end
maker.channel.generator = generator
@@ -189,27 +192,28 @@ module RSS
setup_dummy_channel(maker)
item_size.times do |i|
- item = maker.items.new_item
- item.title = "#{title}#{i}"
- item.link = "#{link}#{i}"
- item.description = "#{description}#{i}"
- item.author = "#{author}#{i}"
- item.comments = "#{comments}#{i}"
- item.date = pubDate
-
- item.guid.isPermaLink = guid_isPermaLink
- item.guid.content = guid_content
-
- item.enclosure.url = enclosure_url
- item.enclosure.length = enclosure_length
- item.enclosure.type = enclosure_type
-
- item.source.url = source_url
- item.source.content = source_content
-
- category = item.categories.new_category
- category.domain = category_domain
- category.content = category_content
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.author = "#{author}#{i}"
+ item.comments = "#{comments}#{i}"
+ item.date = pubDate
+
+ item.guid.isPermaLink = guid_isPermaLink
+ item.guid.content = guid_content
+
+ item.enclosure.url = enclosure_url
+ item.enclosure.length = enclosure_length
+ item.enclosure.type = enclosure_type
+
+ item.source.url = source_url
+ item.source.content = source_content
+
+ category = item.categories.new_category
+ category.domain = category_domain
+ category.content = category_content
+ end
end
end
@@ -270,14 +274,15 @@ module RSS
maker.encoding = encoding
maker.standalone = standalone
- xss = maker.xml_stylesheets.new_xml_stylesheet
- xss.href = href
- xss.type = type
- xss.title = title
- xss.media = media
- xss.charset = charset
- xss.alternate = alternate
-
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
setup_dummy_channel(maker)
end
diff --git a/test/rss/test_setup_maker_atom_entry.rb b/test/rss/test_setup_maker_atom_entry.rb
new file mode 100644
index 00000000000..6f3df65f3ff
--- /dev/null
+++ b/test/rss/test_setup_maker_atom_entry.rb
@@ -0,0 +1,409 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMakerAtomEntry < TestCase
+ def setup
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @dc_elems = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael@oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly &amp; Associates, Inc.",
+ :date => t,
+ }
+ end
+
+ def test_setup_maker_entry(with_dc=true)
+ authors = [
+ {
+ :name => "Bob",
+ :uri => "http://example.com/~bob/",
+ :email => "bob@example.com",
+ },
+ {
+ :name => "Alice",
+ :uri => "http://example.com/~alice/",
+ :email => "alice@example.com",
+ },
+ ]
+ categories = [
+ {
+ :term => "music",
+ :label => "Music",
+ },
+ {
+ :term => "book",
+ :scheme => "http://example.com/category/book/",
+ :label => "Book",
+ },
+ ]
+ contributors = [
+ {
+ :name => "Chris",
+ :email => "chris@example.com",
+ },
+ {
+ :name => "Eva",
+ :uri => "http://example.com/~eva/",
+ },
+ ]
+ id = "urn:uuid:8b105336-7e20-45fc-bb78-37fb3e1db25a"
+ link = "http://hoge.com"
+ published = Time.now - 60 * 3600
+ rights = "Copyrights (c) 2007 Alice and Bob"
+ description = "fugafugafugafuga"
+ title = "fugafuga"
+ updated = Time.now
+
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ maker.items.new_item do |item|
+ authors.each do |author_info|
+ item.authors.new_author do |author|
+ author_info.each do |key, value|
+ author.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ categories.each do |category_info|
+ item.categories.new_category do |category|
+ category_info.each do |key, value|
+ category.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ contributors.each do |contributor_info|
+ item.contributors.new_contributor do |contributor|
+ contributor_info.each do |key, value|
+ contributor.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ item.id = id
+ item.link = link
+ item.published = published
+ item.rights = rights
+ item.description = description
+ item.title = title
+ item.updated = updated
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ item.new_dc_date(value)
+ else
+ item.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+ end
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.setup_maker(maker)
+ end
+ assert_not_nil(new_feed)
+
+ new_authors = new_feed.authors.collect do |author|
+ {
+ :name => author.name.content,
+ :uri => author.uri.content,
+ :email => author.email.content,
+ }
+ end
+ assert_equal(authors, new_authors)
+
+ new_categories = new_feed.categories.collect do |category|
+ {
+ :term => category.term,
+ :scheme => category.scheme,
+ :label => category.label,
+ }.reject {|key, value| value.nil?}
+ end
+ assert_equal(categories, new_categories)
+
+ new_contributors = new_feed.contributors.collect do |contributor|
+ info = {}
+ info[:name] = contributor.name.content
+ info[:uri] = contributor.uri.content if contributor.uri
+ info[:email] = contributor.email.content if contributor.email
+ info
+ end
+ assert_equal(contributors, new_contributors)
+
+ assert_equal(id, new_feed.id.content)
+ assert_equal(link, new_feed.link.href)
+ assert_equal(published, new_feed.published.content)
+ assert_equal(rights, new_feed.rights.content)
+ assert_equal(description, new_feed.summary.content)
+ assert_equal(title, new_feed.title.content)
+ assert_equal(updated, new_feed.updated.content)
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ assert_equal([updated, value],
+ new_feed.dc_dates.collect {|date| date.value})
+ else
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+ end
+ end
+
+ assert_equal(1, new_feed.items.size)
+ end
+
+ def test_setup_maker_entry_without_dc
+ test_setup_maker_entry(false)
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ updated = Time.now
+
+ item_size = 5
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.updated = updated + i * 60
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+
+ feed.items.clear
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(1, new_feed.items.size)
+ new_feed.items[0..1].each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title.content)
+ assert_equal("#{link}#{i}", item.link.href)
+ assert_equal("#{description}#{i}", item.summary.content)
+ assert_equal(updated + i * 60, item.updated.content)
+ end
+ end
+
+ def test_setup_maker_items_sort
+ title = "TITLE"
+ link = "http://hoge.com/"
+ summary = "text hoge fuga"
+ updated = Time.now
+
+ feed_size = 5
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = false
+ end
+ assert_equal(1, feed.items.size)
+
+ assert_equal("#{title}0", feed.title.content)
+ assert_equal("#{link}0", feed.link.href)
+ assert_equal("#{summary}0", feed.summary.content)
+
+
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(1, feed.items.size)
+
+ assert_equal("#{title}#{feed_size - 1}", feed.title.content)
+ assert_equal("#{link}#{feed_size - 1}", feed.link.href)
+ assert_equal("#{summary}#{feed_size - 1}", feed.summary.content)
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "entry"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+
+ def test_setup_maker_full
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ channel_about = "http://hoge.com"
+ channel_title = "fugafuga"
+ channel_link = "http://hoge.com"
+ channel_description = "fugafugafugafuga"
+ channel_author = "Bob"
+
+ image_url = "http://hoge.com/hoge.png"
+
+ item_title = "TITLE"
+ item_link = "http://hoge.com/"
+ item_description = "text hoge fuga"
+
+ entry_size = 5
+ feed = RSS::Maker.make("atom:entry") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ maker.channel.about = channel_about
+ maker.channel.title = channel_title
+ maker.channel.link = channel_link
+ maker.channel.description = channel_description
+ maker.channel.author = channel_author
+ @dc_elems.each do |var, value|
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+
+ maker.image.url = image_url
+
+ entry_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{item_title}#{i}"
+ item.link = "#{item_link}#{i}"
+ item.description = "#{item_description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom:entry") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "entry"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+
+ assert_equal("#{item_title}0", new_feed.title.content)
+ assert_equal("#{item_link}0", new_feed.link.href)
+ assert_equal("#{item_description}0", new_feed.summary.content)
+ @dc_elems.each do |var, value|
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+ assert_equal(1, new_feed.items.size)
+ end
+ end
+end
diff --git a/test/rss/test_setup_maker_atom_feed.rb b/test/rss/test_setup_maker_atom_feed.rb
new file mode 100644
index 00000000000..0caed6cec8f
--- /dev/null
+++ b/test/rss/test_setup_maker_atom_feed.rb
@@ -0,0 +1,443 @@
+require "rss-testcase"
+
+require "rss/maker"
+
+module RSS
+ class TestSetupMakerAtomFeed < TestCase
+ def setup
+ t = Time.iso8601("2000-01-01T12:00:05+00:00")
+ class << t
+ alias_method(:to_s, :iso8601)
+ end
+
+ @dc_elems = {
+ :title => "hoge",
+ :description =>
+ " XML is placing increasingly heavy loads on
+ the existing technical infrastructure of the Internet.",
+ :creator => "Rael Dornfest (mailto:rael@oreilly.com)",
+ :subject => "XML",
+ :publisher => "The O'Reilly Network",
+ :contributor => "hogehoge",
+ :type => "fugafuga",
+ :format => "hohoho",
+ :identifier => "fufufu",
+ :source => "barbar",
+ :language => "ja",
+ :relation => "cococo",
+ :rights => "Copyright (c) 2000 O'Reilly &amp; Associates, Inc.",
+ :date => t,
+ }
+ end
+
+ def test_setup_maker_feed(with_dc=true)
+ authors = [
+ {
+ :name => "Bob",
+ :uri => "http://example.com/~bob/",
+ :email => "bob@example.com",
+ },
+ {
+ :name => "Alice",
+ :uri => "http://example.com/~alice/",
+ :email => "alice@example.com",
+ },
+ ]
+ categories = [
+ {
+ :term => "music",
+ :label => "Music",
+ },
+ {
+ :term => "book",
+ :scheme => "http://example.com/category/book/",
+ :label => "Book",
+ },
+ ]
+ contributors = [
+ {
+ :name => "Chris",
+ :email => "chris@example.com",
+ },
+ {
+ :name => "Eva",
+ :uri => "http://example.com/~eva/",
+ },
+ ]
+ generator = {
+ :uri => "http://example.com/generator/",
+ :version => "0.0.1",
+ :content => "Feed Generator",
+ }
+ icon = "http://example.com/icon.png"
+ about = "http://hoge.com"
+ title = "fugafuga"
+ link = "http://hoge.com"
+ logo = "http://example.com/logo.png"
+ rights = "Copyrights (c) 2007 Alice and Bob"
+ description = "fugafugafugafuga"
+ updated = Time.now
+
+ feed = RSS::Maker.make("atom") do |maker|
+ authors.each do |author_info|
+ maker.channel.authors.new_author do |author|
+ author_info.each do |key, value|
+ author.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ categories.each do |category_info|
+ maker.channel.categories.new_category do |category|
+ category_info.each do |key, value|
+ category.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ contributors.each do |contributor_info|
+ maker.channel.contributors.new_contributor do |contributor|
+ contributor_info.each do |key, value|
+ contributor.__send__("#{key}=", value)
+ end
+ end
+ end
+
+ generator.each do |key, value|
+ maker.channel.generator.__send__("#{key}=", value)
+ end
+
+ maker.channel.icon = icon
+
+ maker.channel.about = about
+ maker.channel.link = link
+ maker.channel.logo = logo
+ maker.channel.rights = rights
+ maker.channel.title = title
+ maker.channel.description = description
+ maker.channel.updated = updated
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ maker.channel.new_dc_date(value)
+ else
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+
+ setup_dummy_item_atom(maker)
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.setup_maker(maker)
+ end
+ assert_not_nil(new_feed)
+
+ new_authors = new_feed.authors.collect do |author|
+ {
+ :name => author.name.content,
+ :uri => author.uri.content,
+ :email => author.email.content,
+ }
+ end
+ assert_equal(authors, new_authors)
+
+ new_categories = new_feed.categories.collect do |category|
+ {
+ :term => category.term,
+ :scheme => category.scheme,
+ :label => category.label,
+ }.reject {|key, value| value.nil?}
+ end
+ assert_equal(categories, new_categories)
+
+ new_contributors = new_feed.contributors.collect do |contributor|
+ info = {}
+ info[:name] = contributor.name.content
+ info[:uri] = contributor.uri.content if contributor.uri
+ info[:email] = contributor.email.content if contributor.email
+ info
+ end
+ assert_equal(contributors, new_contributors)
+
+ new_generator = {
+ :uri => new_feed.generator.uri,
+ :version => new_feed.generator.version,
+ :content => new_feed.generator.content,
+ }
+ assert_equal(generator, new_generator)
+
+ assert_equal(icon, new_feed.icon.content)
+ assert_equal(about, new_feed.id.content)
+ assert_equal(link, new_feed.link.href)
+ assert_equal(logo, new_feed.logo.content)
+ assert_equal(rights, new_feed.rights.content)
+ assert_equal(description, new_feed.subtitle.content)
+ assert_equal(title, new_feed.title.content)
+ assert_equal(updated, new_feed.updated.content)
+
+ if with_dc
+ @dc_elems.each do |var, value|
+ if var == :date
+ assert_equal([updated, value],
+ new_feed.dc_dates.collect {|date| date.value})
+ else
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+ end
+ end
+
+ assert_equal(1, new_feed.items.size)
+ end
+
+ def test_setup_maker_feed_without_dc
+ test_setup_maker_feed(false)
+ end
+
+ def test_setup_maker_items(for_backward_compatibility=false)
+ title = "TITLE"
+ link = "http://hoge.com/"
+ description = "text hoge fuga"
+ updated = Time.now
+
+ item_size = 5
+ feed = RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ item_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{title}#{i}"
+ item.link = "#{link}#{i}"
+ item.description = "#{description}#{i}"
+ item.updated = updated + i * 60
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.items.each do |item|
+ if for_backward_compatibility
+ item.setup_maker(maker)
+ else
+ item.setup_maker(maker.items)
+ end
+ end
+
+ feed.items.clear
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(item_size, new_feed.items.size)
+ new_feed.items.each_with_index do |item, i|
+ assert_equal("#{title}#{i}", item.title.content)
+ assert_equal("#{link}#{i}", item.link.href)
+ assert_equal("#{description}#{i}", item.summary.content)
+ assert_equal(updated + i * 60, item.updated.content)
+ end
+ end
+
+ def test_setup_maker_items_sort
+ title = "TITLE"
+ link = "http://hoge.com/"
+ summary = "text hoge fuga"
+ updated = Time.now
+
+ feed_size = 5
+ feed = RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Feed::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = false
+ end
+ assert_equal(feed_size, feed.entries.size)
+ feed.entries.each_with_index do |entry, i|
+ assert_equal("#{title}#{i}", entry.title.content)
+ assert_equal("#{link}#{i}", entry.link.href)
+ assert_equal("#{summary}#{i}", entry.summary.content)
+ end
+
+
+ feed = RSS::Maker.make("atom") do |maker|
+ setup_dummy_channel_atom(maker)
+
+ feed_size.times do |i|
+ entry_class = RSS::Atom::Feed::Entry
+ entry = entry_class.new
+ entry.title = entry_class::Title.new(:content => "#{title}#{i}")
+ entry.links << entry_class::Link.new(:href => "#{link}#{i}")
+ entry.summary = entry_class::Summary.new(:content => "#{summary}#{i}")
+ entry.updated = entry_class::Updated.new(:content => updated + i * 60)
+ entry.setup_maker(maker.items)
+ end
+ maker.items.do_sort = true
+ end
+ assert_equal(feed_size, feed.entries.size)
+ feed.entries.reverse.each_with_index do |entry, i|
+ assert_equal("#{title}#{i}", entry.title.content)
+ assert_equal("#{link}#{i}", entry.link.href)
+ assert_equal("#{summary}#{i}", entry.summary.content)
+ end
+ end
+
+ def test_setup_maker_items_backward_compatibility
+ test_setup_maker_items(true)
+ end
+
+ def test_setup_maker
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ feed = RSS::Maker.make("atom") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ setup_dummy_channel_atom(maker)
+ setup_dummy_item_atom(maker)
+ end
+ assert_not_nil(feed)
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "feed"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+ end
+
+ def test_setup_maker_full
+ encoding = "EUC-JP"
+ standalone = true
+
+ href = 'a.xsl'
+ type = 'text/xsl'
+ title = 'sample'
+ media = 'printer'
+ charset = 'UTF-8'
+ alternate = 'yes'
+
+ channel_about = "http://hoge.com"
+ channel_title = "fugafuga"
+ channel_link = "http://hoge.com"
+ channel_description = "fugafugafugafuga"
+ channel_author = "Bob"
+
+ image_url = "http://hoge.com/hoge.png"
+
+ item_title = "TITLE"
+ item_link = "http://hoge.com/"
+ item_description = "text hoge fuga"
+
+ entry_size = 5
+ feed = RSS::Maker.make("atom") do |maker|
+ maker.encoding = encoding
+ maker.standalone = standalone
+
+ maker.xml_stylesheets.new_xml_stylesheet do |xss|
+ xss.href = href
+ xss.type = type
+ xss.title = title
+ xss.media = media
+ xss.charset = charset
+ xss.alternate = alternate
+ end
+
+ maker.channel.about = channel_about
+ maker.channel.title = channel_title
+ maker.channel.link = channel_link
+ maker.channel.description = channel_description
+ maker.channel.author = channel_author
+ @dc_elems.each do |var, value|
+ maker.channel.__send__("dc_#{var}=", value)
+ end
+
+ maker.image.url = image_url
+
+ entry_size.times do |i|
+ maker.items.new_item do |item|
+ item.title = "#{item_title}#{i}"
+ item.link = "#{item_link}#{i}"
+ item.description = "#{item_description}#{i}"
+
+ @dc_elems.each do |var, value|
+ item.__send__("dc_#{var}=", value)
+ end
+ end
+ end
+ end
+
+ new_feed = RSS::Maker.make("atom") do |maker|
+ feed.setup_maker(maker)
+ end
+
+ assert_equal(["atom", "1.0", "feed"], new_feed.feed_info)
+ assert_equal(encoding, new_feed.encoding)
+ assert_equal(standalone, new_feed.standalone)
+
+ xss = new_feed.xml_stylesheets.first
+ assert_equal(1, new_feed.xml_stylesheets.size)
+ assert_equal(href, xss.href)
+ assert_equal(type, xss.type)
+ assert_equal(title, xss.title)
+ assert_equal(media, xss.media)
+ assert_equal(charset, xss.charset)
+ assert_equal(alternate, xss.alternate)
+
+ assert_equal(channel_title, new_feed.title.content)
+ assert_equal(channel_link, new_feed.link.href)
+ assert_equal(channel_description, new_feed.subtitle.content)
+ assert_equal(channel_author, new_feed.author.name.content)
+ assert_equal(image_url, new_feed.logo.content)
+ @dc_elems.each do |var, value|
+ assert_equal(value, new_feed.__send__("dc_#{var}"))
+ end
+
+ assert_equal(entry_size, new_feed.entries.size)
+ new_feed.entries.each_with_index do |entry, i|
+ assert_equal("#{item_title}#{i}", entry.title.content)
+ assert_equal("#{item_link}#{i}", entry.link.href)
+ assert_equal("#{item_description}#{i}", entry.summary.content)
+
+ @dc_elems.each do |var, value|
+ assert_equal(value, entry.__send__("dc_#{var}"))
+ end
+ end
+ end
+ end
+end
diff --git a/test/rss/test_syndication.rb b/test/rss/test_syndication.rb
index 894a7855ac6..6aaaa43382b 100644
--- a/test/rss/test_syndication.rb
+++ b/test/rss/test_syndication.rb
@@ -93,7 +93,7 @@ EOR
%w(-2 0.3 -0.4).each do |x|
@parents.each do |parent|
- assert_not_available_value("updateBase", x) do
+ assert_not_available_value("sy:updateBase", x) do
@rss.__send__(parent).sy_updateBase = x
end
end
@@ -107,7 +107,7 @@ EOR
excepted = "<#{@prefix}:#{name}>#{value}</#{@prefix}:#{name}>"
@parents.each do |parent|
assert_equal(excepted,
- @rss.__send__(parent).funcall("sy_#{name}_element"))
+ @rss.__send__(parent).__send!("sy_#{name}_element"))
end
end
@@ -120,8 +120,6 @@ EOR
end
end
end
-
end
-
end
end
diff --git a/test/rss/test_taxonomy.rb b/test/rss/test_taxonomy.rb
index b4950c0004e..42746af490d 100644
--- a/test/rss/test_taxonomy.rb
+++ b/test/rss/test_taxonomy.rb
@@ -140,7 +140,7 @@ EOR
def test_to_s
@topics_parents.each do |parent|
meth = "taxo_topics_element"
- assert_equal(@topics_node, @rss.__send__(parent).funcall(meth))
+ assert_equal(@topics_node, @rss.__send__(parent).__send!(meth))
end
@topic_nodes.each_with_index do |node, i|
diff --git a/test/rss/test_trackback.rb b/test/rss/test_trackback.rb
index 5209a8c06b3..db4f291317f 100644
--- a/test/rss/test_trackback.rb
+++ b/test/rss/test_trackback.rb
@@ -114,7 +114,7 @@ EOR
@parents.each do |parent|
meth = "#{RSS::TRACKBACK_PREFIX}_#{name}_element"
meth << "s" if name == :about
- assert_equal(excepted, @rss.__send__(parent).funcall(meth))
+ assert_equal(excepted, @rss.__send__(parent).__send!(meth))
end
end
diff --git a/test/rss/test_version.rb b/test/rss/test_version.rb
index 237f364b203..2c7d2e0f7a3 100644
--- a/test/rss/test_version.rb
+++ b/test/rss/test_version.rb
@@ -3,7 +3,7 @@ require "rss-testcase"
module RSS
class TestVersion < TestCase
def test_version
- assert_equal("0.1.6", ::RSS::VERSION)
+ assert_equal("0.1.7", ::RSS::VERSION)
end
end
end
diff --git a/test/rss/test_xml-stylesheet.rb b/test/rss/test_xml-stylesheet.rb
index c88a858f56d..b946af12944 100644
--- a/test/rss/test_xml-stylesheet.rb
+++ b/test/rss/test_xml-stylesheet.rb
@@ -14,7 +14,7 @@ module RSS
{:media => "print", :title => "FOO"},
{:charset => "UTF-8", :alternate => "yes"},
].each do |attrs|
- assert_xml_stylesheet_attrs(attrs, XMLStyleSheet.new(*attrs))
+ assert_xml_stylesheet_attrs(attrs, XMLStyleSheet.new(attrs))
end
end
@@ -35,8 +35,8 @@ module RSS
:media => "printer", :charset => "UTF-8",
:alternate => "yes"},
].each do |attrs|
- target, contents = parse_pi(XMLStyleSheet.new(*attrs).to_s)
- assert_xml_stylesheet(target, attrs, XMLStyleSheet.new(*contents))
+ target, contents = parse_pi(XMLStyleSheet.new(attrs).to_s)
+ assert_xml_stylesheet(target, attrs, XMLStyleSheet.new(contents))
end
end
diff --git a/version.h b/version.h
index d8a16e16a8e..09a489f5ac2 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-03-16"
+#define RUBY_RELEASE_DATE "2007-03-17"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20070316
+#define RUBY_RELEASE_CODE 20070317
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 3
-#define RUBY_RELEASE_DAY 16
+#define RUBY_RELEASE_DAY 17
RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[];