From 858362e761a41e7d96efbcb9b38ae815b1e388d7 Mon Sep 17 00:00:00 2001 From: drbrain Date: Thu, 25 Sep 2008 02:43:03 +0000 Subject: Import RDoc 2.2.1 r185 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19537 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/rdoc/binary.dat | Bin 0 -> 1024 bytes .../rdoc/rdoc_markup_to_html_crossref_reference.rb | 31 +++ test/rdoc/test_attribute_manager.rb | 73 ++++++ test/rdoc/test_rdoc_info_formatting.rb | 12 +- test/rdoc/test_rdoc_info_sections.rb | 4 +- test/rdoc/test_rdoc_markup_attribute_manager.rb | 28 +- test/rdoc/test_rdoc_markup_to_html.rb | 18 +- test/rdoc/test_rdoc_markup_to_html_crossref.rb | 284 ++++++++++++++++++++- test/rdoc/test_rdoc_parser.rb | 18 ++ test/rdoc/test_rdoc_parser_c.rb | 31 ++- test/rdoc/test_rdoc_parser_perl.rb | 72 ++++++ test/rdoc/test_rdoc_parser_ruby.rb | 212 ++++++++++++++- test/rdoc/test_rdoc_ri_default_display.rb | 53 ++-- test/rdoc/test_rdoc_ri_driver.rb | 2 +- test/rdoc/test_rdoc_ri_formatter.rb | 2 +- 15 files changed, 777 insertions(+), 63 deletions(-) create mode 100644 test/rdoc/binary.dat create mode 100644 test/rdoc/rdoc_markup_to_html_crossref_reference.rb create mode 100644 test/rdoc/test_attribute_manager.rb create mode 100644 test/rdoc/test_rdoc_parser.rb create mode 100644 test/rdoc/test_rdoc_parser_perl.rb (limited to 'test/rdoc') diff --git a/test/rdoc/binary.dat b/test/rdoc/binary.dat new file mode 100644 index 0000000000..371950efe6 Binary files /dev/null and b/test/rdoc/binary.dat differ diff --git a/test/rdoc/rdoc_markup_to_html_crossref_reference.rb b/test/rdoc/rdoc_markup_to_html_crossref_reference.rb new file mode 100644 index 0000000000..cbf6734b28 --- /dev/null +++ b/test/rdoc/rdoc_markup_to_html_crossref_reference.rb @@ -0,0 +1,31 @@ +# +# This file is parsed by test_rdoc_markup_to_html_crossref.rb +# during its tests. +# +class Ref_Class1 +end + +class Ref_Class2 + class Ref_Class3 + def method + end + + class Helper1 + def method? + end + end + end +end + +class Ref_Class3 + class Helper1 + end + + class Helper2 + end +end + +class Ref_Class4 + class Ref_Class4 + end +end diff --git a/test/rdoc/test_attribute_manager.rb b/test/rdoc/test_attribute_manager.rb new file mode 100644 index 0000000000..298eca0141 --- /dev/null +++ b/test/rdoc/test_attribute_manager.rb @@ -0,0 +1,73 @@ +require 'test/unit' +require 'rdoc/markup/attribute_manager' + +class TestAttributeManager < Test::Unit::TestCase + + def setup + @am = RDoc::Markup::AttributeManager.new + @klass = RDoc::Markup::AttributeManager + end + + def teardown + silently do + @klass.const_set(:MATCHING_WORD_PAIRS, {}) + @klass.const_set(:WORD_PAIR_MAP, {}) + @klass.const_set(:HTML_TAGS, {}) + end + end + + def test_initial_word_pairs + word_pairs = @klass::MATCHING_WORD_PAIRS + assert word_pairs.is_a?(Hash) + assert_equal(3, word_pairs.size) + end + + def test_initial_html + html_tags = @klass::HTML_TAGS + assert html_tags.is_a?(Hash) + assert_equal(5, html_tags.size) + end + + def test_add_matching_word_pair + @am.add_word_pair("x","x", :TEST) + word_pairs = @klass::MATCHING_WORD_PAIRS + assert_equal(4,word_pairs.size) + assert(word_pairs.has_key?("x")) + end + + def test_add_invalid_word_pair + assert_raise ArgumentError do + @am.add_word_pair("<", "<", :TEST) + end + end + + def test_add_word_pair_map + @am.add_word_pair("x", "y", :TEST) + word_pair_map = @klass::WORD_PAIR_MAP + assert_equal(1,word_pair_map.size) + assert_equal(word_pair_map. keys.first.source, "(x)(\\S+)(y)") + end + + def test_add_html_tag + @am.add_html("Test", :TEST) + tags = @klass::HTML_TAGS + assert_equal(6, tags.size) + assert(tags.has_key?("test")) + end + + def test_add_special + @am.add_special("WikiWord", :WIKIWORD) + specials = @klass::SPECIAL + assert_equal(1,specials.size) + assert(specials.has_key?("WikiWord")) + end + + def silently(&block) + warn_level = $VERBOSE + $VERBOSE = nil + result = block.call + $VERBOSE = warn_level + result + end + +end diff --git a/test/rdoc/test_rdoc_info_formatting.rb b/test/rdoc/test_rdoc_info_formatting.rb index 6c024f7454..b18cdf2931 100644 --- a/test/rdoc/test_rdoc_info_formatting.rb +++ b/test/rdoc/test_rdoc_info_formatting.rb @@ -5,7 +5,7 @@ require 'test/unit' require 'rdoc/generator/texinfo' # From chapter 18 of the Pickaxe 3rd ed. and the TexInfo manual. -class TestRdocInfoFormatting < Test::Unit::TestCase +class TestRDocInfoFormatting < Test::Unit::TestCase def setup @output_dir = File.join Dir.tmpdir, "test_rdoc_info_formatting_#{$$}" @output_file = File.join @output_dir, 'rdoc.texinfo' @@ -19,7 +19,7 @@ class TestRdocInfoFormatting < Test::Unit::TestCase end def teardown - FileUtils.rm_rf @output_dir + # FileUtils.rm_rf @output_dir end # Make sure tags like *this* do not make HTML @@ -73,10 +73,10 @@ class TestRdocInfoFormatting < Test::Unit::TestCase # === Everything deeper becomes a regular @heading # ====== Regardless of its nesting level def test_headings - assert_match(/@majorheading\{Huge heading should be a @@majorheading\}/) - assert_match(/@chapheading\{There is also @@chapheading\}/) - assert_match(/@heading\{Everything deeper becomes a regular @@heading\}/) - assert_match(/@heading\{Regardless of its nesting level\}/) + assert_match(/@majorheading Huge heading should be a @@majorheading/) + assert_match(/@chapheading There is also @@chapheading/) + assert_match(/@heading Everything deeper becomes a regular @@heading/) + assert_match(/@heading Regardless of its nesting level/) end # * list item diff --git a/test/rdoc/test_rdoc_info_sections.rb b/test/rdoc/test_rdoc_info_sections.rb index cceba186c1..6825d37a7d 100644 --- a/test/rdoc/test_rdoc_info_sections.rb +++ b/test/rdoc/test_rdoc_info_sections.rb @@ -6,10 +6,10 @@ require 'tmpdir' require 'rdoc/generator/texinfo' # give us access to check this stuff before it's rendered -class RDoc::Generator::Texinfo; attr_reader :files, :classes; end +class RDoc::Generator::TEXINFO; attr_reader :files, :classes; end class RDoc::RDoc; attr_reader :options; attr_reader :gen; end -class TestRdocInfoSections < Test::Unit::TestCase +class TestRDocInfoSections < Test::Unit::TestCase def setup @output_dir = File.join Dir.tmpdir, "test_rdoc_info_sections_#{$$}" diff --git a/test/rdoc/test_rdoc_markup_attribute_manager.rb b/test/rdoc/test_rdoc_markup_attribute_manager.rb index 8ba9d7440a..eea87822a8 100644 --- a/test/rdoc/test_rdoc_markup_attribute_manager.rb +++ b/test/rdoc/test_rdoc_markup_attribute_manager.rb @@ -1,5 +1,6 @@ require "test/unit" require "rdoc/markup/inline" +require "rdoc/markup/to_html_crossref" class TestRDocMarkupAttributeManager < Test::Unit::TestCase @@ -201,24 +202,23 @@ class TestRDocMarkupAttributeManager < Test::Unit::TestCase end def test_special - # class names, variable names, file names, or instance variables - @am.add_special(/( - \b([A-Z]\w+(::\w+)*) - | \#\w+[!?=]? - | \b\w+([_\/\.]+\w+)+[!?=]? - )/x, - :CROSSREF) + @am.add_special(RDoc::Markup::ToHtmlCrossref::CROSSREF_REGEXP, :CROSSREF) - assert_equal(["cat"], @am.flow("cat")) + # + # The apostrophes in "cats'" and "dogs'" suppress the flagging of these + # words as potential cross-references, which is necessary for the unit + # tests. Unfortunately, the markup engine right now does not actually + # check whether a cross-reference is valid before flagging it. + # + assert_equal(["cats'"], @am.flow("cats'")) - assert_equal(["cat ", crossref("#fred"), " dog"].flatten, - @am.flow("cat #fred dog")) + assert_equal(["cats' ", crossref("#fred"), " dogs'"].flatten, + @am.flow("cats' #fred dogs'")) - assert_equal([crossref("#fred"), " dog"].flatten, - @am.flow("#fred dog")) + assert_equal([crossref("#fred"), " dogs'"].flatten, + @am.flow("#fred dogs'")) - assert_equal(["cat ", crossref("#fred")].flatten, @am.flow("cat #fred")) + assert_equal(["cats' ", crossref("#fred")].flatten, @am.flow("cats' #fred")) end end - diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb index 463228cc4a..05fb9f2375 100644 --- a/test/rdoc/test_rdoc_markup_to_html.rb +++ b/test/rdoc/test_rdoc_markup_to_html.rb @@ -2,7 +2,7 @@ require 'test/unit' require 'rdoc/markup' require 'rdoc/markup/to_html' -class TestRdocMarkupToHtml < Test::Unit::TestCase +class TestRDocMarkupToHtml < Test::Unit::TestCase def setup @am = RDoc::Markup::AttributeManager.new @@ -10,11 +10,23 @@ class TestRdocMarkupToHtml < Test::Unit::TestCase end def test_tt_formatting - assert_equal "

\n--(c) ©\n

\n", - util_format("-- -- (c) (c)") + assert_equal "

\n--cats' cats’\n

\n", + util_format("-- -- cats' cats'") assert_equal "

\n\n

\n", util_format("--") end + def test_convert_string_fancy + # + # The HTML typesetting is broken in a number of ways, but I have fixed + # the most glaring issues for single and double quotes. Note that + # "strange" symbols (periods or dashes) need to be at the end of the + # test case strings in order to suppress cross-references. + # + assert_equal "

\n“cats”.\n

\n", util_format("\"cats\".") + assert_equal "

\n‘cats’.\n

\n", util_format("\'cats\'.") + assert_equal "

\ncat’s-\n

\n", util_format("cat\'s-") + end + def util_fragment(text) RDoc::Markup::Fragment.new 0, nil, nil, text end diff --git a/test/rdoc/test_rdoc_markup_to_html_crossref.rb b/test/rdoc/test_rdoc_markup_to_html_crossref.rb index ab4c3e7e9c..de99a58b75 100644 --- a/test/rdoc/test_rdoc_markup_to_html_crossref.rb +++ b/test/rdoc/test_rdoc_markup_to_html_crossref.rb @@ -2,17 +2,287 @@ require 'test/unit' require 'rdoc/generator' require 'rdoc/markup/to_html_crossref' -class TestRdocMarkupToHtmlCrossref < Test::Unit::TestCase +require 'pathname' - def setup - @xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', nil, nil +class TestRDocMarkupToHtmlCrossref < Test::Unit::TestCase + + # + # This method parses a source file and returns a Hash mapping + # class names (Strings) to RDoc::Generator::Class instances + # (classes), which can be used to create RDoc::Markup::ToHtmlCrossref + # instances. The unit tests only test against classes starting with + # Ref_, so this method only includes such classes in the Hash. + # + def create_class_hash + # The relative gem would help here... + # @source_file_name must be cleaned because rdoc does not deal + # well with paths containing "." or "..". + curr_file = Pathname.new(__FILE__) + @source_file_name = curr_file.dirname + "rdoc_markup_to_html_crossref_reference.rb" + @source_file_name = @source_file_name.cleanpath.to_s + + RDoc::TopLevel.reset + + # Reset RDoc::Generator::Method so that the method sequence number starts + # at 1, making the method sequence numbers for the methods in the Ref_ + # predicable. + RDoc::Generator::Method.reset + top_level = RDoc::TopLevel.new @source_file_name + + options = RDoc::Options.new + options.quiet = true + + # If this is false, then RDoc::Generator::Method will attempt to create + # an HTML file containing the method source code when being instantiated, + # which does not work in the context of this unit test. + # + # RDoc::Generator::Method needs to be refactored so that this does *not* + # happen as part of instantiation. + options.inline_source = true + + stats = RDoc::Stats.new 0 + + parser = RDoc::Parser::Ruby.new(top_level, + @source_file_name, + IO.read(@source_file_name), + options, + stats) + top_levels = [] + top_levels.push(parser.scan()) + + files, classes = RDoc::Generator::Context.build_indices(top_levels, options) + + class_hash = {} + classes.each do |klass| + if(klass.name.include?("Ref_")) + class_hash[klass.name] = klass + end + end + + return class_hash end - def test_handle_special_CROSSREF_no_underscore - out = @xref.convert 'foo' + # + # This method uses xref to cross-reference String reference and + # asserts that xref.convert(reference) is equal + # to String expected_result. + # + def verify_convert(xref, reference, expected_result) + # Everything converted in the tests will be within paragraph markup, so + # add paragraph markup to the expected result. + actual_expected_result = "

\n#{expected_result}\n

\n" + + result = xref.convert(reference) + + # RDoc::Markup::ToHtml word-wraps lines. It is tricky to predict where + # a line will be wrapped except that it will happen on a space, so replace + # all newlines with spaces in order to not have to worry about this. + actual_expected_result.gsub!(/\n/, " ") + result.gsub!(/\n/, " ") - assert_equal "

\nfoo\n

\n", out + assert_equal actual_expected_result, result end -end + # + # This method verifies that xref generates no cross-reference link for + # String reference. + # + def verify_no_crossref(xref, reference) + if(reference[0, 1] == "\\") # Remove the markup suppression character + expected_result = reference[1, reference.length() - 1] + else + expected_result = reference + end + + verify_convert(xref, reference, expected_result) + end + + # + # This method verifies that xref generates a cross-reference link to + # class_name (String) for String reference. + # + def verify_class_crossref(xref, reference, class_name) + class_file_name = class_name.gsub(/::/, "/") + + result = "#{reference}" + + verify_convert xref, reference, result + end + # + # This method verifies that xref generates a cross-reference link to method + # method_seq (String, e.g, "M000001") in class_name (String) for + # String reference. + # + def verify_method_crossref(xref, reference, class_name, method_seq) + class_file_name = class_name.gsub(/::/, "/") + + result = "#{reference}" + + verify_convert xref, reference, result + end + + # + # This method verifies that xref generates a cross-reference link to + # file_name (String) for String reference. + # + def verify_file_crossref(xref, reference, file_name) + generated_document_path = Pathname.new("../files/#{file_name.gsub(/\./, '_')}.html").cleanpath.to_s + result = "#{reference}" + + verify_convert xref, reference, result + end + + # + # This method verifies that several invariant cross-references are + # (or are not) generated. + # + def verify_invariant_crossrefs(xref) + # bogus does not exist and so no cross-reference should be generated. + verify_no_crossref xref, "bogus" + verify_no_crossref xref, "\\bogus" + + # Ref_Class1 is in the top-level namespace, and so a cross-reference always + # should be generated, unless markup is suppressed. + verify_class_crossref xref, "Ref_Class1", "Ref_Class1" + verify_no_crossref xref, "\\Ref_Class1" + + # Ref_Class2 is in the top-level namespace, and so a cross-reference always + # should be generated for it and for its nested classes. + verify_class_crossref xref, "Ref_Class2", "Ref_Class2" + verify_class_crossref xref, "Ref_Class2::Ref_Class3", "Ref_Class2::Ref_Class3" + verify_method_crossref xref, "Ref_Class2::Ref_Class3#method", "Ref_Class2::Ref_Class3", "M000001" + verify_method_crossref xref, "Ref_Class2::Ref_Class3#method()", "Ref_Class2::Ref_Class3", "M000001" + verify_method_crossref xref, "Ref_Class2::Ref_Class3.method()", "Ref_Class2::Ref_Class3", "M000001" + verify_method_crossref xref, "Ref_Class2::Ref_Class3.method(*)", "Ref_Class2::Ref_Class3", "M000001" + verify_class_crossref xref, "Ref_Class2::Ref_Class3::Helper1", "Ref_Class2::Ref_Class3::Helper1" + verify_method_crossref xref, "Ref_Class2::Ref_Class3::Helper1#method?", "Ref_Class2::Ref_Class3::Helper1", "M000002" + + # The hyphen character is not a valid class/method separator character, so + # rdoc just generates a class cross-reference (perhaps it should not + # generate anything?). + result = "Ref_Class2::Ref_Class3;method(*)" + verify_convert xref, "Ref_Class2::Ref_Class3;method(*)", result + + # There is one Ref_Class3 nested in Ref_Class2 and one defined in the + # top-level namespace; regardless, ::Ref_Class3 (Ref_Class3 relative + # to the top-level namespace) always should generate a link to the + # top-level Ref_Class3 (unless of course cross-references are suppressed). + verify_class_crossref xref, "::Ref_Class3", "Ref_Class3" + verify_no_crossref xref, "\\::Ref_Class3" + verify_class_crossref xref, "::Ref_Class3::Helper1", "Ref_Class3::Helper1" + verify_class_crossref xref, "::Ref_Class3::Helper2", "Ref_Class3::Helper2" + + # + # Ref_Class3::Helper1 does not have method method. + # + verify_no_crossref xref, "::Ref_Class3::Helper1#method" + verify_no_crossref xref, "\\::Ref_Class3::Helper1#method" + + # References to Ref_Class2 relative to the top-level namespace always should + # generate links to Ref_Class2. + verify_method_crossref xref, "::Ref_Class2::Ref_Class3#method", "Ref_Class2::Ref_Class3", "M000001" + verify_method_crossref xref, "::Ref_Class2::Ref_Class3#method()", "Ref_Class2::Ref_Class3", "M000001" + verify_method_crossref xref, "::Ref_Class2::Ref_Class3#method(*)", "Ref_Class2::Ref_Class3", "M000001" + verify_class_crossref xref, "::Ref_Class2::Ref_Class3::Helper1", "Ref_Class2::Ref_Class3::Helper1" + verify_no_crossref xref, "\\::Ref_Class2::Ref_Class3#method(*)" + + # Suppressing cross-references always should suppress the generation of + # links. + verify_no_crossref xref, "\\#method" + verify_no_crossref xref, "\\#method()" + verify_no_crossref xref, "\\#method(*)" + + # Links never should be generated for words solely consisting of lowercase + # letters, because too many links would get generated by mistake (i.e., the + # word "new" always would be a link). + verify_no_crossref xref, "method" + + # A link always should be generated for a file name. + verify_file_crossref xref, @source_file_name, @source_file_name + + # References should be generated correctly for a class scoped within + # a class of the same name. + verify_class_crossref xref, "Ref_Class4::Ref_Class4", "Ref_Class4::Ref_Class4" + end + + def test_handle_special_CROSSREF_no_underscore + class_hash = create_class_hash + + # Note that we instruct the ToHtmlCrossref instance to show hashes so that + # an exception won't have to be made for words starting with a '#'. + # I'm also not convinced that the current behavior of the rdoc code + # is correct since, without this, it strips the leading # from all + # words, whether or not they end up as cross-references. + # + # After the behavior has been sorted out, this can be changed. + # + # Create a variety of RDoc::Markup::ToHtmlCrossref instances, for + # different classes, and test the cross-references generated by + # each. + klass = class_hash["Ref_Class1"] + xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', klass, true + verify_invariant_crossrefs xref + verify_class_crossref xref, "Ref_Class3", "Ref_Class3" + verify_no_crossref xref, "Ref_Class3#method" + verify_no_crossref xref, "#method" + verify_class_crossref xref, "Ref_Class3::Helper1", "Ref_Class3::Helper1" + verify_class_crossref xref, "Ref_Class3::Helper2", "Ref_Class3::Helper2" + verify_no_crossref xref, "Helper1" + verify_class_crossref xref, "Ref_Class4", "Ref_Class4" + + klass = class_hash["Ref_Class2"] + xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', klass, true + verify_invariant_crossrefs xref + verify_class_crossref xref, "Ref_Class3", "Ref_Class2::Ref_Class3" + verify_method_crossref xref, "Ref_Class3#method", "Ref_Class2::Ref_Class3", "M000001" + verify_no_crossref xref, "#method" + verify_class_crossref xref, "Ref_Class3::Helper1", "Ref_Class2::Ref_Class3::Helper1" + verify_class_crossref xref, "Ref_Class4", "Ref_Class4" + + # This one possibly is an rdoc bug... + # Ref_Class2 has a nested Ref_Class3, but + # Ref_Class2::Ref_Class3::Helper2 does not exist. + # On the other hand, there is a Ref_Class3::Helper2 + # in the top-level namespace... Should rdoc stop + # looking if it finds one class match? + verify_no_crossref xref, "Ref_Class3::Helper2" + verify_no_crossref xref, "Helper1" + + klass = class_hash["Ref_Class2::Ref_Class3"] + xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', klass, true + verify_invariant_crossrefs xref + verify_class_crossref xref, "Ref_Class3", "Ref_Class2::Ref_Class3" + verify_method_crossref xref, "Ref_Class3#method", "Ref_Class2::Ref_Class3", "M000001" + verify_method_crossref xref, "#method", "Ref_Class2::Ref_Class3", "M000001" + verify_class_crossref xref, "Ref_Class3::Helper1", "Ref_Class2::Ref_Class3::Helper1" + verify_no_crossref xref, "Ref_Class3::Helper2" + verify_class_crossref xref, "Helper1", "Ref_Class2::Ref_Class3::Helper1" + verify_class_crossref xref, "Ref_Class4", "Ref_Class4" + + klass = class_hash["Ref_Class3"] + xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', klass, true + verify_invariant_crossrefs xref + verify_class_crossref xref, "Ref_Class3", "Ref_Class3" + verify_no_crossref xref, "Ref_Class3#method" + verify_no_crossref xref, "#method" + verify_class_crossref xref, "Ref_Class3::Helper1", "Ref_Class3::Helper1" + verify_class_crossref xref, "Ref_Class3::Helper2", "Ref_Class3::Helper2" + verify_class_crossref xref, "Helper1", "Ref_Class3::Helper1" + verify_class_crossref xref, "Ref_Class4", "Ref_Class4" + + klass = class_hash["Ref_Class4"] + xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', klass, true + verify_invariant_crossrefs xref + # A Ref_Class4 reference inside a Ref_Class4 class containing a + # Ref_Class4 class should resolve to the contained class. + verify_class_crossref xref, "Ref_Class4", "Ref_Class4::Ref_Class4" + + klass = class_hash["Ref_Class4::Ref_Class4"] + xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', klass, true + verify_invariant_crossrefs xref + # A Ref_Class4 reference inside a Ref_Class4 class contained within + # a Ref_Class4 class should resolve to the inner Ref_Class4 class. + verify_class_crossref xref, "Ref_Class4", "Ref_Class4::Ref_Class4" + end +end diff --git a/test/rdoc/test_rdoc_parser.rb b/test/rdoc/test_rdoc_parser.rb new file mode 100644 index 0000000000..4f71974a5f --- /dev/null +++ b/test/rdoc/test_rdoc_parser.rb @@ -0,0 +1,18 @@ +require 'rdoc/parser' + +class TestRDocParser < Test::Unit::TestCase + def test_can_parse + assert_equal(RDoc::Parser.can_parse(__FILE__), RDoc::Parser::Ruby) + + readme_file_name = File.join(File.dirname(__FILE__), "..", "README.txt") + + unless File.exist? readme_file_name then + readme_file_name = File.join File.dirname(__FILE__), '..', '..', 'README' + end + + assert_equal(RDoc::Parser.can_parse(readme_file_name), RDoc::Parser::Simple) + + binary_file_name = File.join(File.dirname(__FILE__), "binary.dat") + assert_equal(RDoc::Parser.can_parse(binary_file_name), nil) + end +end diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb index fd750070d8..9387a030c0 100644 --- a/test/rdoc/test_rdoc_parser_c.rb +++ b/test/rdoc/test_rdoc_parser_c.rb @@ -10,7 +10,7 @@ class RDoc::Parser::C public :do_classes, :do_constants end -class TestRdocParserC < Test::Unit::TestCase +class TestRDocParserC < Test::Unit::TestCase def setup @tempfile = Tempfile.new self.class.name @@ -244,9 +244,36 @@ Init_Foo(void) { assert_equal " \n a comment for class Foo on Init\n \n", klass.comment end + def test_define_method + content = <<-EOF +/*Method Comment! */ +static VALUE +rb_io_s_read(argc, argv, io) + int argc; + VALUE *argv; + VALUE io; +{ +} + +void +Init_IO(void) { + /* + * a comment for class Foo on rb_define_class + */ + VALUE rb_cIO = rb_define_class("IO", rb_cObject); + rb_define_singleton_method(rb_cIO, "read", rb_io_s_read, -1); +} + EOF + + klass = util_get_class content, 'rb_cIO' + read_method = klass.method_list.first + assert_equal "read", read_method.name + assert_equal " Method Comment! \n", read_method.comment + end + def util_get_class(content, name) parser = util_parser content - parser.do_classes + parser.scan parser.classes[name] end diff --git a/test/rdoc/test_rdoc_parser_perl.rb b/test/rdoc/test_rdoc_parser_perl.rb new file mode 100644 index 0000000000..458e32745e --- /dev/null +++ b/test/rdoc/test_rdoc_parser_perl.rb @@ -0,0 +1,72 @@ +require 'stringio' +require 'tempfile' +require 'test/unit' +require 'rdoc/options' +require 'rdoc/parser/perl' + +class TestRdocParserPerlPOD < Test::Unit::TestCase + + def setup + @tempfile = Tempfile.new self.class.name + filename = @tempfile.path + + @top_level = RDoc::TopLevel.new filename + @fn = filename + @options = RDoc::Options.new + @stats = RDoc::Stats.new 0 + end + + def teardown + @tempfile.close + end + + def test_uncommented_perl + content = <<-EOF +while (<>) { + tr/a-z/A-Z; + print +} + EOF + + comment = util_get_comment content + assert_equal "", comment + end + + def test_perl_without_pod + content = <<-EOF +#!/usr/local/bin/perl +# +#This is a pointless perl program because it does -p. +# +while(<>) {print;}: + EOF + + comment = util_get_comment content + assert_equal "", comment + end + + def test_simple_pod_no_structure + content = <<-EOF +=begin pod + +This just contains plain old documentation + +=end + EOF + comment = util_get_comment content + assert_equal "\nThis just contains plain old documentation\n\n", comment + end + + # Get the comment of the @top_level when it has processed the input. + def util_get_comment(content) + parser = util_parser content + parser.scan.comment + end + + # create a new parser with the supplied content. + def util_parser(content) + RDoc::Parser::PerlPOD.new @top_level, @fn, content, @options, @stats + end + +end + diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb index 77d8bd24fc..30ab3f84f5 100644 --- a/test/rdoc/test_rdoc_parser_ruby.rb +++ b/test/rdoc/test_rdoc_parser_ruby.rb @@ -6,12 +6,16 @@ require 'rdoc/options' require 'rdoc/parser/ruby' require 'rdoc/stats' -class TestRdocParserRuby < Test::Unit::TestCase +class TestRDocParserRuby < Test::Unit::TestCase def setup @tempfile = Tempfile.new self.class.name @filename = @tempfile.path + # Some tests need two paths. + @tempfile2 = Tempfile.new self.class.name + @filename2 = @tempfile2.path + util_toplevel @options = RDoc::Options.new @options.quiet = true @@ -20,6 +24,7 @@ class TestRdocParserRuby < Test::Unit::TestCase def teardown @tempfile.close + @tempfile2.close end def test_look_for_directives_in_commented @@ -158,6 +163,105 @@ class TestRdocParserRuby < Test::Unit::TestCase assert_equal 'Super', bar.superclass end + def test_parse_module + comment = "##\n# my module\n" + + util_parser 'module Foo; end' + + tk = @parser.get_tk + + @parser.parse_module @top_level, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = @top_level.modules.first + assert_equal 'Foo', foo.full_name + assert_equal comment, foo.comment + end + + def test_parse_class_mistaken_for_module +# +# The code below is not strictly legal Ruby (Foo must have been defined +# before Foo::Bar is encountered), but RDoc might encounter Foo::Bar before +# Foo if they live in different files. +# + code = <<-EOF +class Foo::Bar +end + +module Foo::Baz +end + +class Foo +end +EOF + + util_parser code + + @parser.scan() + + assert(@top_level.modules.empty?) + foo = @top_level.classes.first + assert_equal 'Foo', foo.full_name + + bar = foo.classes.first + assert_equal 'Foo::Bar', bar.full_name + + baz = foo.modules.first + assert_equal 'Foo::Baz', baz.full_name + end + + def test_parse_class_definition_encountered_after_class_reference +# +# The code below is not strictly legal Ruby (Foo must have been defined +# before Foo.bar is encountered), but RDoc might encounter Foo.bar before +# Foo if they live in different files. +# + code = <<-EOF +def Foo.bar +end + +class Foo < IO +end +EOF + + util_parser code + + @parser.scan() + + assert(@top_level.modules.empty?) + + foo = @top_level.classes.first + assert_equal 'Foo', foo.full_name + assert_equal 'IO', foo.superclass + + bar = foo.method_list.first + assert_equal 'bar', bar.name + end + + def test_parse_module_relative_to_top_level_namespace + comment = <<-EOF +# +# Weirdly named module +# +EOF + + code = comment + <<-EOF +module ::Foo + class Helper + end +end +EOF + + util_parser code + @parser.scan() + + foo = @top_level.modules.first + assert_equal 'Foo', foo.full_name + assert_equal comment, foo.comment + + helper = foo.classes.first + assert_equal 'Foo::Helper', helper.full_name + end + def test_parse_comment content = <<-EOF class Foo @@ -416,9 +520,107 @@ end @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + foo = @top_level.classes.first.method_list[0] + assert_equal 'foo', foo.name + foo2 = @top_level.classes.first.method_list.last assert_equal 'foo2', foo2.name assert_equal 'foo', foo2.is_alias_for.name + assert @top_level.classes.first.aliases.empty? + end + + def test_parse_statements_identifier_alias_method_before_original_method + # This is not strictly legal Ruby code, but it simulates finding an alias + # for a method before finding the original method, which might happen + # to rdoc if the alias is in a different file than the original method + # and rdoc processes the alias' file first. + content = <<-EOF +class Foo + alias_method :foo2, :foo + + alias_method :foo3, :foo + + def foo() + end + + alias_method :foo4, :foo + + alias_method :foo5, :unknown +end +EOF + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first.method_list[0] + assert_equal 'foo', foo.name + + foo2 = @top_level.classes.first.method_list[1] + assert_equal 'foo2', foo2.name + assert_equal 'foo', foo2.is_alias_for.name + + foo3 = @top_level.classes.first.method_list[2] + assert_equal 'foo3', foo3.name + assert_equal 'foo', foo3.is_alias_for.name + + foo4 = @top_level.classes.first.method_list.last + assert_equal 'foo4', foo4.name + assert_equal 'foo', foo4.is_alias_for.name + + assert_equal 'unknown', @top_level.classes.first.aliases[0].old_name + end + + def test_parse_statements_identifier_constant + content = <<-EOF +class Foo + FIRST_CONSTANT = 5 + + SECOND_CONSTANT = [ + 1, + 2, + 3 + ] + + THIRD_CONSTANT = { + :foo => 'bar', + :x => 'y' + } + + FOURTH_CONSTANT = SECOND_CONSTANT.map do |element| + element + 1 + element + 2 + end + + FIFTH_CONSTANT = SECOND_CONSTANT.map { |element| element + 1 } +end +EOF + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + constants = @top_level.classes.first.constants + + constant = constants[0] + assert_equal 'FIRST_CONSTANT', constant.name + assert_equal '5', constant.value + + constant = constants[1] + assert_equal 'SECOND_CONSTANT', constant.name + assert_equal '[ 1, 2, 3 ]', constant.value + + constant = constants[2] + assert_equal 'THIRD_CONSTANT', constant.name + assert_equal "{ :foo => 'bar', :x => 'y' }", constant.value + + constant = constants[3] + assert_equal 'FOURTH_CONSTANT', constant.name + assert_equal 'SECOND_CONSTANT.map do |element| element + 1 element + 2 end', constant.value + + constant = constants.last + assert_equal 'FIFTH_CONSTANT', constant.name + assert_equal 'SECOND_CONSTANT.map { |element| element + 1 }', constant.value end def test_parse_statements_identifier_attr @@ -530,9 +732,17 @@ end @stats end + def util_two_parsers(first_file_content, second_file_content) + util_parser first_file_content + + @parser2 = RDoc::Parser::Ruby.new @top_level2, @filename, + second_file_content, @options, @stats + end + def util_toplevel RDoc::TopLevel.reset @top_level = RDoc::TopLevel.new @filename + @top_level2 = RDoc::TopLevel.new @filename2 end end diff --git a/test/rdoc/test_rdoc_ri_default_display.rb b/test/rdoc/test_rdoc_ri_default_display.rb index 97fa6c94ae..266b501ebb 100644 --- a/test/rdoc/test_rdoc_ri_default_display.rb +++ b/test/rdoc/test_rdoc_ri_default_display.rb @@ -4,7 +4,7 @@ require 'rdoc/ri/formatter' require 'rdoc/ri/display' require 'rdoc/ri/driver' -class TestRdocRiDefaultDisplay < Test::Unit::TestCase +class TestRDocRiDefaultDisplay < Test::Unit::TestCase def setup @output = StringIO.new @@ -27,7 +27,6 @@ class TestRdocRiDefaultDisplay < Test::Unit::TestCase end def test_display_class_info - ri_reader = nil klass = h \ 'attributes' => [ { 'name' => 'attribute', 'rw' => 'RW', @@ -43,9 +42,9 @@ class TestRdocRiDefaultDisplay < Test::Unit::TestCase ], 'comment' => [RDoc::Markup::Flow::P.new('SomeClass comment')], 'constants' => [ - { 'name' => 'CONSTANT', 'value' => '"value"', + { 'name' => 'CONSTANT', 'value' => '"value1"', 'comment' => [RDoc::Markup::Flow::P.new('CONSTANT value')] }, - { 'name' => 'CONSTANT_NOCOMMENT', 'value' => '"value"', + { 'name' => 'CONSTANT_NOCOMMENT', 'value' => '"value2"', 'comment' => nil }, ], 'display_name' => 'Class', @@ -59,7 +58,7 @@ class TestRdocRiDefaultDisplay < Test::Unit::TestCase ], 'superclass_string' => 'Object' - @dd.display_class_info klass, ri_reader + @dd.display_class_info klass expected = <<-EOF ---------------------------------------------------- Class: SomeClass < Object @@ -71,10 +70,19 @@ class TestRdocRiDefaultDisplay < Test::Unit::TestCase Constants: ---------- - CONSTANT: + CONSTANT = "value1" CONSTANT value - CONSTANT_NOCOMMENT + CONSTANT_NOCOMMENT = "value2" + + +Attributes: +----------- + + attribute (RW): + attribute comment + + attribute_no_comment (RW) Class methods: @@ -99,15 +107,6 @@ Instance method extensions: --------------------------- instance_method_extension - - -Attributes: ------------ - - attribute (RW): - attribute comment - - attribute_no_comment (RW) EOF assert_equal expected, @output.string @@ -140,7 +139,7 @@ Attributes: -------------------------------------------------------- SomeClass#some_method some_method(arg1, arg2) {|block_param| ...} - Extension from /nonexistent + From /nonexistent ------------------------------------------------------------------------------ some comment @@ -152,7 +151,7 @@ Attributes: end def test_display_method_info_singleton - method = RDoc::RI::Driver::Hash.new.update \ + method = RDoc::RI::Driver::OpenStructHash.new.update \ 'aliases' => [], 'block_params' => nil, 'comment' => nil, @@ -167,6 +166,8 @@ Attributes: expected = <<-EOF ------------------------------------------------------- SomeClass::some_method SomeClass::some_method(arg1, arg2) + + From ------------------------------------------------------------------------------ [no description] EOF @@ -176,7 +177,7 @@ Attributes: def test_display_method_list methods = [ - RDoc::RI::Driver::Hash.new.update( + RDoc::RI::Driver::OpenStructHash.new.update( "aliases" => [], "block_params" => nil, "comment" => nil, @@ -186,7 +187,7 @@ Attributes: "params" => "()", "visibility" => "public" ), - RDoc::RI::Driver::Hash.new.update( + RDoc::RI::Driver::OpenStructHash.new.update( "aliases" => [], "block_params" => nil, "comment" => nil, @@ -204,7 +205,8 @@ Attributes: More than one method matched your request. You can refine your search by asking for information on one of: - SomeClass#some_method, SomeClass#some_other_method +SomeClass#some_method [] +SomeClass#some_other_method [] EOF assert_equal expected, @output.string @@ -216,7 +218,7 @@ Attributes: expected = <<-EOF some_method(arg1, arg2) {|block_param| ...} - Extension from /nonexistent + From /nonexistent EOF assert_equal expected, @output.string @@ -234,7 +236,7 @@ some_method(start, length) some_method(index) some_method(start, length) - Extension from /nonexistent + From /nonexistent EOF assert_equal expected, @output.string @@ -249,7 +251,7 @@ some_method(start, length) expected = <<-EOF SomeClass::some_method(arg1, arg2) {|block_param| ...} - Extension from /nonexistent + From /nonexistent EOF assert_equal expected, @output.string @@ -289,8 +291,7 @@ install an additional package, or ask the packager to enable ri generation. end def h(hash) - RDoc::RI::Driver::Hash.convert hash + RDoc::RI::Driver::OpenStructHash.convert hash end end - diff --git a/test/rdoc/test_rdoc_ri_driver.rb b/test/rdoc/test_rdoc_ri_driver.rb index cddd4e60d1..22643d61d3 100644 --- a/test/rdoc/test_rdoc_ri_driver.rb +++ b/test/rdoc/test_rdoc_ri_driver.rb @@ -14,7 +14,7 @@ class TestRDocRIDriver < Test::Unit::TestCase FileUtils.mkdir_p @home_ri FileUtils.mkdir_p @cache_dir - @driver = RDoc::RI::Driver.new + @driver = RDoc::RI::Driver.new(RDoc::RI::Driver.process_args([])) @driver.homepath = @home_ri end diff --git a/test/rdoc/test_rdoc_ri_formatter.rb b/test/rdoc/test_rdoc_ri_formatter.rb index ed2ccba22d..539359033e 100644 --- a/test/rdoc/test_rdoc_ri_formatter.rb +++ b/test/rdoc/test_rdoc_ri_formatter.rb @@ -245,7 +245,7 @@ class TestRDocRIFormatter < Test::Unit::TestCase def test_raw_print_line @f.raw_print_line 'a b c' - assert_equal "a b c\n", @output.string + assert_equal "a b c", @output.string end def test_strip_attributes_b -- cgit v1.2.3