require File.expand_path '../xref_test_case', __FILE__ class TestRDocContext < XrefTestCase def setup super @context = RDoc::Context.new @context.store = @store @enumerator = # 1.8 vs 1.9 Object.const_defined?(:Enumerator) ? Enumerator : Enumerable::Enumerator end def test_initialize assert_empty @context.in_files assert_equal 'unknown', @context.name assert_equal '', @context.comment assert_equal nil, @context.parent assert_equal :public, @context.visibility assert_equal 1, @context.sections.length assert_equal nil, @context.temporary_section assert_empty @context.classes_hash assert_empty @context.modules_hash assert_empty @context.method_list assert_empty @context.attributes assert_empty @context.aliases assert_empty @context.requires assert_empty @context.includes assert_empty @context.constants end def test_add_alias as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment' @context.add_alias as assert_equal [as], @context.external_aliases assert_equal [as], @context.unmatched_alias_lists['#old_name'] end def test_add @context.add RDoc::Extend, 'Ext', 'comment' @context.add RDoc::Include, 'Incl', 'comment' refute_empty @context.extends refute_empty @context.includes end def test_add_alias_method_attr top_level = @store.add_file 'file.rb' attr = RDoc::Attr.new nil, 'old_name', 'R', '' as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment' as.record_location top_level as.parent = @context @context.add_attribute attr @context.add_alias as assert_empty @context.aliases assert_empty @context.unmatched_alias_lists assert_equal %w[old_name new_name], @context.attributes.map { |m| m.name } new = @context.attributes.last assert_equal top_level, new.file end def test_add_alias_method top_level = @store.add_file 'file.rb' meth = RDoc::AnyMethod.new nil, 'old_name' meth.singleton = false as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment' as.record_location top_level as.parent = @context @context.add_method meth @context.add_alias as assert_empty @context.aliases assert_empty @context.unmatched_alias_lists assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name } new = @context.method_list.last assert_equal top_level, new.file end def test_add_alias_method_singleton meth = RDoc::AnyMethod.new nil, 'old_name' meth.singleton = true as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment' as.singleton = true as.parent = @context @context.add_method meth @context.add_alias as assert_empty @context.aliases assert_empty @context.unmatched_alias_lists assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name } assert @context.method_list.last.singleton end def test_add_class @c1.add_class RDoc::NormalClass, 'Klass', 'Object' assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass' assert_includes @store.all_classes.map { |k| k.full_name }, 'C1::Klass' end def test_add_class_basic_object skip 'BasicObject is 1.9 only' unless defined?(BasicObject) @xref_data.add_class RDoc::NormalClass, 'BasicObject' basic = @xref_data.find_module_named 'BasicObject' assert_nil basic.superclass @c1.add_class RDoc::NormalClass, 'BasicObject' basic = @c1.find_module_named 'BasicObject' assert_equal 'Object', basic.superclass end def test_add_class_object root_class = defined?(BasicObject) ? 'BasicObject' : nil @xref_data.add_class RDoc::NormalClass, 'Object' object = @xref_data.find_module_named 'Object' assert_equal root_class, object.superclass @c1.add_class RDoc::NormalClass, 'Object' object = @c1.find_module_named 'Object' assert_equal 'Object', object.superclass.full_name end def test_add_class_singleton @c1.add_class RDoc::NormalClass, 'Klass', 'Object' assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass' assert_includes @store.all_classes.map { |k| k.full_name }, 'C1::Klass' end def test_add_class_superclass @c1.add_class RDoc::NormalClass, 'Klass', 'Object' @c1.add_class RDoc::NormalClass, 'Klass', 'Other' @c1.add_class RDoc::NormalClass, 'Klass', 'Object' klass = @c1.find_module_named 'Klass' assert_equal 'Other', klass.superclass end def test_add_class_upgrade @c1.add_module RDoc::NormalModule, 'Klass' @c1.add_class RDoc::NormalClass, 'Klass', nil assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass', 'c1 classes' refute_includes @c1.modules.map { |k| k.full_name }, 'C1::Klass', 'c1 modules' assert_includes @store.all_classes.map { |k| k.full_name }, 'C1::Klass', 'TopLevel classes' refute_includes @store.all_modules.map { |k| k.full_name }, 'C1::Klass', 'TopLevel modules' end def test_add_constant const = RDoc::Constant.new 'NAME', 'value', 'comment' @context.add_constant const assert_equal [const], @context.constants end def test_add_extend ext = RDoc::Extend.new 'Name', 'comment' @context.add_extend ext assert_equal [ext], @context.extends end def test_add_include incl = RDoc::Include.new 'Name', 'comment' @context.add_include incl assert_equal [incl], @context.includes end def test_add_method meth = RDoc::AnyMethod.new nil, 'old_name' meth.visibility = nil @context.add_method meth assert_equal [meth], @context.method_list assert_equal :public, meth.visibility end def test_add_method_alias as = RDoc::Alias.new nil, 'old_name', 'new_name', 'comment' meth = RDoc::AnyMethod.new nil, 'old_name' @context.add_alias as refute_empty @context.external_aliases @context.add_method meth assert_empty @context.external_aliases assert_empty @context.unmatched_alias_lists assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name } end def test_add_method_duplicate @store.rdoc.options.verbosity = 2 meth1 = RDoc::AnyMethod.new nil, 'name' meth1.record_location @store.add_file 'first.rb' meth1.visibility = nil meth1.comment = comment 'first' @context.add_method meth1 meth2 = RDoc::AnyMethod.new nil, 'name' meth2.record_location @store.add_file 'second.rb' meth2.comment = comment 'second' _, err = verbose_capture_io do @context.add_method meth2 end expected = 'Duplicate method (unknown)#name in file second.rb, ' \ 'previously in file first.rb' assert_equal expected, err.chomp method = @context.method_list.first assert_equal 'first', method.comment.text end def test_add_method_duplicate_loading @context.store = nil meth1 = RDoc::AnyMethod.new nil, 'name' meth1.record_location @store.add_file 'first.rb' meth1.visibility = nil meth1.comment = comment 'first' @context.add_method meth1 meth2 = RDoc::AnyMethod.new nil, 'name' meth2.record_location @store.add_file 'second.rb' meth2.comment = comment 'second' _, err = verbose_capture_io do @context.add_method meth2 end assert_empty err method = @context.method_list.first assert_equal 'first', method.comment.text end def test_add_module @c1.add_module RDoc::NormalModule, 'Mod' assert_includes @c1.modules.map { |m| m.full_name }, 'C1::Mod' end def test_add_module_alias tl = @store.add_file 'file.rb' c3_c4 = @c2.add_module_alias @c2_c3, 'C4', tl alias_constant = @c2.constants.first assert_equal 'C2::C4', c3_c4.full_name assert_equal tl, alias_constant.file end def test_add_module_alias_top_level store = RDoc::Store.new top_level = store.add_file 'file.rb' klass = top_level.add_class RDoc::NormalClass, 'Klass' klass.comment = 'klass comment' object = top_level.add_class RDoc::NormalClass, 'Object' top_level.add_module_alias klass, 'A', top_level refute_empty object.constants constant = object.constants.first assert_equal 'klass comment', constant.comment end def test_add_module_class k = @c1.add_class RDoc::NormalClass, 'Klass', nil m = @c1.add_module RDoc::NormalModule, 'Klass' assert_equal k, m, 'returns class' assert_empty @c1.modules end def test_add_require req = RDoc::Require.new 'require', 'comment' @c1.add_require req assert_empty @c1.requires assert_includes @c1.top_level.requires, req end def test_add_section default_section = @context.sections.first @context.add_section nil, comment('comment', @top_level) assert_equal 1, @context.sections.length assert_equal [comment("comment", @top_level)], @context.sections.first.comments @context.add_section nil, comment('new comment', @top_level) assert_equal 1, @context.sections.length assert_equal [comment('comment', @top_level), comment('new comment', @top_level)], @context.sections.first.comments @context.add_section 'other', comment('', @top_level) assert_equal 2, @context.sections.length new_section = @context.sections.find { |section| section.title == 'other' } assert new_section assert_equal default_section, @context.current_section end def test_add_section_no_comment default_section = @context.sections.first @context.add_section nil assert_equal 1, @context.sections.length @context.add_section 'other' assert_equal 2, @context.sections.length new_section = @context.sections.find { |section| section.title == 'other' } assert new_section assert_equal default_section, @context.current_section end def test_add_to incl = RDoc::Include.new 'Name', 'comment' arr = [] @context.add_to arr, incl assert_includes arr, incl assert_equal @context, incl.parent assert_equal @context.current_section, incl.section end def test_add_to_temporary_section incl = RDoc::Include.new 'Name', 'comment' arr = [] section = @context.add_section 'temporary', RDoc::Comment.new('', @top_level) @context.temporary_section = section @context.add_to arr, incl assert_includes arr, incl assert_equal @context, incl.parent assert_equal section, incl.section end def test_add_to_no_document_self incl = RDoc::Include.new 'Name', 'comment' arr = [] @context.document_self = false @context.add_to arr, incl refute_includes arr, incl end def test_add_to_done_documenting incl = RDoc::Include.new 'Name', 'comment' arr = [] @context.done_documenting = true @context.add_to arr, incl refute_includes arr, incl end def bench_add_include cm = RDoc::ClassModule.new 'Klass' assert_performance_linear 0.9 do |count| count.times do |i| cm.add_include RDoc::Include.new("N::M#{i}", nil) end end end def test_child_name assert_equal 'C1::C1', @c1.child_name('C1') end def test_classes assert_equal %w[C2::C3], @c2.classes.map { |k| k.full_name } assert_equal %w[C3::H1 C3::H2], @c3.classes.map { |k| k.full_name }.sort end def test_current_section default_section = @context.current_section new_section = @context.add_section 'other', RDoc::Comment.new('', @top_level) @context.temporary_section = new_section assert_equal new_section, @context.current_section assert_equal default_section, @context.current_section end def test_defined_in_eh assert @c1.defined_in?(@c1.top_level) refute @c1.defined_in?(@store.add_file('name.rb')) end def test_equals2 assert_equal @c3, @c3 refute_equal @c2, @c3 refute_equal @c2_c3, @c3 end def test_each_method_enumerator assert_kind_of @enumerator, @c1.each_method end def test_each_section sects = [] consts = [] attrs = [] @c1.each_section do |section, constants, attributes| sects << section consts << constants attrs << attributes end assert_equal [nil, 'separate'], sects.map { |section| section.title } expected_consts = [ [@c1.constants.first], [], ] assert_equal expected_consts, consts expected_attrs = [ [@c1.attributes[0], @c1.attributes[3]], [@c1.attributes[1], @c1.attributes[2]], ] assert_equal expected_attrs, attrs end def test_each_section_enumerator assert_kind_of @enumerator, @c1.each_section end def test_find_attribute_named assert_equal nil, @c1.find_attribute_named('none') assert_equal 'R', @c1.find_attribute_named('attr').rw assert_equal 'R', @c1.find_attribute_named('attr_reader').rw assert_equal 'W', @c1.find_attribute_named('attr_writer').rw assert_equal 'RW', @c1.find_attribute_named('attr_accessor').rw end def test_find_class_method_named assert_equal nil, @c1.find_class_method_named('none') m = @c1.find_class_method_named('m') assert_instance_of RDoc::AnyMethod, m assert m.singleton end def test_find_constant_named assert_equal nil, @c1.find_constant_named('NONE') assert_equal ':const', @c1.find_constant_named('CONST').value end def test_find_enclosing_module_named assert_equal nil, @c2_c3.find_enclosing_module_named('NONE') assert_equal @c1, @c2_c3.find_enclosing_module_named('C1') assert_equal @c2, @c2_c3.find_enclosing_module_named('C2') end def test_find_file_named assert_equal nil, @c1.find_file_named('nonexistent.rb') assert_equal @xref_data, @c1.find_file_named(@file_name) end def test_find_instance_method_named assert_equal nil, @c1.find_instance_method_named('none') m = @c1.find_instance_method_named('m') assert_instance_of RDoc::AnyMethod, m refute m.singleton end def test_find_local_symbol assert_equal true, @c1.find_local_symbol('m').singleton assert_equal ':const', @c1.find_local_symbol('CONST').value assert_equal 'R', @c1.find_local_symbol('attr').rw assert_equal @xref_data, @c1.find_local_symbol(@file_name) assert_equal @c2_c3, @c2.find_local_symbol('C3') end def test_find_method_named assert_equal true, @c1.find_method_named('m').singleton end def test_find_module_named assert_equal @c2_c3, @c2.find_module_named('C3') assert_equal @c2, @c2.find_module_named('C2') assert_equal @c1, @c2.find_module_named('C1') assert_equal 'C2::C3', @c2.find_module_named('C3').full_name end def test_find_symbol c3 = @xref_data.find_module_named('C3') assert_equal c3, @xref_data.find_symbol('C3') assert_equal c3, @c2.find_symbol('::C3') assert_equal @c2_c3, @c2.find_symbol('C3') end def test_find_symbol_method assert_equal @c1__m, @c1.find_symbol('m') assert_equal @c1_m, @c1.find_symbol('#m') assert_equal @c1__m, @c1.find_symbol('::m') end def test_find_symbol_module assert_nil @m1_m2.find_symbol_module 'N' assert_nil @m1_m2.find_symbol_module 'M2::M1' @m1_m2.parent = nil # loaded from legacy ri store assert_nil @m1_m2.find_symbol_module 'N' assert_nil @m1_m2.find_symbol_module 'M2::M1' end def test_fully_documented_eh context = RDoc::Context.new refute context.fully_documented? context.comment = 'hi' assert context.fully_documented? m = @c1_m context.add_method m refute context.fully_documented? m.comment = 'hi' assert context.fully_documented? c = RDoc::Constant.new 'C', '0', nil context.add_constant c refute context.fully_documented? c.comment = 'hi' assert context.fully_documented? a = RDoc::Attr.new '', 'a', 'RW', nil context.add_attribute a refute context.fully_documented? a.comment = 'hi' assert context.fully_documented? end def test_spaceship assert_equal(-1, @c2.<=>(@c3)) assert_equal 0, @c2.<=>(@c2) assert_equal 1, @c3.<=>(@c2) assert_equal 1, @c2_c3.<=>(@c2) assert_equal(-1, @c2_c3.<=>(@c3)) assert_nil @c2.<=>(Gem.loaded_specs.values.first) end def test_methods_by_type expected = { 'instance' => { :private => [], :protected => [], :public => [@c1_m], }, 'class' => { :private => [], :protected => [], :public => [@c1__m], }, } assert_equal expected, @c1.methods_by_type end def test_methods_by_type_section separate = @c1.sections_hash['separate'] @c1_m.section = separate expected = { 'instance' => { :private => [], :protected => [], :public => [@c1_m], }, 'class' => { :private => [], :protected => [], :public => [], }, } assert_equal expected, @c1.methods_by_type(separate) end def test_methods_matching methods = [] @parent.methods_matching 'm' do |m| methods << m end assert_equal [@parent_m], methods end def test_methods_matching_singleton methods = [] @parent.methods_matching 'm', true do |m| methods << m end assert_equal [@parent__m], methods end def test_methods_matching_inherit methods = [] @child.methods_matching 'm' do |m| methods << m end assert_equal [@parent_m], methods end def test_remove_invisible_private util_visibilities @vis.remove_invisible :private assert_equal [@pub, @prot, @priv], @vis.method_list assert_equal [@apub, @aprot, @apriv], @vis.attributes end def test_remove_invisible_nodoc util_visibilities @vis.remove_invisible :nodoc assert_equal [@pub, @prot, @priv], @vis.method_list assert_equal [@apub, @aprot, @apriv], @vis.attributes end def test_remove_invisible_protected util_visibilities @vis.remove_invisible :protected assert_equal [@pub, @prot], @vis.method_list assert_equal [@apub, @aprot], @vis.attributes end def test_remove_invisible_public util_visibilities @vis.remove_invisible :public assert_equal [@pub], @vis.method_list assert_equal [@apub], @vis.attributes end def test_remove_invisible_public_force util_visibilities @priv.force_documentation = true @prot.force_documentation = true @apriv.force_documentation = true @aprot.force_documentation = true @vis.remove_invisible :public assert_equal [@pub, @prot, @priv], @vis.method_list assert_equal [@apub, @aprot, @apriv], @vis.attributes end def test_remove_invisible_in_protected util_visibilities methods = [@pub, @prot, @priv] @c1.remove_invisible_in methods, :protected assert_equal [@pub, @prot], methods end def test_remove_invisible_in_protected_force util_visibilities @priv.force_documentation = true methods = [@pub, @prot, @priv] @c1.remove_invisible_in methods, :protected assert_equal [@pub, @prot, @priv], methods end def test_remove_invisible_in_public util_visibilities methods = [@pub, @prot, @priv] @c1.remove_invisible_in methods, :public assert_equal [@pub], methods end def test_remove_invisible_in_public_force util_visibilities @prot.force_documentation = true @priv.force_documentation = true methods = [@pub, @prot, @priv] @c1.remove_invisible_in methods, :public assert_equal [@pub, @prot, @priv], methods end def test_section_contents default = @context.sections.first @context.add_method RDoc::AnyMethod.new(nil, 'm1') b = @context.add_section 'B' m = @context.add_method RDoc::AnyMethod.new(nil, 'm2') m.section = b assert_equal [default, b], @context.section_contents end def test_section_contents_no_default @context = RDoc::Context.new b = @context.add_section 'B' m = @context.add_method RDoc::AnyMethod.new(nil, 'm') m.section = b assert_equal [b], @context.section_contents end def test_section_contents_only_default @context = RDoc::Context.new @context.add_method RDoc::AnyMethod.new(nil, 'm') assert_empty @context.section_contents end def test_section_contents_unused @context = RDoc::Context.new @context.add_method RDoc::AnyMethod.new(nil, 'm') @context.add_section 'B' assert_empty @context.section_contents end def test_set_current_section default_section = @context.sections.first @context.set_current_section nil, RDoc::Comment.new('', @top_level) assert_equal default_section, @context.current_section @context.set_current_section 'other', RDoc::Comment.new('', @top_level) new_section = @context.sections.find { |section| section != default_section } assert_equal new_section, @context.current_section end def test_sort_sections c = RDoc::Context.new c.add_section 'C' c.add_section 'A' c.add_section 'B' titles = c.sort_sections.map { |section| section.title } assert_equal [nil, 'A', 'B', 'C'], titles end def test_sort_sections_tomdoc c = RDoc::Context.new c.add_section 'Public' c.add_section 'Internal' c.add_section 'Deprecated' titles = c.sort_sections.map { |section| section.title } assert_equal [nil, 'Public', 'Internal', 'Deprecated'], titles end def test_sort_sections_tomdoc_missing c = RDoc::Context.new c.add_section 'Internal' c.add_section 'Public' titles = c.sort_sections.map { |section| section.title } assert_equal [nil, 'Public', 'Internal'], titles end def util_visibilities @pub = RDoc::AnyMethod.new nil, 'pub' @prot = RDoc::AnyMethod.new nil, 'prot' @priv = RDoc::AnyMethod.new nil, 'priv' @apub = RDoc::Attr.new nil, 'pub', 'RW', nil @aprot = RDoc::Attr.new nil, 'prot', 'RW', nil @apriv = RDoc::Attr.new nil, 'priv', 'RW', nil @vis = RDoc::NormalClass.new 'Vis' @vis.add_method @pub @vis.add_method @prot @vis.add_method @priv @vis.add_attribute @apub @vis.add_attribute @aprot @vis.add_attribute @apriv @prot.visibility = :protected @priv.visibility = :private @aprot.visibility = :protected @apriv.visibility = :private end end