mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/rss, sample/rss, test/rss:
- 0.1.7 -> 0.1.8. - supported <itunes:XXX>. - reverted backward incompatibility API changes introduced 0.1.7. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
43009063c7
commit
71976790ec
43 changed files with 3055 additions and 1457 deletions
|
@ -1,3 +1,10 @@
|
|||
Sun Aug 5 11:51:39 2007 Kouhei Sutou <kou@cozmixng.org>
|
||||
|
||||
* lib/rss, sample/rss, test/rss:
|
||||
- 0.1.7 -> 0.1.8.
|
||||
- supported <itunes:XXX>.
|
||||
- reverted backward incompatibility API changes introduced 0.1.7.
|
||||
|
||||
Sun Aug 5 04:56:25 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* io.c (pipe_open_v, pipe_open_s): separate array and string
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2003-2006 Kouhei Sutou. You can redistribute it and/or
|
||||
# Copyright (c) 2003-2007 Kouhei Sutou. You can redistribute it and/or
|
||||
# modify it under the same terms as Ruby.
|
||||
#
|
||||
# Author:: Kouhei Sutou <kou@cozmixng.org>
|
||||
|
@ -10,6 +10,7 @@ require 'rss/atom'
|
|||
require 'rss/content'
|
||||
require 'rss/dublincore'
|
||||
require 'rss/image'
|
||||
require 'rss/itunes'
|
||||
require 'rss/syndication'
|
||||
require 'rss/taxonomy'
|
||||
require 'rss/trackback'
|
||||
|
|
|
@ -131,7 +131,7 @@ module RSS
|
|||
|
||||
private
|
||||
def maker_target(target)
|
||||
target.__send__(self.class.name.split(/::/).last.downcase)
|
||||
target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}
|
||||
end
|
||||
|
||||
def setup_maker_attributes(target)
|
||||
|
@ -239,6 +239,11 @@ module RSS
|
|||
|
||||
alias_method :items, :entries
|
||||
|
||||
def have_author?
|
||||
authors.any? {|author| !author.to_s.empty?} or
|
||||
entries.any? {|entry| entry.have_author?(false)}
|
||||
end
|
||||
|
||||
private
|
||||
def atom_validate(ignore_unknown_element, tags, uri)
|
||||
unless have_author?
|
||||
|
@ -251,11 +256,6 @@ module RSS
|
|||
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
|
||||
|
@ -315,9 +315,10 @@ module RSS
|
|||
|
||||
private
|
||||
def setup_maker_attributes(target)
|
||||
generator = target.generator
|
||||
generator.uri = uri if uri
|
||||
generator.version = version if version
|
||||
target.generator do |generator|
|
||||
generator.uri = uri if uri
|
||||
generator.version = version if version
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -408,6 +409,12 @@ module RSS
|
|||
tag, URI, occurs, tag, *args)
|
||||
end
|
||||
|
||||
def have_author?(check_parent=true)
|
||||
authors.any? {|author| !author.to_s.empty?} or
|
||||
(check_parent and @parent and @parent.have_author?) or
|
||||
(source and source.have_author?)
|
||||
end
|
||||
|
||||
private
|
||||
def atom_validate(ignore_unknown_element, tags, uri)
|
||||
unless have_author?
|
||||
|
@ -420,12 +427,6 @@ module RSS
|
|||
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
|
||||
|
@ -606,7 +607,6 @@ module RSS
|
|||
tag, URI, occurs, tag, *args)
|
||||
end
|
||||
|
||||
private
|
||||
def have_author?
|
||||
!author.to_s.empty?
|
||||
end
|
||||
|
@ -674,6 +674,11 @@ module RSS
|
|||
super(maker)
|
||||
end
|
||||
|
||||
def have_author?
|
||||
authors.any? {|author| !author.to_s.empty?} or
|
||||
(source and source.have_author?)
|
||||
end
|
||||
|
||||
private
|
||||
def atom_validate(ignore_unknown_element, tags, uri)
|
||||
unless have_author?
|
||||
|
@ -686,11 +691,6 @@ module RSS
|
|||
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
|
||||
|
|
|
@ -142,8 +142,8 @@ module RSS
|
|||
end
|
||||
|
||||
AVAILABLE_SIZES = %w(small medium large)
|
||||
alias_method :_size=, :size=
|
||||
private :_size=
|
||||
alias_method :set_size, :size=
|
||||
private :set_size
|
||||
def size=(new_value)
|
||||
if @do_validate and !new_value.nil?
|
||||
new_value = new_value.strip
|
||||
|
@ -152,7 +152,7 @@ module RSS
|
|||
raise NotAvailableValueError.new(full_name, new_value, attr_name)
|
||||
end
|
||||
end
|
||||
__send!(:_size=, new_value)
|
||||
set_size(new_value)
|
||||
end
|
||||
|
||||
alias image_size= size=
|
||||
|
|
410
lib/rss/itunes.rb
Normal file
410
lib/rss/itunes.rb
Normal file
|
@ -0,0 +1,410 @@
|
|||
require 'rss/2.0'
|
||||
|
||||
module RSS
|
||||
ITUNES_PREFIX = 'itunes'
|
||||
ITUNES_URI = 'http://www.itunes.com/dtds/podcast-1.0.dtd'
|
||||
|
||||
Rss.install_ns(ITUNES_PREFIX, ITUNES_URI)
|
||||
|
||||
module ITunesModelUtils
|
||||
include Utils
|
||||
|
||||
def def_class_accessor(klass, name, type, *args)
|
||||
normalized_name = name.gsub(/-/, "_")
|
||||
full_name = "#{ITUNES_PREFIX}_#{normalized_name}"
|
||||
klass_name = "ITunes#{Utils.to_class_name(normalized_name)}"
|
||||
|
||||
case type
|
||||
when :element, :attribute
|
||||
klass::ELEMENTS << full_name
|
||||
def_element_class_accessor(klass, name, full_name, klass_name, *args)
|
||||
when :elements
|
||||
klass::ELEMENTS << full_name
|
||||
def_elements_class_accessor(klass, name, full_name, klass_name, *args)
|
||||
else
|
||||
klass.install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
|
||||
klass.install_text_element(normalized_name, ITUNES_URI, "?",
|
||||
full_name, type, name)
|
||||
end
|
||||
end
|
||||
|
||||
def def_element_class_accessor(klass, name, full_name, klass_name,
|
||||
recommended_attribute_name=nil)
|
||||
klass.install_have_child_element(name, ITUNES_PREFIX, "?", full_name)
|
||||
end
|
||||
|
||||
def def_elements_class_accessor(klass, name, full_name, klass_name,
|
||||
plural_name, recommended_attribute_name=nil)
|
||||
full_plural_name = "#{ITUNES_PREFIX}_#{plural_name}"
|
||||
klass.install_have_children_element(name, ITUNES_PREFIX, "*",
|
||||
full_name, full_plural_name)
|
||||
end
|
||||
end
|
||||
|
||||
module ITunesBaseModel
|
||||
extend ITunesModelUtils
|
||||
|
||||
ELEMENTS = []
|
||||
|
||||
ELEMENT_INFOS = [["author"],
|
||||
["block", :yes_other],
|
||||
["explicit", :yes_clean_other],
|
||||
["keywords", :csv],
|
||||
["subtitle"],
|
||||
["summary"]]
|
||||
end
|
||||
|
||||
module ITunesChannelModel
|
||||
extend BaseModel
|
||||
extend ITunesModelUtils
|
||||
include ITunesBaseModel
|
||||
|
||||
ELEMENTS = []
|
||||
|
||||
class << self
|
||||
def append_features(klass)
|
||||
super
|
||||
|
||||
return if klass.instance_of?(Module)
|
||||
ELEMENT_INFOS.each do |name, type, *additional_infos|
|
||||
def_class_accessor(klass, name, type, *additional_infos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ELEMENT_INFOS = [
|
||||
["category", :elements, "categories", "text"],
|
||||
["image", :attribute, "href"],
|
||||
["owner", :element],
|
||||
["new-feed-url"],
|
||||
] + ITunesBaseModel::ELEMENT_INFOS
|
||||
|
||||
class ITunesCategory < Element
|
||||
include RSS09
|
||||
|
||||
@tag_name = "category"
|
||||
|
||||
class << self
|
||||
def required_prefix
|
||||
ITUNES_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
ITUNES_URI
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
["text", "", true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
ITunesCategory = self
|
||||
install_have_children_element("category", ITUNES_URI, "*",
|
||||
"#{ITUNES_PREFIX}_category",
|
||||
"#{ITUNES_PREFIX}_categories")
|
||||
|
||||
def initialize(*args)
|
||||
if Utils.element_initialize_arguments?(args)
|
||||
super
|
||||
else
|
||||
super()
|
||||
self.text = args[0]
|
||||
end
|
||||
end
|
||||
|
||||
def full_name
|
||||
tag_name_with_prefix(ITUNES_PREFIX)
|
||||
end
|
||||
|
||||
private
|
||||
def maker_target(categories)
|
||||
if text or !itunes_categories.empty?
|
||||
categories.new_category
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def setup_maker_attributes(category)
|
||||
category.text = text if text
|
||||
end
|
||||
|
||||
def setup_maker_elements(category)
|
||||
super(category)
|
||||
itunes_categories.each do |sub_category|
|
||||
sub_category.setup_maker(category)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesImage < Element
|
||||
include RSS09
|
||||
|
||||
@tag_name = "image"
|
||||
|
||||
class << self
|
||||
def required_prefix
|
||||
ITUNES_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
ITUNES_URI
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
["href", "", true]
|
||||
].each do |name, uri, required|
|
||||
install_get_attribute(name, uri, required)
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
if Utils.element_initialize_arguments?(args)
|
||||
super
|
||||
else
|
||||
super()
|
||||
self.href = args[0]
|
||||
end
|
||||
end
|
||||
|
||||
def full_name
|
||||
tag_name_with_prefix(ITUNES_PREFIX)
|
||||
end
|
||||
|
||||
private
|
||||
def maker_target(target)
|
||||
if href
|
||||
target.itunes_image {|image| image}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def setup_maker_attributes(image)
|
||||
image.href = href
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesOwner < Element
|
||||
include RSS09
|
||||
|
||||
@tag_name = "owner"
|
||||
|
||||
class << self
|
||||
def required_prefix
|
||||
ITUNES_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
ITUNES_URI
|
||||
end
|
||||
end
|
||||
|
||||
install_must_call_validator(ITUNES_PREFIX, ITUNES_URI)
|
||||
[
|
||||
["name"],
|
||||
["email"],
|
||||
].each do |name,|
|
||||
ITunesBaseModel::ELEMENT_INFOS << name
|
||||
install_text_element(name, ITUNES_URI, nil, "#{ITUNES_PREFIX}_#{name}")
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
if Utils.element_initialize_arguments?(args)
|
||||
super
|
||||
else
|
||||
super()
|
||||
self.itunes_name = args[0]
|
||||
self.itunes_email = args[1]
|
||||
end
|
||||
end
|
||||
|
||||
def full_name
|
||||
tag_name_with_prefix(ITUNES_PREFIX)
|
||||
end
|
||||
|
||||
private
|
||||
def maker_target(target)
|
||||
target.itunes_owner
|
||||
end
|
||||
|
||||
def setup_maker_element(owner)
|
||||
super(owner)
|
||||
owner.itunes_name = itunes_name
|
||||
owner.itunes_email = itunes_email
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ITunesItemModel
|
||||
extend BaseModel
|
||||
extend ITunesModelUtils
|
||||
include ITunesBaseModel
|
||||
|
||||
class << self
|
||||
def append_features(klass)
|
||||
super
|
||||
|
||||
return if klass.instance_of?(Module)
|
||||
ELEMENT_INFOS.each do |name, type|
|
||||
def_class_accessor(klass, name, type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ELEMENT_INFOS = ITunesBaseModel::ELEMENT_INFOS +
|
||||
[["duration", :element, "content"]]
|
||||
|
||||
class ITunesDuration < Element
|
||||
include RSS09
|
||||
|
||||
@tag_name = "duration"
|
||||
|
||||
class << self
|
||||
def required_prefix
|
||||
ITUNES_PREFIX
|
||||
end
|
||||
|
||||
def required_uri
|
||||
ITUNES_URI
|
||||
end
|
||||
|
||||
def parse(duration, do_validate=true)
|
||||
if do_validate and /\A(?:
|
||||
\d?\d:[0-5]\d:[0-5]\d|
|
||||
[0-5]?\d:[0-5]\d
|
||||
)\z/x !~ duration
|
||||
raise ArgumentError,
|
||||
"must be one of HH:MM:SS, H:MM:SS, MM::SS, M:SS: " +
|
||||
duration.inspect
|
||||
end
|
||||
|
||||
components = duration.split(':')
|
||||
components[3..-1] = nil if components.size > 3
|
||||
|
||||
components.unshift("00") until components.size == 3
|
||||
|
||||
components.collect do |component|
|
||||
component.to_i
|
||||
end
|
||||
end
|
||||
|
||||
def construct(hour, minute, second)
|
||||
components = [minute, second]
|
||||
if components.include?(nil)
|
||||
nil
|
||||
else
|
||||
components.unshift(hour) if hour and hour > 0
|
||||
components.collect do |component|
|
||||
"%02d" % component
|
||||
end.join(":")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
content_setup
|
||||
alias_method(:value, :content)
|
||||
remove_method(:content=)
|
||||
|
||||
attr_reader :hour, :minute, :second
|
||||
def initialize(*args)
|
||||
if Utils.element_initialize_arguments?(args)
|
||||
super
|
||||
else
|
||||
super()
|
||||
args = args[0] if args.size == 1 and args[0].is_a?(Array)
|
||||
if args.size == 1
|
||||
self.content = args[0]
|
||||
elsif args.size > 3
|
||||
raise ArgumentError,
|
||||
"must be (do_validate, params), (content), " +
|
||||
"(minute, second), ([minute, second]), " +
|
||||
"(hour, minute, second) or ([hour, minute, second]): " +
|
||||
args.inspect
|
||||
else
|
||||
@second, @minute, @hour = args.reverse
|
||||
update_content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def content=(value)
|
||||
if value.nil?
|
||||
@content = nil
|
||||
elsif value.is_a?(self.class)
|
||||
self.content = value.content
|
||||
else
|
||||
begin
|
||||
@hour, @minute, @second = self.class.parse(value, @do_validate)
|
||||
rescue ArgumentError
|
||||
raise NotAvailableValueError.new(tag_name, value)
|
||||
end
|
||||
@content = value
|
||||
end
|
||||
end
|
||||
alias_method(:value=, :content=)
|
||||
|
||||
def hour=(hour)
|
||||
@hour = @do_validate ? Integer(hour) : hour.to_i
|
||||
update_content
|
||||
hour
|
||||
end
|
||||
|
||||
def minute=(minute)
|
||||
@minute = @do_validate ? Integer(minute) : minute.to_i
|
||||
update_content
|
||||
minute
|
||||
end
|
||||
|
||||
def second=(second)
|
||||
@second = @do_validate ? Integer(second) : second.to_i
|
||||
update_content
|
||||
second
|
||||
end
|
||||
|
||||
def full_name
|
||||
tag_name_with_prefix(ITUNES_PREFIX)
|
||||
end
|
||||
|
||||
private
|
||||
def update_content
|
||||
@content = self.class.construct(hour, minute, second)
|
||||
end
|
||||
|
||||
def maker_target(target)
|
||||
if @content
|
||||
target.itunes_duration {|duration| duration}
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def setup_maker_element(duration)
|
||||
super(duration)
|
||||
duration.content = @content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Rss
|
||||
class Channel
|
||||
include ITunesChannelModel
|
||||
class Item; include ITunesItemModel; end
|
||||
end
|
||||
end
|
||||
|
||||
element_infos =
|
||||
ITunesChannelModel::ELEMENT_INFOS + ITunesItemModel::ELEMENT_INFOS
|
||||
element_infos.each do |name, type|
|
||||
class_name = Utils.to_class_name(name)
|
||||
case type
|
||||
when :element, :elements, :attribute
|
||||
BaseListener.install_class_name(ITUNES_URI, name, "ITunes#{class_name}")
|
||||
else
|
||||
accessor_base = "#{ITUNES_PREFIX}_#{name.gsub(/-/, '_')}"
|
||||
BaseListener.install_get_text_element(ITUNES_URI, name, accessor_base)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -40,3 +40,4 @@ require "rss/maker/syndication"
|
|||
require "rss/maker/taxonomy"
|
||||
require "rss/maker/trackback"
|
||||
require "rss/maker/image"
|
||||
require "rss/maker/itunes"
|
||||
|
|
|
@ -22,7 +22,6 @@ module RSS
|
|||
end
|
||||
|
||||
class Channel < ChannelBase
|
||||
|
||||
def to_feed(rss)
|
||||
channel = Rss::Channel.new
|
||||
set = setup_values(channel)
|
||||
|
@ -63,8 +62,8 @@ module RSS
|
|||
|
||||
def not_set_required_variables
|
||||
vars = super
|
||||
vars << "description" unless description.have_required_values?
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "description" unless description {|d| d.have_required_values?}
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
|
||||
|
@ -259,7 +258,7 @@ module RSS
|
|||
def to_feed(rss)
|
||||
item = Rss::Channel::Item.new
|
||||
set = setup_values(item)
|
||||
if set or title.have_required_values?
|
||||
if set or title {|t| t.have_required_values?}
|
||||
rss.items << item
|
||||
set_parent(item, rss.channel)
|
||||
setup_other_elements(rss, item)
|
||||
|
@ -268,10 +267,6 @@ module RSS
|
|||
end
|
||||
end
|
||||
|
||||
def have_required_values?
|
||||
super and title.have_required_values?
|
||||
end
|
||||
|
||||
private
|
||||
def required_variable_names
|
||||
%w(link)
|
||||
|
@ -279,7 +274,7 @@ module RSS
|
|||
|
||||
def not_set_required_variables
|
||||
vars = super
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
|
||||
|
|
|
@ -83,8 +83,8 @@ module RSS
|
|||
|
||||
def not_set_required_variables
|
||||
vars = super
|
||||
vars << "description" unless description.have_required_values?
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "description" unless description {|d| d.have_required_values?}
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
|
||||
|
@ -256,7 +256,7 @@ module RSS
|
|||
def not_set_required_variables
|
||||
set_default_values do
|
||||
vars = super
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ module RSS
|
|||
|
||||
private
|
||||
def required_variable_names
|
||||
%w(title link description)
|
||||
%w(link)
|
||||
end
|
||||
|
||||
class SkipDays < RSS09::Channel::SkipDays
|
||||
|
@ -90,13 +90,7 @@ module RSS
|
|||
end
|
||||
|
||||
class Items < RSS09::Items
|
||||
|
||||
class Item < RSS09::Items::Item
|
||||
|
||||
def have_required_values?
|
||||
@title or @description
|
||||
end
|
||||
|
||||
private
|
||||
def required_variable_names
|
||||
%w(title description)
|
||||
|
|
|
@ -147,11 +147,11 @@ EOC
|
|||
def to_feed(feed, current)
|
||||
logo = current.class::Logo.new
|
||||
class << logo
|
||||
alias uri= content=
|
||||
alias_method(:uri=, :content=)
|
||||
end
|
||||
set = setup_values(logo)
|
||||
class << logo
|
||||
undef uri=
|
||||
remove_method(:uri=)
|
||||
end
|
||||
if set
|
||||
current.logo = logo
|
||||
|
|
|
@ -4,85 +4,155 @@ require 'rss/rss'
|
|||
|
||||
module RSS
|
||||
module Maker
|
||||
module Base
|
||||
def self.append_features(klass)
|
||||
super
|
||||
class Base
|
||||
extend Utils::InheritedReader
|
||||
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__)
|
||||
OTHER_ELEMENTS = []
|
||||
NEED_INITIALIZE_VARIABLES = []
|
||||
|
||||
OTHER_ELEMENTS = []
|
||||
NEED_INITIALIZE_VARIABLES = []
|
||||
class << self
|
||||
def other_elements
|
||||
inherited_array_reader("OTHER_ELEMENTS")
|
||||
end
|
||||
def need_initialize_variables
|
||||
inherited_array_reader("NEED_INITIALIZE_VARIABLES")
|
||||
end
|
||||
|
||||
def self.inherited(subclass)
|
||||
def inherited_base
|
||||
::RSS::Maker::Base
|
||||
end
|
||||
|
||||
def inherited(subclass)
|
||||
subclass.const_set("OTHER_ELEMENTS", [])
|
||||
subclass.const_set("NEED_INITIALIZE_VARIABLES", [])
|
||||
|
||||
subclass.module_eval(<<-EOEOC, __FILE__, __LINE__)
|
||||
def self.other_elements
|
||||
OTHER_ELEMENTS + super
|
||||
end
|
||||
|
||||
def self.need_initialize_variables
|
||||
NEED_INITIALIZE_VARIABLES + super
|
||||
end
|
||||
EOEOC
|
||||
end
|
||||
|
||||
def self.add_other_element(variable_name)
|
||||
OTHER_ELEMENTS << variable_name
|
||||
def add_other_element(variable_name)
|
||||
self::OTHER_ELEMENTS << variable_name
|
||||
end
|
||||
|
||||
def self.other_elements
|
||||
OTHER_ELEMENTS
|
||||
def add_need_initialize_variable(variable_name, init_value="nil")
|
||||
self::NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
|
||||
end
|
||||
|
||||
def self.add_need_initialize_variable(variable_name, init_value="nil")
|
||||
NEED_INITIALIZE_VARIABLES << [variable_name, init_value]
|
||||
end
|
||||
|
||||
def self.need_initialize_variables
|
||||
NEED_INITIALIZE_VARIABLES
|
||||
end
|
||||
|
||||
def self.def_array_element(name, plural=nil, klass=nil)
|
||||
def def_array_element(name, plural=nil, klass_name=nil)
|
||||
include Enumerable
|
||||
extend Forwardable
|
||||
|
||||
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)
|
||||
plural ||= "#{name}s"
|
||||
klass_name ||= 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}
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def new_#{name}
|
||||
#{name} = self.class::#{klass_name}.new(@maker)
|
||||
@#{plural} << #{name}
|
||||
if block_given?
|
||||
yield \#{name}
|
||||
yield #{name}
|
||||
else
|
||||
\#{name}
|
||||
#{name}
|
||||
end
|
||||
end
|
||||
alias new_child new_\#{name}
|
||||
alias new_child new_#{name}
|
||||
|
||||
def to_feed(*args)
|
||||
@\#{plural}.each do |\#{name}|
|
||||
\#{name}.to_feed(*args)
|
||||
@#{plural}.each do |#{name}|
|
||||
#{name}.to_feed(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def replace(elements)
|
||||
@\#{plural}.replace(elements.to_a)
|
||||
@#{plural}.replace(elements.to_a)
|
||||
end
|
||||
EOM
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_classed_element_without_accessor(name, class_name=nil)
|
||||
class_name ||= Utils.to_class_name(name)
|
||||
add_other_element(name)
|
||||
add_need_initialize_variable(name, "make_#{name}")
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
private
|
||||
def setup_#{name}(feed, current)
|
||||
@#{name}.to_feed(feed, current)
|
||||
end
|
||||
|
||||
def make_#{name}
|
||||
self.class::#{class_name}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_classed_element(name, class_name=nil, attribute_name=nil)
|
||||
def_classed_element_without_accessor(name, class_name)
|
||||
if attribute_name
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{name}
|
||||
if block_given?
|
||||
yield(@#{name})
|
||||
else
|
||||
@#{name}.#{attribute_name}
|
||||
end
|
||||
end
|
||||
|
||||
def #{name}=(new_value)
|
||||
@#{name}.#{attribute_name} = new_value
|
||||
end
|
||||
EOC
|
||||
else
|
||||
attr_reader name
|
||||
end
|
||||
end
|
||||
|
||||
def def_classed_elements(name, attribute, plural_class_name=nil,
|
||||
plural_name=nil, new_name=nil)
|
||||
plural_name ||= "#{name}s"
|
||||
new_name ||= name
|
||||
def_classed_element(plural_name, plural_class_name)
|
||||
local_variable_name = "_#{name}"
|
||||
new_value_variable_name = "new_value"
|
||||
additional_setup_code = nil
|
||||
if block_given?
|
||||
additional_setup_code = yield(local_variable_name,
|
||||
new_value_variable_name)
|
||||
end
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{name}
|
||||
#{local_variable_name} = #{plural_name}.first
|
||||
#{local_variable_name} ? #{local_variable_name}.#{attribute} : nil
|
||||
end
|
||||
|
||||
def #{name}=(#{new_value_variable_name})
|
||||
#{local_variable_name} =
|
||||
#{plural_name}.first || #{plural_name}.new_#{new_name}
|
||||
#{additional_setup_code}
|
||||
#{local_variable_name}.#{attribute} = #{new_value_variable_name}
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_other_element(name)
|
||||
attr_accessor name
|
||||
def_other_element_without_accessor(name)
|
||||
end
|
||||
|
||||
def def_other_element_without_accessor(name)
|
||||
add_need_initialize_variable(name)
|
||||
add_other_element(name)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def setup_#{name}(feed, current)
|
||||
if !@#{name}.nil? and current.respond_to?(:#{name}=)
|
||||
current.#{name} = @#{name}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
|
||||
attr_reader :maker
|
||||
def initialize(maker)
|
||||
@maker = maker
|
||||
|
@ -183,12 +253,27 @@ EOM
|
|||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
module AtomTextConstructBase
|
||||
module EnsureXMLContent
|
||||
class << self
|
||||
def included(base)
|
||||
super
|
||||
base.class_eval do
|
||||
%w(type content xml_content).each do |element|
|
||||
attr_reader element
|
||||
attr_writer element if element != "xml_content"
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
|
||||
alias_method(:xhtml, :xml_content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_xml_content(content)
|
||||
xhtml_uri = ::RSS::Atom::XHTML_URI
|
||||
unless content.is_a?(RSS::XML::Element) and
|
||||
|
@ -203,6 +288,14 @@ EOC
|
|||
content
|
||||
end
|
||||
|
||||
def xml_content=(content)
|
||||
@xml_content = ensure_xml_content(content)
|
||||
end
|
||||
|
||||
def xhtml=(content)
|
||||
self.xml_content = content
|
||||
end
|
||||
|
||||
private
|
||||
def set_xhtml_uri_as_default_uri(children)
|
||||
children.collect do |child|
|
||||
|
@ -221,21 +314,9 @@ EOC
|
|||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
klass.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
klass.class_eval do
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -248,7 +329,7 @@ EOC
|
|||
}
|
||||
_date = date
|
||||
if _date and !dc_dates.any? {|dc_date| dc_date.value == _date}
|
||||
dc_date = self.class::DublinCoreDates::Date.new(self)
|
||||
dc_date = self.class::DublinCoreDates::DublinCoreDate.new(self)
|
||||
dc_date.value = _date.dup
|
||||
dc_dates.unshift(dc_date)
|
||||
end
|
||||
|
@ -260,9 +341,7 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class RSSBase
|
||||
include Base
|
||||
|
||||
class RSSBase < Base
|
||||
class << self
|
||||
def make(&block)
|
||||
new.make(&block)
|
||||
|
@ -281,7 +360,7 @@ EOC
|
|||
def make_#{element}
|
||||
self.class::#{Utils.to_class_name(element)}.new(self)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
attr_reader :feed_version
|
||||
|
@ -326,13 +405,10 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class XMLStyleSheets
|
||||
include Base
|
||||
|
||||
class XMLStyleSheets < Base
|
||||
def_array_element("xml_stylesheet", nil, "XMLStyleSheet")
|
||||
|
||||
class XMLStyleSheet
|
||||
include Base
|
||||
class XMLStyleSheet < Base
|
||||
|
||||
::RSS::XMLStyleSheet::ATTRIBUTES.each do |attribute|
|
||||
attr_accessor attribute
|
||||
|
@ -362,26 +438,23 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class ChannelBase
|
||||
include Base
|
||||
class ChannelBase < Base
|
||||
include SetupDefaultDate
|
||||
|
||||
%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}(feed, current)
|
||||
@#{element}.to_feed(feed, current)
|
||||
end
|
||||
%w(cloud categories skipDays skipHours).each do |name|
|
||||
def_classed_element(name)
|
||||
end
|
||||
|
||||
def make_#{element}
|
||||
self.class::#{Utils.to_class_name(element)}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
%w(generator copyright description title).each do |name|
|
||||
def_classed_element(name, nil, "content")
|
||||
end
|
||||
|
||||
[
|
||||
["link", "href", Proc.new {|target,| "#{target}.href = 'self'"}],
|
||||
["author", "name"],
|
||||
["contributor", "name"],
|
||||
].each do |name, attribute, additional_setup_maker|
|
||||
def_classed_elements(name, attribute, &additional_setup_maker)
|
||||
end
|
||||
|
||||
%w(id about language
|
||||
|
@ -407,59 +480,12 @@ EOC
|
|||
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 icon
|
||||
image_favicon.about
|
||||
end
|
||||
|
@ -476,14 +502,10 @@ EOC
|
|||
maker.image.url = url
|
||||
end
|
||||
|
||||
class SkipDaysBase
|
||||
include Base
|
||||
|
||||
class SkipDaysBase < Base
|
||||
def_array_element("day")
|
||||
|
||||
class DayBase
|
||||
include Base
|
||||
|
||||
class DayBase < Base
|
||||
%w(content).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -491,14 +513,10 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class SkipHoursBase
|
||||
include Base
|
||||
|
||||
class SkipHoursBase < Base
|
||||
def_array_element("hour")
|
||||
|
||||
class HourBase
|
||||
include Base
|
||||
|
||||
class HourBase < Base
|
||||
%w(content).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -506,23 +524,17 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class CloudBase
|
||||
include Base
|
||||
|
||||
class CloudBase < Base
|
||||
%w(domain port path registerProcedure protocol).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
end
|
||||
|
||||
class CategoriesBase
|
||||
include Base
|
||||
|
||||
class CategoriesBase < Base
|
||||
def_array_element("category", "categories")
|
||||
|
||||
class CategoryBase
|
||||
include Base
|
||||
|
||||
class CategoryBase < Base
|
||||
%w(domain content label).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -535,14 +547,10 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class LinksBase
|
||||
include Base
|
||||
|
||||
class LinksBase < Base
|
||||
def_array_element("link")
|
||||
|
||||
class LinkBase
|
||||
include Base
|
||||
|
||||
class LinkBase < Base
|
||||
%w(href rel type hreflang title length).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -550,56 +558,43 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class AuthorsBase
|
||||
include Base
|
||||
|
||||
class AuthorsBase < Base
|
||||
def_array_element("author")
|
||||
|
||||
class AuthorBase
|
||||
include Base
|
||||
class AuthorBase < Base
|
||||
include AtomPersonConstructBase
|
||||
end
|
||||
end
|
||||
|
||||
class ContributorsBase
|
||||
include Base
|
||||
|
||||
class ContributorsBase < Base
|
||||
def_array_element("contributor")
|
||||
|
||||
class ContributorBase
|
||||
include Base
|
||||
class ContributorBase < Base
|
||||
include AtomPersonConstructBase
|
||||
end
|
||||
end
|
||||
|
||||
class GeneratorBase
|
||||
include Base
|
||||
|
||||
class GeneratorBase < Base
|
||||
%w(uri version content).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
end
|
||||
|
||||
class CopyrightBase
|
||||
include Base
|
||||
class CopyrightBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
|
||||
class DescriptionBase
|
||||
include Base
|
||||
class DescriptionBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
|
||||
class TitleBase
|
||||
include Base
|
||||
class TitleBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
end
|
||||
|
||||
class ImageBase
|
||||
include Base
|
||||
|
||||
class ImageBase < Base
|
||||
%w(title url width height description).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -610,9 +605,7 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class ItemsBase
|
||||
include Base
|
||||
|
||||
class ItemsBase < Base
|
||||
def_array_element("item")
|
||||
|
||||
attr_accessor :do_sort, :max_size
|
||||
|
@ -646,27 +639,25 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class ItemBase
|
||||
include Base
|
||||
class ItemBase < Base
|
||||
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}(feed, current)
|
||||
@#{element}.to_feed(feed, current)
|
||||
end
|
||||
|
||||
def make_#{element}
|
||||
self.class::#{Utils.to_class_name(element)}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
%w(guid enclosure source categories content).each do |name|
|
||||
def_classed_element(name)
|
||||
end
|
||||
|
||||
%w(rights description title).each do |name|
|
||||
def_classed_element(name, nil, "content")
|
||||
end
|
||||
|
||||
[
|
||||
["author", "name"],
|
||||
["link", "href", Proc.new {|target,| "#{target}.href = 'alternate'"}],
|
||||
["contributor", "name"],
|
||||
].each do |name, attribute|
|
||||
def_classed_elements(name, attribute)
|
||||
end
|
||||
|
||||
%w(date comments id published).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -688,42 +679,9 @@ EOC
|
|||
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)
|
||||
_date = date || dc_date
|
||||
_other_date = other.date || other.dc_date
|
||||
|
@ -738,42 +696,30 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class GuidBase
|
||||
include Base
|
||||
|
||||
class GuidBase < Base
|
||||
%w(isPermaLink content).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
end
|
||||
|
||||
class EnclosureBase
|
||||
include Base
|
||||
|
||||
class EnclosureBase < Base
|
||||
%w(url length type).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
end
|
||||
|
||||
class SourceBase
|
||||
include Base
|
||||
|
||||
class SourceBase < Base
|
||||
%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
|
||||
logo rights subtitle title).each do |name|
|
||||
def_classed_element(name)
|
||||
end
|
||||
|
||||
def make_#{element}
|
||||
self.class::#{Utils.to_class_name(element)}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
[
|
||||
["link", "href"],
|
||||
].each do |name, attribute|
|
||||
def_classed_elements(name, attribute)
|
||||
end
|
||||
|
||||
%w(id content date).each do |element|
|
||||
|
@ -781,15 +727,8 @@ EOC
|
|||
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
|
||||
alias_method(:url, :link)
|
||||
alias_method(:url=, :link=)
|
||||
|
||||
def updated
|
||||
date
|
||||
|
@ -805,9 +744,7 @@ EOC
|
|||
ContributorsBase = ChannelBase::ContributorsBase
|
||||
GeneratorBase = ChannelBase::GeneratorBase
|
||||
|
||||
class IconBase
|
||||
include Base
|
||||
|
||||
class IconBase < Base
|
||||
%w(url).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
@ -816,27 +753,22 @@ EOC
|
|||
|
||||
LinksBase = ChannelBase::LinksBase
|
||||
|
||||
class LogoBase
|
||||
include Base
|
||||
|
||||
class LogoBase < Base
|
||||
%w(uri).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
end
|
||||
|
||||
class RightsBase
|
||||
include Base
|
||||
class RightsBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
|
||||
class SubtitleBase
|
||||
include Base
|
||||
class SubtitleBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
|
||||
class TitleBase
|
||||
include Base
|
||||
class TitleBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
end
|
||||
|
@ -846,22 +778,19 @@ EOC
|
|||
LinksBase = ChannelBase::LinksBase
|
||||
ContributorsBase = ChannelBase::ContributorsBase
|
||||
|
||||
class RightsBase
|
||||
include Base
|
||||
class RightsBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
|
||||
class DescriptionBase
|
||||
include Base
|
||||
class DescriptionBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
|
||||
class ContentBase
|
||||
include Base
|
||||
class ContentBase < Base
|
||||
include AtomTextConstructBase::EnsureXMLContent
|
||||
|
||||
%w(type src content xml_content).each do |element|
|
||||
attr element, element != "xml_content"
|
||||
%w(src).each do |element|
|
||||
attr_accessor(element)
|
||||
add_need_initialize_variable(element)
|
||||
end
|
||||
|
||||
|
@ -870,13 +799,9 @@ EOC
|
|||
@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
|
||||
|
@ -913,16 +838,13 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
class TitleBase
|
||||
include Base
|
||||
class TitleBase < Base
|
||||
include AtomTextConstructBase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class TextinputBase
|
||||
include Base
|
||||
|
||||
class TextinputBase < Base
|
||||
%w(title description name link).each do |element|
|
||||
attr_accessor element
|
||||
add_need_initialize_variable(element)
|
||||
|
|
|
@ -7,17 +7,8 @@ module RSS
|
|||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
::RSS::ContentModel::ELEMENTS.each do |element|
|
||||
klass.add_need_initialize_variable(element)
|
||||
klass.add_other_element(element)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
|
||||
attr_accessor :#{element}
|
||||
def setup_#{element}(rss, current)
|
||||
if #{element} and current.respond_to?(:#{element}=)
|
||||
current.#{element} = @#{element} if @#{element}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
::RSS::ContentModel::ELEMENTS.each do |name|
|
||||
klass.def_other_element(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,61 +15,40 @@ module RSS
|
|||
plural_klass_name = "DublinCore#{Utils.to_class_name(plural_name)}"
|
||||
full_plural_klass_name = "self.class::#{plural_klass_name}"
|
||||
full_klass_name = "#{full_plural_klass_name}::#{klass_name}"
|
||||
klass.add_need_initialize_variable(full_plural_name,
|
||||
"make_#{full_plural_name}")
|
||||
klass.add_other_element(full_plural_name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
|
||||
attr_accessor :#{full_plural_name}
|
||||
def make_#{full_plural_name}
|
||||
#{full_plural_klass_name}.new(@maker)
|
||||
end
|
||||
|
||||
def setup_#{full_plural_name}(feed, current)
|
||||
@#{full_plural_name}.to_feed(feed, current)
|
||||
end
|
||||
|
||||
def #{full_name}
|
||||
@#{full_plural_name}[0] and @#{full_plural_name}[0].value
|
||||
end
|
||||
|
||||
def #{full_name}=(new_value)
|
||||
@#{full_plural_name}[0] = #{full_klass_name}.new(self)
|
||||
@#{full_plural_name}[0].value = new_value
|
||||
end
|
||||
|
||||
klass.def_classed_elements(full_name, "value", plural_klass_name,
|
||||
full_plural_name, name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def new_#{full_name}(value=nil)
|
||||
#{full_name} = #{full_klass_name}.new(self)
|
||||
#{full_name}.value = value
|
||||
@#{full_plural_name} << #{full_name}
|
||||
_#{full_name} = #{full_plural_name}.new_#{name}
|
||||
_#{full_name}.value = value
|
||||
if block_given?
|
||||
yield #{full_name}
|
||||
yield _#{full_name}
|
||||
else
|
||||
#{full_name}
|
||||
_#{full_name}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
# For backward compatibility
|
||||
alias #{DC_PREFIX}_rightses #{DC_PREFIX}_rights_list
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
::RSS::DublinCoreModel::ELEMENT_NAME_INFOS.each do |name, plural_name|
|
||||
plural_name ||= "#{name}s"
|
||||
full_name ||= "#{DC_PREFIX}_#{name}"
|
||||
full_plural_name ||= "#{DC_PREFIX}_#{plural_name}"
|
||||
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(#{name.dump}, #{plural_name.dump})
|
||||
|
||||
class #{klass_name}Base
|
||||
include Base
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
class #{plural_klass_name}Base < Base
|
||||
def_array_element(#{name.dump}, #{full_plural_name.dump},
|
||||
#{full_klass_name.dump})
|
||||
|
||||
class #{full_klass_name}Base < Base
|
||||
attr_accessor :value
|
||||
add_need_initialize_variable("value")
|
||||
alias_method(:content, :value)
|
||||
|
@ -80,12 +59,13 @@ EOC
|
|||
end
|
||||
|
||||
def to_feed(feed, current)
|
||||
if value and current.respond_to?(:dc_#{name})
|
||||
if value and current.respond_to?(:#{full_name})
|
||||
new_item = current.class::#{full_klass_name}.new(value)
|
||||
current.dc_#{plural_name} << new_item
|
||||
current.#{full_plural_name} << new_item
|
||||
end
|
||||
end
|
||||
end
|
||||
#{klass_name}Base = #{full_klass_name}Base
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
@ -94,11 +74,13 @@ 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)}"
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
class #{plural_klass_name} < #{plural_klass_name}Base
|
||||
class #{klass_name} < #{klass_name}Base
|
||||
class #{full_klass_name} < #{full_klass_name}Base
|
||||
end
|
||||
#{klass_name} = #{full_klass_name}
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
|
|
@ -75,12 +75,6 @@ module RSS
|
|||
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)
|
||||
|
@ -100,7 +94,7 @@ module RSS
|
|||
if authors.all? {|author| !author.have_required_values?}
|
||||
vars << "author"
|
||||
end
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
end
|
||||
|
@ -126,9 +120,11 @@ module RSS
|
|||
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
|
||||
@maker.channel.rights {|r| @rights = r}
|
||||
end
|
||||
unless keep[:title].variable_is_set?
|
||||
@maker.channel.title {|t| @title = t}
|
||||
end
|
||||
@title = @maker.channel.title unless keep[:title].variable_is_set?
|
||||
self.updated ||= @maker.channel.updated
|
||||
super(&block)
|
||||
ensure
|
||||
|
|
|
@ -64,7 +64,7 @@ module RSS
|
|||
@maker.items.all? {|item| item.author.to_s.empty?}
|
||||
vars << "author"
|
||||
end
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
|
||||
|
@ -148,11 +148,11 @@ module RSS
|
|||
def to_feed(feed)
|
||||
logo = feed.class::Logo.new
|
||||
class << logo
|
||||
alias url= content=
|
||||
alias_method(:url=, :content=)
|
||||
end
|
||||
set = setup_values(logo)
|
||||
class << logo
|
||||
undef url=
|
||||
remove_method(:url=)
|
||||
end
|
||||
if set
|
||||
feed.logo = logo
|
||||
|
@ -194,7 +194,7 @@ module RSS
|
|||
|
||||
def have_required_values?
|
||||
set_default_values do
|
||||
super and title.have_required_values?
|
||||
super and title {|t| t.have_required_values?}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -209,7 +209,7 @@ module RSS
|
|||
|
||||
def not_set_required_variables
|
||||
vars = super
|
||||
vars << "title" unless title.have_required_values?
|
||||
vars << "title" unless title {|t| t.have_required_values?}
|
||||
vars
|
||||
end
|
||||
|
||||
|
@ -282,11 +282,11 @@ module RSS
|
|||
def to_feed(feed, current)
|
||||
icon = current.class::Icon.new
|
||||
class << icon
|
||||
alias url= content=
|
||||
alias_method(:url=, :content=)
|
||||
end
|
||||
set = setup_values(icon)
|
||||
class << icon
|
||||
undef url=
|
||||
remove_method(:url=)
|
||||
end
|
||||
if set
|
||||
current.icon = icon
|
||||
|
|
|
@ -9,20 +9,7 @@ module RSS
|
|||
super
|
||||
|
||||
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)
|
||||
attr_reader :#{name}
|
||||
def setup_#{name}(feed, current)
|
||||
if @#{name}
|
||||
@#{name}.to_feed(feed, current)
|
||||
end
|
||||
end
|
||||
|
||||
def make_#{name}
|
||||
self.class::#{Utils.to_class_name(name)}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
klass.def_classed_element(name)
|
||||
end
|
||||
|
||||
def self.install_image_item(klass)
|
||||
|
@ -33,8 +20,7 @@ EOC
|
|||
EOC
|
||||
end
|
||||
|
||||
class ImageItemBase
|
||||
include Base
|
||||
class ImageItemBase < Base
|
||||
include Maker::DublinCoreModel
|
||||
|
||||
attr_accessor :about, :resource, :image_width, :image_height
|
||||
|
@ -67,20 +53,7 @@ EOC
|
|||
super
|
||||
|
||||
name = "#{RSS::IMAGE_PREFIX}_favicon"
|
||||
klass.add_need_initialize_variable(name, "make_#{name}")
|
||||
klass.add_other_element(name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
|
||||
attr_reader :#{name}
|
||||
def setup_#{name}(feed, current)
|
||||
if @#{name}
|
||||
@#{name}.to_feed(feed, current)
|
||||
end
|
||||
end
|
||||
|
||||
def make_#{name}
|
||||
self.class::#{Utils.to_class_name(name)}.new(@maker)
|
||||
end
|
||||
EOC
|
||||
klass.def_classed_element(name)
|
||||
end
|
||||
|
||||
def self.install_image_favicon(klass)
|
||||
|
@ -88,11 +61,10 @@ EOC
|
|||
class ImageFavicon < ImageFaviconBase
|
||||
DublinCoreModel.install_dublin_core(self)
|
||||
end
|
||||
EOC
|
||||
EOC
|
||||
end
|
||||
|
||||
class ImageFaviconBase
|
||||
include Base
|
||||
class ImageFaviconBase < Base
|
||||
include Maker::DublinCoreModel
|
||||
|
||||
attr_accessor :about, :image_size
|
||||
|
|
248
lib/rss/maker/itunes.rb
Normal file
248
lib/rss/maker/itunes.rb
Normal file
|
@ -0,0 +1,248 @@
|
|||
require 'rss/itunes'
|
||||
require 'rss/maker/2.0'
|
||||
|
||||
module RSS
|
||||
module Maker
|
||||
module ITunesBaseModel
|
||||
def def_class_accessor(klass, name, type, *args)
|
||||
name = name.gsub(/-/, "_").gsub(/^itunes_/, '')
|
||||
full_name = "#{RSS::ITUNES_PREFIX}_#{name}"
|
||||
case type
|
||||
when nil
|
||||
klass.def_other_element(full_name)
|
||||
when :yes_other
|
||||
def_yes_other_accessor(klass, full_name)
|
||||
when :yes_clean_other
|
||||
def_yes_clean_other_accessor(klass, full_name)
|
||||
when :csv
|
||||
def_csv_accessor(klass, full_name)
|
||||
when :element, :attribute
|
||||
recommended_attribute_name, = *args
|
||||
klass_name = "ITunes#{Utils.to_class_name(name)}"
|
||||
klass.def_classed_element(full_name, klass_name,
|
||||
recommended_attribute_name)
|
||||
when :elements
|
||||
plural_name, recommended_attribute_name = args
|
||||
plural_name ||= "#{name}s"
|
||||
full_plural_name = "#{RSS::ITUNES_PREFIX}_#{plural_name}"
|
||||
klass_name = "ITunes#{Utils.to_class_name(name)}"
|
||||
plural_klass_name = "ITunes#{Utils.to_class_name(plural_name)}"
|
||||
def_elements_class_accessor(klass, full_name, full_plural_name,
|
||||
klass_name, plural_klass_name,
|
||||
recommended_attribute_name)
|
||||
end
|
||||
end
|
||||
|
||||
def def_yes_other_accessor(klass, full_name)
|
||||
klass.def_other_element(full_name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{full_name}?
|
||||
Utils::YesOther.parse(@#{full_name})
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_yes_clean_other_accessor(klass, full_name)
|
||||
klass.def_other_element(full_name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{full_name}?
|
||||
Utils::YesCleanOther.parse(#{full_name})
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_csv_accessor(klass, full_name)
|
||||
klass.def_other_element_without_accessor(full_name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_reader :#{full_name}
|
||||
def #{full_name}=(value)
|
||||
@#{full_name} = Utils::CSV.parse(value)
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_elements_class_accessor(klass, full_name, full_plural_name,
|
||||
klass_name, plural_klass_name,
|
||||
recommended_attribute_name=nil)
|
||||
if recommended_attribute_name
|
||||
klass.def_classed_elements(full_name, recommended_attribute_name,
|
||||
plural_klass_name, full_plural_name)
|
||||
else
|
||||
klass.def_classed_element(full_plural_name, plural_klass_name)
|
||||
end
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def new_#{full_name}(text=nil)
|
||||
#{full_name} = @#{full_plural_name}.new_#{full_name}
|
||||
#{full_name}.text = text
|
||||
if block_given?
|
||||
yield #{full_name}
|
||||
else
|
||||
#{full_name}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
module ITunesChannelModel
|
||||
extend ITunesBaseModel
|
||||
|
||||
class << self
|
||||
def append_features(klass)
|
||||
super
|
||||
|
||||
::RSS::ITunesChannelModel::ELEMENT_INFOS.each do |name, type, *args|
|
||||
def_class_accessor(klass, name, type, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesCategoriesBase < Base
|
||||
def_array_element("category", "itunes_categories",
|
||||
"ITunesCategory")
|
||||
class ITunesCategoryBase < Base
|
||||
attr_accessor :text
|
||||
add_need_initialize_variable("text")
|
||||
def_array_element("category", "itunes_categories",
|
||||
"ITunesCategory")
|
||||
|
||||
def have_required_values?
|
||||
text
|
||||
end
|
||||
|
||||
alias_method :to_feed_for_categories, :to_feed
|
||||
def to_feed(feed, current)
|
||||
if text and current.respond_to?(:itunes_category)
|
||||
new_item = current.class::ITunesCategory.new(text)
|
||||
to_feed_for_categories(feed, new_item)
|
||||
current.itunes_categories << new_item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesImageBase < Base
|
||||
add_need_initialize_variable("href")
|
||||
attr_accessor("href")
|
||||
|
||||
def to_feed(feed, current)
|
||||
if @href and current.respond_to?(:itunes_image)
|
||||
current.itunes_image ||= current.class::ITunesImage.new
|
||||
current.itunes_image.href = @href
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesOwnerBase < Base
|
||||
%w(itunes_name itunes_email).each do |name|
|
||||
add_need_initialize_variable(name)
|
||||
attr_accessor(name)
|
||||
end
|
||||
|
||||
def to_feed(feed, current)
|
||||
if current.respond_to?(:itunes_owner=)
|
||||
_not_set_required_variables = not_set_required_variables
|
||||
if (required_variable_names - _not_set_required_variables).empty?
|
||||
return
|
||||
end
|
||||
|
||||
unless have_required_values?
|
||||
raise NotSetError.new("maker.channel.itunes_owner",
|
||||
_not_set_required_variables)
|
||||
end
|
||||
current.itunes_owner ||= current.class::ITunesOwner.new
|
||||
current.itunes_owner.itunes_name = @itunes_name
|
||||
current.itunes_owner.itunes_email = @itunes_email
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def required_variable_names
|
||||
%w(itunes_name itunes_email)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ITunesItemModel
|
||||
extend ITunesBaseModel
|
||||
|
||||
class << self
|
||||
def append_features(klass)
|
||||
super
|
||||
|
||||
::RSS::ITunesItemModel::ELEMENT_INFOS.each do |name, type, *args|
|
||||
def_class_accessor(klass, name, type, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesDurationBase < Base
|
||||
attr_reader :content
|
||||
add_need_initialize_variable("content")
|
||||
|
||||
%w(hour minute second).each do |name|
|
||||
attr_reader(name)
|
||||
add_need_initialize_variable(name, '0')
|
||||
end
|
||||
|
||||
def content=(content)
|
||||
if content.nil?
|
||||
@hour, @minute, @second, @content = nil
|
||||
else
|
||||
@hour, @minute, @second =
|
||||
::RSS::ITunesItemModel::ITunesDuration.parse(content)
|
||||
@content = content
|
||||
end
|
||||
end
|
||||
|
||||
def hour=(hour)
|
||||
@hour = Integer(hour)
|
||||
update_content
|
||||
end
|
||||
|
||||
def minute=(minute)
|
||||
@minute = Integer(minute)
|
||||
update_content
|
||||
end
|
||||
|
||||
def second=(second)
|
||||
@second = Integer(second)
|
||||
update_content
|
||||
end
|
||||
|
||||
def to_feed(feed, current)
|
||||
if @content and current.respond_to?(:itunes_duration=)
|
||||
current.itunes_duration ||= current.class::ITunesDuration.new
|
||||
current.itunes_duration.content = @content
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def update_content
|
||||
components = [@hour, @minute, @second]
|
||||
@content =
|
||||
::RSS::ITunesItemModel::ITunesDuration.construct(*components)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ChannelBase
|
||||
include Maker::ITunesChannelModel
|
||||
class ITunesCategories < ITunesCategoriesBase
|
||||
class ITunesCategory < ITunesCategoryBase
|
||||
ITunesCategory = self
|
||||
end
|
||||
end
|
||||
|
||||
class ITunesImage < ITunesImageBase; end
|
||||
class ITunesOwner < ITunesOwnerBase; end
|
||||
end
|
||||
|
||||
class ItemsBase
|
||||
class ItemBase
|
||||
include Maker::ITunesItemModel
|
||||
class ITunesDuration < ITunesDurationBase; end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,17 +7,8 @@ module RSS
|
|||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
::RSS::SyndicationModel::ELEMENTS.each do |element|
|
||||
klass.add_need_initialize_variable(element)
|
||||
klass.add_other_element(element)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__+1)
|
||||
attr_accessor :#{element}
|
||||
def setup_#{element}(rss, current)
|
||||
if #{element} and current.respond_to?(:#{element}=)
|
||||
current.#{element} = @#{element} if @#{element}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
::RSS::SyndicationModel::ELEMENTS.each do |name|
|
||||
klass.def_other_element(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,18 +8,8 @@ module RSS
|
|||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics")
|
||||
klass.add_other_element("taxo_topics")
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_reader :taxo_topics
|
||||
def make_taxo_topics
|
||||
self.class::TaxonomyTopics.new(@maker)
|
||||
end
|
||||
|
||||
def setup_taxo_topics(feed, current)
|
||||
@taxo_topics.to_feed(feed, current)
|
||||
end
|
||||
EOC
|
||||
klass.def_classed_element("#{RSS::TAXO_PREFIX}_topics",
|
||||
"TaxonomyTopics")
|
||||
end
|
||||
|
||||
def self.install_taxo_topics(klass)
|
||||
|
@ -39,9 +29,7 @@ EOC
|
|||
EOC
|
||||
end
|
||||
|
||||
class TaxonomyTopicsBase
|
||||
include Base
|
||||
|
||||
class TaxonomyTopicsBase < Base
|
||||
attr_reader :resources
|
||||
def_array_element("resource")
|
||||
remove_method :new_resource
|
||||
|
@ -52,29 +40,10 @@ EOC
|
|||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
klass.add_need_initialize_variable("taxo_topics", "make_taxo_topics")
|
||||
klass.add_other_element("taxo_topics")
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_reader :taxo_topics
|
||||
def make_taxo_topics
|
||||
self.class::TaxonomyTopics.new(@maker)
|
||||
end
|
||||
|
||||
def setup_taxo_topics(feed, current)
|
||||
@taxo_topics.to_feed(feed, current)
|
||||
end
|
||||
|
||||
def taxo_topic
|
||||
@taxo_topics[0] and @taxo_topics[0].value
|
||||
end
|
||||
|
||||
def taxo_topic=(new_value)
|
||||
@taxo_topic[0] = self.class::TaxonomyTopic.new(self)
|
||||
@taxo_topic[0].value = new_value
|
||||
end
|
||||
EOC
|
||||
class_name = "TaxonomyTopics"
|
||||
klass.def_classed_elements("#{TAXO_PREFIX}_topic", "value", class_name)
|
||||
end
|
||||
|
||||
|
||||
def self.install_taxo_topic(klass)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
class TaxonomyTopics < TaxonomyTopicsBase
|
||||
|
@ -96,13 +65,10 @@ EOC
|
|||
EOC
|
||||
end
|
||||
|
||||
class TaxonomyTopicsBase
|
||||
include Base
|
||||
|
||||
def_array_element("taxo_topic", nil, "self.class::TaxonomyTopic")
|
||||
class TaxonomyTopicsBase < Base
|
||||
def_array_element("taxo_topic", nil, "TaxonomyTopic")
|
||||
|
||||
class TaxonomyTopicBase
|
||||
include Base
|
||||
class TaxonomyTopicBase < Base
|
||||
include DublinCoreModel
|
||||
include TaxonomyTopicsModel
|
||||
|
||||
|
|
|
@ -8,41 +8,15 @@ module RSS
|
|||
def self.append_features(klass)
|
||||
super
|
||||
|
||||
name = "#{RSS::TRACKBACK_PREFIX}_ping"
|
||||
klass.add_need_initialize_variable(name)
|
||||
klass.add_other_element(name)
|
||||
klass.module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_accessor :#{name}
|
||||
def setup_#{name}(feed, current)
|
||||
if #{name} and current.respond_to?(:#{name}=)
|
||||
current.#{name} = #{name}
|
||||
end
|
||||
end
|
||||
EOC
|
||||
|
||||
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)
|
||||
attr_accessor :#{name}
|
||||
def make_#{name}
|
||||
self.class::TrackBackAbouts.new(self)
|
||||
end
|
||||
|
||||
def setup_#{name}(feed, current)
|
||||
@#{name}.to_feed(feed, current)
|
||||
end
|
||||
EOC
|
||||
klass.def_other_element("#{RSS::TRACKBACK_PREFIX}_ping")
|
||||
klass.def_classed_elements("#{RSS::TRACKBACK_PREFIX}_about", "value",
|
||||
"TrackBackAbouts")
|
||||
end
|
||||
|
||||
class TrackBackAboutsBase
|
||||
include Base
|
||||
|
||||
def_array_element("about", nil, "self.class::TrackBackAbout")
|
||||
|
||||
class TrackBackAboutBase
|
||||
include Base
|
||||
class TrackBackAboutsBase < Base
|
||||
def_array_element("about", nil, "TrackBackAbout")
|
||||
|
||||
class TrackBackAboutBase < Base
|
||||
attr_accessor :value
|
||||
add_need_initialize_variable("value")
|
||||
|
||||
|
|
|
@ -222,25 +222,22 @@ module RSS
|
|||
@@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)
|
||||
def def_get_text_element(uri, element_name, file, line)
|
||||
register_uri(uri, element_name)
|
||||
method_name = "start_#{element_name}"
|
||||
unless private_method_defined?(method_name)
|
||||
define_method(method_name) do |name, prefix, attrs, ns|
|
||||
uri = _ns(ns, prefix)
|
||||
if self.class.uri_registered?(uri, #{name.inspect})
|
||||
if self.class.uri_registered?(uri, element_name)
|
||||
start_get_text_element(name, prefix, ns, uri)
|
||||
else
|
||||
start_else_element(name, prefix, attrs, ns)
|
||||
end
|
||||
end
|
||||
EOT
|
||||
__send!("private", "start_#{name}")
|
||||
private(method_name)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module ListenerMixin
|
||||
|
@ -368,10 +365,10 @@ module RSS
|
|||
def start_else_element(local, prefix, attrs, ns)
|
||||
class_name = self.class.class_name(_ns(ns, prefix), local)
|
||||
current_class = @last_element.class
|
||||
if current_class.const_defined?(class_name)
|
||||
next_class = nil
|
||||
begin
|
||||
next_class = current_class.const_get(class_name)
|
||||
start_have_something_element(local, prefix, attrs, ns, next_class)
|
||||
else
|
||||
rescue NameError
|
||||
if !@do_validate or @ignore_unknown_element
|
||||
@proc_stack.push(nil)
|
||||
else
|
||||
|
@ -382,6 +379,9 @@ module RSS
|
|||
raise NotExpectedTagError.new(local, _ns(ns, prefix), parent)
|
||||
end
|
||||
end
|
||||
if next_class
|
||||
start_have_something_element(local, prefix, attrs, ns, next_class)
|
||||
end
|
||||
end
|
||||
|
||||
NAMESPLIT = /^(?:([\w:][-\w\d.]*):)?([\w:][-\w\d.]*)/
|
||||
|
@ -460,7 +460,7 @@ module RSS
|
|||
|
||||
previous = @last_element
|
||||
next_element = klass.new(@do_validate, attributes)
|
||||
previous.__send!(:set_next_element, tag_name, next_element)
|
||||
previous.set_next_element(tag_name, next_element)
|
||||
@last_element = next_element
|
||||
@last_element.parent = previous if klass.need_parent?
|
||||
@xml_child_mode = @last_element.have_xml_content?
|
||||
|
|
387
lib/rss/rss.rb
387
lib/rss/rss.rb
|
@ -53,7 +53,7 @@ require "rss/xml-stylesheet"
|
|||
|
||||
module RSS
|
||||
|
||||
VERSION = "0.1.7"
|
||||
VERSION = "0.1.8"
|
||||
|
||||
URI = "http://purl.org/rss/1.0/"
|
||||
|
||||
|
@ -162,7 +162,6 @@ module RSS
|
|||
end
|
||||
|
||||
module BaseModel
|
||||
|
||||
include Utils
|
||||
|
||||
def install_have_child_element(tag_name, uri, occurs, name=nil, type=nil)
|
||||
|
@ -190,7 +189,7 @@ EOC
|
|||
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)
|
||||
install_model(tag_name, uri, occurs, plural_name, true)
|
||||
|
||||
def_children_accessor(name, plural_name)
|
||||
install_element(name, "s") do |n, elem_name|
|
||||
|
@ -205,20 +204,26 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
def install_text_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
|
||||
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
|
||||
def_corresponded_attr_writer(name, type, disp_name)
|
||||
def_corresponded_attr_reader(name, type || :convert)
|
||||
install_element(name) do |n, elem_name|
|
||||
<<-EOC
|
||||
if @#{n}
|
||||
if respond_to?(:#{n}_content)
|
||||
content = #{n}_content
|
||||
else
|
||||
content = @#{n}
|
||||
end
|
||||
if content
|
||||
rv = "\#{indent}<#{elem_name}>"
|
||||
value = html_escape(@#{n})
|
||||
value = html_escape(content)
|
||||
if need_convert
|
||||
rv << convert(value)
|
||||
else
|
||||
|
@ -331,6 +336,46 @@ EOC
|
|||
end
|
||||
end
|
||||
|
||||
def yes_clean_other_attr_reader(*attrs)
|
||||
attrs.each do |attr|
|
||||
attr = attr.id2name if attr.kind_of?(Integer)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_reader(:#{attr})
|
||||
def #{attr}?
|
||||
YesCleanOther.parse(@#{attr})
|
||||
end
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
def yes_other_attr_reader(*attrs)
|
||||
attrs.each do |attr|
|
||||
attr = attr.id2name if attr.kind_of?(Integer)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_reader(:#{attr})
|
||||
def #{attr}?
|
||||
Utils::YesOther.parse(@#{attr})
|
||||
end
|
||||
EOC
|
||||
end
|
||||
end
|
||||
|
||||
def csv_attr_reader(*attrs)
|
||||
attrs.each do |attr|
|
||||
attr = attr.id2name if attr.kind_of?(Integer)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
attr_reader(:#{attr})
|
||||
def #{attr}_content
|
||||
if @#{attr}.nil?
|
||||
@#{attr}
|
||||
else
|
||||
@#{attr}.join(", ")
|
||||
end
|
||||
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)
|
||||
|
@ -458,6 +503,34 @@ EOC
|
|||
EOC
|
||||
end
|
||||
|
||||
def yes_clean_other_writer(name, disp_name=name)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{name}=(value)
|
||||
value = (value ? "yes" : "no") if [true, false].include?(value)
|
||||
@#{name} = value
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def yes_other_writer(name, disp_name=name)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{name}=(new_value)
|
||||
if [true, false].include?(new_value)
|
||||
new_value = new_value ? "yes" : "no"
|
||||
end
|
||||
@#{name} = new_value
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def csv_writer(name, disp_name=name)
|
||||
module_eval(<<-EOC, __FILE__, __LINE__ + 1)
|
||||
def #{name}=(new_value)
|
||||
@#{name} = Utils::CSV.parse(new_value)
|
||||
end
|
||||
EOC
|
||||
end
|
||||
|
||||
def def_children_accessor(accessor_name, plural_name)
|
||||
module_eval(<<-EOC, *get_file_and_line_from_caller(2))
|
||||
def #{plural_name}
|
||||
|
@ -511,6 +584,7 @@ EOC
|
|||
def setup_maker_element(target)
|
||||
self.class.need_initialize_variables.each do |var|
|
||||
value = __send__(var)
|
||||
next if value.nil?
|
||||
if value.respond_to?("setup_maker") and
|
||||
!not_need_to_call_setup_maker_variables.include?(var)
|
||||
value.setup_maker(target)
|
||||
|
@ -540,9 +614,9 @@ EOC
|
|||
end
|
||||
|
||||
class Element
|
||||
|
||||
extend BaseModel
|
||||
include Utils
|
||||
extend Utils::InheritedReader
|
||||
include SetupMaker
|
||||
|
||||
INDENT = " "
|
||||
|
@ -554,32 +628,34 @@ EOC
|
|||
TO_ELEMENT_METHODS = []
|
||||
NEED_INITIALIZE_VARIABLES = []
|
||||
PLURAL_FORMS = {}
|
||||
|
||||
class << self
|
||||
|
||||
class << self
|
||||
def must_call_validators
|
||||
MUST_CALL_VALIDATORS
|
||||
inherited_hash_reader("MUST_CALL_VALIDATORS")
|
||||
end
|
||||
def models
|
||||
MODELS
|
||||
inherited_array_reader("MODELS")
|
||||
end
|
||||
def get_attributes
|
||||
GET_ATTRIBUTES
|
||||
inherited_array_reader("GET_ATTRIBUTES")
|
||||
end
|
||||
def have_children_elements
|
||||
HAVE_CHILDREN_ELEMENTS
|
||||
inherited_array_reader("HAVE_CHILDREN_ELEMENTS")
|
||||
end
|
||||
def to_element_methods
|
||||
TO_ELEMENT_METHODS
|
||||
inherited_array_reader("TO_ELEMENT_METHODS")
|
||||
end
|
||||
def need_initialize_variables
|
||||
NEED_INITIALIZE_VARIABLES
|
||||
inherited_array_reader("NEED_INITIALIZE_VARIABLES")
|
||||
end
|
||||
def plural_forms
|
||||
PLURAL_FORMS
|
||||
inherited_hash_reader("PLURAL_FORMS")
|
||||
end
|
||||
|
||||
def inherited_base
|
||||
::RSS::Element
|
||||
end
|
||||
|
||||
|
||||
def inherited(klass)
|
||||
klass.const_set("MUST_CALL_VALIDATORS", {})
|
||||
klass.const_set("MODELS", [])
|
||||
|
@ -589,123 +665,108 @@ EOC
|
|||
klass.const_set("NEED_INITIALIZE_VARIABLES", [])
|
||||
klass.const_set("PLURAL_FORMS", {})
|
||||
|
||||
klass.module_eval(<<-EOC)
|
||||
public
|
||||
|
||||
@tag_name = name.split(/::/).last
|
||||
@tag_name[0,1] = @tag_name[0,1].downcase
|
||||
@have_content = false
|
||||
tag_name = klass.name.split(/::/).last
|
||||
tag_name[0, 1] = tag_name[0, 1].downcase
|
||||
klass.instance_variable_set("@tag_name", tag_name)
|
||||
klass.instance_variable_set("@have_content", false)
|
||||
end
|
||||
|
||||
def self.must_call_validators
|
||||
super.merge(MUST_CALL_VALIDATORS)
|
||||
end
|
||||
def self.models
|
||||
MODELS + super
|
||||
end
|
||||
def self.get_attributes
|
||||
GET_ATTRIBUTES + super
|
||||
end
|
||||
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
|
||||
def self.plural_forms
|
||||
super.merge(PLURAL_FORMS)
|
||||
end
|
||||
def install_must_call_validator(prefix, uri)
|
||||
self::MUST_CALL_VALIDATORS[uri] = prefix
|
||||
end
|
||||
|
||||
|
||||
def self.install_must_call_validator(prefix, uri)
|
||||
MUST_CALL_VALIDATORS[uri] = prefix
|
||||
end
|
||||
|
||||
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
|
||||
MODELS << [tag, uri, occurs, getter]
|
||||
end
|
||||
def install_model(tag, uri, occurs=nil, getter=nil, plural=false)
|
||||
getter ||= tag
|
||||
if m = self::MODELS.find {|t, u, o, g, p| t == tag and u == uri}
|
||||
m[2] = occurs
|
||||
else
|
||||
self::MODELS << [tag, uri, occurs, getter, plural]
|
||||
end
|
||||
end
|
||||
|
||||
def self.install_get_attribute(name, uri, required=true,
|
||||
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, element_name]
|
||||
add_need_initialize_variable(disp_name)
|
||||
def install_get_attribute(name, uri, required=true,
|
||||
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
|
||||
self::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=nil)
|
||||
disp_name ||= name
|
||||
case type
|
||||
when :integer
|
||||
integer_writer name, disp_name
|
||||
when :positive_integer
|
||||
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
|
||||
def def_corresponded_attr_writer(name, type=nil, disp_name=nil)
|
||||
disp_name ||= name
|
||||
case type
|
||||
when :integer
|
||||
integer_writer name, disp_name
|
||||
when :positive_integer
|
||||
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
|
||||
when :yes_clean_other
|
||||
yes_clean_other_writer name, disp_name
|
||||
when :yes_other
|
||||
yes_other_writer name, disp_name
|
||||
when :csv
|
||||
csv_writer name
|
||||
else
|
||||
attr_writer name
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
def def_corresponded_attr_reader(name, type=nil)
|
||||
case type
|
||||
when :inherit
|
||||
inherit_convert_attr_reader name
|
||||
when :uri
|
||||
uri_convert_attr_reader name
|
||||
when :yes_clean_other
|
||||
yes_clean_other_attr_reader name
|
||||
when :yes_other
|
||||
yes_other_attr_reader name
|
||||
when :csv
|
||||
csv_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
|
||||
def 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
|
||||
|
||||
def self.have_content?
|
||||
@have_content
|
||||
end
|
||||
def have_content?
|
||||
@have_content
|
||||
end
|
||||
|
||||
def self.add_have_children_element(variable_name, plural_name)
|
||||
HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
|
||||
end
|
||||
|
||||
def self.add_to_element_method(method_name)
|
||||
TO_ELEMENT_METHODS << method_name
|
||||
end
|
||||
def add_have_children_element(variable_name, plural_name)
|
||||
self::HAVE_CHILDREN_ELEMENTS << [variable_name, plural_name]
|
||||
end
|
||||
|
||||
def self.add_need_initialize_variable(variable_name)
|
||||
NEED_INITIALIZE_VARIABLES << variable_name
|
||||
end
|
||||
|
||||
def self.add_plural_form(singular, plural)
|
||||
PLURAL_FORMS[singular] = plural
|
||||
end
|
||||
|
||||
EOC
|
||||
def add_to_element_method(method_name)
|
||||
self::TO_ELEMENT_METHODS << method_name
|
||||
end
|
||||
|
||||
def add_need_initialize_variable(variable_name)
|
||||
self::NEED_INITIALIZE_VARIABLES << variable_name
|
||||
end
|
||||
|
||||
def add_plural_form(singular, plural)
|
||||
self::PLURAL_FORMS[singular] = plural
|
||||
end
|
||||
|
||||
def required_prefix
|
||||
|
@ -719,7 +780,7 @@ EOC
|
|||
def need_parent?
|
||||
false
|
||||
end
|
||||
|
||||
|
||||
def install_ns(prefix, uri)
|
||||
if self::NSPOOL.has_key?(prefix)
|
||||
raise OverlappedPrefixError.new(prefix)
|
||||
|
@ -821,6 +882,36 @@ EOC
|
|||
false
|
||||
end
|
||||
|
||||
def set_next_element(tag_name, next_element)
|
||||
klass = next_element.class
|
||||
prefix = ""
|
||||
prefix << "#{klass.required_prefix}_" if klass.required_prefix
|
||||
key = "#{prefix}#{tag_name.gsub(/-/, '_')}"
|
||||
if self.class.plural_forms.has_key?(key)
|
||||
ary = __send__("#{self.class.plural_forms[key]}")
|
||||
ary << next_element
|
||||
else
|
||||
__send__("#{key}=", next_element)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
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? {|c| c.have_required_elements?}
|
||||
else
|
||||
!child.to_s.empty?
|
||||
end
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def initialize_variables(attrs)
|
||||
normalized_attrs = {}
|
||||
|
@ -832,7 +923,7 @@ EOC
|
|||
if value
|
||||
__send__("#{variable_name}=", value)
|
||||
else
|
||||
instance_eval("@#{variable_name} = nil")
|
||||
instance_variable_set("@#{variable_name}", nil)
|
||||
end
|
||||
end
|
||||
initialize_have_children_elements
|
||||
|
@ -841,7 +932,7 @@ EOC
|
|||
|
||||
def initialize_have_children_elements
|
||||
self.class.have_children_elements.each do |variable_name, plural_name|
|
||||
instance_eval("@#{variable_name} = []")
|
||||
instance_variable_set("@#{variable_name}", [])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -911,19 +1002,6 @@ EOC
|
|||
''
|
||||
end
|
||||
|
||||
def set_next_element(tag_name, next_element)
|
||||
klass = next_element.class
|
||||
prefix = ""
|
||||
prefix << "#{klass.required_prefix}_" if klass.required_prefix
|
||||
key = "#{prefix}#{tag_name}"
|
||||
if self.class.plural_forms.has_key?(key)
|
||||
ary = __send__("#{self.class.plural_forms[key]}")
|
||||
ary << next_element
|
||||
else
|
||||
__send__("#{prefix}#{tag_name}=", next_element)
|
||||
end
|
||||
end
|
||||
|
||||
def children
|
||||
rv = []
|
||||
self.class.models.each do |name, uri, occurs, getter|
|
||||
|
@ -939,10 +1017,10 @@ EOC
|
|||
|
||||
def _tags
|
||||
rv = []
|
||||
self.class.models.each do |name, uri, occurs, getter|
|
||||
self.class.models.each do |name, uri, occurs, getter, plural|
|
||||
value = __send__(getter)
|
||||
next if value.nil?
|
||||
if value.is_a?(Array)
|
||||
if plural and value.is_a?(Array)
|
||||
rv.concat([[uri, name]] * value.size)
|
||||
else
|
||||
rv << [uri, name]
|
||||
|
@ -997,11 +1075,12 @@ EOC
|
|||
tags = tags.sort_by {|x| element_names.index(x) || tags_size}
|
||||
end
|
||||
|
||||
_tags = tags.dup if tags
|
||||
models.each_with_index do |model, i|
|
||||
name, model_uri, occurs, getter = model
|
||||
|
||||
if DEBUG
|
||||
p "before"
|
||||
p "before"
|
||||
p tags
|
||||
p model
|
||||
end
|
||||
|
@ -1095,7 +1174,7 @@ EOC
|
|||
if have_xml_content?
|
||||
__send__(self.class.xml_getter)
|
||||
else
|
||||
@content
|
||||
content
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1103,25 +1182,9 @@ EOC
|
|||
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
|
||||
_content = content
|
||||
_content = Base64.encode64(_content) if need_base64_encode?
|
||||
h(_content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,14 +2,16 @@ module RSS
|
|||
module Utils
|
||||
module_function
|
||||
def to_class_name(name)
|
||||
name.split(/_/).collect do |part|
|
||||
name.split(/[_\-]/).collect do |part|
|
||||
"#{part[0, 1].upcase}#{part[1..-1]}"
|
||||
end.join("")
|
||||
end
|
||||
|
||||
def get_file_and_line_from_caller(i=0)
|
||||
file, line, = caller[i].split(':')
|
||||
[file, line.to_i]
|
||||
line = line.to_i
|
||||
line += 1 if i.zero?
|
||||
[file, line]
|
||||
end
|
||||
|
||||
def html_escape(s)
|
||||
|
@ -28,5 +30,75 @@ module RSS
|
|||
def element_initialize_arguments?(args)
|
||||
[true, false].include?(args[0]) and args[1].is_a?(Hash)
|
||||
end
|
||||
|
||||
module YesCleanOther
|
||||
module_function
|
||||
def parse(value)
|
||||
if [true, false, nil].include?(value)
|
||||
value
|
||||
else
|
||||
case value.to_s
|
||||
when /\Ayes\z/i
|
||||
true
|
||||
when /\Aclean\z/i
|
||||
false
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module YesOther
|
||||
module_function
|
||||
def parse(value)
|
||||
if [true, false].include?(value)
|
||||
value
|
||||
else
|
||||
/\Ayes\z/i.match(value.to_s) ? true : false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module CSV
|
||||
module_function
|
||||
def parse(value)
|
||||
if value.is_a?(String)
|
||||
value.strip.split(/\s*,\s*/)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module InheritedReader
|
||||
def inherited_reader(constant_name)
|
||||
base_class = inherited_base
|
||||
result = base_class.const_get(constant_name)
|
||||
found_base_class = false
|
||||
ancestors.reverse_each do |klass|
|
||||
if found_base_class
|
||||
if klass.const_defined?(constant_name)
|
||||
result = yield(result, klass.const_get(constant_name))
|
||||
end
|
||||
else
|
||||
found_base_class = klass == base_class
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def inherited_array_reader(constant_name)
|
||||
inherited_reader(constant_name) do |result, current|
|
||||
current + result
|
||||
end
|
||||
end
|
||||
|
||||
def inherited_hash_reader(constant_name)
|
||||
inherited_reader(constant_name) do |result, current|
|
||||
result.merge(current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -66,7 +66,7 @@ rss = RSS::Maker.make("1.0") do |maker|
|
|||
end
|
||||
|
||||
maker.items.each do |item|
|
||||
item.title.content ||= "UNKNOWN"
|
||||
item.title ||= "UNKNOWN"
|
||||
item.link ||= "UNKNOWN"
|
||||
end
|
||||
|
||||
|
|
|
@ -59,9 +59,9 @@ ARGV.each do |fname|
|
|||
|
||||
rss = rss.to_rss("1.0") do |maker|
|
||||
maker.channel.about ||= maker.channel.link
|
||||
maker.channel.description.content ||= "No description"
|
||||
maker.channel.description ||= "No description"
|
||||
maker.items.each do |item|
|
||||
item.title.content ||= "No title"
|
||||
item.title ||= "No title"
|
||||
item.link ||= "UNKNOWN"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,8 +58,9 @@ ARGV.each do |fname|
|
|||
|
||||
rss = rss.to_rss("1.0") do |maker|
|
||||
maker.channel.about ||= maker.channel.link
|
||||
maker.channel.description.content ||= "No description"
|
||||
maker.channel.description ||= "No description"
|
||||
maker.items.each do |item|
|
||||
item.title ||= "UNKNOWN"
|
||||
item.link ||= "UNKNOWN"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
require 'erb'
|
||||
|
||||
module RSS
|
||||
module Assertions
|
||||
def assert_parse(rss, assert_method, *args)
|
||||
|
@ -90,6 +92,7 @@ module RSS
|
|||
flunk("Not raise NotSetError")
|
||||
rescue ::RSS::NotSetError => e
|
||||
assert_equal(name, e.name)
|
||||
assert_kind_of(Array, variables)
|
||||
assert_equal(variables.sort, e.variables.sort)
|
||||
end
|
||||
end
|
||||
|
@ -152,237 +155,6 @@ module RSS
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
def assert_channel10(attrs, channel)
|
||||
_wrap_assertion do
|
||||
n_attrs = normalized_attrs(attrs)
|
||||
|
||||
names = %w(about title link description)
|
||||
assert_attributes(attrs, names, channel)
|
||||
|
||||
%w(image items textinput).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = channel.__send__(name)
|
||||
__send__("assert_channel10_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel10_image(attrs, image)
|
||||
_wrap_assertion do
|
||||
assert_attributes(attrs, %w(resource), image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel10_textinput(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
assert_attributes(attrs, %w(resource), textinput)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel10_items(attrs, items)
|
||||
_wrap_assertion do
|
||||
assert_equal(items.resources, items.Seq.lis.collect {|x| x.resource})
|
||||
items.Seq.lis.each_with_index do |li, i|
|
||||
assert_attributes(attrs[i], %w(resource), li)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_image10(attrs, image)
|
||||
_wrap_assertion do
|
||||
names = %w(about title url link)
|
||||
assert_attributes(attrs, names, image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items10(attrs, items)
|
||||
_wrap_assertion do
|
||||
names = %w(about title link description)
|
||||
items.each_with_index do |item, i|
|
||||
assert_attributes(attrs[i], names, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_textinput10(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
names = %w(about title description name link)
|
||||
assert_attributes(attrs, names, textinput)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def assert_channel09(attrs, channel)
|
||||
_wrap_assertion do
|
||||
n_attrs = normalized_attrs(attrs)
|
||||
|
||||
names = %w(title description link language rating
|
||||
copyright pubDate lastBuildDate docs
|
||||
managingEditor webMaster)
|
||||
assert_attributes(attrs, names, channel)
|
||||
|
||||
%w(skipHours skipDays).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = channel.__send__(name)
|
||||
__send__("assert_channel09_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel09_skipDays(contents, skipDays)
|
||||
_wrap_assertion do
|
||||
days = skipDays.days
|
||||
contents.each_with_index do |content, i|
|
||||
assert_equal(content, days[i].content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel09_skipHours(contents, skipHours)
|
||||
_wrap_assertion do
|
||||
hours = skipHours.hours
|
||||
contents.each_with_index do |content, i|
|
||||
assert_equal(content.to_i, hours[i].content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_image09(attrs, image)
|
||||
_wrap_assertion do
|
||||
names = %w(url link title description)
|
||||
names << ["width", :integer]
|
||||
names << ["height", :integer]
|
||||
assert_attributes(attrs, names, image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items09(attrs, items)
|
||||
_wrap_assertion do
|
||||
names = %w(title link description)
|
||||
items.each_with_index do |item, i|
|
||||
assert_attributes(attrs[i], names, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_textinput09(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
names = %w(title description name link)
|
||||
assert_attributes(attrs, names, textinput)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def assert_channel20(attrs, channel)
|
||||
_wrap_assertion do
|
||||
n_attrs = normalized_attrs(attrs)
|
||||
|
||||
names = %w(title link description language copyright
|
||||
managingEditor webMaster pubDate
|
||||
lastBuildDate generator docs rating)
|
||||
names << ["ttl", :integer]
|
||||
assert_attributes(attrs, names, channel)
|
||||
|
||||
%w(cloud categories skipHours skipDays).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = channel.__send__(name)
|
||||
__send__("assert_channel20_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel20_skipDays(contents, skipDays)
|
||||
assert_channel09_skipDays(contents, skipDays)
|
||||
end
|
||||
|
||||
def assert_channel20_skipHours(contents, skipHours)
|
||||
assert_channel09_skipHours(contents, skipHours)
|
||||
end
|
||||
|
||||
def assert_channel20_cloud(attrs, cloud)
|
||||
_wrap_assertion do
|
||||
names = %w(domain path registerProcedure protocol)
|
||||
names << ["port", :integer]
|
||||
assert_attributes(attrs, names, cloud)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel20_categories(attrs, categories)
|
||||
_wrap_assertion do
|
||||
names = %w(domain content)
|
||||
categories.each_with_index do |category, i|
|
||||
assert_attributes(attrs[i], names, category)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_image20(attrs, image)
|
||||
_wrap_assertion do
|
||||
names = %w(url link title description)
|
||||
names << ["width", :integer]
|
||||
names << ["height", :integer]
|
||||
assert_attributes(attrs, names, image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20(attrs, items)
|
||||
_wrap_assertion do
|
||||
names = %w(about title link description)
|
||||
items.each_with_index do |item, i|
|
||||
assert_attributes(attrs[i], names, item)
|
||||
|
||||
n_attrs = normalized_attrs(attrs[i])
|
||||
|
||||
%w(source enclosure categories guid).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = item.__send__(name)
|
||||
__send__("assert_items20_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_source(attrs, source)
|
||||
_wrap_assertion do
|
||||
assert_attributes(attrs, %w(url content), source)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_enclosure(attrs, enclosure)
|
||||
_wrap_assertion do
|
||||
names = ["url", ["length", :integer], "type"]
|
||||
assert_attributes(attrs, names, enclosure)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_categories(attrs, categories)
|
||||
_wrap_assertion do
|
||||
assert_channel20_categories(attrs, categories)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_guid(attrs, guid)
|
||||
_wrap_assertion do
|
||||
names = [["isPermaLink", :boolean], ["content"]]
|
||||
assert_attributes(attrs, names, guid)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_textinput20(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
names = %w(title description name link)
|
||||
assert_attributes(attrs, names, textinput)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_atom_person(tag_name, generator)
|
||||
_wrap_assertion do
|
||||
|
@ -1146,401 +918,6 @@ EOA
|
|||
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 = []
|
||||
|
@ -1565,7 +942,6 @@ EOA
|
|||
: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
|
||||
|
@ -1765,7 +1141,7 @@ EOA
|
|||
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 = chain_reader(maker, maker_readers) {|x| x}
|
||||
target.type = "text"
|
||||
end
|
||||
end
|
||||
|
@ -1773,7 +1149,7 @@ EOA
|
|||
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 = chain_reader(maker, maker_readers) {|x| x}
|
||||
target.type = "html"
|
||||
end
|
||||
end
|
||||
|
@ -1781,7 +1157,7 @@ EOA
|
|||
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 = chain_reader(maker, maker_readers) {|x| x}
|
||||
target.type = "xhtml"
|
||||
end
|
||||
end
|
||||
|
@ -1789,7 +1165,7 @@ EOA
|
|||
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 = chain_reader(maker, maker_readers) {|x| x}
|
||||
target.type = "xhtml"
|
||||
target.content = "Content"
|
||||
end
|
||||
|
@ -1797,28 +1173,28 @@ EOA
|
|||
|
||||
_assert_maker_atom_text_construct(*args) do |maker|
|
||||
yield maker
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target = chain_reader(maker, maker_readers) {|x| x}
|
||||
target.type = "text"
|
||||
target.content = "Content"
|
||||
end
|
||||
|
||||
_assert_maker_atom_text_construct(*args) do |maker|
|
||||
yield maker
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target = chain_reader(maker, maker_readers) {|x| x}
|
||||
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 = chain_reader(maker, maker_readers) {|x| x}
|
||||
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 = chain_reader(maker, maker_readers) {|x| x}
|
||||
target.type = "xhtml"
|
||||
target.xml_content = RSS::XML::Element.new("unknown")
|
||||
end
|
||||
|
@ -1877,7 +1253,7 @@ EOA
|
|||
element = nil
|
||||
feed = RSS::Maker.make("atom:#{feed_type}") do |maker|
|
||||
yield maker
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target = chain_reader(maker, maker_readers) {|x| x}
|
||||
element = maker_extractor.call(target)
|
||||
end
|
||||
|
||||
|
@ -1942,7 +1318,7 @@ EOA
|
|||
__send__(assert_method_name, feed_type, maker_readers,
|
||||
feed_readers, *additional_args) do |maker|
|
||||
yield maker
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target = chain_reader(maker, maker_readers) {|x| x}
|
||||
setup_target.call(target, have)
|
||||
end
|
||||
end
|
||||
|
@ -1950,7 +1326,7 @@ EOA
|
|||
__send__(assert_method_name, feed_type, maker_readers, feed_readers,
|
||||
*additional_args) do |maker|
|
||||
yield maker
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target = chain_reader(maker, maker_readers) {|x| x}
|
||||
setup_target.call(target, have_required_variable_too)
|
||||
end
|
||||
end
|
||||
|
@ -2302,14 +1678,14 @@ EOA
|
|||
: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?),
|
||||
: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?,
|
||||
}
|
||||
content[:src] = nil if content[:src] and content[:content]
|
||||
if content[:type] or content[:content]
|
||||
|
@ -2642,10 +2018,10 @@ EOA
|
|||
end
|
||||
end
|
||||
|
||||
def chain_reader(target, readers)
|
||||
def chain_reader(target, readers, &block)
|
||||
readers.inject(target) do |result, reader|
|
||||
return nil if result.nil?
|
||||
result.__send__(reader)
|
||||
result.__send__(reader, &block)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2669,5 +2045,18 @@ EOA
|
|||
end + combination(rest, n)
|
||||
end
|
||||
end
|
||||
|
||||
def tag(name, content=nil, attributes={})
|
||||
attributes = attributes.collect do |key, value|
|
||||
"#{ERB::Util.h(key)}=\"#{ERB::Util.h(value)}\""
|
||||
end.join(" ")
|
||||
begin_tag = "<#{name}"
|
||||
begin_tag << " #{attributes}" unless attributes.empty?
|
||||
if content
|
||||
"#{begin_tag}>#{content}</#{name}>\n"
|
||||
else
|
||||
"#{begin_tag}/>\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -217,7 +217,7 @@ module RSS
|
|||
end
|
||||
|
||||
|
||||
def test_to_xml
|
||||
def test_to_xml(with_convenience_way=true)
|
||||
atom = RSS::Parser.parse(make_feed)
|
||||
assert_equal(atom.to_s, atom.to_xml)
|
||||
assert_equal(atom.to_s, atom.to_xml("atom"))
|
||||
|
@ -228,7 +228,11 @@ module RSS
|
|||
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
|
||||
if with_convenience_way
|
||||
maker.channel.description = atom.title.content
|
||||
else
|
||||
maker.channel.description {|d| d.content = atom.title.content}
|
||||
end
|
||||
|
||||
maker.image.url = "http://example.com/logo.png"
|
||||
maker.image.title = "Logo"
|
||||
|
@ -238,13 +242,21 @@ module RSS
|
|||
|
||||
rss20_xml = atom.to_xml("2.0") do |maker|
|
||||
maker.channel.link = "http://example.com/"
|
||||
maker.channel.description.content = atom.title.content
|
||||
if with_convenience_way
|
||||
maker.channel.description = atom.title.content
|
||||
else
|
||||
maker.channel.description {|d| d.content = atom.title.content}
|
||||
end
|
||||
end
|
||||
rss20 = RSS::Parser.parse(rss20_xml)
|
||||
assert_equal("2.0", rss20.rss_version)
|
||||
assert_equal(["rss", "2.0", nil], rss20.feed_info)
|
||||
end
|
||||
|
||||
def test_to_xml_with_new_api_since_018
|
||||
test_to_xml(false)
|
||||
end
|
||||
|
||||
private
|
||||
def setup_entry(entry)
|
||||
_wrap_assertion do
|
||||
|
@ -277,5 +289,400 @@ module RSS
|
|||
assert_not_equal("", entry.to_s)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -65,12 +65,12 @@ EOR
|
|||
|
||||
@rss = Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
|
||||
def test_parser
|
||||
assert_nothing_raised do
|
||||
Parser.parse(@rss_source)
|
||||
end
|
||||
|
||||
|
||||
assert_too_much_tag("favicon", "channel") do
|
||||
Parser.parse(make_RDF(<<-EOR, @ns))
|
||||
#{make_channel(@channel_nodes * 2)}
|
||||
|
@ -88,7 +88,7 @@ EOR
|
|||
EOR
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def test_favicon_accessor
|
||||
favicon = @rss.channel.image_favicon
|
||||
[
|
||||
|
@ -145,7 +145,7 @@ EOR
|
|||
image_item.__send__("#{name}=", attrs[full_name])
|
||||
assert_equal(attrs[full_name], image_item.__send__(name))
|
||||
end
|
||||
|
||||
|
||||
[
|
||||
["width", "image:width", "111"],
|
||||
["image_width", "image:width", "44"],
|
||||
|
@ -188,7 +188,7 @@ EOR
|
|||
actual = REXML::Document.new(item.image_item.to_s(false, ""))
|
||||
|
||||
assert_equal(expected[0].attributes, actual[0].attributes)
|
||||
|
||||
|
||||
%w(image:height image:width dc:title).each do |name|
|
||||
actual_target = actual.elements["//#{name}"]
|
||||
expected_target = expected.elements["//#{name}"]
|
||||
|
|
|
@ -9,7 +9,7 @@ module RSS
|
|||
def self.indent_size; 1; end
|
||||
def self.tag_name; 'image'; end
|
||||
end
|
||||
|
||||
|
||||
def setup
|
||||
@rss = make_RDF(<<-EOR)
|
||||
#{make_channel}
|
||||
|
@ -18,7 +18,7 @@ module RSS
|
|||
#{make_textinput}
|
||||
EOR
|
||||
end
|
||||
|
||||
|
||||
def test_inherit
|
||||
rss = RSS::Parser.parse(@rss)
|
||||
orig_image = rss.image
|
||||
|
@ -36,6 +36,5 @@ EOR
|
|||
assert_equal("#{prefix} #{orig_image.url}", new_image.url)
|
||||
assert_equal("#{prefix} #{orig_image.link}", new_image.link)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
347
test/rss/test_itunes.rb
Normal file
347
test/rss/test_itunes.rb
Normal file
|
@ -0,0 +1,347 @@
|
|||
require "cgi"
|
||||
require "rexml/document"
|
||||
|
||||
require "rss-testcase"
|
||||
|
||||
require "rss/2.0"
|
||||
require "rss/itunes"
|
||||
|
||||
module RSS
|
||||
class TestITunes < TestCase
|
||||
def test_author
|
||||
assert_itunes_author(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
|
||||
assert_itunes_author(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_block
|
||||
assert_itunes_block(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_category
|
||||
assert_itunes_category(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_image
|
||||
assert_itunes_image(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_duration
|
||||
assert_itunes_duration(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_explicit
|
||||
assert_itunes_explicit(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
|
||||
assert_itunes_explicit(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_keywords
|
||||
assert_itunes_keywords(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
|
||||
assert_itunes_keywords(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_feed_url
|
||||
assert_itunes_new_feed_url(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_owner
|
||||
assert_itunes_owner(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_subtitle
|
||||
assert_itunes_subtitle(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
|
||||
assert_itunes_subtitle(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
def test_summary
|
||||
assert_itunes_summary(%w(channel)) do |content, xmlns|
|
||||
make_rss20(make_channel20(content), xmlns)
|
||||
end
|
||||
|
||||
assert_itunes_summary(%w(items last)) do |content, xmlns|
|
||||
make_rss20(make_channel20(make_item20(content)), xmlns)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def itunes_rss20_parse(content, &maker)
|
||||
xmlns = {"itunes" => "http://www.itunes.com/dtds/podcast-1.0.dtd"}
|
||||
rss20_xml = maker.call(content, xmlns)
|
||||
::RSS::Parser.parse(rss20_xml)
|
||||
end
|
||||
|
||||
def assert_itunes_author(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
author = "John Lennon"
|
||||
rss20 = itunes_rss20_parse(tag("itunes:author", author), &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(author, target.itunes_author)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_block(value, boolean_value, readers, &rss20_maker)
|
||||
rss20 = itunes_rss20_parse(tag("itunes:block", value), &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(value, target.itunes_block)
|
||||
assert_equal(boolean_value, target.itunes_block?)
|
||||
end
|
||||
|
||||
def assert_itunes_block(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_block("yes", true, readers, &rss20_maker)
|
||||
_assert_itunes_block("Yes", true, readers, &rss20_maker)
|
||||
_assert_itunes_block("no", false, readers, &rss20_maker)
|
||||
_assert_itunes_block("", false, readers, &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_category(categories, readers, &rss20_maker)
|
||||
cats = categories.collect do |category|
|
||||
if category.is_a?(Array)
|
||||
category, sub_category = category
|
||||
tag("itunes:category",
|
||||
tag("itunes:category", nil, {"text" => sub_category}),
|
||||
{"text" => category})
|
||||
else
|
||||
tag("itunes:category", nil, {"text" => category})
|
||||
end
|
||||
end.join
|
||||
rss20 = itunes_rss20_parse(cats, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
actual_categories = target.itunes_categories.collect do |category|
|
||||
cat = category.text
|
||||
if category.itunes_categories.empty?
|
||||
cat
|
||||
else
|
||||
[cat, *category.itunes_categories.collect {|c| c.text}]
|
||||
end
|
||||
end
|
||||
assert_equal(categories, actual_categories)
|
||||
end
|
||||
|
||||
def assert_itunes_category(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_category(["Audio Blogs"], readers, &rss20_maker)
|
||||
_assert_itunes_category([["Arts & Entertainment", "Games"]],
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_category([["Arts & Entertainment", "Games"],
|
||||
["Technology", "Computers"],
|
||||
"Audio Blogs"],
|
||||
readers, &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_itunes_image(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
url = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
|
||||
content = tag("itunes:image", nil, {"href" => url})
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_not_nil(target.itunes_image)
|
||||
assert_equal(url, target.itunes_image.href)
|
||||
|
||||
assert_missing_attribute("image", "href") do
|
||||
content = tag("itunes:image")
|
||||
itunes_rss20_parse(content, &rss20_maker)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_duration(hour, minute, second, value,
|
||||
readers, &rss20_maker)
|
||||
content = tag("itunes:duration", value)
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
duration = chain_reader(rss20, readers).itunes_duration
|
||||
assert_equal(value, duration.content)
|
||||
assert_equal(hour, duration.hour)
|
||||
assert_equal(minute, duration.minute)
|
||||
assert_equal(second, duration.second)
|
||||
end
|
||||
|
||||
def _assert_itunes_duration_not_available_value(value, &rss20_maker)
|
||||
assert_not_available_value("duration", value) do
|
||||
content = tag("itunes:duration", value)
|
||||
itunes_rss20_parse(content, &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_itunes_duration(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_duration(7, 14, 5, "07:14:05", readers, &rss20_maker)
|
||||
_assert_itunes_duration(7, 14, 5, "7:14:05", readers, &rss20_maker)
|
||||
_assert_itunes_duration(0, 4, 55, "04:55", readers, &rss20_maker)
|
||||
_assert_itunes_duration(0, 4, 5, "4:05", readers, &rss20_maker)
|
||||
|
||||
_assert_itunes_duration_not_available_value("5", &rss20_maker)
|
||||
_assert_itunes_duration_not_available_value("09:07:14:05", &rss20_maker)
|
||||
_assert_itunes_duration_not_available_value("10:5", &rss20_maker)
|
||||
_assert_itunes_duration_not_available_value("10:03:5", &rss20_maker)
|
||||
_assert_itunes_duration_not_available_value("10:3:05", &rss20_maker)
|
||||
|
||||
_assert_itunes_duration_not_available_value("xx:xx:xx", &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_explicit(explicit, value, readers, &rss20_maker)
|
||||
content = tag("itunes:explicit", value)
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(value, target.itunes_explicit)
|
||||
assert_equal(explicit, target.itunes_explicit?)
|
||||
end
|
||||
|
||||
def assert_itunes_explicit(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_explicit(true, "yes", readers, &rss20_maker)
|
||||
_assert_itunes_explicit(false, "clean", readers, &rss20_maker)
|
||||
_assert_itunes_explicit(nil, "no", readers, &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_keywords(keywords, value, readers, &rss20_maker)
|
||||
content = tag("itunes:keywords", value)
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(keywords, target.itunes_keywords)
|
||||
end
|
||||
|
||||
def assert_itunes_keywords(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_keywords(["salt"], "salt", readers, &rss20_maker)
|
||||
_assert_itunes_keywords(["salt"], " salt ", readers, &rss20_maker)
|
||||
_assert_itunes_keywords(["salt", "pepper", "shaker", "exciting"],
|
||||
"salt, pepper, shaker, exciting",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_keywords(["metric", "socket", "wrenches", "toolsalt"],
|
||||
"metric, socket, wrenches, toolsalt",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_keywords(["olitics", "red", "blue", "state"],
|
||||
"olitics, red, blue, state",
|
||||
readers, &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_itunes_new_feed_url(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
url = "http://newlocation.com/example.rss"
|
||||
content = tag("itunes:new-feed-url", url)
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(url, target.itunes_new_feed_url)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_owner(name, email, readers, &rss20_maker)
|
||||
content = tag("itunes:owner",
|
||||
tag("itunes:name", name) + tag("itunes:email", email))
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
owner = chain_reader(rss20, readers).itunes_owner
|
||||
assert_equal(name, owner.itunes_name)
|
||||
assert_equal(email, owner.itunes_email)
|
||||
end
|
||||
|
||||
def assert_itunes_owner(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_owner("John Doe", "john.doe@example.com",
|
||||
readers, &rss20_maker)
|
||||
|
||||
assert_missing_tag("name", "owner") do
|
||||
content = tag("itunes:owner")
|
||||
itunes_rss20_parse(content, &rss20_maker)
|
||||
end
|
||||
|
||||
assert_missing_tag("name", "owner") do
|
||||
content = tag("itunes:owner",
|
||||
tag("itunes:email", "john.doe@example.com"))
|
||||
itunes_rss20_parse(content, &rss20_maker)
|
||||
end
|
||||
|
||||
assert_missing_tag("email", "owner") do
|
||||
content = tag("itunes:owner", tag("itunes:name", "John Doe"))
|
||||
itunes_rss20_parse(content, &rss20_maker)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_subtitle(value, readers, &rss20_maker)
|
||||
content = tag("itunes:subtitle", value)
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(value, target.itunes_subtitle)
|
||||
end
|
||||
|
||||
def assert_itunes_subtitle(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_subtitle("A show about everything", readers, &rss20_maker)
|
||||
_assert_itunes_subtitle("A short primer on table spices",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_subtitle("Comparing socket wrenches is fun!",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_subtitle("Red + Blue != Purple", readers, &rss20_maker)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_itunes_summary(value, readers, &rss20_maker)
|
||||
content = tag("itunes:summary", value)
|
||||
rss20 = itunes_rss20_parse(content, &rss20_maker)
|
||||
target = chain_reader(rss20, readers)
|
||||
assert_equal(value, target.itunes_summary)
|
||||
end
|
||||
|
||||
def assert_itunes_summary(readers, &rss20_maker)
|
||||
_wrap_assertion do
|
||||
_assert_itunes_summary("All About Everything is a show about " +
|
||||
"everything. Each week we dive into any " +
|
||||
"subject known to man and talk about it as " +
|
||||
"much as we can. Look for our Podcast in " +
|
||||
"the iTunes Music Store",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_summary("This week we talk about salt and pepper " +
|
||||
"shakers, comparing and contrasting pour " +
|
||||
"rates, construction materials, and overall " +
|
||||
"aesthetics. Come and join the party!",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_summary("This week we talk about metric vs. old " +
|
||||
"english socket wrenches. Which one is " +
|
||||
"better? Do you really need both? Get all " +
|
||||
"of your answers here.",
|
||||
readers, &rss20_maker)
|
||||
_assert_itunes_summary("This week we talk about surviving in a " +
|
||||
"Red state if you’re a Blue person. Or " +
|
||||
"vice versa.",
|
||||
readers, &rss20_maker)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -267,7 +267,7 @@ module RSS
|
|||
end
|
||||
end
|
||||
|
||||
def test_items
|
||||
def test_items(with_convenience_way=true)
|
||||
title = "TITLE"
|
||||
link = "http://hoge.com/"
|
||||
description = "text hoge fuga"
|
||||
|
@ -301,10 +301,10 @@ module RSS
|
|||
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}"
|
||||
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
|
||||
|
@ -312,36 +312,44 @@ module RSS
|
|||
setup_dummy_image(maker)
|
||||
end
|
||||
assert_equal(item_size, rss.items.size)
|
||||
rss.channel.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)
|
||||
rss.channel.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
|
||||
|
||||
rss = RSS::Maker.make("0.91") 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}"
|
||||
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.content[-1] <=> x.title.content[-1]
|
||||
if with_convenience_way
|
||||
y.title[-1] <=> x.title[-1]
|
||||
else
|
||||
y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}
|
||||
end
|
||||
end
|
||||
|
||||
setup_dummy_image(maker)
|
||||
end
|
||||
assert_equal(item_size, rss.items.size)
|
||||
rss.channel.items.reverse.each_with_index do |item, i|
|
||||
assert_equal("#{title}#{i}", item.title)
|
||||
assert_equal("#{link}#{i}", item.link)
|
||||
assert_equal("#{description}#{i}", item.description)
|
||||
rss.channel.items.reverse.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_items_with_new_api_since_018
|
||||
test_items(false)
|
||||
end
|
||||
|
||||
def test_textInput
|
||||
title = "fugafuga"
|
||||
description = "text hoge fuga"
|
||||
|
|
|
@ -209,7 +209,7 @@ module RSS
|
|||
end
|
||||
end
|
||||
|
||||
def test_items
|
||||
def test_items(with_convenience_way=true)
|
||||
title = "TITLE"
|
||||
link = "http://hoge.com/"
|
||||
description = "text hoge fuga"
|
||||
|
@ -242,42 +242,46 @@ module RSS
|
|||
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}"
|
||||
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
|
||||
assert_equal(item_size, rss.items.size)
|
||||
rss.items.each_with_index do |item, i|
|
||||
assert_equal("#{link}#{i}", item.about)
|
||||
assert_equal("#{title}#{i}", item.title)
|
||||
assert_equal("#{link}#{i}", item.link)
|
||||
assert_equal("#{description}#{i}", item.description)
|
||||
rss.items.each_with_index do |_item, i|
|
||||
assert_equal("#{link}#{i}", _item.about)
|
||||
assert_equal("#{title}#{i}", _item.title)
|
||||
assert_equal("#{link}#{i}", _item.link)
|
||||
assert_equal("#{description}#{i}", _item.description)
|
||||
end
|
||||
|
||||
rss = 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}"
|
||||
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.content[-1] <=> x.title.content[-1]
|
||||
if with_convenience_way
|
||||
y.title[-1] <=> x.title[-1]
|
||||
else
|
||||
y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}
|
||||
end
|
||||
end
|
||||
end
|
||||
assert_equal(item_size, rss.items.size)
|
||||
rss.items.reverse.each_with_index do |item, i|
|
||||
assert_equal("#{link}#{i}", item.about)
|
||||
assert_equal("#{title}#{i}", item.title)
|
||||
assert_equal("#{link}#{i}", item.link)
|
||||
assert_equal("#{description}#{i}", item.description)
|
||||
rss.items.reverse.each_with_index do |_item, i|
|
||||
assert_equal("#{link}#{i}", _item.about)
|
||||
assert_equal("#{title}#{i}", _item.title)
|
||||
assert_equal("#{link}#{i}", _item.link)
|
||||
assert_equal("#{description}#{i}", _item.description)
|
||||
end
|
||||
|
||||
max_size = item_size / 2
|
||||
|
@ -285,20 +289,20 @@ module RSS
|
|||
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}"
|
||||
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
|
||||
assert_equal(max_size, rss.items.size)
|
||||
rss.items.each_with_index do |item, i|
|
||||
assert_equal("#{link}#{i}", item.about)
|
||||
assert_equal("#{title}#{i}", item.title)
|
||||
assert_equal("#{link}#{i}", item.link)
|
||||
assert_equal("#{description}#{i}", item.description)
|
||||
rss.items.each_with_index do |_item, i|
|
||||
assert_equal("#{link}#{i}", _item.about)
|
||||
assert_equal("#{title}#{i}", _item.title)
|
||||
assert_equal("#{link}#{i}", _item.link)
|
||||
assert_equal("#{description}#{i}", _item.description)
|
||||
end
|
||||
|
||||
max_size = 0
|
||||
|
@ -307,10 +311,10 @@ module RSS
|
|||
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}"
|
||||
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
|
||||
|
@ -322,23 +326,27 @@ module RSS
|
|||
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}"
|
||||
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
|
||||
assert_equal(item_size + max_size + 1, rss.items.size)
|
||||
rss.items.each_with_index do |item, i|
|
||||
assert_equal("#{link}#{i}", item.about)
|
||||
assert_equal("#{title}#{i}", item.title)
|
||||
assert_equal("#{link}#{i}", item.link)
|
||||
assert_equal("#{description}#{i}", item.description)
|
||||
rss.items.each_with_index do |_item, i|
|
||||
assert_equal("#{link}#{i}", _item.about)
|
||||
assert_equal("#{title}#{i}", _item.title)
|
||||
assert_equal("#{link}#{i}", _item.link)
|
||||
assert_equal("#{description}#{i}", _item.description)
|
||||
end
|
||||
end
|
||||
|
||||
def test_items_with_new_api_since_018
|
||||
test_items(false)
|
||||
end
|
||||
|
||||
def test_not_valid_items
|
||||
title = "TITLE"
|
||||
link = "http://hoge.com/"
|
||||
|
|
|
@ -353,7 +353,7 @@ module RSS
|
|||
assert_nil(rss.image)
|
||||
end
|
||||
|
||||
def test_items
|
||||
def test_items(with_convenience_way=true)
|
||||
title = "TITLE"
|
||||
link = "http://hoge.com/"
|
||||
description = "text hoge fuga"
|
||||
|
@ -407,7 +407,11 @@ module RSS
|
|||
end
|
||||
end
|
||||
maker.items.do_sort = Proc.new do |x, y|
|
||||
y.title.content[-1] <=> x.title.content[-1]
|
||||
if with_convenience_way
|
||||
y.title[-1] <=> x.title[-1]
|
||||
else
|
||||
y.title {|t| t.content[-1]} <=> x.title {|t| t.content[-1]}
|
||||
end
|
||||
end
|
||||
end
|
||||
assert_equal(item_size, rss.items.size)
|
||||
|
@ -422,6 +426,10 @@ module RSS
|
|||
end
|
||||
end
|
||||
|
||||
def test_items_with_new_api_since_018
|
||||
test_items(false)
|
||||
end
|
||||
|
||||
def test_guid
|
||||
isPermaLink = "true"
|
||||
content = "http://inessential.com/2002/09/01.php#a2"
|
||||
|
|
|
@ -268,7 +268,16 @@ module RSS
|
|||
nil, nil,
|
||||
"maker.channel.description") do |maker|
|
||||
setup_dummy_channel_atom(maker)
|
||||
maker.channel.description.content = nil
|
||||
maker.channel.description = nil
|
||||
end
|
||||
|
||||
assert_maker_atom_text_construct("feed",
|
||||
["channel", "subtitle"],
|
||||
["subtitle"],
|
||||
nil, nil,
|
||||
"maker.channel.description") do |maker|
|
||||
setup_dummy_channel_atom(maker)
|
||||
maker.channel.description {|d| d.content = nil}
|
||||
end
|
||||
|
||||
assert_maker_atom_text_construct("feed",
|
||||
|
|
471
test/rss/test_maker_itunes.rb
Normal file
471
test/rss/test_maker_itunes.rb
Normal file
|
@ -0,0 +1,471 @@
|
|||
require "rss-testcase"
|
||||
|
||||
require "rss/maker"
|
||||
|
||||
module RSS
|
||||
class TestMakerITunes < TestCase
|
||||
def test_author
|
||||
assert_maker_itunes_author(%w(channel))
|
||||
assert_maker_itunes_author(%w(items last))
|
||||
end
|
||||
|
||||
def test_block
|
||||
assert_maker_itunes_block(%w(channel))
|
||||
assert_maker_itunes_block(%w(items last))
|
||||
end
|
||||
|
||||
def test_category
|
||||
assert_maker_itunes_category(%w(channel))
|
||||
end
|
||||
|
||||
def test_image
|
||||
assert_maker_itunes_image(%w(channel))
|
||||
end
|
||||
|
||||
def test_duration
|
||||
assert_maker_itunes_duration(%w(items last))
|
||||
end
|
||||
|
||||
def test_explicit
|
||||
assert_maker_itunes_explicit(%w(channel))
|
||||
assert_maker_itunes_explicit(%w(items last))
|
||||
end
|
||||
|
||||
def test_keywords
|
||||
assert_maker_itunes_keywords(%w(channel))
|
||||
assert_maker_itunes_keywords(%w(items last))
|
||||
end
|
||||
|
||||
def test_new_feed_url
|
||||
assert_maker_itunes_new_feed_url(%w(channel))
|
||||
end
|
||||
|
||||
def test_owner
|
||||
assert_maker_itunes_owner(%w(channel))
|
||||
end
|
||||
|
||||
def test_subtitle
|
||||
assert_maker_itunes_subtitle(%w(channel))
|
||||
assert_maker_itunes_subtitle(%w(items last))
|
||||
end
|
||||
|
||||
def test_summary
|
||||
assert_maker_itunes_summary(%w(channel))
|
||||
assert_maker_itunes_summary(%w(items last))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_maker_itunes_author(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
author = "John Doe"
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_author = author
|
||||
end
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_equal(author, target.itunes_author)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_block(value, boolean_value, maker_readers,
|
||||
feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_block = value
|
||||
assert_equal(value, target.itunes_block)
|
||||
assert_equal(boolean_value, target.itunes_block?)
|
||||
end
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
if [true, false].include?(value)
|
||||
feed_expected_value = value = value ? "yes" : "no"
|
||||
else
|
||||
feed_expected_value = value
|
||||
end
|
||||
assert_equal(value, target.itunes_block)
|
||||
assert_equal(boolean_value, target.itunes_block?)
|
||||
end
|
||||
|
||||
def assert_maker_itunes_block(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_block("yes", true, maker_readers, feed_readers)
|
||||
_assert_maker_itunes_block("Yes", true, maker_readers, feed_readers)
|
||||
_assert_maker_itunes_block("no", false, maker_readers, feed_readers)
|
||||
_assert_maker_itunes_block("", false, maker_readers, feed_readers)
|
||||
_assert_maker_itunes_block(true, true, maker_readers, feed_readers)
|
||||
_assert_maker_itunes_block(false, false, maker_readers, feed_readers)
|
||||
_assert_maker_itunes_block(nil, false, maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_category(categories, maker_readers, feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
categories.each do |category|
|
||||
sub_target = target.itunes_categories
|
||||
if category.is_a?(Array)
|
||||
category.each do |sub_category|
|
||||
sub_target = sub_target.new_category
|
||||
sub_target.text = sub_category
|
||||
end
|
||||
else
|
||||
sub_target.new_category.text = category
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
actual_categories = target.itunes_categories.collect do |category|
|
||||
cat = category.text
|
||||
if category.itunes_categories.empty?
|
||||
cat
|
||||
else
|
||||
[cat, *category.itunes_categories.collect {|c| c.text}]
|
||||
end
|
||||
end
|
||||
assert_equal(categories, actual_categories)
|
||||
end
|
||||
|
||||
def assert_maker_itunes_category(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_category(["Audio Blogs"],
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_category([["Arts & Entertainment", "Games"]],
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_category([["Arts & Entertainment", "Games"],
|
||||
["Technology", "Computers"],
|
||||
"Audio Blogs"],
|
||||
maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_maker_itunes_image(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
url = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
|
||||
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_image = url
|
||||
end
|
||||
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_not_nil(target.itunes_image)
|
||||
assert_equal(url, target.itunes_image.href)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_duration(hour, minute, second, value,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_duration_by_value(hour, minute, second, value,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,
|
||||
value,
|
||||
maker_readers,
|
||||
feed_readers)
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_duration_by(hour, minute, second, value,
|
||||
maker_readers, feed_readers)
|
||||
expected_value = nil
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
expected_value = yield(target)
|
||||
assert_equal(expected_value, target.itunes_duration)
|
||||
target.itunes_duration do |duration|
|
||||
assert_equal([hour, minute, second, expected_value],
|
||||
[duration.hour, duration.minute,
|
||||
duration.second, duration.content])
|
||||
end
|
||||
end
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
duration = target.itunes_duration
|
||||
assert_not_nil(duration)
|
||||
assert_equal([hour, minute, second, expected_value],
|
||||
[duration.hour, duration.minute,
|
||||
duration.second, duration.content])
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_duration_by_value(hour, minute, second, value,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_duration_by(hour, minute, second, value,
|
||||
maker_readers, feed_readers) do |target|
|
||||
target.itunes_duration = value
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_duration_by_hour_minute_second(hour, minute, second,
|
||||
value,
|
||||
maker_readers,
|
||||
feed_readers)
|
||||
_assert_maker_itunes_duration_by(hour, minute, second, value,
|
||||
maker_readers, feed_readers) do |target|
|
||||
target.itunes_duration do |duration|
|
||||
duration.hour = hour
|
||||
duration.minute = minute
|
||||
duration.second = second
|
||||
end
|
||||
value.split(":").collect {|v| "%02d" % v.to_i}.join(":")
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_duration_invalid_value(value, maker_readers)
|
||||
assert_raise(ArgumentError) do
|
||||
::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_duration = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_maker_itunes_duration(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_duration(7, 14, 5, "07:14:05", maker_readers,
|
||||
feed_readers)
|
||||
_assert_maker_itunes_duration(7, 14, 5, "7:14:05", maker_readers,
|
||||
feed_readers)
|
||||
_assert_maker_itunes_duration(0, 4, 55, "04:55", maker_readers,
|
||||
feed_readers)
|
||||
_assert_maker_itunes_duration(0, 4, 5, "4:05", maker_readers,
|
||||
feed_readers)
|
||||
|
||||
_assert_maker_itunes_duration_invalid_value("5", maker_readers)
|
||||
_assert_maker_itunes_duration_invalid_value("09:07:14:05", maker_readers)
|
||||
_assert_maker_itunes_duration_invalid_value("10:5", maker_readers)
|
||||
_assert_maker_itunes_duration_invalid_value("10:03:5", maker_readers)
|
||||
_assert_maker_itunes_duration_invalid_value("10:3:05", maker_readers)
|
||||
|
||||
_assert_maker_itunes_duration_invalid_value("xx:xx:xx", maker_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_explicit(explicit, value,
|
||||
maker_readers, feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_explicit = value
|
||||
assert_equal(explicit, target.itunes_explicit?)
|
||||
end
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_equal(value, target.itunes_explicit)
|
||||
assert_equal(explicit, target.itunes_explicit?)
|
||||
end
|
||||
|
||||
def assert_maker_itunes_explicit(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_explicit(true, "yes", maker_readers, feed_readers)
|
||||
_assert_maker_itunes_explicit(false, "clean",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_explicit(nil, "no", maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_keywords(keywords, value,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords_by_value(keywords, value,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords_by_keywords(keywords, maker_readers,
|
||||
feed_readers)
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_keywords_by(keywords, maker_readers, feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
yield(target)
|
||||
end
|
||||
assert_nothing_raised do
|
||||
rss20 = ::RSS::Parser.parse(rss20.to_s)
|
||||
end
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_equal(keywords, target.itunes_keywords)
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_keywords_by_value(keywords, value,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords_by(keywords, maker_readers,
|
||||
feed_readers) do |target|
|
||||
target.itunes_keywords = value
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_keywords_by_keywords(keywords,
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords_by(keywords, maker_readers,
|
||||
feed_readers) do |target|
|
||||
target.itunes_keywords = keywords
|
||||
end
|
||||
end
|
||||
|
||||
def assert_maker_itunes_keywords(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_keywords(["salt"], "salt",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords(["salt"], " salt ",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords(["salt", "pepper", "shaker", "exciting"],
|
||||
"salt, pepper, shaker, exciting",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords(["metric", "socket", "wrenches",
|
||||
"toolsalt"],
|
||||
"metric, socket, wrenches, toolsalt",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_keywords(["olitics", "red", "blue", "state"],
|
||||
"olitics, red, blue, state",
|
||||
maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_maker_itunes_new_feed_url(maker_readers, feed_readers=nil)
|
||||
feed_readers ||= maker_readers
|
||||
url = "http://newlocation.com/example.rss"
|
||||
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_new_feed_url = url
|
||||
end
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_equal(url, target.itunes_new_feed_url)
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_owner(name, email, maker_readers, feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
owner = target.itunes_owner
|
||||
owner.itunes_name = name
|
||||
owner.itunes_email = email
|
||||
end
|
||||
owner = chain_reader(rss20, feed_readers).itunes_owner
|
||||
if name.nil? and email.nil?
|
||||
assert_nil(owner)
|
||||
else
|
||||
assert_not_nil(owner)
|
||||
assert_equal(name, owner.itunes_name)
|
||||
assert_equal(email, owner.itunes_email)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_maker_itunes_owner(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_owner("John Doe", "john.doe@example.com",
|
||||
maker_readers, feed_readers)
|
||||
|
||||
not_set_name = (["maker"] + maker_readers + ["itunes_owner"]).join(".")
|
||||
assert_not_set_error(not_set_name, ["itunes_name"]) do
|
||||
_assert_maker_itunes_owner(nil, "john.doe@example.com",
|
||||
maker_readers, feed_readers)
|
||||
end
|
||||
assert_not_set_error(not_set_name, ["itunes_email"]) do
|
||||
_assert_maker_itunes_owner("John Doe", nil,
|
||||
maker_readers, feed_readers)
|
||||
end
|
||||
|
||||
_assert_maker_itunes_owner(nil, nil, maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_subtitle(subtitle, maker_readers, feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_subtitle = subtitle
|
||||
end
|
||||
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_equal(subtitle, target.itunes_subtitle)
|
||||
end
|
||||
|
||||
def assert_maker_itunes_subtitle(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_subtitle("A show about everything",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_subtitle("A short primer on table spices",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_subtitle("Comparing socket wrenches is fun!",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_subtitle("Red + Blue != Purple",
|
||||
maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
|
||||
def _assert_maker_itunes_summary(summary, maker_readers, feed_readers)
|
||||
rss20 = ::RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
target = chain_reader(maker, maker_readers)
|
||||
target.itunes_summary = summary
|
||||
end
|
||||
|
||||
target = chain_reader(rss20, feed_readers)
|
||||
assert_equal(summary, target.itunes_summary)
|
||||
end
|
||||
|
||||
def assert_maker_itunes_summary(maker_readers, feed_readers=nil)
|
||||
_wrap_assertion do
|
||||
feed_readers ||= maker_readers
|
||||
_assert_maker_itunes_summary("All About Everything is a show about " +
|
||||
"everything. Each week we dive into any " +
|
||||
"subject known to man and talk about it " +
|
||||
"as much as we can. Look for our Podcast " +
|
||||
"in the iTunes Music Store",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_summary("This week we talk about salt and pepper " +
|
||||
"shakers, comparing and contrasting pour " +
|
||||
"rates, construction materials, and " +
|
||||
"overall aesthetics. Come and join the " +
|
||||
"party!",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_summary("This week we talk about metric vs. old " +
|
||||
"english socket wrenches. Which one is " +
|
||||
"better? Do you really need both? Get " +
|
||||
"all of your answers here.",
|
||||
maker_readers, feed_readers)
|
||||
_assert_maker_itunes_summary("This week we talk about surviving in a " +
|
||||
"Red state if you’re a Blue person. Or " +
|
||||
"vice versa.",
|
||||
maker_readers, feed_readers)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -39,8 +39,8 @@ module RSS
|
|||
href = 'http://example.com/index.xsl'
|
||||
type = 'text/xsl'
|
||||
rss = RSS::Maker.make("1.0") do |maker|
|
||||
maker.xml_stylesheets.new_xml_stylesheet do |xss|
|
||||
xss.href = href
|
||||
maker.xml_stylesheets.new_xml_stylesheet do |_xss|
|
||||
_xss.href = href
|
||||
end
|
||||
|
||||
setup_dummy_channel(maker)
|
||||
|
|
|
@ -1,14 +1,4 @@
|
|||
begin
|
||||
require "fileutils"
|
||||
rescue LoadError
|
||||
module FileUtils
|
||||
module_function
|
||||
def rm_f(target)
|
||||
File.unlink(target)
|
||||
rescue Errno::ENOENT
|
||||
end
|
||||
end
|
||||
end
|
||||
require 'fileutils'
|
||||
|
||||
require "rss-testcase"
|
||||
|
||||
|
@ -28,7 +18,7 @@ EOR
|
|||
@rss_file = "rss10.rdf"
|
||||
File.open(@rss_file, "w") {|f| f.print(@rss10)}
|
||||
end
|
||||
|
||||
|
||||
def teardown
|
||||
Parser.default_parser = @_default_parser
|
||||
FileUtils.rm_f(@rss_file)
|
||||
|
|
|
@ -262,8 +262,8 @@ module RSS
|
|||
|
||||
assert_equal(@trackback_elems[:ping], item.trackback_ping)
|
||||
assert_equal(@trackback_elems[:about].size, item.trackback_abouts.size)
|
||||
item.trackback_abouts.each_with_index do |about, i|
|
||||
assert_equal(@trackback_elems[:about][i], about.value)
|
||||
item.trackback_abouts.each_with_index do |about, j|
|
||||
assert_equal(@trackback_elems[:about][j], about.value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -538,8 +538,8 @@ module RSS
|
|||
|
||||
assert_equal(@trackback_elems[:ping], item.trackback_ping)
|
||||
assert_equal(@trackback_elems[:about].size, item.trackback_abouts.size)
|
||||
item.trackback_abouts.each_with_index do |about, i|
|
||||
assert_equal(@trackback_elems[:about][i], about.value)
|
||||
item.trackback_abouts.each_with_index do |about, j|
|
||||
assert_equal(@trackback_elems[:about][j], about.value)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -104,7 +104,9 @@ module RSS
|
|||
end
|
||||
|
||||
generator.each do |key, value|
|
||||
maker.channel.generator.__send__("#{key}=", value)
|
||||
maker.channel.generator do |g|
|
||||
g.__send__("#{key}=", value)
|
||||
end
|
||||
end
|
||||
|
||||
maker.channel.icon = icon
|
||||
|
|
144
test/rss/test_setup_maker_itunes.rb
Normal file
144
test/rss/test_setup_maker_itunes.rb
Normal file
|
@ -0,0 +1,144 @@
|
|||
require "rss-testcase"
|
||||
|
||||
require "rss/maker"
|
||||
|
||||
module RSS
|
||||
class TestSetupMakerITunes < TestCase
|
||||
def test_setup_maker_simple
|
||||
author = "John Doe"
|
||||
block = true
|
||||
categories = ["Audio Blogs"]
|
||||
image = "http://example.com/podcasts/everything/AllAboutEverything.jpg"
|
||||
duration = "4:05"
|
||||
duration_components = [0, 4, 5]
|
||||
explicit = true
|
||||
keywords = ["salt", "pepper", "shaker", "exciting"]
|
||||
new_feed_url = "http://newlocation.com/example.rss"
|
||||
owner = {:name => "John Doe", :email => "john.doe@example.com"}
|
||||
subtitle = "A show about everything"
|
||||
summary = "All About Everything is a show about " +
|
||||
"everything. Each week we dive into any " +
|
||||
"subject known to man and talk about it " +
|
||||
"as much as we can. Look for our Podcast " +
|
||||
"in the iTunes Music Store"
|
||||
|
||||
feed = RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
channel = maker.channel
|
||||
channel.itunes_author = author
|
||||
channel.itunes_block = block
|
||||
categories.each do |category|
|
||||
channel.itunes_categories.new_category.text = category
|
||||
end
|
||||
channel.itunes_image = image
|
||||
channel.itunes_explicit = explicit
|
||||
channel.itunes_keywords = keywords
|
||||
channel.itunes_owner.itunes_name = owner[:name]
|
||||
channel.itunes_owner.itunes_email = owner[:email]
|
||||
channel.itunes_subtitle = subtitle
|
||||
channel.itunes_summary = summary
|
||||
|
||||
item = maker.items.last
|
||||
item.itunes_author = author
|
||||
item.itunes_block = block
|
||||
item.itunes_duration = duration
|
||||
item.itunes_explicit = explicit
|
||||
item.itunes_keywords = keywords
|
||||
item.itunes_subtitle = subtitle
|
||||
item.itunes_summary = summary
|
||||
end
|
||||
assert_not_nil(feed)
|
||||
|
||||
new_feed = RSS::Maker.make("rss2.0") do |maker|
|
||||
feed.setup_maker(maker)
|
||||
end
|
||||
assert_not_nil(new_feed)
|
||||
|
||||
channel = new_feed.channel
|
||||
item = new_feed.items.last
|
||||
|
||||
assert_equal(author, channel.itunes_author)
|
||||
assert_equal(author, item.itunes_author)
|
||||
|
||||
assert_equal(block, channel.itunes_block?)
|
||||
assert_equal(block, item.itunes_block?)
|
||||
|
||||
assert_equal(categories,
|
||||
collect_itunes_categories(channel.itunes_categories))
|
||||
|
||||
assert_equal(image, channel.itunes_image.href)
|
||||
|
||||
assert_equal(duration_components,
|
||||
[item.itunes_duration.hour,
|
||||
item.itunes_duration.minute,
|
||||
item.itunes_duration.second])
|
||||
|
||||
assert_equal(explicit, channel.itunes_explicit?)
|
||||
assert_equal(explicit, item.itunes_explicit?)
|
||||
|
||||
assert_equal(keywords, channel.itunes_keywords)
|
||||
assert_equal(keywords, item.itunes_keywords)
|
||||
|
||||
assert_equal(owner,
|
||||
{
|
||||
:name => channel.itunes_owner.itunes_name,
|
||||
:email => channel.itunes_owner.itunes_email
|
||||
})
|
||||
|
||||
assert_equal(subtitle, channel.itunes_subtitle)
|
||||
assert_equal(subtitle, item.itunes_subtitle)
|
||||
|
||||
assert_equal(summary, channel.itunes_summary)
|
||||
assert_equal(summary, item.itunes_summary)
|
||||
end
|
||||
|
||||
def test_setup_maker_with_nested_categories
|
||||
categories = [["Arts & Entertainment", "Games"],
|
||||
["Technology", "Computers"],
|
||||
"Audio Blogs"]
|
||||
|
||||
feed = RSS::Maker.make("rss2.0") do |maker|
|
||||
setup_dummy_channel(maker)
|
||||
setup_dummy_item(maker)
|
||||
|
||||
channel = maker.channel
|
||||
categories.each do |category|
|
||||
target = channel.itunes_categories
|
||||
if category.is_a?(Array)
|
||||
category.each do |sub_category|
|
||||
target = target.new_category
|
||||
target.text = sub_category
|
||||
end
|
||||
else
|
||||
target.new_category.text = category
|
||||
end
|
||||
end
|
||||
end
|
||||
assert_not_nil(feed)
|
||||
|
||||
new_feed = RSS::Maker.make("rss2.0") do |maker|
|
||||
feed.setup_maker(maker)
|
||||
end
|
||||
assert_not_nil(new_feed)
|
||||
|
||||
channel = new_feed.channel
|
||||
|
||||
assert_equal(categories,
|
||||
collect_itunes_categories(channel.itunes_categories))
|
||||
end
|
||||
|
||||
private
|
||||
def collect_itunes_categories(categories)
|
||||
categories.collect do |c|
|
||||
rest = collect_itunes_categories(c.itunes_categories)
|
||||
if rest.empty?
|
||||
c.text
|
||||
else
|
||||
[c.text, *rest]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,7 +12,6 @@ require "rss/trackback"
|
|||
|
||||
module RSS
|
||||
class TestToS < TestCase
|
||||
|
||||
def setup
|
||||
@image_url = "http://example.com/foo.png"
|
||||
@textinput_link = "http://example.com/search.cgi"
|
||||
|
@ -435,6 +434,237 @@ module RSS
|
|||
new_about.value = about
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def assert_channel10(attrs, channel)
|
||||
_wrap_assertion do
|
||||
n_attrs = normalized_attrs(attrs)
|
||||
|
||||
names = %w(about title link description)
|
||||
assert_attributes(attrs, names, channel)
|
||||
|
||||
%w(image items textinput).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = channel.__send__(name)
|
||||
__send__("assert_channel10_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel10_image(attrs, image)
|
||||
_wrap_assertion do
|
||||
assert_attributes(attrs, %w(resource), image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel10_textinput(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
assert_attributes(attrs, %w(resource), textinput)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel10_items(attrs, items)
|
||||
_wrap_assertion do
|
||||
assert_equal(items.resources, items.Seq.lis.collect {|x| x.resource})
|
||||
items.Seq.lis.each_with_index do |li, i|
|
||||
assert_attributes(attrs[i], %w(resource), li)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_image10(attrs, image)
|
||||
_wrap_assertion do
|
||||
names = %w(about title url link)
|
||||
assert_attributes(attrs, names, image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items10(attrs, items)
|
||||
_wrap_assertion do
|
||||
names = %w(about title link description)
|
||||
items.each_with_index do |item, i|
|
||||
assert_attributes(attrs[i], names, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_textinput10(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
names = %w(about title description name link)
|
||||
assert_attributes(attrs, names, textinput)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def assert_channel09(attrs, channel)
|
||||
_wrap_assertion do
|
||||
n_attrs = normalized_attrs(attrs)
|
||||
|
||||
names = %w(title description link language rating
|
||||
copyright pubDate lastBuildDate docs
|
||||
managingEditor webMaster)
|
||||
assert_attributes(attrs, names, channel)
|
||||
|
||||
%w(skipHours skipDays).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = channel.__send__(name)
|
||||
__send__("assert_channel09_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel09_skipDays(contents, skipDays)
|
||||
_wrap_assertion do
|
||||
days = skipDays.days
|
||||
contents.each_with_index do |content, i|
|
||||
assert_equal(content, days[i].content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel09_skipHours(contents, skipHours)
|
||||
_wrap_assertion do
|
||||
hours = skipHours.hours
|
||||
contents.each_with_index do |content, i|
|
||||
assert_equal(content.to_i, hours[i].content)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_image09(attrs, image)
|
||||
_wrap_assertion do
|
||||
names = %w(url link title description)
|
||||
names << ["width", :integer]
|
||||
names << ["height", :integer]
|
||||
assert_attributes(attrs, names, image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items09(attrs, items)
|
||||
_wrap_assertion do
|
||||
names = %w(title link description)
|
||||
items.each_with_index do |item, i|
|
||||
assert_attributes(attrs[i], names, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_textinput09(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
names = %w(title description name link)
|
||||
assert_attributes(attrs, names, textinput)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def assert_channel20(attrs, channel)
|
||||
_wrap_assertion do
|
||||
n_attrs = normalized_attrs(attrs)
|
||||
|
||||
names = %w(title link description language copyright
|
||||
managingEditor webMaster pubDate
|
||||
lastBuildDate generator docs rating)
|
||||
names << ["ttl", :integer]
|
||||
assert_attributes(attrs, names, channel)
|
||||
|
||||
%w(cloud categories skipHours skipDays).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = channel.__send__(name)
|
||||
__send__("assert_channel20_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel20_skipDays(contents, skipDays)
|
||||
assert_channel09_skipDays(contents, skipDays)
|
||||
end
|
||||
|
||||
def assert_channel20_skipHours(contents, skipHours)
|
||||
assert_channel09_skipHours(contents, skipHours)
|
||||
end
|
||||
|
||||
def assert_channel20_cloud(attrs, cloud)
|
||||
_wrap_assertion do
|
||||
names = %w(domain path registerProcedure protocol)
|
||||
names << ["port", :integer]
|
||||
assert_attributes(attrs, names, cloud)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_channel20_categories(attrs, categories)
|
||||
_wrap_assertion do
|
||||
names = %w(domain content)
|
||||
categories.each_with_index do |category, i|
|
||||
assert_attributes(attrs[i], names, category)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_image20(attrs, image)
|
||||
_wrap_assertion do
|
||||
names = %w(url link title description)
|
||||
names << ["width", :integer]
|
||||
names << ["height", :integer]
|
||||
assert_attributes(attrs, names, image)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20(attrs, items)
|
||||
_wrap_assertion do
|
||||
names = %w(about title link description)
|
||||
items.each_with_index do |item, i|
|
||||
assert_attributes(attrs[i], names, item)
|
||||
|
||||
n_attrs = normalized_attrs(attrs[i])
|
||||
|
||||
%w(source enclosure categories guid).each do |name|
|
||||
value = n_attrs[name]
|
||||
if value
|
||||
target = item.__send__(name)
|
||||
__send__("assert_items20_#{name}", value, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_source(attrs, source)
|
||||
_wrap_assertion do
|
||||
assert_attributes(attrs, %w(url content), source)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_enclosure(attrs, enclosure)
|
||||
_wrap_assertion do
|
||||
names = ["url", ["length", :integer], "type"]
|
||||
assert_attributes(attrs, names, enclosure)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_categories(attrs, categories)
|
||||
_wrap_assertion do
|
||||
assert_channel20_categories(attrs, categories)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_items20_guid(attrs, guid)
|
||||
_wrap_assertion do
|
||||
names = [["isPermaLink", :boolean], ["content"]]
|
||||
assert_attributes(attrs, names, guid)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_textinput20(attrs, textinput)
|
||||
_wrap_assertion do
|
||||
names = %w(title description name link)
|
||||
assert_attributes(attrs, names, textinput)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ require "rss-testcase"
|
|||
module RSS
|
||||
class TestVersion < TestCase
|
||||
def test_version
|
||||
assert_equal("0.1.7", ::RSS::VERSION)
|
||||
assert_equal("0.1.8", ::RSS::VERSION)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue