mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* lib/rss/taxonomy.rb: implemented taxonomy module.
* test/rss/test_taxonomy.rb: added tests for taxonomy support. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									9680ebebe1
								
							
						
					
					
						commit
						fb1d1a917d
					
				
					 3 changed files with 335 additions and 15 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,9 @@
 | 
			
		|||
Thu Nov 17 17:53:30 2005  Kouhei Sutou  <kou@cozmixng.org>
 | 
			
		||||
 | 
			
		||||
	* lib/rss/taxonomy.rb: implemented taxonomy module.
 | 
			
		||||
 | 
			
		||||
	* test/rss/test_taxonomy.rb: added tests for taxonomy support.
 | 
			
		||||
 | 
			
		||||
Thu Nov 17 17:40:19 2005  Kouhei Sutou  <kou@cozmixng.org>
 | 
			
		||||
 | 
			
		||||
	* lib/rss/1.0.rb: added rdf:Bag.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,32 +1,198 @@
 | 
			
		|||
# Experimental
 | 
			
		||||
 | 
			
		||||
require "rss/1.0"
 | 
			
		||||
require "rss/dublincore"
 | 
			
		||||
 | 
			
		||||
module RSS
 | 
			
		||||
 | 
			
		||||
  TAXO_PREFIX = "taxo"
 | 
			
		||||
  TAXO_NS = "http://purl.org/rss/1.0/modules/taxonomy/"
 | 
			
		||||
  TAXO_URI = "http://purl.org/rss/1.0/modules/taxonomy/"
 | 
			
		||||
 | 
			
		||||
  Element.install_ns(TAXO_PREFIX, TAXO_NS)
 | 
			
		||||
  RDF.install_ns(TAXO_PREFIX, TAXO_URI)
 | 
			
		||||
 | 
			
		||||
  TAXO_ELEMENTS = []
 | 
			
		||||
 | 
			
		||||
  %w(link).each do |name|
 | 
			
		||||
    full_name = "#{TAXO_PREFIX}_#{name}"
 | 
			
		||||
    BaseListener.install_get_text_element(TAXO_NS, name, "#{full_name}=")
 | 
			
		||||
    BaseListener.install_get_text_element(TAXO_URI, name, "#{full_name}=")
 | 
			
		||||
    TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  %w(topic topics).each do |name|
 | 
			
		||||
    class_name = Utils.to_class_name(name)
 | 
			
		||||
    BaseListener.install_class_name(TAXO_URI, name, "Taxo#{class_name}")
 | 
			
		||||
    TAXO_ELEMENTS << "#{TAXO_PREFIX}_#{name}"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  module TaxoTopicsModel
 | 
			
		||||
    extend BaseModel
 | 
			
		||||
    
 | 
			
		||||
  module TaxonomyModel
 | 
			
		||||
    attr_writer(*%w(title description creator subject publisher
 | 
			
		||||
                    contributor date format identifier source
 | 
			
		||||
                    language relation coverage rights
 | 
			
		||||
                   ).collect{|name| "#{TAXO_PREFIX}_#{name}"})
 | 
			
		||||
    def self.append_features(klass)
 | 
			
		||||
      super
 | 
			
		||||
 | 
			
		||||
      var_name = "#{TAXO_PREFIX}_topics"
 | 
			
		||||
      klass.install_have_child_element(var_name)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def taxo_validate(tags)
 | 
			
		||||
      found_topics = false
 | 
			
		||||
      tags.each do |tag|
 | 
			
		||||
        if tag == "topics"
 | 
			
		||||
          if found_topics
 | 
			
		||||
            raise TooMuchTagError.new(tag, tag_name)
 | 
			
		||||
          else
 | 
			
		||||
            found_topics = true
 | 
			
		||||
          end
 | 
			
		||||
        else
 | 
			
		||||
          raise UnknownTagError.new(tag, TAXO_URI)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    class TaxoTopics < Element
 | 
			
		||||
      include RSS10
 | 
			
		||||
      
 | 
			
		||||
      Bag = ::RSS::RDF::Bag
 | 
			
		||||
 | 
			
		||||
      class << self
 | 
			
		||||
        def required_prefix
 | 
			
		||||
          TAXO_PREFIX
 | 
			
		||||
        end
 | 
			
		||||
        
 | 
			
		||||
        def required_uri
 | 
			
		||||
          TAXO_URI
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @tag_name = "topics"
 | 
			
		||||
      
 | 
			
		||||
      install_have_child_element("Bag")
 | 
			
		||||
        
 | 
			
		||||
      install_must_call_validator('rdf', ::RSS::RDF::URI)
 | 
			
		||||
 | 
			
		||||
      def initialize(bag=Bag.new)
 | 
			
		||||
        super()
 | 
			
		||||
        @Bag = bag
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def full_name
 | 
			
		||||
        tag_name_with_prefix(TAXO_PREFIX)
 | 
			
		||||
      end
 | 
			
		||||
      
 | 
			
		||||
      def to_s(need_convert=true, indent=calc_indent)
 | 
			
		||||
        rv = tag(indent) do |next_indent|
 | 
			
		||||
          [
 | 
			
		||||
           Bag_element(need_convert, next_indent),
 | 
			
		||||
           other_element(need_convert, next_indent),
 | 
			
		||||
          ]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      private
 | 
			
		||||
      def children
 | 
			
		||||
        [@Bag]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def _tags
 | 
			
		||||
        rv = []
 | 
			
		||||
        rv << [::RSS::RDF::URI, 'Bag'] unless @Bag.nil?
 | 
			
		||||
        rv
 | 
			
		||||
      end
 | 
			
		||||
      
 | 
			
		||||
      def rdf_validate(tags)
 | 
			
		||||
        _validate(tags, [["Bag", nil]])
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  class Channel; extend TaxonomyModel;	end
 | 
			
		||||
  class Item; extend TaxonomyModel;	end
 | 
			
		||||
  class Image; extend TaxonomyModel;	end
 | 
			
		||||
  class TextInput; extend TaxonomyModel;	end
 | 
			
		||||
  
 | 
			
		||||
  module TaxoTopicModel
 | 
			
		||||
    extend BaseModel
 | 
			
		||||
    
 | 
			
		||||
    def self.append_features(klass)
 | 
			
		||||
      super
 | 
			
		||||
      var_name = "#{TAXO_PREFIX}_topic"
 | 
			
		||||
      klass.install_have_children_element(var_name)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def taxo_validate(tags)
 | 
			
		||||
      tags.each do |tag|
 | 
			
		||||
        if tag != "topic"
 | 
			
		||||
          raise UnknownTagError.new(tag, TAXO_URI)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    class TaxoTopic < Element
 | 
			
		||||
      include RSS10
 | 
			
		||||
 | 
			
		||||
      include DublinCoreModel
 | 
			
		||||
      include TaxoTopicsModel
 | 
			
		||||
      
 | 
			
		||||
      class << self
 | 
			
		||||
        def required_prefix
 | 
			
		||||
          TAXO_PREFIX
 | 
			
		||||
        end
 | 
			
		||||
        
 | 
			
		||||
        def required_uri
 | 
			
		||||
          TAXO_URI
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      @tag_name = "topic"
 | 
			
		||||
 | 
			
		||||
      install_get_attribute("about", ::RSS::RDF::URI, true)
 | 
			
		||||
      install_text_element("#{TAXO_PREFIX}_link")
 | 
			
		||||
        
 | 
			
		||||
      def initialize(about=nil)
 | 
			
		||||
        super()
 | 
			
		||||
        @about = about
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def full_name
 | 
			
		||||
        tag_name_with_prefix(TAXO_PREFIX)
 | 
			
		||||
      end
 | 
			
		||||
      
 | 
			
		||||
      def to_s(need_convert=true, indent=calc_indent)
 | 
			
		||||
        rv = tag(indent) do |next_indent|
 | 
			
		||||
          [
 | 
			
		||||
           link_element(need_convert, next_indent),
 | 
			
		||||
           other_element(need_convert, next_indent),
 | 
			
		||||
          ]
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def taxo_validate(tags)
 | 
			
		||||
        elements = %w(link topics)
 | 
			
		||||
        counter = {}
 | 
			
		||||
        
 | 
			
		||||
        tags.each do |tag|
 | 
			
		||||
          if elements.include?(tag)
 | 
			
		||||
            counter[tag] ||= 0
 | 
			
		||||
            counter[tag] += 1
 | 
			
		||||
            raise TooMuchTagError.new(tag, tag_name) if counter[tag] > 1
 | 
			
		||||
          else
 | 
			
		||||
            raise UnknownTagError.new(tag, TAXO_URI)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      private
 | 
			
		||||
      def children
 | 
			
		||||
        [@taxo_link, @taxo_topics]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def _tags
 | 
			
		||||
        rv = []
 | 
			
		||||
        rv << [TAXO_URI, "link"] unless @taxo_link.nil?
 | 
			
		||||
        rv << [TAXO_URI, "topics"] unless @taxo_topics.nil?
 | 
			
		||||
        rv
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  class RDF
 | 
			
		||||
    include TaxoTopicModel
 | 
			
		||||
    class Channel
 | 
			
		||||
      include TaxoTopicsModel
 | 
			
		||||
    end
 | 
			
		||||
    class Item; include TaxoTopicsModel; end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										148
									
								
								test/rss/test_taxonomy.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								test/rss/test_taxonomy.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,148 @@
 | 
			
		|||
require "cgi"
 | 
			
		||||
 | 
			
		||||
require "rss-testcase"
 | 
			
		||||
 | 
			
		||||
require "rss/1.0"
 | 
			
		||||
require "rss/2.0"
 | 
			
		||||
require "rss/taxonomy"
 | 
			
		||||
 | 
			
		||||
module RSS
 | 
			
		||||
  class TestTaxonomy < TestCase
 | 
			
		||||
    
 | 
			
		||||
    def setup
 | 
			
		||||
      @prefix = "taxo"
 | 
			
		||||
      @uri = "http://purl.org/rss/1.0/modules/taxonomy/"
 | 
			
		||||
      @dc_prefix = "dc"
 | 
			
		||||
      @dc_uri = "http://purl.org/dc/elements/1.1/"
 | 
			
		||||
 | 
			
		||||
      @ns = {
 | 
			
		||||
        @prefix => @uri,
 | 
			
		||||
        @dc_prefix => @dc_uri,
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      @parents = %w(channel item)
 | 
			
		||||
      
 | 
			
		||||
      @topics_lis = [
 | 
			
		||||
        "http://meerkat.oreillynet.com/?c=cat23",
 | 
			
		||||
        "http://meerkat.oreillynet.com/?c=47",
 | 
			
		||||
        "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
 | 
			
		||||
      ]
 | 
			
		||||
 | 
			
		||||
      @topics_node = "<#{@prefix}:topics>\n"
 | 
			
		||||
      @topics_node << "  <rdf:Bag>\n"
 | 
			
		||||
      @topics_lis.each do |value|
 | 
			
		||||
        resource = CGI.escapeHTML(value)
 | 
			
		||||
        @topics_node << "    <rdf:li resource=\"#{resource}\"/>\n"
 | 
			
		||||
      end
 | 
			
		||||
      @topics_node << "  </rdf:Bag>\n"
 | 
			
		||||
      @topics_node << "</#{@prefix}:topics>"
 | 
			
		||||
 | 
			
		||||
      @topic_topics_lis = \
 | 
			
		||||
      [
 | 
			
		||||
       "http://meerkat.oreillynet.com/?c=cat23",
 | 
			
		||||
       "http://dmoz.org/Computers/Data_Formats/Markup_Languages/SGML/",
 | 
			
		||||
       "http://dmoz.org/Computers/Programming/Internet/",
 | 
			
		||||
      ]
 | 
			
		||||
 | 
			
		||||
      @topic_contents = \
 | 
			
		||||
      [
 | 
			
		||||
       {
 | 
			
		||||
         :link => "http://meerkat.oreillynet.com/?c=cat23",
 | 
			
		||||
         :title => "Data: XML",
 | 
			
		||||
         :description => "A Meerkat channel",
 | 
			
		||||
       },
 | 
			
		||||
       {
 | 
			
		||||
         :link => "http://dmoz.org/Computers/Data_Formats/Markup_Languages/XML/",
 | 
			
		||||
         :title => "XML",
 | 
			
		||||
         :subject => "XML",
 | 
			
		||||
         :description => "DMOZ category",
 | 
			
		||||
         :topics => @topic_topics_lis,
 | 
			
		||||
       }
 | 
			
		||||
      ]
 | 
			
		||||
 | 
			
		||||
      @topic_nodes = @topic_contents.collect do |info|
 | 
			
		||||
        link = info[:link]
 | 
			
		||||
        rv = "<#{@prefix}:topic rdf:about=\"#{link}\">\n"
 | 
			
		||||
        info.each do |name, value|
 | 
			
		||||
          case name
 | 
			
		||||
          when :topics
 | 
			
		||||
            rv << "<#{@prefix}:topics>\n"
 | 
			
		||||
            rv << "  <rdf:Bag>\n"
 | 
			
		||||
            value.each do |li|
 | 
			
		||||
              resource = CGI.escapeHTML(li)
 | 
			
		||||
              rv << "    <rdf:li resource=\"#{resource}\"/>\n"
 | 
			
		||||
            end
 | 
			
		||||
            rv << "  </rdf:Bag>\n"
 | 
			
		||||
            rv << "</#{@prefix}:topics>"
 | 
			
		||||
          else
 | 
			
		||||
            prefix = (name == :link ? @prefix : @dc_prefix)
 | 
			
		||||
            rv << "  <#{prefix}:#{name}>#{value}</#{prefix}:#{name}>\n"
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
        rv << "</#{@prefix}:topic>"
 | 
			
		||||
      end.join("\n")
 | 
			
		||||
      
 | 
			
		||||
      @rss_source = make_RDF(<<-EOR, @ns)
 | 
			
		||||
#{make_channel(@topics_node)}
 | 
			
		||||
#{make_image()}
 | 
			
		||||
#{make_item(@topics_node)}
 | 
			
		||||
#{make_textinput()}
 | 
			
		||||
#{@topic_nodes}
 | 
			
		||||
EOR
 | 
			
		||||
 | 
			
		||||
      @rss = Parser.parse(@rss_source)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def test_parser
 | 
			
		||||
      assert_nothing_raised do
 | 
			
		||||
        Parser.parse(@rss_source)
 | 
			
		||||
      end
 | 
			
		||||
      
 | 
			
		||||
      assert_too_much_tag("topics", "channel") do
 | 
			
		||||
        Parser.parse(make_RDF(<<-EOR, @ns))
 | 
			
		||||
#{make_channel(@topics_node * 2)}
 | 
			
		||||
#{make_item()}
 | 
			
		||||
EOR
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      assert_too_much_tag("topics", "item") do
 | 
			
		||||
        Parser.parse(make_RDF(<<-EOR, @ns))
 | 
			
		||||
#{make_channel()}
 | 
			
		||||
#{make_item(@topics_node * 2)}
 | 
			
		||||
EOR
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  
 | 
			
		||||
    def test_accessor
 | 
			
		||||
      topics = @rss.channel.taxo_topics
 | 
			
		||||
      assert_equal(@topics_lis.sort,
 | 
			
		||||
                   topics.Bag.lis.collect {|li| li.resource}.sort)
 | 
			
		||||
 | 
			
		||||
      assert_equal(@rss.taxo_topics.first, @rss.taxo_topic)
 | 
			
		||||
 | 
			
		||||
      @topic_contents.each_with_index do |info, i|
 | 
			
		||||
        topic = @rss.taxo_topics[i]
 | 
			
		||||
        info.each do |name, value|
 | 
			
		||||
          case name
 | 
			
		||||
          when :link
 | 
			
		||||
            assert_equal(value, topic.about)
 | 
			
		||||
            assert_equal(value, topic.taxo_link)
 | 
			
		||||
          when :topics
 | 
			
		||||
            assert_equal(value.sort,
 | 
			
		||||
                         topic.taxo_topics.Bag.lis.collect {|li| li.resource}.sort)
 | 
			
		||||
          else
 | 
			
		||||
            assert_equal(value, topic.__send__("dc_#{name}"))
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
    def test_to_s
 | 
			
		||||
      @parents.each do |parent|
 | 
			
		||||
        meth = "taxo_topics_element"
 | 
			
		||||
        assert_equal(@topics_node, @rss.__send__(parent).funcall(meth))
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue