mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	in trunk. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32305 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			473 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			473 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
require 'rubygems'
 | 
						|
require 'minitest/autorun'
 | 
						|
require 'rdoc/rdoc'
 | 
						|
require 'rdoc/ri'
 | 
						|
require 'rdoc/markup'
 | 
						|
require 'tmpdir'
 | 
						|
require 'fileutils'
 | 
						|
require 'pp'
 | 
						|
 | 
						|
class TestRDocRIStore < MiniTest::Unit::TestCase
 | 
						|
 | 
						|
  OBJECT_ANCESTORS = defined?(::BasicObject) ? %w[BasicObject] : []
 | 
						|
 | 
						|
  def setup
 | 
						|
    RDoc::TopLevel.reset
 | 
						|
 | 
						|
    @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_store_#{$$}"
 | 
						|
    @s = RDoc::RI::Store.new @tmpdir
 | 
						|
 | 
						|
    @top_level = RDoc::TopLevel.new 'file.rb'
 | 
						|
 | 
						|
    @klass = @top_level.add_class RDoc::NormalClass, 'Object'
 | 
						|
    @klass.add_comment 'original', @top_level
 | 
						|
 | 
						|
    @cmeth = RDoc::AnyMethod.new nil, 'cmethod'
 | 
						|
    @cmeth.singleton = true
 | 
						|
    @cmeth.record_location @top_level
 | 
						|
 | 
						|
    @meth = RDoc::AnyMethod.new nil, 'method'
 | 
						|
    @meth.record_location @top_level
 | 
						|
 | 
						|
    @meth_bang = RDoc::AnyMethod.new nil, 'method!'
 | 
						|
    @meth_bang.record_location @top_level
 | 
						|
 | 
						|
    @attr = RDoc::Attr.new nil, 'attr', 'RW', ''
 | 
						|
    @attr.record_location @top_level
 | 
						|
 | 
						|
    @klass.add_method @cmeth
 | 
						|
    @klass.add_method @meth
 | 
						|
    @klass.add_method @meth_bang
 | 
						|
    @klass.add_attribute @attr
 | 
						|
 | 
						|
    @nest_klass = @klass.add_class RDoc::NormalClass, 'SubClass'
 | 
						|
    @nest_meth = RDoc::AnyMethod.new nil, 'method'
 | 
						|
    @nest_meth.record_location @top_level
 | 
						|
 | 
						|
    @nest_incl = RDoc::Include.new 'Incl', ''
 | 
						|
    @nest_incl.record_location @top_level
 | 
						|
 | 
						|
    @nest_klass.add_method @nest_meth
 | 
						|
    @nest_klass.add_include @nest_incl
 | 
						|
 | 
						|
    @RM = RDoc::Markup
 | 
						|
  end
 | 
						|
 | 
						|
  def teardown
 | 
						|
    FileUtils.rm_rf @tmpdir
 | 
						|
  end
 | 
						|
 | 
						|
  def mu_pp obj
 | 
						|
    s = ''
 | 
						|
    s = PP.pp obj, s
 | 
						|
    s.force_encoding Encoding.default_external if defined? Encoding
 | 
						|
    s.chomp
 | 
						|
  end
 | 
						|
 | 
						|
  def assert_cache imethods, cmethods, attrs, modules, ancestors = {}
 | 
						|
    imethods ||= { 'Object' => %w[method method!] }
 | 
						|
    cmethods ||= { 'Object' => %w[cmethod] }
 | 
						|
    attrs    ||= { 'Object' => ['attr_accessor attr'] }
 | 
						|
 | 
						|
    # this is sort-of a hack
 | 
						|
    @s.clean_cache_collection ancestors
 | 
						|
 | 
						|
    expected = {
 | 
						|
      :ancestors        => ancestors,
 | 
						|
      :attributes       => attrs,
 | 
						|
      :class_methods    => cmethods,
 | 
						|
      :encoding         => nil,
 | 
						|
      :instance_methods => imethods,
 | 
						|
      :modules          => modules,
 | 
						|
    }
 | 
						|
 | 
						|
    @s.save_cache
 | 
						|
 | 
						|
    assert_equal expected, @s.cache
 | 
						|
  end
 | 
						|
 | 
						|
  def assert_directory path
 | 
						|
    assert File.directory?(path), "#{path} is not a directory"
 | 
						|
  end
 | 
						|
 | 
						|
  def assert_file path
 | 
						|
    assert File.file?(path), "#{path} is not a file"
 | 
						|
  end
 | 
						|
 | 
						|
  def refute_file path
 | 
						|
    refute File.exist?(path), "#{path} exists"
 | 
						|
  end
 | 
						|
 | 
						|
  def test_attributes
 | 
						|
    @s.cache[:attributes]['Object'] = %w[attr]
 | 
						|
 | 
						|
    expected = { 'Object' => %w[attr] }
 | 
						|
 | 
						|
    assert_equal expected, @s.attributes
 | 
						|
  end
 | 
						|
 | 
						|
  def test_class_file
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'cdesc-Object.ri'),
 | 
						|
                 @s.class_file('Object')
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'SubClass', 'cdesc-SubClass.ri'),
 | 
						|
                 @s.class_file('Object::SubClass')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_class_methods
 | 
						|
    @s.cache[:class_methods]['Object'] = %w[method]
 | 
						|
 | 
						|
    expected = { 'Object' => %w[method] }
 | 
						|
 | 
						|
    assert_equal expected, @s.class_methods
 | 
						|
  end
 | 
						|
 | 
						|
  def test_class_path
 | 
						|
    assert_equal File.join(@tmpdir, 'Object'), @s.class_path('Object')
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'SubClass'),
 | 
						|
                 @s.class_path('Object::SubClass')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_dry_run
 | 
						|
    refute @s.dry_run
 | 
						|
 | 
						|
    @s.dry_run = true
 | 
						|
 | 
						|
    assert @s.dry_run
 | 
						|
  end
 | 
						|
 | 
						|
  def test_friendly_path
 | 
						|
    @s.path = @tmpdir
 | 
						|
    @s.type = nil
 | 
						|
    assert_equal @s.path, @s.friendly_path
 | 
						|
 | 
						|
    @s.type = :extra
 | 
						|
    assert_equal @s.path, @s.friendly_path
 | 
						|
 | 
						|
    @s.type = :system
 | 
						|
    assert_equal "ruby core", @s.friendly_path
 | 
						|
 | 
						|
    @s.type = :site
 | 
						|
    assert_equal "ruby site", @s.friendly_path
 | 
						|
 | 
						|
    @s.type = :home
 | 
						|
    assert_equal "~/.ri", @s.friendly_path
 | 
						|
 | 
						|
    @s.type = :gem
 | 
						|
    @s.path = "#{@tmpdir}/gem_repository/doc/gem_name-1.0/ri"
 | 
						|
    assert_equal "gem gem_name-1.0", @s.friendly_path
 | 
						|
  end
 | 
						|
 | 
						|
  def test_instance_methods
 | 
						|
    @s.cache[:instance_methods]['Object'] = %w[method]
 | 
						|
 | 
						|
    expected = { 'Object' => %w[method] }
 | 
						|
 | 
						|
    assert_equal expected, @s.instance_methods
 | 
						|
  end
 | 
						|
 | 
						|
  def test_load_cache
 | 
						|
    cache = {
 | 
						|
      :encoding => :encoding_value,
 | 
						|
      :methods  => %w[Object#method],
 | 
						|
      :modules  => %w[Object],
 | 
						|
    }
 | 
						|
 | 
						|
    Dir.mkdir @tmpdir
 | 
						|
 | 
						|
    open File.join(@tmpdir, 'cache.ri'), 'wb' do |io|
 | 
						|
      Marshal.dump cache, io
 | 
						|
    end
 | 
						|
 | 
						|
    @s.load_cache
 | 
						|
 | 
						|
    assert_equal cache, @s.cache
 | 
						|
 | 
						|
    assert_equal :encoding_value, @s.encoding
 | 
						|
  end
 | 
						|
 | 
						|
  def test_load_cache_encoding_differs
 | 
						|
    skip "Encoding not implemented" unless Object.const_defined? :Encoding
 | 
						|
 | 
						|
    cache = {
 | 
						|
      :encoding => Encoding::ISO_8859_1,
 | 
						|
      :methods  => %w[Object#method],
 | 
						|
      :modules  => %w[Object],
 | 
						|
    }
 | 
						|
 | 
						|
    Dir.mkdir @tmpdir
 | 
						|
 | 
						|
    open File.join(@tmpdir, 'cache.ri'), 'wb' do |io|
 | 
						|
      Marshal.dump cache, io
 | 
						|
    end
 | 
						|
 | 
						|
    @s.encoding = Encoding::UTF_8
 | 
						|
 | 
						|
    @s.load_cache
 | 
						|
 | 
						|
    assert_equal cache, @s.cache
 | 
						|
 | 
						|
    assert_equal Encoding::UTF_8, @s.encoding
 | 
						|
  end
 | 
						|
 | 
						|
  def test_load_cache_no_cache
 | 
						|
    cache = {
 | 
						|
      :ancestors        => {},
 | 
						|
      :attributes       => {},
 | 
						|
      :class_methods    => {},
 | 
						|
      :encoding         => nil,
 | 
						|
      :instance_methods => {},
 | 
						|
      :modules          => [],
 | 
						|
    }
 | 
						|
 | 
						|
    @s.load_cache
 | 
						|
 | 
						|
    assert_equal cache, @s.cache
 | 
						|
  end
 | 
						|
 | 
						|
  def test_load_class
 | 
						|
    @s.save_class @klass
 | 
						|
 | 
						|
    assert_equal @klass, @s.load_class('Object')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_load_method_bang
 | 
						|
    @s.save_method @klass, @meth_bang
 | 
						|
 | 
						|
    meth = @s.load_method('Object', '#method!')
 | 
						|
    assert_equal @meth_bang, meth
 | 
						|
  end
 | 
						|
 | 
						|
  def test_method_file
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'method-i.ri'),
 | 
						|
                 @s.method_file('Object', 'Object#method')
 | 
						|
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'method%21-i.ri'),
 | 
						|
                 @s.method_file('Object', 'Object#method!')
 | 
						|
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'SubClass', 'method%21-i.ri'),
 | 
						|
                 @s.method_file('Object::SubClass', 'Object::SubClass#method!')
 | 
						|
 | 
						|
    assert_equal File.join(@tmpdir, 'Object', 'method-c.ri'),
 | 
						|
                 @s.method_file('Object', 'Object::method')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_cache
 | 
						|
    @s.save_class @klass
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
    @s.save_method @klass, @cmeth
 | 
						|
    @s.save_class @nest_klass
 | 
						|
    @s.encoding = :encoding_value
 | 
						|
 | 
						|
    @s.save_cache
 | 
						|
 | 
						|
    assert_file File.join(@tmpdir, 'cache.ri')
 | 
						|
 | 
						|
    expected = {
 | 
						|
      :attributes => { 'Object' => ['attr_accessor attr'] },
 | 
						|
      :class_methods => { 'Object' => %w[cmethod] },
 | 
						|
      :instance_methods => {
 | 
						|
        'Object' => %w[method method!],
 | 
						|
        'Object::SubClass' => %w[method],
 | 
						|
      },
 | 
						|
      :modules => %w[Object Object::SubClass],
 | 
						|
      :ancestors => {
 | 
						|
        'Object::SubClass' => %w[Incl Object],
 | 
						|
      },
 | 
						|
      :encoding => :encoding_value,
 | 
						|
    }
 | 
						|
 | 
						|
    expected[:ancestors]['Object'] = %w[BasicObject] if defined?(::BasicObject)
 | 
						|
 | 
						|
    open File.join(@tmpdir, 'cache.ri'), 'rb' do |io|
 | 
						|
      cache = Marshal.load io.read
 | 
						|
 | 
						|
      assert_equal expected, cache
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_cache_dry_run
 | 
						|
    @s.dry_run = true
 | 
						|
 | 
						|
    @s.save_class @klass
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
    @s.save_method @klass, @cmeth
 | 
						|
    @s.save_class @nest_klass
 | 
						|
 | 
						|
    @s.save_cache
 | 
						|
 | 
						|
    refute_file File.join(@tmpdir, 'cache.ri')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_cache_duplicate_methods
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
 | 
						|
    @s.save_cache
 | 
						|
 | 
						|
    assert_cache({ 'Object' => %w[method] }, {}, {}, [])
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class
 | 
						|
    @s.save_class @klass
 | 
						|
 | 
						|
    assert_directory File.join(@tmpdir, 'Object')
 | 
						|
    assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
 | 
						|
 | 
						|
    assert_cache nil, nil, nil, %w[Object], 'Object' => OBJECT_ANCESTORS
 | 
						|
 | 
						|
    assert_equal @klass, @s.load_class('Object')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class_basic_object
 | 
						|
    @klass.instance_variable_set :@superclass, nil
 | 
						|
 | 
						|
    @s.save_class @klass
 | 
						|
 | 
						|
    assert_directory File.join(@tmpdir, 'Object')
 | 
						|
    assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
 | 
						|
 | 
						|
    assert_cache(nil, nil, nil, %w[Object])
 | 
						|
 | 
						|
    assert_equal @klass, @s.load_class('Object')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class_delete
 | 
						|
    # save original
 | 
						|
    @s.save_class @klass
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
    @s.save_method @klass, @meth_bang
 | 
						|
    @s.save_method @klass, @cmeth
 | 
						|
    @s.save_cache
 | 
						|
 | 
						|
    klass = RDoc::NormalClass.new 'Object'
 | 
						|
 | 
						|
    meth = klass.add_method RDoc::AnyMethod.new(nil, 'replace')
 | 
						|
    meth.record_location @top_level
 | 
						|
 | 
						|
    # load original, save newly updated class
 | 
						|
    @s = RDoc::RI::Store.new @tmpdir
 | 
						|
    @s.load_cache
 | 
						|
    @s.save_class klass
 | 
						|
    @s.save_cache
 | 
						|
 | 
						|
    # load from disk again
 | 
						|
    @s = RDoc::RI::Store.new @tmpdir
 | 
						|
    @s.load_cache
 | 
						|
 | 
						|
    @s.load_class 'Object'
 | 
						|
 | 
						|
    assert_cache({ 'Object' => %w[replace] }, {},
 | 
						|
                 { 'Object' => %w[attr_accessor\ attr] }, %w[Object],
 | 
						|
                 'Object' => OBJECT_ANCESTORS)
 | 
						|
 | 
						|
    refute File.exist? @s.method_file(@klass.full_name, @meth.full_name)
 | 
						|
    refute File.exist? @s.method_file(@klass.full_name, @meth_bang.full_name)
 | 
						|
    refute File.exist? @s.method_file(@klass.full_name, @cmeth.full_name)
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class_dry_run
 | 
						|
    @s.dry_run = true
 | 
						|
 | 
						|
    @s.save_class @klass
 | 
						|
 | 
						|
    refute_file File.join(@tmpdir, 'Object')
 | 
						|
    refute_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class_merge
 | 
						|
    @s.save_class @klass
 | 
						|
 | 
						|
    klass = RDoc::NormalClass.new 'Object'
 | 
						|
    klass.add_comment 'new comment', @top_level
 | 
						|
 | 
						|
    s = RDoc::RI::Store.new @tmpdir
 | 
						|
    s.save_class klass
 | 
						|
 | 
						|
    s = RDoc::RI::Store.new @tmpdir
 | 
						|
 | 
						|
    inner = @RM::Document.new @RM::Paragraph.new 'new comment'
 | 
						|
    inner.file = @top_level.absolute_name
 | 
						|
 | 
						|
    document = @RM::Document.new inner
 | 
						|
 | 
						|
    assert_equal document, s.load_class('Object').comment
 | 
						|
  end
 | 
						|
 | 
						|
  # This is a functional test
 | 
						|
  def test_save_class_merge_constant
 | 
						|
    tl = RDoc::TopLevel.new 'file.rb'
 | 
						|
    klass = RDoc::NormalClass.new 'C'
 | 
						|
    klass.add_comment 'comment', tl
 | 
						|
 | 
						|
    const = klass.add_constant RDoc::Constant.new('CONST', nil, nil)
 | 
						|
    const.record_location tl
 | 
						|
 | 
						|
    @s.save_class klass
 | 
						|
 | 
						|
    RDoc::RDoc.reset
 | 
						|
 | 
						|
    klass2 = RDoc::NormalClass.new 'C'
 | 
						|
    klass2.record_location tl
 | 
						|
 | 
						|
    s = RDoc::RI::Store.new @tmpdir
 | 
						|
    s.save_class klass2
 | 
						|
 | 
						|
    s = RDoc::RI::Store.new @tmpdir
 | 
						|
 | 
						|
    result = s.load_class 'C'
 | 
						|
 | 
						|
    assert_empty result.constants
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class_methods
 | 
						|
    @s.save_class @klass
 | 
						|
 | 
						|
    assert_directory File.join(@tmpdir, 'Object')
 | 
						|
    assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
 | 
						|
 | 
						|
    assert_cache nil, nil, nil, %w[Object], 'Object' => OBJECT_ANCESTORS
 | 
						|
 | 
						|
    assert_equal @klass, @s.load_class('Object')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_class_nested
 | 
						|
    @s.save_class @nest_klass
 | 
						|
 | 
						|
    assert_directory File.join(@tmpdir, 'Object', 'SubClass')
 | 
						|
    assert_file File.join(@tmpdir, 'Object', 'SubClass', 'cdesc-SubClass.ri')
 | 
						|
 | 
						|
    assert_cache({ 'Object::SubClass' => %w[method] }, {}, {},
 | 
						|
                 %w[Object::SubClass], 'Object::SubClass' => %w[Incl Object])
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_method
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
 | 
						|
    assert_directory File.join(@tmpdir, 'Object')
 | 
						|
    assert_file File.join(@tmpdir, 'Object', 'method-i.ri')
 | 
						|
 | 
						|
    assert_cache({ 'Object' => %w[method] }, {}, {}, [])
 | 
						|
 | 
						|
    assert_equal @meth, @s.load_method('Object', '#method')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_method_dry_run
 | 
						|
    @s.dry_run = true
 | 
						|
 | 
						|
    @s.save_method @klass, @meth
 | 
						|
 | 
						|
    refute_file File.join(@tmpdir, 'Object')
 | 
						|
    refute_file File.join(@tmpdir, 'Object', 'method-i.ri')
 | 
						|
  end
 | 
						|
 | 
						|
  def test_save_method_nested
 | 
						|
    @s.save_method @nest_klass, @nest_meth
 | 
						|
 | 
						|
    assert_directory File.join(@tmpdir, 'Object', 'SubClass')
 | 
						|
    assert_file File.join(@tmpdir, 'Object', 'SubClass', 'method-i.ri')
 | 
						|
 | 
						|
    assert_cache({ 'Object::SubClass' => %w[method] }, {}, {}, [])
 | 
						|
  end
 | 
						|
 | 
						|
end
 | 
						|
 |