From 6db079b0e7bfb3014f32bfb4e9ca5ddeed5b3bcf Mon Sep 17 00:00:00 2001 From: drbrain Date: Fri, 18 Jul 2008 00:46:16 +0000 Subject: Import RDoc r101. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@18121 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/rdoc/test_rdoc_c_parser.rb | 261 ------------- test/rdoc/test_rdoc_info_formatting.rb | 179 +++++++++ test/rdoc/test_rdoc_info_sections.rb | 93 +++++ test/rdoc/test_rdoc_markup_to_html.rb | 30 ++ test/rdoc/test_rdoc_markup_to_html_crossref.rb | 18 + test/rdoc/test_rdoc_parser_c.rb | 262 +++++++++++++ test/rdoc/test_rdoc_parser_ruby.rb | 500 +++++++++++++++++++++++++ test/rdoc/test_rdoc_ri_default_display.rb | 33 +- test/rdoc/test_rdoc_ri_driver.rb | 100 +++++ 9 files changed, 1199 insertions(+), 277 deletions(-) delete mode 100644 test/rdoc/test_rdoc_c_parser.rb create mode 100644 test/rdoc/test_rdoc_info_formatting.rb create mode 100644 test/rdoc/test_rdoc_info_sections.rb create mode 100644 test/rdoc/test_rdoc_markup_to_html.rb create mode 100644 test/rdoc/test_rdoc_markup_to_html_crossref.rb create mode 100644 test/rdoc/test_rdoc_parser_c.rb create mode 100644 test/rdoc/test_rdoc_parser_ruby.rb create mode 100644 test/rdoc/test_rdoc_ri_driver.rb (limited to 'test/rdoc') diff --git a/test/rdoc/test_rdoc_c_parser.rb b/test/rdoc/test_rdoc_c_parser.rb deleted file mode 100644 index 72d09038a..000000000 --- a/test/rdoc/test_rdoc_c_parser.rb +++ /dev/null @@ -1,261 +0,0 @@ -require 'stringio' -require 'tempfile' -require 'test/unit' -require 'rdoc/parsers/parse_c' - -class RDoc::C_Parser - attr_accessor :classes - - public :do_classes, :do_constants -end - -class TestRdocC_Parser < 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 Hash.new - @stats = RDoc::Stats.new - - @progress = StringIO.new - end - - def teardown - @tempfile.close - end - - def test_do_classes_boot_class - content = <<-EOF -/* Document-class: Foo - * this is the Foo boot class - */ -VALUE cFoo = boot_defclass("Foo", 0); - EOF - - klass = util_get_class content, 'cFoo' - assert_equal " this is the Foo boot class\n ", klass.comment - end - - def test_do_classes_class - content = <<-EOF -/* Document-class: Foo - * this is the Foo class - */ -VALUE cFoo = rb_define_class("Foo", rb_cObject); - EOF - - klass = util_get_class content, 'cFoo' - assert_equal " this is the Foo class\n ", klass.comment - end - - def test_do_classes_class_under - content = <<-EOF -/* Document-class: Kernel::Foo - * this is the Foo class under Kernel - */ -VALUE cFoo = rb_define_class_under(rb_mKernel, "Foo", rb_cObject); - EOF - - klass = util_get_class content, 'cFoo' - assert_equal " this is the Foo class under Kernel\n ", klass.comment - end - - def test_do_classes_module - content = <<-EOF -/* Document-module: Foo - * this is the Foo module - */ -VALUE mFoo = rb_define_module("Foo"); - EOF - - klass = util_get_class content, 'mFoo' - assert_equal " this is the Foo module\n ", klass.comment - end - - def test_do_classes_module_under - content = <<-EOF -/* Document-module: Kernel::Foo - * this is the Foo module under Kernel - */ -VALUE mFoo = rb_define_module_under(rb_mKernel, "Foo"); - EOF - - klass = util_get_class content, 'mFoo' - assert_equal " this is the Foo module under Kernel\n ", klass.comment - end - - def test_do_constants - content = <<-EOF -#include - -void Init_foo(){ - VALUE cFoo = rb_define_class("Foo", rb_cObject); - - /* 300: The highest possible score in bowling */ - rb_define_const(cFoo, "PERFECT", INT2FIX(300)); - - /* Huzzah!: What you cheer when you roll a perfect game */ - rb_define_const(cFoo, "CHEER", rb_str_new2("Huzzah!")); - - /* TEST\:TEST: Checking to see if escaped semicolon works */ - rb_define_const(cFoo, "TEST", rb_str_new2("TEST:TEST")); - - /* \\: The file separator on MS Windows */ - rb_define_const(cFoo, "MSEPARATOR", rb_str_new2("\\")); - - /* /: The file separator on Unix */ - rb_define_const(cFoo, "SEPARATOR", rb_str_new2("/")); - - /* C:\\Program Files\\Stuff: A directory on MS Windows */ - rb_define_const(cFoo, "STUFF", rb_str_new2("C:\\Program Files\\Stuff")); - - /* Default definition */ - rb_define_const(cFoo, "NOSEMI", INT2FIX(99)); - - rb_define_const(cFoo, "NOCOMMENT", rb_str_new2("No comment")); - - /* - * Multiline comment goes here because this comment spans multiple lines. - * Multiline comment goes here because this comment spans multiple lines. - */ - rb_define_const(cFoo, "MULTILINE", INT2FIX(1)); - - /* - * 1: Multiline comment goes here because this comment spans multiple lines. - * Multiline comment goes here because this comment spans multiple lines. - */ - rb_define_const(cFoo, "MULTILINE_VALUE", INT2FIX(1)); - - /* Multiline comment goes here because this comment spans multiple lines. - * Multiline comment goes here because this comment spans multiple lines. - */ - rb_define_const(cFoo, "MULTILINE_NOT_EMPTY", INT2FIX(1)); - -} - EOF - - parser = util_parser content - - parser.do_classes - parser.do_constants - - klass = parser.classes['cFoo'] - assert klass - - constants = klass.constants - assert !klass.constants.empty? - - constants = constants.map { |c| [c.name, c.value, c.comment] } - - assert_equal ['PERFECT', '300', - "\n The highest possible score in bowling \n "], - constants.shift - assert_equal ['CHEER', 'Huzzah!', - "\n What you cheer when you roll a perfect game \n "], - constants.shift - assert_equal ['TEST', 'TEST:TEST', - "\n Checking to see if escaped semicolon works \n "], - constants.shift - assert_equal ['MSEPARATOR', '\\', - "\n The file separator on MS Windows \n "], - constants.shift - assert_equal ['SEPARATOR', '/', - "\n The file separator on Unix \n "], - constants.shift - assert_equal ['STUFF', 'C:\\Program Files\\Stuff', - "\n A directory on MS Windows \n "], - constants.shift - assert_equal ['NOSEMI', 'INT2FIX(99)', - "\n Default definition \n "], - constants.shift - assert_equal ['NOCOMMENT', 'rb_str_new2("No comment")', nil], - constants.shift - - comment = <<-EOF.chomp - - - Multiline comment goes here because this comment spans multiple lines. - Multiline comment goes here because this comment spans multiple lines. - - - EOF - assert_equal ['MULTILINE', 'INT2FIX(1)', comment], constants.shift - assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift - - comment = <<-EOF.chomp - - Multiline comment goes here because this comment spans multiple lines. - Multiline comment goes here because this comment spans multiple lines. - - - EOF - assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift - - assert constants.empty?, constants.inspect - end - - def test_find_class_comment_init - content = <<-EOF -/* - * a comment for class Foo - */ -void -Init_Foo(void) { - VALUE foo = rb_define_class("Foo", rb_cObject); -} - EOF - - klass = util_get_class content, 'foo' - - assert_equal " \n a comment for class Foo\n \n", klass.comment - end - - def test_find_class_comment_define_class - content = <<-EOF -/* - * a comment for class Foo - */ -VALUE foo = rb_define_class("Foo", rb_cObject); - EOF - - klass = util_get_class content, 'foo' - - assert_equal " \n a comment for class Foo\n ", klass.comment - end - - def test_find_class_comment_define_class_Init_Foo - content = <<-EOF -/* - * a comment for class Foo on Init - */ -void -Init_Foo(void) { - /* - * a comment for class Foo on rb_define_class - */ - VALUE foo = rb_define_class("Foo", rb_cObject); -} - EOF - - klass = util_get_class content, 'foo' - - assert_equal " \n a comment for class Foo on Init\n \n", klass.comment - end - - def util_get_class(content, name) - parser = util_parser content - parser.do_classes - parser.classes[name] - end - - def util_parser(content) - parser = RDoc::C_Parser.new @top_level, @fn, content, @options, @stats - parser.progress = @progress - parser - end - -end - diff --git a/test/rdoc/test_rdoc_info_formatting.rb b/test/rdoc/test_rdoc_info_formatting.rb new file mode 100644 index 000000000..bcc55ddf5 --- /dev/null +++ b/test/rdoc/test_rdoc_info_formatting.rb @@ -0,0 +1,179 @@ +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib/' +require 'fileutils' +require 'test/unit' +require 'rdoc/generator/texinfo' +require 'yaml' + +# From chapter 18 of the Pickaxe 3rd ed. and the TexInfo manual. +class TestRdocInfoFormatting < Test::Unit::TestCase + OUTPUT_DIR = "/tmp/rdoc-#{$$}" + + def setup + # supress stdout + $stdout = File.new('/dev/null','w') + $stderr = File.new('/dev/null','w') + + RDoc::RDoc.new.document(['--fmt=texinfo', + File.expand_path(__FILE__), + "--op=#{OUTPUT_DIR}"]) + @text = File.read(OUTPUT_DIR + '/rdoc.texinfo') + # File.open('rdoc.texinfo', 'w') { |f| f.puts @text } + end + + def teardown + $stdout = STDOUT + $stderr = STDERR + FileUtils.rm_rf OUTPUT_DIR + end + + # Make sure tags like *this* do not make HTML + def test_descriptions_are_not_html + assert_no_match Regexp.new("\this\<\/b\>"), @text, "We had some HTML; icky!" + end + + # Ensure we get a reasonable amount + # + # of space in between paragraphs. + def test_paragraphs_are_spaced + assert_match(/amount\n\n\nof space/, @text) + end + + # @ and {} should be at-sign-prefixed + def test_escaping + assert_match(/@@ and @\{@\} should be at-sign-prefixed/) + end + + # This tests that *bold* and bold me become @strong{bolded} + def test_bold + # Seems like a limitation of the Info format: @strong{bold} + # becomes *bold* when read in Info or M-x info. highly lame! + assert_match(/@strong\{bold\}/) + assert_match(/@strong\{bold me\}/) + end + + # Test that _italics_ and italicize me becomes @emph{italicized} + def test_italics + assert_match(/@emph\{italics\}/) + assert_match(/@emph\{italicize me\}/) + end + + # And that typewriter +text+ and typewriter me becomes @code{typewriter} + def test_tt + assert_match(/@code\{text\}/) + assert_match(/@code\{typewriter me\}/) + end + + # Check that + # anything indented is + # verbatim @verb{|foo bar baz|} + def test_literal_code + assert_match("@verb{| anything indented is + verbatim @@verb@{|foo bar baz|@} +|}") + end + + # = Huge heading should be a @majorheading + # == There is also @chapheading + # === 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\}/) + end + + # * list item + # * list item2 + # + # with a paragraph in between + # + # - hyphen lists + # - are also allowed + # and items may flow over lines + def test_bullet_lists + assert_match("@itemize @bullet +@item +list item +@item +list item2 +@end itemize") + assert_match("@itemize @bullet +@item +hyphen lists +@item +are also allowed and items may flow over lines +@end itemize") + end + + # 2. numbered lists + # 8. are made by + # 9. a digit followed by a period + def test_numbered_lists + end + + # a. alpha lists + # b. should be parsed too + def test_alpha_lists + end + + # [cat] small domestic animal + # [+cat+] command to copy standard input + # to standard output + def test_labelled_lists + end + + # * First item. + # * Inner item. + # * Second inner item. + # * Second outer item. + def test_nested_lists + assert_match("@itemize @bullet +@item +First item. +@itemize @bullet +@item +Inner item. +@item +Second inner item. +@end itemize +@item +Second outer item. +@end itemize") + end + + def test_internal_hyperlinks + # be sure to test multi-word hyperlinks as well. + end + + def test_hyperlink_targets + end + + def test_web_links + # An example of the two-argument form: The official + # @uref{ftp://ftp.gnu.org/gnu, GNU ftp site} holds programs and texts. + + # produces: + # The official GNU ftp site (ftp://ftp.gnu.org/gnu) + # holds programs and texts. + # and the HTML output is this: + # The official GNU ftp site + # holds programs and texts. + end + + # three or more hyphens + # ---- + # should produce a horizontal rule + def test_horizontal_rule + # gah; not sure texinfo supports horizontal rules + end + + private + + # We don't want the whole string inspected if we pass our own + # message in. + def assert_match(regex, string = @text, + message = "Didn't find #{regex.inspect} in #{string}.") + assert string[regex] #, message + end +end diff --git a/test/rdoc/test_rdoc_info_sections.rb b/test/rdoc/test_rdoc_info_sections.rb new file mode 100644 index 000000000..2b6ff6adc --- /dev/null +++ b/test/rdoc/test_rdoc_info_sections.rb @@ -0,0 +1,93 @@ +$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib/' +require 'fileutils' +require 'test/unit' +require 'rdoc/generator/texinfo' +require 'yaml' + +# give us access to check this stuff before it's rendered +class RDoc::Generator::Texinfo; attr_reader :files, :classes; end +class RDoc::RDoc; attr_reader :options; attr_reader :gen; end + +class TestRdocInfoSections < Test::Unit::TestCase + OUTPUT_DIR = "/tmp/rdoc-#{$$}" + + def setup + # supress stdout + $stdout = File.new('/dev/null','w') + $stderr = File.new('/dev/null','w') + + @rdoc = RDoc::RDoc.new + @rdoc.document(['--fmt=texinfo', + File.expand_path(File.dirname(__FILE__) + '/../lib/rdoc/generator/texinfo.rb'), + File.expand_path(File.dirname(__FILE__) + '/../README.txt'), + "--op=#{OUTPUT_DIR}"]) + @text = File.read(OUTPUT_DIR + '/rdoc.texinfo') + end + + def teardown + $stdout = STDOUT + $stderr = STDERR + FileUtils.rm_rf OUTPUT_DIR + end + + def test_output_exists + assert ! @text.empty? + end + + def test_each_class_has_a_chapter + assert_section "Class RDoc::Generator::Texinfo", '@chapter' + assert_section "Class RDoc::Generator::TexinfoTemplate", '@chapter' + end + + def test_class_descriptions_are_given + assert_match(/This generates .*Texinfo.* files for viewing with GNU Info or Emacs from .*RDoc.* extracted from Ruby source files/, @text.gsub("\n", ' ')) + end + + def test_included_modules_are_given + assert_match(/Includes.* Generator::MarkUp/m, @text) + end + + def test_class_methods_are_given + assert_match(/new\(options\)/, @text) + end + + def test_classes_instance_methods_are_given + assert_section 'Class RDoc::Generator::Texinfo#generate' + assert_match(/generate\(toplevels\)/, @text) + end + + def test_each_module_has_a_chapter + assert_section "RDoc", '@chapter' + assert_section "Generator", '@chapter' + end + + def test_methods_are_shown_only_once + methods = @rdoc.gen.classes.map { |c| c.methods.map{ |m| c.name + '#' + m.name } }.flatten + assert_equal methods, methods.uniq + end + +# if system "makeinfo --version > /dev/null" +# def test_compiles_to_info +# makeinfo_output = `cd #{OUTPUT_DIR} && makeinfo rdoc.texinfo` +# assert(File.exist?(File.join(OUTPUT_DIR, 'rdoc.info')), +# "Info file was not compiled: #{makeinfo_output}") +# end +# end + +# def test_constants_are_documented_somehow +# assert_section 'DEFAULT_FILENAME' # what kind of section? +# assert_section 'DEFAULT_INFO_FILENAME' +# end + +# def test_oh_yeah_dont_forget_files +# end + + private + def assert_section(name, command = '@section') + assert_match Regexp.new("^#{command}.*#{Regexp.escape name}"), @text, "Could not find a #{command} #{name}" + end + +# def puts(*args) +# @real_stdout.puts(*args) +# end +end diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb new file mode 100644 index 000000000..463228cc4 --- /dev/null +++ b/test/rdoc/test_rdoc_markup_to_html.rb @@ -0,0 +1,30 @@ +require 'test/unit' +require 'rdoc/markup' +require 'rdoc/markup/to_html' + +class TestRdocMarkupToHtml < Test::Unit::TestCase + + def setup + @am = RDoc::Markup::AttributeManager.new + @th = RDoc::Markup::ToHtml.new + end + + def test_tt_formatting + assert_equal "

\n--(c) ©\n

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

\n\n

\n", util_format("--") + end + + def util_fragment(text) + RDoc::Markup::Fragment.new 0, nil, nil, text + end + + def util_format(text) + fragment = util_fragment text + + @th.start_accepting + @th.accept_paragraph @am, fragment + @th.end_accepting + end + +end diff --git a/test/rdoc/test_rdoc_markup_to_html_crossref.rb b/test/rdoc/test_rdoc_markup_to_html_crossref.rb new file mode 100644 index 000000000..ab4c3e7e9 --- /dev/null +++ b/test/rdoc/test_rdoc_markup_to_html_crossref.rb @@ -0,0 +1,18 @@ +require 'test/unit' +require 'rdoc/generator' +require 'rdoc/markup/to_html_crossref' + +class TestRdocMarkupToHtmlCrossref < Test::Unit::TestCase + + def setup + @xref = RDoc::Markup::ToHtmlCrossref.new 'from_path', nil, nil + end + + def test_handle_special_CROSSREF_no_underscore + out = @xref.convert 'foo' + + assert_equal "

\nfoo\n

\n", out + end + +end + diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb new file mode 100644 index 000000000..a52018f37 --- /dev/null +++ b/test/rdoc/test_rdoc_parser_c.rb @@ -0,0 +1,262 @@ +require 'stringio' +require 'tempfile' +require 'test/unit' +require 'rdoc/options' +require 'rdoc/parser/c' + +class RDoc::Parser::C + attr_accessor :classes + + public :do_classes, :do_constants +end + +class TestRdocParserC < 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 Hash.new + @stats = RDoc::Stats.new + + @progress = StringIO.new + end + + def teardown + @tempfile.close + end + + def test_do_classes_boot_class + content = <<-EOF +/* Document-class: Foo + * this is the Foo boot class + */ +VALUE cFoo = boot_defclass("Foo", 0); + EOF + + klass = util_get_class content, 'cFoo' + assert_equal " this is the Foo boot class\n ", klass.comment + end + + def test_do_classes_class + content = <<-EOF +/* Document-class: Foo + * this is the Foo class + */ +VALUE cFoo = rb_define_class("Foo", rb_cObject); + EOF + + klass = util_get_class content, 'cFoo' + assert_equal " this is the Foo class\n ", klass.comment + end + + def test_do_classes_class_under + content = <<-EOF +/* Document-class: Kernel::Foo + * this is the Foo class under Kernel + */ +VALUE cFoo = rb_define_class_under(rb_mKernel, "Foo", rb_cObject); + EOF + + klass = util_get_class content, 'cFoo' + assert_equal " this is the Foo class under Kernel\n ", klass.comment + end + + def test_do_classes_module + content = <<-EOF +/* Document-module: Foo + * this is the Foo module + */ +VALUE mFoo = rb_define_module("Foo"); + EOF + + klass = util_get_class content, 'mFoo' + assert_equal " this is the Foo module\n ", klass.comment + end + + def test_do_classes_module_under + content = <<-EOF +/* Document-module: Kernel::Foo + * this is the Foo module under Kernel + */ +VALUE mFoo = rb_define_module_under(rb_mKernel, "Foo"); + EOF + + klass = util_get_class content, 'mFoo' + assert_equal " this is the Foo module under Kernel\n ", klass.comment + end + + def test_do_constants + content = <<-EOF +#include + +void Init_foo(){ + VALUE cFoo = rb_define_class("Foo", rb_cObject); + + /* 300: The highest possible score in bowling */ + rb_define_const(cFoo, "PERFECT", INT2FIX(300)); + + /* Huzzah!: What you cheer when you roll a perfect game */ + rb_define_const(cFoo, "CHEER", rb_str_new2("Huzzah!")); + + /* TEST\:TEST: Checking to see if escaped semicolon works */ + rb_define_const(cFoo, "TEST", rb_str_new2("TEST:TEST")); + + /* \\: The file separator on MS Windows */ + rb_define_const(cFoo, "MSEPARATOR", rb_str_new2("\\")); + + /* /: The file separator on Unix */ + rb_define_const(cFoo, "SEPARATOR", rb_str_new2("/")); + + /* C:\\Program Files\\Stuff: A directory on MS Windows */ + rb_define_const(cFoo, "STUFF", rb_str_new2("C:\\Program Files\\Stuff")); + + /* Default definition */ + rb_define_const(cFoo, "NOSEMI", INT2FIX(99)); + + rb_define_const(cFoo, "NOCOMMENT", rb_str_new2("No comment")); + + /* + * Multiline comment goes here because this comment spans multiple lines. + * Multiline comment goes here because this comment spans multiple lines. + */ + rb_define_const(cFoo, "MULTILINE", INT2FIX(1)); + + /* + * 1: Multiline comment goes here because this comment spans multiple lines. + * Multiline comment goes here because this comment spans multiple lines. + */ + rb_define_const(cFoo, "MULTILINE_VALUE", INT2FIX(1)); + + /* Multiline comment goes here because this comment spans multiple lines. + * Multiline comment goes here because this comment spans multiple lines. + */ + rb_define_const(cFoo, "MULTILINE_NOT_EMPTY", INT2FIX(1)); + +} + EOF + + parser = util_parser content + + parser.do_classes + parser.do_constants + + klass = parser.classes['cFoo'] + assert klass + + constants = klass.constants + assert !klass.constants.empty? + + constants = constants.map { |c| [c.name, c.value, c.comment] } + + assert_equal ['PERFECT', '300', + "\n The highest possible score in bowling \n "], + constants.shift + assert_equal ['CHEER', 'Huzzah!', + "\n What you cheer when you roll a perfect game \n "], + constants.shift + assert_equal ['TEST', 'TEST:TEST', + "\n Checking to see if escaped semicolon works \n "], + constants.shift + assert_equal ['MSEPARATOR', '\\', + "\n The file separator on MS Windows \n "], + constants.shift + assert_equal ['SEPARATOR', '/', + "\n The file separator on Unix \n "], + constants.shift + assert_equal ['STUFF', 'C:\\Program Files\\Stuff', + "\n A directory on MS Windows \n "], + constants.shift + assert_equal ['NOSEMI', 'INT2FIX(99)', + "\n Default definition \n "], + constants.shift + assert_equal ['NOCOMMENT', 'rb_str_new2("No comment")', nil], + constants.shift + + comment = <<-EOF.chomp + + + Multiline comment goes here because this comment spans multiple lines. + Multiline comment goes here because this comment spans multiple lines. + + + EOF + assert_equal ['MULTILINE', 'INT2FIX(1)', comment], constants.shift + assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift + + comment = <<-EOF.chomp + + Multiline comment goes here because this comment spans multiple lines. + Multiline comment goes here because this comment spans multiple lines. + + + EOF + assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift + + assert constants.empty?, constants.inspect + end + + def test_find_class_comment_init + content = <<-EOF +/* + * a comment for class Foo + */ +void +Init_Foo(void) { + VALUE foo = rb_define_class("Foo", rb_cObject); +} + EOF + + klass = util_get_class content, 'foo' + + assert_equal " \n a comment for class Foo\n \n", klass.comment + end + + def test_find_class_comment_define_class + content = <<-EOF +/* + * a comment for class Foo + */ +VALUE foo = rb_define_class("Foo", rb_cObject); + EOF + + klass = util_get_class content, 'foo' + + assert_equal " \n a comment for class Foo\n ", klass.comment + end + + def test_find_class_comment_define_class_Init_Foo + content = <<-EOF +/* + * a comment for class Foo on Init + */ +void +Init_Foo(void) { + /* + * a comment for class Foo on rb_define_class + */ + VALUE foo = rb_define_class("Foo", rb_cObject); +} + EOF + + klass = util_get_class content, 'foo' + + assert_equal " \n a comment for class Foo on Init\n \n", klass.comment + end + + def util_get_class(content, name) + parser = util_parser content + parser.do_classes + parser.classes[name] + end + + def util_parser(content) + parser = RDoc::Parser::C.new @top_level, @fn, content, @options, @stats + parser.progress = @progress + parser + end + +end + diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb new file mode 100644 index 000000000..2bf659e56 --- /dev/null +++ b/test/rdoc/test_rdoc_parser_ruby.rb @@ -0,0 +1,500 @@ +require 'stringio' +require 'tempfile' +require 'test/unit' + +require 'rdoc/options' +require 'rdoc/parser/ruby' +require 'rdoc/stats' + +class TestRdocParserRuby < Test::Unit::TestCase + + def setup + @tempfile = Tempfile.new self.class.name + @filename = @tempfile.path + + util_toplevel + @options = RDoc::Options.new Hash.new + @options.quiet = true + @stats = RDoc::Stats.new + + @progress = StringIO.new + end + + def teardown + @tempfile.unlink + end + + def test_look_for_directives_in_commented + util_parser "" + + comment = "# how to make a section:\n# # :section: new section\n" + + @parser.look_for_directives_in @top_level, comment + + section = @top_level.current_section + assert_equal nil, section.title + assert_equal nil, section.comment + + assert_equal "# how to make a section:\n# # :section: new section\n", + comment + end + + def test_look_for_directives_in_enddoc + util_parser "" + + assert_throws :enddoc do + @parser.look_for_directives_in @top_level, "# :enddoc:\n" + end + end + + def test_look_for_directives_in_main + util_parser "" + + @parser.look_for_directives_in @top_level, "# :main: new main page\n" + + assert_equal 'new main page', @options.main_page + end + + def test_look_for_directives_in_method + util_parser "" + + comment = "# :method: my_method\n" + + @parser.look_for_directives_in @top_level, comment + + assert_equal "# :method: my_method\n", comment + + comment = "# :singleton-method: my_method\n" + + @parser.look_for_directives_in @top_level, comment + + assert_equal "# :singleton-method: my_method\n", comment + end + + def test_look_for_directives_in_startdoc + util_parser "" + + @top_level.stop_doc + assert !@top_level.document_self + assert !@top_level.document_children + assert !@top_level.force_documentation + + @parser.look_for_directives_in @top_level, "# :startdoc:\n" + + assert @top_level.document_self + assert @top_level.document_children + assert @top_level.force_documentation + end + + def test_look_for_directives_in_stopdoc + util_parser "" + + assert @top_level.document_self + assert @top_level.document_children + + @parser.look_for_directives_in @top_level, "# :stopdoc:\n" + + assert !@top_level.document_self + assert !@top_level.document_children + end + + def test_look_for_directives_in_section + util_parser "" + + comment = "# :section: new section\n# woo stuff\n" + + @parser.look_for_directives_in @top_level, comment + + section = @top_level.current_section + assert_equal 'new section', section.title + assert_equal "# woo stuff\n", section.comment + + assert_equal '', comment + end + + def test_look_for_directives_in_title + util_parser "" + + @parser.look_for_directives_in @top_level, "# :title: new title\n" + + assert_equal 'new title', @options.title + end + + def test_look_for_directives_in_unhandled + util_parser "" + + comment = "# :unhandled: \n# :title: hi\n" + + @parser.look_for_directives_in @top_level, comment + + assert_equal "# :unhandled: \n", comment + + assert_equal 'hi', @options.title + end + + def test_parse_meta_method + klass = RDoc::NormalClass.new 'Foo' + klass.parent = @top_level + + comment = "##\n# my method\n" + + util_parser "add_my_method :foo, :bar\nadd_my_method :baz" + + tk = @parser.get_tk + + @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = klass.method_list.first + assert_equal 'foo', foo.name + assert_equal comment, foo.comment + + assert_equal [], foo.aliases + assert_equal nil, foo.block_params + assert_equal nil, foo.call_seq + assert_equal true, foo.document_children + assert_equal true, foo.document_self + assert_equal false, foo.done_documenting + assert_equal false, foo.dont_rename_initialize + assert_equal false, foo.force_documentation + assert_equal nil, foo.is_alias_for + assert_equal '', foo.params + assert_equal klass, foo.parent + assert_equal false, foo.singleton + assert_equal 'add_my_method :foo', foo.text + assert_equal nil, foo.viewer + assert_equal :public, foo.visibility + assert_equal klass.current_section, foo.section + + stream = [ + tk(:COMMENT, 1, 1, nil, "# File #{@top_level.file_absolute_name}, line 1"), + RDoc::Parser::Ruby::NEWLINE_TOKEN, + tk(:SPACE, 1, 1, nil, ''), + tk(:IDENTIFIER, 1, 0, 'add_my_method', 'add_my_method'), + tk(:SPACE, 1, 13, nil, ' '), + tk(:SYMBOL, 1, 14, nil, ':foo'), + tk(:COMMA, 1, 18, nil, ','), + tk(:SPACE, 1, 19, nil, ' '), + tk(:SYMBOL, 1, 20, nil, ':bar'), + tk(:NL, 1, 24, nil, "\n"), + ] + + assert_equal stream, foo.token_stream + end + + def test_parse_meta_method_name + klass = RDoc::NormalClass.new 'Foo' + klass.parent = @top_level + + comment = "##\n# :method: woo_hoo!\n# my method\n" + + util_parser "add_my_method :foo, :bar\nadd_my_method :baz" + + tk = @parser.get_tk + + @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = klass.method_list.first + assert_equal 'woo_hoo!', foo.name + assert_equal "##\n# my method\n", foo.comment + end + + def test_parse_meta_method_singleton + klass = RDoc::NormalClass.new 'Foo' + klass.parent = @top_level + + comment = "##\n# :singleton-method:\n# my method\n" + + util_parser "add_my_method :foo, :bar\nadd_my_method :baz" + + tk = @parser.get_tk + + @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = klass.method_list.first + assert_equal 'foo', foo.name + assert_equal true, foo.singleton, 'singleton method' + assert_equal "##\n# my method\n", foo.comment + end + + def test_parse_meta_method_singleton_name + klass = RDoc::NormalClass.new 'Foo' + klass.parent = @top_level + + comment = "##\n# :singleton-method: woo_hoo!\n# my method\n" + + util_parser "add_my_method :foo, :bar\nadd_my_method :baz" + + tk = @parser.get_tk + + @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = klass.method_list.first + assert_equal 'woo_hoo!', foo.name + assert_equal true, foo.singleton, 'singleton method' + assert_equal "##\n# my method\n", foo.comment + end + + def test_parse_meta_method_string_name + klass = RDoc::NormalClass.new 'Foo' + comment = "##\n# my method\n" + + util_parser "add_my_method 'foo'" + + tk = @parser.get_tk + + @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = klass.method_list.first + assert_equal 'foo', foo.name + assert_equal comment, foo.comment + end + + def test_parse_method + klass = RDoc::NormalClass.new 'Foo' + klass.parent = @top_level + + comment = "##\n# my method\n" + + util_parser "def foo() :bar end" + + tk = @parser.get_tk + + @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment + + foo = klass.method_list.first + assert_equal 'foo', foo.name + assert_equal comment, foo.comment + + assert_equal [], foo.aliases + assert_equal nil, foo.block_params + assert_equal nil, foo.call_seq + assert_equal nil, foo.is_alias_for + assert_equal nil, foo.viewer + assert_equal true, foo.document_children + assert_equal true, foo.document_self + assert_equal '()', foo.params + assert_equal false, foo.done_documenting + assert_equal false, foo.dont_rename_initialize + assert_equal false, foo.force_documentation + assert_equal klass, foo.parent + assert_equal false, foo.singleton + assert_equal :public, foo.visibility + assert_equal 'def foo', foo.text + assert_equal klass.current_section, foo.section + + stream = [ + tk(:COMMENT, 1, 1, nil, "# File #{@top_level.file_absolute_name}, line 1"), + RDoc::Parser::Ruby::NEWLINE_TOKEN, + tk(:SPACE, 1, 1, nil, ''), + tk(:DEF, 1, 0, 'def', 'def'), + tk(:SPACE, 1, 3, nil, ' '), + tk(:IDENTIFIER, 1, 4, 'foo', 'foo'), + tk(:LPAREN, 1, 7, nil, '('), + tk(:RPAREN, 1, 8, nil, ')'), + tk(:SPACE, 1, 9, nil, ' '), + tk(:COLON, 1, 10, nil, ':'), + tk(:IDENTIFIER, 1, 11, 'bar', 'bar'), + tk(:SPACE, 1, 14, nil, ' '), + tk(:END, 1, 15, 'end', 'end'), + ] + + assert_equal stream, foo.token_stream + end + + def test_parse_statements_comment + content = <<-EOF +class Foo + ## + # :method: my_method + # my method comment + +end + EOF + klass = RDoc::NormalClass.new 'Foo' + klass.parent = @top_level + + comment = "##\n# :method: foo\n# my method\n" + + util_parser "\n" + + tk = @parser.get_tk + + @parser.parse_comment klass, tk, comment + + foo = klass.method_list.first + assert_equal 'foo', foo.name + assert_equal comment, foo.comment + + assert_equal [], foo.aliases + assert_equal nil, foo.block_params + assert_equal nil, foo.call_seq + assert_equal nil, foo.is_alias_for + assert_equal nil, foo.viewer + assert_equal true, foo.document_children + assert_equal true, foo.document_self + assert_equal '', foo.params + assert_equal false, foo.done_documenting + assert_equal false, foo.dont_rename_initialize + assert_equal false, foo.force_documentation + assert_equal klass, foo.parent + assert_equal false, foo.singleton + assert_equal :public, foo.visibility + assert_equal "\n", foo.text + assert_equal klass.current_section, foo.section + + stream = [ + tk(:COMMENT, 1, 1, nil, "# File #{@top_level.file_absolute_name}, line 1"), + RDoc::Parser::Ruby::NEWLINE_TOKEN, + tk(:SPACE, 1, 1, nil, ''), + ] + + assert_equal stream, foo.token_stream + end + + def test_parse_statements_identifier_meta_method + content = <<-EOF +class Foo + ## + # this is my method + add_my_method :foo +end + EOF + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first.method_list.first + assert_equal 'foo', foo.name + end + + def test_parse_statements_identifier_alias_method + content = "class Foo def foo() end; alias_method :foo2, :foo end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo2 = @top_level.classes.first.method_list.last + assert_equal 'foo2', foo2.name + assert_equal 'foo', foo2.is_alias_for.name + end + + def test_parse_statements_identifier_attr + content = "class Foo; attr :foo; end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first.attributes.first + assert_equal 'foo', foo.name + assert_equal 'R', foo.rw + end + + def test_parse_statements_identifier_attr_accessor + content = "class Foo; attr_accessor :foo; end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first.attributes.first + assert_equal 'foo', foo.name + assert_equal 'RW', foo.rw + end + + def test_parse_statements_identifier_extra_accessors + @options.extra_accessors = /^my_accessor$/ + + content = "class Foo; my_accessor :foo; end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first.attributes.first + assert_equal 'foo', foo.name + assert_equal '?', foo.rw + end + + def test_parse_statements_identifier_include + content = "class Foo; include Bar; end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first + assert_equal 'Foo', foo.name + assert_equal 1, foo.includes.length + end + + def test_parse_statements_identifier_module_function + content = "module Foo def foo() end; module_function :foo; end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo, s_foo = @top_level.modules.first.method_list + assert_equal 'foo', foo.name, 'instance method name' + assert_equal :private, foo.visibility, 'instance method visibility' + assert_equal false, foo.singleton, 'instance method singleton' + + assert_equal 'foo', s_foo.name, 'module function name' + assert_equal :public, s_foo.visibility, 'module function visibility' + assert_equal true, s_foo.singleton, 'module function singleton' + end + + def test_parse_statements_identifier_private + content = "class Foo private; def foo() end end" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + foo = @top_level.classes.first.method_list.first + assert_equal 'foo', foo.name + assert_equal :private, foo.visibility + end + + def test_parse_statements_identifier_require + content = "require 'bar'" + + util_parser content + + @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' + + assert_equal 1, @top_level.requires.length + end + + def tk(klass, line, char, name, text) + klass = RDoc::RubyToken.const_get "Tk#{klass.to_s.upcase}" + + token = if klass.instance_method(:initialize).arity == 2 then + raise ArgumentError, "name not used for #{klass}" unless name.nil? + klass.new line, char + else + klass.new line, char, name + end + + token.set_text text + + token + end + + def util_parser(content) + @parser = RDoc::Parser::Ruby.new @top_level, @filename, content, @options, + @stats + @parser.progress = @progress + @parser + end + + def util_toplevel + RDoc::TopLevel.reset + @top_level = RDoc::TopLevel.new @filename + end + +end + diff --git a/test/rdoc/test_rdoc_ri_default_display.rb b/test/rdoc/test_rdoc_ri_default_display.rb index d92516f3a..97fa6c94a 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 @@ -14,7 +14,7 @@ class TestRDocRIDefaultDisplay < Test::Unit::TestCase @dd = RDoc::RI::DefaultDisplay.new RDoc::RI::Formatter, @width, true, @output - @some_method = { + @some_method = h \ 'aliases' => [{'name' => 'some_method_alias'}], 'block_params' => 'block_param', 'comment' => [RDoc::Markup::Flow::P.new('some comment')], @@ -23,13 +23,12 @@ class TestRDocRIDefaultDisplay < Test::Unit::TestCase 'name' => 'some_method', 'params' => '(arg1, arg2) {|block_param| ...}', 'source_path' => '/nonexistent', - 'visibility' => 'public', - } + 'visibility' => 'public' end def test_display_class_info ri_reader = nil - klass = { + klass = h \ 'attributes' => [ { 'name' => 'attribute', 'rw' => 'RW', 'comment' => [RDoc::Markup::Flow::P.new('attribute comment')] }, @@ -58,8 +57,7 @@ class TestRDocRIDefaultDisplay < Test::Unit::TestCase 'instance_method_extensions' => [ { 'name' => 'instance_method_extension' }, ], - 'superclass_string' => 'Object', - } + 'superclass_string' => 'Object' @dd.display_class_info klass, ri_reader @@ -154,7 +152,7 @@ Attributes: end def test_display_method_info_singleton - method = { + method = RDoc::RI::Driver::Hash.new.update \ 'aliases' => [], 'block_params' => nil, 'comment' => nil, @@ -162,8 +160,7 @@ Attributes: 'is_singleton' => true, 'name' => 'some_method', 'params' => '(arg1, arg2)', - 'visibility' => 'public', - } + 'visibility' => 'public' @dd.display_method_info method @@ -179,7 +176,7 @@ Attributes: def test_display_method_list methods = [ - { + RDoc::RI::Driver::Hash.new.update( "aliases" => [], "block_params" => nil, "comment" => nil, @@ -187,9 +184,9 @@ Attributes: "is_singleton" => false, "name" => "some_method", "params" => "()", - "visibility" => "public", - }, - { + "visibility" => "public" + ), + RDoc::RI::Driver::Hash.new.update( "aliases" => [], "block_params" => nil, "comment" => nil, @@ -197,8 +194,8 @@ Attributes: "is_singleton" => false, "name" => "some_other_method", "params" => "()", - "visibility" => "public", - }, + "visibility" => "public" + ), ] @dd.display_method_list methods @@ -291,5 +288,9 @@ install an additional package, or ask the packager to enable ri generation. assert_equal expected, @output.string end + def h(hash) + RDoc::RI::Driver::Hash.convert hash + end + end diff --git a/test/rdoc/test_rdoc_ri_driver.rb b/test/rdoc/test_rdoc_ri_driver.rb new file mode 100644 index 000000000..5db831915 --- /dev/null +++ b/test/rdoc/test_rdoc_ri_driver.rb @@ -0,0 +1,100 @@ +require 'test/unit' +require 'tmpdir' +require 'rdoc/ri/driver' + +class TestRDocRIDriver < Test::Unit::TestCase + + def setup + @tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_driver_#{$$}" + @home_ri = File.join @tmpdir, 'dot_ri' + @cache_dir = File.join @home_ri, 'cache' + @class_cache = File.join @cache_dir, 'classes' + + FileUtils.mkdir_p @tmpdir + FileUtils.mkdir_p @home_ri + FileUtils.mkdir_p @cache_dir + + @driver = RDoc::RI::Driver.new + @driver.homepath = @home_ri + end + + def teardown + FileUtils.rm_rf @tmpdir + end + + def test_lookup_method + def @driver.load_cache_for(klassname) + { 'Foo#bar' => :found } + end + + assert @driver.lookup_method('Foo#bar', 'Foo') + end + + def test_lookup_method_class_method + def @driver.load_cache_for(klassname) + { 'Foo::Bar' => :found } + end + + assert @driver.lookup_method('Foo::Bar', 'Foo::Bar') + end + + def test_lookup_method_class_missing + def @driver.load_cache_for(klassname) end + + e = assert_raise RDoc::RI::Driver::NotFoundError do + @driver.lookup_method 'Foo#bar', 'Foo' + end + + assert_equal 'Nothing known about Foo#bar', e.message + end + + def test_lookup_method_dot_instance + def @driver.load_cache_for(klassname) + { 'Foo#bar' => :instance, 'Foo::bar' => :klass } + end + + assert_equal :instance, @driver.lookup_method('Foo.bar', 'Foo') + end + + def test_lookup_method_dot_class + def @driver.load_cache_for(klassname) + { 'Foo::bar' => :found } + end + + assert @driver.lookup_method('Foo.bar', 'Foo') + end + + def test_lookup_method_method_missing + def @driver.load_cache_for(klassname) {} end + + e = assert_raise RDoc::RI::Driver::NotFoundError do + @driver.lookup_method 'Foo#bar', 'Foo' + end + + assert_equal 'Nothing known about Foo#bar', e.message + end + + def test_parse_name + klass, meth = @driver.parse_name 'Foo::Bar' + + assert_equal 'Foo::Bar', klass, 'Foo::Bar class' + assert_equal nil, meth, 'Foo::Bar method' + + klass, meth = @driver.parse_name 'Foo#Bar' + + assert_equal 'Foo', klass, 'Foo#Bar class' + assert_equal 'Bar', meth, 'Foo#Bar method' + + klass, meth = @driver.parse_name 'Foo.Bar' + + assert_equal 'Foo', klass, 'Foo#Bar class' + assert_equal 'Bar', meth, 'Foo#Bar method' + + klass, meth = @driver.parse_name 'Foo::bar' + + assert_equal 'Foo', klass, 'Foo::bar class' + assert_equal 'bar', meth, 'Foo::bar method' + end + +end + -- cgit