From 0b6da24a5e24ff9ce8e153d2f073c2363e94b28e Mon Sep 17 00:00:00 2001 From: drbrain Date: Sat, 14 May 2011 00:39:16 +0000 Subject: [PATCH] * lib/rdoc.rb: Updated to RDoc 3.6 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 + NEWS | 2 +- lib/rdoc.rb | 36 ++++--- lib/rdoc/attr.rb | 13 +++ lib/rdoc/class_module.rb | 16 ++- lib/rdoc/code_object.rb | 14 +++ lib/rdoc/context.rb | 20 +++- lib/rdoc/method_attr.rb | 2 + lib/rdoc/options.rb | 4 +- lib/rdoc/parser/c.rb | 2 +- lib/rdoc/parser/ruby.rb | 35 +++++-- lib/rdoc/rdoc.rb | 39 ++++--- lib/rdoc/ri/driver.rb | 46 +++++--- lib/rdoc/ri/store.rb | 12 +++ lib/rdoc/ruby_lex.rb | 6 +- lib/rdoc/stats.rb | 2 +- lib/rdoc/task.rb | 21 ++-- lib/rdoc/text.rb | 16 +-- test/rdoc/test_rdoc_class_module.rb | 17 +++ test/rdoc/test_rdoc_code_object.rb | 10 ++ test/rdoc/test_rdoc_context.rb | 151 +++++++++++++++++++++++++++ test/rdoc/test_rdoc_markup_parser.rb | 19 ++++ test/rdoc/test_rdoc_parser_c.rb | 33 +++++- test/rdoc/test_rdoc_parser_ruby.rb | 97 +++++++++++++++++ test/rdoc/test_rdoc_ri_driver.rb | 51 +++++++-- test/rdoc/test_rdoc_top_level.rb | 6 +- test/rdoc/xref_data.rb | 9 ++ test/rdoc/xref_test_case.rb | 7 +- 28 files changed, 593 insertions(+), 97 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1e180c532..1d1f8adfaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sat May 14 09:31:43 2011 Eric Hodel + + * lib/rdoc.rb: Updated to RDoc 3.6 + Sat May 14 07:30:29 2011 Aaron Patterson * ext/psych/lib/psych.rb: released a new gem, so increasing version. diff --git a/NEWS b/NEWS index 1a9a14a9c3..c3cad45a5c 100644 --- a/NEWS +++ b/NEWS @@ -108,7 +108,7 @@ with all sufficient information, see the ChangeLog file. * support for bash/zsh completion. * RDoc - * RDoc has been upgraded to RDoc 3.5.3. For full release notes see + * RDoc has been upgraded to RDoc 3.6. For full release notes see http://docs.seattlerb.org/rdoc/History_txt.html * rexml diff --git a/lib/rdoc.rb b/lib/rdoc.rb index d9948deebb..6414bd7683 100644 --- a/lib/rdoc.rb +++ b/lib/rdoc.rb @@ -3,31 +3,39 @@ $DEBUG_RDOC = nil # :main: README.txt ## -# = \RDoc - Ruby Documentation System +# RDoc is a Ruby documentation system which contains RDoc::RDoc for generating +# documentation, RDoc::RI for interactive documentation and RDoc::Markup for +# text markup. # -# This package contains RDoc and RDoc::Markup. RDoc is an application that -# produces documentation for one or more Ruby source files. It works similarly -# to JavaDoc, parsing the source, and extracting the definition for classes, -# modules, and methods (along with includes and requires). It associates with -# these optional documentation contained in the immediately preceding comment -# block, and then renders the result using a pluggable output formatter. -# RDoc::Markup is a library that converts plain text into various output -# formats. The markup library is used to interpret the comment blocks that -# RDoc uses to document methods, classes, and so on. +# RDoc::RDoc produces documentation for Ruby source files. It works similarly +# to JavaDoc, parsing the source and extracting the definition for classes, +# modules, methods, includes and requires. It associates these with optional +# documentation contained in an immediately preceding comment block then +# renders the result using an output formatter. +# +# RDoc::Markup that converts plain text into various output formats. The +# markup library is used to interpret the comment blocks that RDoc uses to +# document methods, classes, and so on. +# +# RDoc::RI implements the +ri+ command-line tool which displays on-line +# documentation for ruby classes, methods, etc. +ri+ features several output +# formats and an interactive mode (ri -i). See ri --help +# for further details. # # == Roadmap # # * If you want to use RDoc to create documentation for your Ruby source files, -# read the summary below, and refer to rdoc --help for command line -# usage, and RDoc::Markup for a detailed description of RDoc's markup. +# see RDoc::Markup and refer to rdoc --help for command line +# usage. # * If you want to generate documentation for extensions written in C, see # RDoc::Parser::C +# * If you want to generate documentation using rake see RDoc::Task. # * If you want to drive RDoc programmatically, see RDoc::RDoc. # * If you want to use the library to format text blocks into HTML, look at # RDoc::Markup. # * If you want to make an RDoc plugin such as a generator or directive # handler see RDoc::RDoc. -# * If you want to try writing your own output generator see RDoc::Generator. +# * If you want to write your own output generator see RDoc::Generator. # # == Summary # @@ -95,7 +103,7 @@ module RDoc ## # RDoc version you are using - VERSION = '3.5.3' + VERSION = '3.6' ## # Method visibilities diff --git a/lib/rdoc/attr.rb b/lib/rdoc/attr.rb index 97fac3222d..f04fe168b1 100644 --- a/lib/rdoc/attr.rb +++ b/lib/rdoc/attr.rb @@ -68,6 +68,19 @@ class RDoc::Attr < RDoc::MethodAttr end end + def inspect # :nodoc: + alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + visibility = self.visibility + visibility = "forced #{visibility}" if force_documentation + "#<%s:0x%x %s %s (%s)%s>" % [ + self.class, object_id, + full_name, + rw, + visibility, + alias_for, + ] + end + ## # Dumps this Attr for use by ri. See also #marshal_load diff --git a/lib/rdoc/class_module.rb b/lib/rdoc/class_module.rb index 3f2d04488e..89441b3e68 100644 --- a/lib/rdoc/class_module.rb +++ b/lib/rdoc/class_module.rb @@ -137,12 +137,22 @@ class RDoc::ClassModule < RDoc::Context remove_invisible min_visibility end + ## + # Iterates the ancestors of this class or module for which an + # RDoc::ClassModule exists. + + def each_ancestor # :yields: module + ancestors.each do |mod| + next if String === mod + yield mod + end + end + ## # Looks for a symbol in the #ancestors. See Context#find_local_symbol. def find_ancestor_local_symbol symbol - ancestors.each do |m| - next if m.is_a?(String) + each_ancestor do |m| res = m.find_local_symbol(symbol) return res if res end @@ -263,7 +273,7 @@ class RDoc::ClassModule < RDoc::Context class_module.each_attribute do |attr| if match = attributes.find { |a| a.name == attr.name } then - match.rw = [match.rw, attr.rw].compact.join + match.rw = [match.rw, attr.rw].compact.uniq.join else add_attribute attr end diff --git a/lib/rdoc/code_object.rb b/lib/rdoc/code_object.rb index 3a8adfab67..63f86afc64 100644 --- a/lib/rdoc/code_object.rb +++ b/lib/rdoc/code_object.rb @@ -180,6 +180,20 @@ class RDoc::CodeObject @document_children = @document_self end + ## + # Yields each parent of this CodeObject. See also + # RDoc::ClassModule#each_ancestor + + def each_parent + code_object = self + + while code_object = code_object.parent do + yield code_object + end + + self + end + ## # Force the documentation of this object unless documentation # has been turned off by :endoc: diff --git a/lib/rdoc/context.rb b/lib/rdoc/context.rb index 3f2856db05..0d7fc41529 100644 --- a/lib/rdoc/context.rb +++ b/lib/rdoc/context.rb @@ -480,7 +480,7 @@ class RDoc::Context < RDoc::CodeObject # Adds included module +include+ which should be an RDoc::Include def add_include(include) - add_to @includes, include + add_to @includes, include unless @includes.map { |i| i.full_name }.include?( include.full_name ) end ## @@ -950,10 +950,14 @@ class RDoc::Context < RDoc::CodeObject ## # Yields AnyMethod and Attr entries matching the list of names in +methods+. - def methods_matching(methods, singleton = false) + def methods_matching(methods, singleton = false, &block) (@method_list + @attributes).each do |m| yield m if methods.include?(m.name) and m.singleton == singleton end + + each_ancestor do |parent| + parent.methods_matching(methods, singleton, &block) + end end ## @@ -1021,11 +1025,19 @@ class RDoc::Context < RDoc::CodeObject remove_invisible_in @attributes, min_visibility end + ## + # Only called when min_visibility == :public or :private + def remove_invisible_in(array, min_visibility) # :nodoc: if min_visibility == :public - array.reject! { |e| e.visibility != :public } + array.reject! { |e| + e.visibility != :public and not e.force_documentation + } else - array.reject! { |e| e.visibility == :private } + array.reject! { |e| + e.visibility == :private and + not e.force_documentation + } end end diff --git a/lib/rdoc/method_attr.rb b/lib/rdoc/method_attr.rb index 15924d9ed0..a4cd3c5fff 100644 --- a/lib/rdoc/method_attr.rb +++ b/lib/rdoc/method_attr.rb @@ -333,6 +333,8 @@ class RDoc::MethodAttr < RDoc::CodeObject def inspect # :nodoc: alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + visibility = self.visibility + visibility = "forced #{visibility}" if force_documentation "#<%s:0x%x %s (%s)%s>" % [ self.class, object_id, full_name, diff --git a/lib/rdoc/options.rb b/lib/rdoc/options.rb index dd91706638..bab5463897 100644 --- a/lib/rdoc/options.rb +++ b/lib/rdoc/options.rb @@ -256,7 +256,9 @@ class RDoc::Options @rdoc_include << "." if @rdoc_include.empty? - if @exclude.empty? then + if @exclude.nil? or Regexp === @exclude then + # done, #finish is being re-run + elsif @exclude.empty? then @exclude = nil else @exclude = Regexp.new(@exclude.join("|")) diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb index bb015690bd..0f2196b2e8 100644 --- a/lib/rdoc/parser/c.rb +++ b/lib/rdoc/parser/c.rb @@ -376,7 +376,7 @@ class RDoc::Parser::C < RDoc::Parser when %r%((?>/\*.*?\*/\s*)?) ((?:(?:static|SWIGINTERN)\s+)? (?:intern\s+)?VALUE\s+#{meth_name} - \s*(\(.*?\))([^;]|$))%xm then + \s*(\([^)]*\))([^;]|$))%xm then comment = $1 body = $2 offset = $~.offset(2).first diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb index bcf0ac1150..6bf1c8d308 100644 --- a/lib/rdoc/parser/ruby.rb +++ b/lib/rdoc/parser/ruby.rb @@ -1558,32 +1558,45 @@ class RDoc::Parser::Ruby < RDoc::Parser when TkNL, TkUNLESS_MOD, TkIF_MOD, TkSEMICOLON then container.ongoing_visibility = vis else - if vis_type == 'module_function' then + new_methods = [] + + case vis_type + when 'module_function' then args = parse_symbol_arg container.set_visibility_for args, :private, false - module_functions = [] - container.methods_matching args do |m| s_m = m.dup s_m.record_location @top_level s_m.singleton = true - s_m.visibility = :public - module_functions << s_m + new_methods << s_m end + when 'public_class_method', 'private_class_method' then + args = parse_symbol_arg - module_functions.each do |s_m| - case s_m - when RDoc::AnyMethod then - container.add_method s_m - when RDoc::Attr then - container.add_attribute s_m + container.methods_matching args, true do |m| + if m.parent != container then + m = m.dup + m.record_location @top_level + new_methods << m end + + m.visibility = vis end else args = parse_symbol_arg container.set_visibility_for args, vis, singleton end + + new_methods.each do |method| + case method + when RDoc::AnyMethod then + container.add_method method + when RDoc::Attr then + container.add_attribute method + end + method.visibility = vis + end end end diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb index 3eab6cdfc4..6d7c4eace6 100644 --- a/lib/rdoc/rdoc.rb +++ b/lib/rdoc/rdoc.rb @@ -418,7 +418,7 @@ The internal error was: @last_modified = setup_output_dir @options.op_dir, @options.force_update end - start_time = Time.now + @start_time = Time.now file_info = parse_files @options.files @@ -439,20 +439,7 @@ The internal error was: @generator = gen_klass.new @options - Dir.chdir @options.op_dir do - begin - self.class.current = self - - unless @options.quiet then - $stderr.puts "\nGenerating #{gen_klass.name.sub(/^.*::/, '')} format into #{Dir.pwd}..." - end - - @generator.generate file_info - update_output_dir ".", start_time, @last_modified - ensure - self.class.current = nil - end - end + generate file_info end if @stats and (@options.coverage_report or not @options.quiet) then @@ -463,6 +450,28 @@ The internal error was: exit @stats.fully_documented? if @options.coverage_report end + ## + # Generates documentation for +file_info+ (from #parse_files) into the + # output dir using the generator selected + # by the RDoc options + + def generate file_info + Dir.chdir @options.op_dir do + begin + self.class.current = self + + unless @options.quiet then + $stderr.puts "\nGenerating #{@generator.class.name.sub(/^.*::/, '')} format into #{Dir.pwd}..." + end + + @generator.generate file_info + update_output_dir '.', @start_time, @last_modified + ensure + self.class.current = nil + end + end + end + ## # Removes a siginfo handler and replaces the previous diff --git a/lib/rdoc/ri/driver.rb b/lib/rdoc/ri/driver.rb index 9a336f7f3f..46aeaeebc2 100644 --- a/lib/rdoc/ri/driver.rb +++ b/lib/rdoc/ri/driver.rb @@ -197,6 +197,13 @@ Options may also be set in the 'RI' environment variable. opt.separator nil + opt.on("--list", "-l", + "List classes ri knows about.") do + options[:list] = true + end + + opt.separator nil + opt.on("--[no-]profile", "Run with the ruby profiler") do |value| options[:profile] = value @@ -331,6 +338,7 @@ Options may also be set in the 'RI' environment variable. require 'profile' if options[:profile] @names = options[:names] + @list = options[:list] @doc_dirs = [] @stores = [] @@ -524,7 +532,10 @@ Options may also be set in the 'RI' environment variable. klass_name = method ? name : klass if name !~ /#|\./ then - completions.push(*klasses.grep(/^#{klass_name}/)) + completions = klasses.grep(/^#{klass_name}[^:]*$/) + completions.concat klasses.grep(/^#{name}[^:]*$/) if name =~ /::$/ + + completions << klass if classes.key? klass # to complete a method name elsif selector then completions << klass if classes.key? klass elsif classes.key? klass_name then @@ -546,7 +557,7 @@ Options may also be set in the 'RI' environment variable. completions.push(*methods) end - completions.sort + completions.sort.uniq end ## @@ -878,9 +889,10 @@ Options may also be set in the 'RI' environment variable. end ## - # Lists classes known to ri + # Lists classes known to ri starting with +names+. If +names+ is empty all + # known classes are shown. - def list_known_classes + def list_known_classes names = [] classes = [] stores.each do |store| @@ -889,9 +901,19 @@ Options may also be set in the 'RI' environment variable. classes = classes.flatten.uniq.sort + unless names.empty? then + filter = Regexp.union names.map { |name| /^#{name}/ } + + classes = classes.grep filter + end + page do |io| if paging? or io.tty? then - io.puts "Classes and Modules known to ri:" + if names.empty? then + io.puts "Classes and Modules known to ri:" + else + io.puts "Classes and Modules starting with #{names.join ', '}:" + end io.puts end @@ -910,7 +932,7 @@ Options may also be set in the 'RI' environment variable. methods = store.instance_methods[ancestor] if methods then - matches = methods.grep(/^#{method}/) + matches = methods.grep(/^#{Regexp.escape method.to_s}/) matches = matches.map do |match| "#{klass}##{match}" @@ -924,7 +946,7 @@ Options may also be set in the 'RI' environment variable. methods = store.class_methods[ancestor] next unless methods - matches = methods.grep(/^#{method}/) + matches = methods.grep(/^#{Regexp.escape method.to_s}/) matches = matches.map do |match| "#{klass}::#{match}" @@ -996,9 +1018,9 @@ Options may also be set in the 'RI' environment variable. case type when '#', '::' then - /^#{klass}#{type}#{name}$/ + /^#{klass}#{type}#{Regexp.escape name}$/ else - /^#{klass}(#|::)#{name}$/ + /^#{klass}(#|::)#{Regexp.escape name}$/ end end @@ -1064,10 +1086,10 @@ Options may also be set in the 'RI' environment variable. def run if @list_doc_dirs then puts @doc_dirs - elsif @interactive then + elsif @list then + list_known_classes @names + elsif @interactive or @names.empty? then interactive - elsif @names.empty? then - list_known_classes else display_names @names end diff --git a/lib/rdoc/ri/store.rb b/lib/rdoc/ri/store.rb index 1fcd313d0f..c3939c493a 100644 --- a/lib/rdoc/ri/store.rb +++ b/lib/rdoc/ri/store.rb @@ -7,6 +7,18 @@ require 'fileutils' # The store manages reading and writing ri data for a project (gem, path, # etc.) and maintains a cache of methods, classes and ancestors in the # store. +# +# The store maintains a #cache of its contents for faster lookup. After +# adding items to the store it must be flushed using #save_cache. The cache +# contains the following structures: +# +# @cache = { +# :class_methods => {}, # class name => class methods +# :instance_methods => {}, # class name => instance methods +# :attributes => {}, # class name => attributes +# :modules => [], # classes and modules in this store +# :ancestors => {}, # class name => ancestor names +# } class RDoc::RI::Store diff --git a/lib/rdoc/ruby_lex.rb b/lib/rdoc/ruby_lex.rb index e4f2445438..60d4a4c76b 100644 --- a/lib/rdoc/ruby_lex.rb +++ b/lib/rdoc/ruby_lex.rb @@ -403,9 +403,11 @@ class RDoc::RubyLex res = '' nil until (ch = getc) == "\n" - until peek_equal?("=end") && peek(4) =~ /\s/ do - until (ch = getc) == "\n" do res << ch end + until ( peek_equal?("=end") && peek(4) =~ /\s/ ) do + (ch = getc) + res << ch end + gets # consume =end @ltype = nil diff --git a/lib/rdoc/stats.rb b/lib/rdoc/stats.rb index c46a610d45..e6101bb457 100644 --- a/lib/rdoc/stats.rb +++ b/lib/rdoc/stats.rb @@ -31,7 +31,7 @@ class RDoc::Stats @coverage_level = 0 @doc_items = nil - @fully_documented = nil + @fully_documented = false @num_params = 0 @percent_doc = nil @start = Time.now diff --git a/lib/rdoc/task.rb b/lib/rdoc/task.rb index ebf8ccc188..ec7459729a 100644 --- a/lib/rdoc/task.rb +++ b/lib/rdoc/task.rb @@ -37,9 +37,8 @@ require 'rake' require 'rake/tasklib' ## -# Create a documentation task that will generate the RDoc files for a project. -# -# The RDoc::Task will create the following targets: +# RDoc::Task creates the following rake tasks to generate and clean up RDoc +# output: # # [rdoc] # Main task for this RDoc task. @@ -56,12 +55,12 @@ require 'rake/tasklib' # gem 'rdoc' # require 'rdoc/task' # -# RDoc::Task.new do |rd| -# rd.main = "README.rdoc" -# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") +# RDoc::Task.new do |rdoc| +# rdoc.main = "README.rdoc" +# rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb") # end # -# The +rd+ object passed to the block is an RDoc::Task object. See the +# The +rdoc+ object passed to the block is an RDoc::Task object. See the # attributes list for the RDoc::Task class for available customization options. # # == Specifying different task names @@ -73,10 +72,10 @@ require 'rake/tasklib' # gem 'rdoc' # require 'rdoc/task' # -# RDoc::Task.new :rdoc_dev do |rd| -# rd.main = "README.doc" -# rd.rdoc_files.include("README.rdoc", "lib/**/*.rb") -# rd.options << "--all" +# RDoc::Task.new :rdoc_dev do |rdoc| +# rdoc.main = "README.doc" +# rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb") +# rdoc.options << "--all" # end # # The tasks would then be named :rdoc_dev, diff --git a/lib/rdoc/text.rb b/lib/rdoc/text.rb index adbc630cf1..ace44bf56f 100644 --- a/lib/rdoc/text.rb +++ b/lib/rdoc/text.rb @@ -61,25 +61,17 @@ module RDoc::Text # Flush +text+ left based on the shortest line def flush_left text - indents = [] + indent = 9999 text.each_line do |line| - indents << (line =~ /[^\s]/ || 9999) + line_indent = line =~ /\S/ || 9999 + indent = line_indent if indent > line_indent end - indent = indents.min - - flush = [] - empty = '' empty.force_encoding text.encoding if Object.const_defined? :Encoding - text.each_line do |line| - line[/^ {0,#{indent}}/] = empty - flush << line - end - - flush.join + text.gsub(/^ {0,#{indent}}/, empty) end ## diff --git a/test/rdoc/test_rdoc_class_module.rb b/test/rdoc/test_rdoc_class_module.rb index e7a68c2b4c..59190a6e3b 100644 --- a/test/rdoc/test_rdoc_class_module.rb +++ b/test/rdoc/test_rdoc_class_module.rb @@ -8,6 +8,10 @@ class TestRDocClassModule < XrefTestCase @RM = RDoc::Markup end + def test_ancestors + assert_equal [@parent], @child.ancestors + end + def test_comment_equals cm = RDoc::ClassModule.new 'Klass' cm.comment = '# comment 1' @@ -23,6 +27,16 @@ class TestRDocClassModule < XrefTestCase assert_equal "comment 1\n---\ncomment 2\n---\n* comment 3", cm.comment end + def test_each_ancestor + ancestors = [] + + @child.each_ancestor do |mod| + ancestors << mod + end + + assert_equal [@parent], ancestors + end + # handle making a short module alias of yourself def test_find_class_named @@ -36,6 +50,7 @@ class TestRDocClassModule < XrefTestCase cm1.comment = 'klass 1' cm1.add_attribute RDoc::Attr.new(nil, 'a1', 'RW', '') cm1.add_attribute RDoc::Attr.new(nil, 'a3', 'R', '') + cm1.add_attribute RDoc::Attr.new(nil, 'a4', 'R', '') cm1.add_constant RDoc::Constant.new('C1', nil, '') cm1.add_include RDoc::Include.new('I1', '') cm1.add_method RDoc::AnyMethod.new(nil, 'm1') @@ -46,6 +61,7 @@ class TestRDocClassModule < XrefTestCase @RM::Paragraph.new('klass 2'))) cm2.add_attribute RDoc::Attr.new(nil, 'a2', 'RW', '') cm2.add_attribute RDoc::Attr.new(nil, 'a3', 'W', '') + cm2.add_attribute RDoc::Attr.new(nil, 'a4', 'R', '') cm2.add_constant RDoc::Constant.new('C2', nil, '') cm2.add_include RDoc::Include.new('I2', '') cm2.add_method RDoc::AnyMethod.new(nil, 'm2') @@ -62,6 +78,7 @@ class TestRDocClassModule < XrefTestCase RDoc::Attr.new(nil, 'a1', 'RW', ''), RDoc::Attr.new(nil, 'a2', 'RW', ''), RDoc::Attr.new(nil, 'a3', 'RW', ''), + RDoc::Attr.new(nil, 'a4', 'R', ''), ] expected.each do |a| a.parent = cm1 end diff --git a/test/rdoc/test_rdoc_code_object.rb b/test/rdoc/test_rdoc_code_object.rb index 5328ab26b1..b4ebfc4b3e 100644 --- a/test/rdoc/test_rdoc_code_object.rb +++ b/test/rdoc/test_rdoc_code_object.rb @@ -119,6 +119,16 @@ class TestRDocCodeObject < XrefTestCase assert @co.document_children end + def test_each_parent + parents = [] + + @parent_m.each_parent do |code_object| + parents << code_object + end + + assert_equal [@parent, @xref_data], parents + end + def test_full_name_equals @co.full_name = 'hi' diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb index 71870c545f..02f7311d01 100644 --- a/test/rdoc/test_rdoc_context.rb +++ b/test/rdoc/test_rdoc_context.rb @@ -143,6 +143,16 @@ class TestRDocContext < XrefTestCase assert_equal [incl], @context.includes end + def test_add_include_twice + incl1 = RDoc::Include.new 'Name', 'comment' + @context.add_include incl1 + + incl2 = RDoc::Include.new 'Name', 'comment' + @context.add_include incl2 + + assert_equal [incl1], @context.includes + end + def test_add_method meth = RDoc::AnyMethod.new nil, 'old_name' meth.visibility = nil @@ -438,5 +448,146 @@ class TestRDocContext < XrefTestCase 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_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 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 diff --git a/test/rdoc/test_rdoc_markup_parser.rb b/test/rdoc/test_rdoc_markup_parser.rb index a7951d9d01..98c16a18ef 100644 --- a/test/rdoc/test_rdoc_markup_parser.rb +++ b/test/rdoc/test_rdoc_markup_parser.rb @@ -625,6 +625,25 @@ for all good men assert_equal expected, @RMP.parse(str).parts end + def test_parse_rule + str = <<-STR +now is the time + +--- + +for all good men + STR + + expected = [ + @RM::Paragraph.new('now is the time'), + @RM::BlankLine.new, + @RM::Rule.new(1), + @RM::BlankLine.new, + @RM::Paragraph.new('for all good men')] + + assert_equal expected, @RMP.parse(str).parts + end + def test_parse_ualpha str = <<-STR A. l1 diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb index 6a3a92001a..9649933fd0 100644 --- a/test/rdoc/test_rdoc_parser_c.rb +++ b/test/rdoc/test_rdoc_parser_c.rb @@ -680,7 +680,7 @@ Init_Foo(void) { baz = methods.last assert_equal 'Foo#baz', baz.full_name - assert_equal "a comment for bar", bar.comment + assert_equal "a comment for bar", baz.comment end def test_find_modifiers_call_seq @@ -911,6 +911,37 @@ rb_io_s_read(argc, argv, 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! ", read_method.comment + assert_equal "rb_io_s_read", read_method.c_function + assert read_method.singleton + end + + def test_define_method_with_prototype + content = <<-EOF +static VALUE rb_io_s_read(int, VALUE*, VALUE); + +/* Method Comment! */ +static VALUE +rb_io_s_read(argc, argv, io) + int argc; + VALUE *argv; + VALUE io; +{ +} + void Init_IO(void) { /* diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb index ff1f1c9191..6c2b445ef3 100644 --- a/test/rdoc/test_rdoc_parser_ruby.rb +++ b/test/rdoc/test_rdoc_parser_ruby.rb @@ -1799,6 +1799,56 @@ EOF assert_equal :private, foo.visibility end + def test_parse_statements_identifier_public_class_method + content = <<-CONTENT +class Date + def self.now; end + private_class_method :now +end + +class DateTime < Date + public_class_method :now +end + CONTENT + + util_parser content + + @parser.parse_statements @top_level + + date, date_time = @top_level.classes + + date_now = date.method_list.first + date_time_now = date_time.method_list.first + + assert_equal :private, date_now.visibility + assert_equal :public, date_time_now.visibility + end + + def test_parse_statements_identifier_private_class_method + content = <<-CONTENT +class Date + def self.now; end + public_class_method :now +end + +class DateTime < Date + private_class_method :now +end + CONTENT + + util_parser content + + @parser.parse_statements @top_level + + date, date_time = @top_level.classes + + date_now = date.method_list.first + date_time_now = date_time.method_list.first + + assert_equal :public, date_now.visibility, date_now.full_name + assert_equal :private, date_time_now.visibility, date_time_now.full_name + end + def test_parse_statements_identifier_require content = "require 'bar'" @@ -1978,6 +2028,53 @@ end assert_equal 'm comment', m.comment end + def test_scan_block_comment_notflush + ## + # + # The previous test assumes that between the =begin/=end blocs that there is + # only one line, or minima formatting directives. This test tests for those + # who use the =begin bloc with longer / more advanced formatting within. + # + ## + content = <<-CONTENT +=begin rdoc + += DESCRIPTION + +This is a simple test class + += RUMPUS + +Is a silly word + +=end +class StevenSimpleClass + # A band on my iPhone as I wrote this test + FRUIT_BATS="Make nice music" + +=begin rdoc +A nice girl +=end + + def lauren + puts "Summoning Lauren!" + end +end + CONTENT + util_parser content + + @parser.scan + + foo = @top_level.classes.first + + assert_equal "= DESCRIPTION\n\nThis is a simple test class\n\n= RUMPUS\n\nIs a silly word", + foo.comment + + m = foo.method_list.first + + assert_equal 'A nice girl', m.comment + end + def test_scan_meta_method_block content = <<-CONTENT class C diff --git a/test/rdoc/test_rdoc_ri_driver.rb b/test/rdoc/test_rdoc_ri_driver.rb index 2d735044dd..b0e0e787c0 100644 --- a/test/rdoc/test_rdoc_ri_driver.rb +++ b/test/rdoc/test_rdoc_ri_driver.rb @@ -3,6 +3,7 @@ require 'rubygems' require 'minitest/autorun' require 'tmpdir' require 'fileutils' +require 'stringio' require 'rdoc/ri/driver' class TestRDocRIDriver < MiniTest::Unit::TestCase @@ -249,12 +250,14 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase @driver.stores = [store] - assert_equal %w[Foo Foo::Bar], @driver.complete('F') + assert_equal %w[Foo ], @driver.complete('F') assert_equal %w[ Foo::Bar], @driver.complete('Foo::B') - assert_equal %w[Foo#Bar], @driver.complete('Foo#'), 'Foo#' - assert_equal %w[Foo#Bar Foo::bar], @driver.complete('Foo.'), 'Foo.' - assert_equal %w[Foo::Bar Foo::bar], @driver.complete('Foo::'), 'Foo::' + assert_equal %w[Foo#Bar], @driver.complete('Foo#'), 'Foo#' + assert_equal %w[Foo#Bar Foo::bar], @driver.complete('Foo.'), 'Foo.' + assert_equal %w[Foo::Bar Foo::bar], @driver.complete('Foo::'), 'Foo::' + + assert_equal %w[ Foo::bar], @driver.complete('Foo::b'), 'Foo::b' end def test_complete_ancestor @@ -269,7 +272,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase def test_complete_classes util_store - assert_equal %w[Foo Foo::Bar Foo::Baz], @driver.complete('F') + assert_equal %w[Foo ], @driver.complete('F') assert_equal %w[Foo:: Foo::Bar Foo::Baz], @driver.complete('Foo::') assert_equal %w[ Foo::Bar Foo::Baz], @driver.complete('Foo::B') end @@ -278,7 +281,8 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase util_multi_store assert_equal %w[Bar], @driver.complete('B') - assert_equal %w[Foo Foo::Bar Foo::Baz], @driver.complete('F') + assert_equal %w[Foo], @driver.complete('F') + assert_equal %w[Foo::Bar Foo::Baz], @driver.complete('Foo::B') end def test_display @@ -572,11 +576,18 @@ Foo::Bar#bother def test_name_regexp assert_equal %r%^RDoc::AnyMethod#new$%, @driver.name_regexp('RDoc::AnyMethod#new') + assert_equal %r%^RDoc::AnyMethod::new$%, @driver.name_regexp('RDoc::AnyMethod::new') assert_equal %r%^RDoc::AnyMethod(#|::)new$%, @driver.name_regexp('RDoc::AnyMethod.new') + + assert_equal %r%^Hash(#|::)\[\]$%, + @driver.name_regexp('Hash.[]') + + assert_equal %r%^Hash::\[\]$%, + @driver.name_regexp('Hash::[]') end def test_list_known_classes @@ -589,6 +600,16 @@ Foo::Bar#bother assert_equal "Ambiguous\nFoo\nFoo::Bar\nFoo::Baz\nInc\n", out end + def test_list_known_classes_name + util_store + + out, = capture_io do + @driver.list_known_classes %w[F I] + end + + assert_equal "Foo\nFoo::Bar\nFoo::Baz\nInc\n", out + end + def test_list_methods_matching util_store @@ -596,6 +617,24 @@ Foo::Bar#bother @driver.list_methods_matching('Foo::Bar.') end + def test_list_methods_matching_regexp + util_store + + index = RDoc::AnyMethod.new nil, '[]' + @cFoo.add_method index + @store.save_method @cFoo, index + + c_index = RDoc::AnyMethod.new nil, '[]' + c_index.singleton = true + @cFoo.add_method c_index + @store.save_method @cFoo, c_index + + @store.save_cache + + assert_equal %w[Foo#[]], @driver.list_methods_matching('Foo#[]') + assert_equal %w[Foo::[]], @driver.list_methods_matching('Foo::[]') + end + def test_load_method util_store diff --git a/test/rdoc/test_rdoc_top_level.rb b/test/rdoc/test_rdoc_top_level.rb index a1eef0fa22..89f64247f9 100644 --- a/test/rdoc/test_rdoc_top_level.rb +++ b/test/rdoc/test_rdoc_top_level.rb @@ -12,7 +12,10 @@ class TestRDocTopLevel < XrefTestCase def test_class_all_classes_and_modules expected = %w[ - C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 M1 M1::M2 + C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 + Child + M1 M1::M2 + Parent ] assert_equal expected, @@ -22,6 +25,7 @@ class TestRDocTopLevel < XrefTestCase def test_class_classes expected = %w[ C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1 + Child Parent ] assert_equal expected, RDoc::TopLevel.classes.map { |m| m.full_name }.sort diff --git a/test/rdoc/xref_data.rb b/test/rdoc/xref_data.rb index 5a7e98d671..4525a293ab 100644 --- a/test/rdoc/xref_data.rb +++ b/test/rdoc/xref_data.rb @@ -63,5 +63,14 @@ end module M1::M2 end + +class Parent + def m() end + def self.m() end +end + +class Child < Parent +end + XREF_DATA diff --git a/test/rdoc/xref_test_case.rb b/test/rdoc/xref_test_case.rb index 307e8f3350..00c6e8e09d 100644 --- a/test/rdoc/xref_test_case.rb +++ b/test/rdoc/xref_test_case.rb @@ -38,7 +38,6 @@ class XrefTestCase < MiniTest::Unit::TestCase @c1_m = @c1.method_list.last # C1#m @c1__m = @c1.method_list.first # C1::m - @c2 = @xref_data.find_module_named 'C2' @c2_a = @c2.method_list.last @c2_b = @c2.method_list.first @@ -55,6 +54,12 @@ class XrefTestCase < MiniTest::Unit::TestCase @m1_m = @m1.method_list.first @m1_m2 = @xref_data.find_module_named 'M1::M2' + + @parent = @xref_data.find_module_named 'Parent' + @child = @xref_data.find_module_named 'Child' + + @parent_m = @parent.method_list.first # Parent#m + @parent__m = @parent.method_list.last # Parent::m end end