mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Import RDoc 3.5.1
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30760 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									918f625a5e
								
							
						
					
					
						commit
						cc2a16d94d
					
				
					 49 changed files with 2119 additions and 273 deletions
				
			
		|  | @ -1,3 +1,7 @@ | |||
| Wed Feb  2 09:27:53 2011  Eric Hodel  <drbrain@segment7.net> | ||||
| 
 | ||||
| 	* lib/rdoc: Upgrade to RDoc 3.5.1 | ||||
| 
 | ||||
| Wed Feb  2 00:30:43 2011  KOSAKI Motohiro  <kosaki.motohiro@gmail.com> | ||||
| 
 | ||||
| 	* include/ruby/st.h (st_table): Added comment why we need __extension__. | ||||
|  |  | |||
							
								
								
									
										2
									
								
								NEWS
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								NEWS
									
										
									
									
									
								
							|  | @ -92,7 +92,7 @@ with all sufficient information, see the ChangeLog file. | |||
|   * support for bash/zsh completion. | ||||
| 
 | ||||
| * RDoc | ||||
|   * RDoc has been upgraded to RDoc 3.1.  For full release notes see | ||||
|   * RDoc has been upgraded to RDoc 3.5.1.  For full release notes see | ||||
|     http://rdoc.rubyforge.org/History_txt.html | ||||
| 
 | ||||
| * rexml | ||||
|  |  | |||
|  | @ -95,7 +95,7 @@ module RDoc | |||
|   ## | ||||
|   # RDoc version you are using | ||||
| 
 | ||||
|   VERSION = '3.1' | ||||
|   VERSION = '3.5.1' | ||||
| 
 | ||||
|   ## | ||||
|   # Method visibilities | ||||
|  |  | |||
|  | @ -4,6 +4,8 @@ require 'rdoc/class_module' | |||
| # An anonymous class like: | ||||
| # | ||||
| #   c = Class.new do end | ||||
| # | ||||
| # AnonClass is currently not used. | ||||
| 
 | ||||
| class RDoc::AnonClass < RDoc::ClassModule | ||||
| end | ||||
|  |  | |||
|  | @ -13,6 +13,11 @@ class RDoc::AnyMethod < RDoc::MethodAttr | |||
| 
 | ||||
|   attr_accessor :dont_rename_initialize | ||||
| 
 | ||||
|   ## | ||||
|   # The C function that implements this method (if it was defined in a C file) | ||||
| 
 | ||||
|   attr_accessor :c_function | ||||
| 
 | ||||
|   ## | ||||
|   # Different ways to call this method | ||||
| 
 | ||||
|  | @ -31,8 +36,9 @@ class RDoc::AnyMethod < RDoc::MethodAttr | |||
|   def initialize text, name | ||||
|     super | ||||
| 
 | ||||
|     @c_function = nil | ||||
|     @dont_rename_initialize = false | ||||
|     @token_stream           = nil | ||||
|     @token_stream = nil | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -140,12 +146,41 @@ class RDoc::AnyMethod < RDoc::MethodAttr | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Pretty parameter list for this method | ||||
|   # A list of this method's method and yield parameters.  +call-seq+ params | ||||
|   # are preferred over parsed method and block params. | ||||
| 
 | ||||
|   def param_list | ||||
|     if @call_seq then | ||||
|       params = @call_seq.split("\n").last | ||||
|       params = params.sub(/.*?\((.*)\)/, '\1') | ||||
|       params = params.sub(/(\{|do)\s*\|([^|]*)\|.*/, ',\2') | ||||
|     elsif @params then | ||||
|       params = @params.sub(/\((.*)\)/, '\1') | ||||
| 
 | ||||
|       params << ",#{@block_params}" if @block_params | ||||
|     elsif @block_params then | ||||
|       params = @block_params | ||||
|     else | ||||
|       return [] | ||||
|     end | ||||
| 
 | ||||
|     params.gsub(/\s+/, '').split ',' | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Pretty parameter list for this method.  If the method's parameters were | ||||
|   # given by +call-seq+ it is preferred over the parsed values. | ||||
| 
 | ||||
|   def param_seq | ||||
|     params = @params.gsub(/\s*\#.*/, '') | ||||
|     params = params.tr("\n", " ").squeeze(" ") | ||||
|     params = "(#{params})" unless params[0] == ?( | ||||
|     if @call_seq then | ||||
|       params = @call_seq.split("\n").last | ||||
|       params = params.sub(/[^( ]+/, '') | ||||
|       params = params.sub(/(\|[^|]+\|)\s*\.\.\.\s*(end|\})/, '\1 \2') | ||||
|     else | ||||
|       params = @params.gsub(/\s*\#.*/, '') | ||||
|       params = params.tr("\n", " ").squeeze(" ") | ||||
|       params = "(#{params})" unless params[0] == ?( | ||||
|     end | ||||
| 
 | ||||
|     if @block_params then | ||||
|       # If this method has explicit block parameters, remove any explicit | ||||
|  |  | |||
|  | @ -151,7 +151,7 @@ class RDoc::ClassModule < RDoc::Context | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Finds a class or module with +name+ in this namespace or its descendents | ||||
|   # Finds a class or module with +name+ in this namespace or its descendants | ||||
| 
 | ||||
|   def find_class_named name | ||||
|     return self if full_name == name | ||||
|  | @ -308,7 +308,7 @@ class RDoc::ClassModule < RDoc::Context | |||
|   ## | ||||
|   # Name to use to generate the url: | ||||
|   # modules and classes that are aliases for another | ||||
|   # module or classe return the name of the latter. | ||||
|   # module or class return the name of the latter. | ||||
| 
 | ||||
|   def name_for_path | ||||
|     is_alias_for ? is_alias_for.full_name : full_name | ||||
|  |  | |||
|  | @ -60,11 +60,23 @@ class RDoc::CodeObject | |||
| 
 | ||||
|   attr_reader :force_documentation | ||||
| 
 | ||||
|   ## | ||||
|   # Line in #file where this CodeObject was defined | ||||
| 
 | ||||
|   attr_accessor :line | ||||
| 
 | ||||
|   ## | ||||
|   # Hash of arbitrary metadata for this CodeObject | ||||
| 
 | ||||
|   attr_reader :metadata | ||||
| 
 | ||||
|   ## | ||||
|   # Offset in #file where this CodeObject was defined | ||||
|   #-- | ||||
|   # TODO character or byte? | ||||
| 
 | ||||
|   attr_accessor :offset | ||||
| 
 | ||||
|   ## | ||||
|   # Our parent CodeObject | ||||
| 
 | ||||
|  | @ -115,6 +127,12 @@ class RDoc::CodeObject | |||
|                  if comment and not comment.empty? then | ||||
|                    normalize_comment comment | ||||
|                  else | ||||
|                    # TODO is this sufficient? | ||||
|                    # HACK correct fix is to have #initialize create @comment | ||||
|                    #      with the correct encoding | ||||
|                    if Object.const_defined? :Encoding and @comment.empty? then | ||||
|                      @comment.force_encoding comment.encoding | ||||
|                    end | ||||
|                    @comment | ||||
|                  end | ||||
|                end | ||||
|  |  | |||
|  | @ -188,7 +188,6 @@ class RDoc::Context < RDoc::CodeObject | |||
|     @in_files = [] | ||||
| 
 | ||||
|     @name    ||= "unknown" | ||||
|     @comment ||= "" | ||||
|     @parent  = nil | ||||
|     @visibility = :public | ||||
| 
 | ||||
|  | @ -440,10 +439,13 @@ class RDoc::Context < RDoc::CodeObject | |||
|     # HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code) | ||||
|     # (this is a #ifdef: should be handled by the C parser) | ||||
|     known = @constants_hash[constant.name] | ||||
|     if known | ||||
|       #$stderr.puts "\nconstant #{constant.name} already registered" | ||||
| 
 | ||||
|     if known then | ||||
|       known.comment = constant.comment if known.comment.empty? | ||||
|       known.value = constant.value if known.value.nil? or known.value.strip.empty? | ||||
| 
 | ||||
|       known.value = constant.value if | ||||
|         known.value.nil? or known.value.strip.empty? | ||||
| 
 | ||||
|       known.is_alias_for ||= constant.is_alias_for | ||||
|     else | ||||
|       @constants_hash[constant.name] = constant | ||||
|  | @ -495,9 +497,10 @@ class RDoc::Context < RDoc::CodeObject | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Adds an alias from +from+ (a class or module) to +name+. | ||||
|   # Adds an alias from +from+ (a class or module) to +name+ which was defined | ||||
|   # in +file+. | ||||
| 
 | ||||
|   def add_module_alias from, name | ||||
|   def add_module_alias from, name, file | ||||
|     return from if @done_documenting | ||||
| 
 | ||||
|     to_name = child_name(name) | ||||
|  | @ -519,7 +522,8 @@ class RDoc::Context < RDoc::CodeObject | |||
|     # HACK: register a constant for this alias: | ||||
|     # constant value and comment will be updated after, | ||||
|     # when the Ruby parser adds the constant | ||||
|     const = RDoc::Constant.new(name, nil, '') | ||||
|     const = RDoc::Constant.new name, nil, '' | ||||
|     const.record_location file | ||||
|     const.is_alias_for = from | ||||
|     add_constant const | ||||
| 
 | ||||
|  |  | |||
|  | @ -78,4 +78,3 @@ module RDoc::Encoding | |||
| 
 | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ require 'rdoc' | |||
| # use RDoc::Options#option_parser to add command-line options to the +rdoc+ | ||||
| # tool.  See OptionParser for details on how to add options. | ||||
| # | ||||
| # You can extend the RDoc::Options instance with additional accesors for your | ||||
| # You can extend the RDoc::Options instance with additional accessors for your | ||||
| # generator. | ||||
| # | ||||
| # = Generator Instantiation | ||||
|  |  | |||
|  | @ -1,7 +1,11 @@ | |||
| # This file is loaded by generators.  It allows RDoc's CodeObject tree to | ||||
| # avoid loading generator code to increase startup time (for ri). | ||||
| 
 | ||||
| require 'rdoc/text' | ||||
| require 'rdoc/code_objects' | ||||
| require 'rdoc/generator' | ||||
| require 'rdoc/markup/to_html_crossref' | ||||
| require 'rdoc/ruby_token' | ||||
| 
 | ||||
| ## | ||||
| # Handle common RDoc::Markup tasks for various CodeObjects | ||||
|  |  | |||
|  | @ -228,7 +228,7 @@ | |||
|         <% if method.call_seq %> | ||||
|         <% method.call_seq.strip.split("\n").each_with_index do |call_seq, i| %> | ||||
|         <div class="method-heading"> | ||||
|           <span class="method-callseq"><%= call_seq.strip.gsub(/->/, '→').gsub( /^\w.+\./m, '') %></span> | ||||
|           <span class="method-callseq"><%= call_seq.strip.gsub(/->/, '→').gsub( /^\w+\./m, '') %></span> | ||||
|           <% if i == 0 %> | ||||
|           <span class="method-click-advice">click to toggle source</span> | ||||
|           <% end %> | ||||
|  |  | |||
|  | @ -97,6 +97,11 @@ body.file p { | |||
|   margin: 1em 0; | ||||
| } | ||||
| 
 | ||||
| .indexpage ol, | ||||
| .file #documentation ol { | ||||
|   line-height: 160%; | ||||
| } | ||||
| 
 | ||||
| .indexpage ul, | ||||
| .file #documentation ul { | ||||
|   line-height: 160%; | ||||
|  | @ -110,6 +115,20 @@ body.file p { | |||
| .indexpage li, | ||||
| .file #documentation li { | ||||
|   padding-left: 20px; | ||||
| } | ||||
| 
 | ||||
| .indexpage ol, | ||||
| .file #documentation ol { | ||||
|   margin-left: 20px; | ||||
| } | ||||
| 
 | ||||
| .indexpage ol > li, | ||||
| .file #documentation ol > li { | ||||
|   padding-left: 0; | ||||
| } | ||||
| 
 | ||||
| .indexpage ul > li, | ||||
| .file #documentation ul > li { | ||||
|   background: url(images/bullet_black.png) no-repeat left 4px; | ||||
| } | ||||
| .indexpage li.module { | ||||
|  | @ -389,9 +408,14 @@ ul.link-list .type { | |||
| #documentation .method-description, | ||||
| #documentation .aliases { | ||||
|   margin: 0 20px; | ||||
|   line-height: 1.2em; | ||||
|   color: #666; | ||||
| } | ||||
| 
 | ||||
| #documentation .method-description p, | ||||
| #documentation .aliases p { | ||||
|   line-height: 1.2em; | ||||
| } | ||||
| 
 | ||||
| #documentation .aliases { | ||||
|   padding-top: 4px; | ||||
|   font-style: italic; | ||||
|  |  | |||
|  | @ -483,7 +483,7 @@ require 'rdoc' | |||
| # [+:include:+ _filename_] | ||||
| #   Include the contents of the named file at this point. This directive | ||||
| #   must appear alone on one line, possibly preceded by spaces. In this | ||||
| #   position, it can be escapd with a \ in front of the first colon. | ||||
| #   position, it can be escaped with a \ in front of the first colon. | ||||
| # | ||||
| #   The file will be searched for in the directories listed by the +--include+ | ||||
| #   option, or in the current directory by default.  The contents of the file | ||||
|  | @ -537,8 +537,8 @@ class RDoc::Markup | |||
|   # structure (paragraphs, lists, and so on).  Invoke an event handler as we | ||||
|   # identify significant chunks. | ||||
| 
 | ||||
|   def initialize | ||||
|     @attribute_manager = RDoc::Markup::AttributeManager.new | ||||
|   def initialize attribute_manager = nil | ||||
|     @attribute_manager = attribute_manager || RDoc::Markup::AttributeManager.new | ||||
|     @output = nil | ||||
|   end | ||||
| 
 | ||||
|  |  | |||
|  | @ -74,7 +74,6 @@ class RDoc::Markup::AttributeManager | |||
|     add_html "code", :TT | ||||
|   end | ||||
| 
 | ||||
| 
 | ||||
|   ## | ||||
|   # Return an attribute object with the given turn_on and turn_off bits set | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| class RDoc::Markup::Heading < Struct.new :level, :text | ||||
| 
 | ||||
|   ## | ||||
|   # Calls #accept_heading on +wisitor+ | ||||
|   # Calls #accept_heading on +visitor+ | ||||
| 
 | ||||
|   def accept visitor | ||||
|     visitor.accept_heading self | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ class RDoc::Markup | |||
|     end | ||||
| 
 | ||||
|     ## | ||||
|     # Returns a string reperesentation of +bitmap+ | ||||
|     # Returns a string representation of +bitmap+ | ||||
| 
 | ||||
|     def self.as_string(bitmap) | ||||
|       return "none" if bitmap.zero? | ||||
|  |  | |||
|  | @ -321,7 +321,7 @@ class RDoc::Markup::Parser | |||
|         next | ||||
|       end | ||||
| 
 | ||||
|       # indentation change: break or verbattim | ||||
|       # indentation change: break or verbatim | ||||
|       if column < indent then | ||||
|         unget | ||||
|         break | ||||
|  |  | |||
|  | @ -130,7 +130,7 @@ class RDoc::Markup::ToHtml < RDoc::Markup::Formatter | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Here's a hypedlink where the label is different to the URL | ||||
|   # Here's a hyperlink where the label is different to the URL | ||||
|   # <label>[url] or {long label}[url] | ||||
| 
 | ||||
|   def handle_special_TIDYLINK(special) | ||||
|  |  | |||
|  | @ -34,10 +34,10 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml | |||
|                       # A::B::C.meth | ||||
|                       #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} | ||||
| 
 | ||||
|                       # Stand-alone method (preceeded by a #) | ||||
|                       # Stand-alone method (preceded by a #) | ||||
|                       | \\?\##{METHOD_REGEXP_STR} | ||||
| 
 | ||||
|                       # Stand-alone method (preceeded by ::) | ||||
|                       # Stand-alone method (preceded by ::) | ||||
|                       | ::#{METHOD_REGEXP_STR} | ||||
| 
 | ||||
|                       # A::B::C | ||||
|  | @ -51,7 +51,7 @@ class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml | |||
|                       # In order that words like "can't" not | ||||
|                       # be flagged as potential cross-references, only | ||||
|                       # flag potential class cross-references if the character | ||||
|                       # after the cross-referece is a space, sentence | ||||
|                       # after the cross-reference is a space, sentence | ||||
|                       # punctuation, tag start character, or attribute | ||||
|                       # marker. | ||||
|                       | #{CLASS_REGEXP_STR}(?=[\s\)\.\?\!\,\;<\000]|\z) | ||||
|  |  | |||
|  | @ -217,7 +217,7 @@ class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Removes preceeding \\ from the suppressed crossref +special+ | ||||
|   # Removes preceding \\ from the suppressed crossref +special+ | ||||
| 
 | ||||
|   def handle_special_SUPPRESSED_CROSSREF special | ||||
|     text = special.text | ||||
|  |  | |||
|  | @ -12,6 +12,13 @@ class RDoc::NormalClass < RDoc::ClassModule | |||
|     superclass ? super + [superclass] : super | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # The definition of this class, <tt>class MyClassName</tt> | ||||
| 
 | ||||
|   def definition | ||||
|     "class #{full_name}" | ||||
|   end | ||||
| 
 | ||||
|   def inspect # :nodoc: | ||||
|     superclass = @superclass ? " < #{@superclass}" : nil | ||||
|     "<%s:0x%x class %s%s includes: %p attributes: %p methods: %p aliases: %p>" % [ | ||||
|  |  | |||
|  | @ -12,6 +12,13 @@ class RDoc::NormalModule < RDoc::ClassModule | |||
|     ] | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # The definition of this module, <tt>module MyModuleName</tt> | ||||
| 
 | ||||
|   def definition | ||||
|     "module #{full_name}" | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # This is a module, returns true | ||||
| 
 | ||||
|  |  | |||
|  | @ -71,7 +71,7 @@ class RDoc::Options | |||
|   attr_accessor :formatter | ||||
| 
 | ||||
|   ## | ||||
|   # Description of the output generator (set with the <tt>-fmt</tt> option) | ||||
|   # Description of the output generator (set with the <tt>--fmt</tt> option) | ||||
| 
 | ||||
|   attr_accessor :generator | ||||
| 
 | ||||
|  | @ -148,6 +148,11 @@ class RDoc::Options | |||
| 
 | ||||
|   attr_accessor :title | ||||
| 
 | ||||
|   ## | ||||
|   # Should RDoc update the timestamps in the output dir? | ||||
| 
 | ||||
|   attr_accessor :update_output_dir | ||||
| 
 | ||||
|   ## | ||||
|   # Verbosity, zero means quiet | ||||
| 
 | ||||
|  | @ -188,6 +193,7 @@ class RDoc::Options | |||
|     @template = nil | ||||
|     @template_dir = nil | ||||
|     @title = nil | ||||
|     @update_output_dir = true | ||||
|     @verbosity = 1 | ||||
|     @visibility = :protected | ||||
|     @webcvs = nil | ||||
|  | @ -240,6 +246,35 @@ class RDoc::Options | |||
|     @title ||= string | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Completes any unfinished option setup business such as filtering for | ||||
|   # existent files, creating a regexp for #exclude and setting a default | ||||
|   # #template. | ||||
| 
 | ||||
|   def finish | ||||
|     @op_dir ||= 'doc' | ||||
| 
 | ||||
|     @rdoc_include << "." if @rdoc_include.empty? | ||||
| 
 | ||||
|     if @exclude.empty? then | ||||
|       @exclude = nil | ||||
|     else | ||||
|       @exclude = Regexp.new(@exclude.join("|")) | ||||
|     end | ||||
| 
 | ||||
|     check_files | ||||
| 
 | ||||
|     # If no template was specified, use the default template for the output | ||||
|     # formatter | ||||
| 
 | ||||
|     unless @template then | ||||
|       @template     = @generator_name | ||||
|       @template_dir = template_dir_for @template | ||||
|     end | ||||
| 
 | ||||
|     self | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Returns a properly-space list of generators and their descriptions. | ||||
| 
 | ||||
|  | @ -267,7 +302,7 @@ class RDoc::Options | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Parse command line options. | ||||
|   # Parses command line options. | ||||
| 
 | ||||
|   def parse(argv) | ||||
|     ignore_invalid = true | ||||
|  | @ -449,9 +484,11 @@ Usage: #{opt.program_name} [options] [names...] | |||
| 
 | ||||
|       opt.separator nil | ||||
| 
 | ||||
|       opt.on("--[no-]coverage-report", "--[no-]dcov", "-C", | ||||
|       opt.on("--[no-]coverage-report=[LEVEL]", "--[no-]dcov", "-C", Integer, | ||||
|              "Prints a report on undocumented items.", | ||||
|              "Does not generate files.") do |value| | ||||
|         value = 0 if value.nil? # Integer converts -C to nil | ||||
| 
 | ||||
|         @coverage_report = value | ||||
|         @force_update = true if value | ||||
|       end | ||||
|  | @ -669,26 +706,9 @@ Usage: #{opt.program_name} [options] [names...] | |||
|       end | ||||
|     end | ||||
| 
 | ||||
|     @op_dir ||= 'doc' | ||||
|     @files = argv.dup | ||||
| 
 | ||||
|     @rdoc_include << "." if @rdoc_include.empty? | ||||
| 
 | ||||
|     if @exclude.empty? then | ||||
|       @exclude = nil | ||||
|     else | ||||
|       @exclude = Regexp.new(@exclude.join("|")) | ||||
|     end | ||||
| 
 | ||||
|     check_files | ||||
| 
 | ||||
|     # If no template was specified, use the default template for the output | ||||
|     # formatter | ||||
| 
 | ||||
|     unless @template then | ||||
|       @template     = @generator_name | ||||
|       @template_dir = template_dir_for @template | ||||
|     end | ||||
|     finish | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -725,7 +745,10 @@ Usage: #{opt.program_name} [options] [names...] | |||
|     @generator_name = generator_name | ||||
|     @generator_options << @generator | ||||
| 
 | ||||
|     @generator.setup_options self if @generator.respond_to? :setup_options | ||||
|     if @generator.respond_to? :setup_options then | ||||
|       @option_parser ||= OptionParser.new | ||||
|       @generator.setup_options self  | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ class RDoc::Parser | |||
|   class << self | ||||
| 
 | ||||
|     ## | ||||
|     # A Hash that maps file exetensions regular expressions to parsers that | ||||
|     # A Hash that maps file extensions regular expressions to parsers that | ||||
|     # will consume them. | ||||
|     # | ||||
|     # Use parse_files_matching to register a parser's file extensions. | ||||
|  |  | |||
|  | @ -71,7 +71,7 @@ require 'rdoc/known_classes' | |||
| #   Documentation for the named attribute. | ||||
| # | ||||
| # [call-seq:  <i>text up to an empty line</i>] | ||||
| #   Because C source doesn't give descripive names to Ruby-level parameters, | ||||
| #   Because C source doesn't give descriptive names to Ruby-level parameters, | ||||
| #   you need to document the calling sequence explicitly | ||||
| # | ||||
| # In addition, RDoc assumes by default that the C method implementing a | ||||
|  | @ -156,6 +156,7 @@ class RDoc::Parser::C < RDoc::Parser | |||
|       comment = strip_stars comment | ||||
|       al.comment = comment | ||||
| 
 | ||||
|       al.record_location @top_level | ||||
|       class_obj.add_alias al | ||||
|       @stats.add_alias al | ||||
|     end | ||||
|  | @ -284,7 +285,7 @@ class RDoc::Parser::C < RDoc::Parser | |||
|                      \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, | ||||
|                      \s*(-?\w+)\s*\) | ||||
|                    (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? | ||||
|                  %xm) do |type, var_name, meth_name, meth_body, param_count, source_file| | ||||
|                  %xm) do |type, var_name, meth_name, function, param_count, source_file| | ||||
| 
 | ||||
|       # Ignore top-object and weird struct.c dynamic stuff | ||||
|       next if var_name == "ruby_top_self" | ||||
|  | @ -293,7 +294,7 @@ class RDoc::Parser::C < RDoc::Parser | |||
|       next if var_name == "argf"   # it'd be nice to handle this one | ||||
| 
 | ||||
|       var_name = "rb_cObject" if var_name == "rb_mKernel" | ||||
|       handle_method(type, var_name, meth_name, meth_body, param_count, | ||||
|       handle_method(type, var_name, meth_name, function, param_count, | ||||
|                     source_file) | ||||
|     end | ||||
| 
 | ||||
|  | @ -302,18 +303,19 @@ class RDoc::Parser::C < RDoc::Parser | |||
|                              \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, | ||||
|                              \s*(-?\w+)\s*\) | ||||
|                 (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? | ||||
|                 %xm) do |meth_name, meth_body, param_count, source_file| | ||||
|       handle_method("method", "rb_mKernel", meth_name, | ||||
|                     meth_body, param_count, source_file) | ||||
|                 %xm) do |meth_name, function, param_count, source_file| | ||||
|       handle_method("method", "rb_mKernel", meth_name, function, param_count, | ||||
|                     source_file) | ||||
|     end | ||||
| 
 | ||||
|     @content.scan(/define_filetest_function\s*\( | ||||
|                      \s*"([^"]+)", | ||||
|                      \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, | ||||
|                      \s*(-?\w+)\s*\)/xm) do |meth_name, meth_body, param_count| | ||||
|                      \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count| | ||||
| 
 | ||||
|       handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count) | ||||
|       handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count) | ||||
|       handle_method("method", "rb_mFileTest", meth_name, function, param_count) | ||||
|       handle_method("singleton_method", "rb_cFile", meth_name, function, | ||||
|                     param_count) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  | @ -369,21 +371,20 @@ class RDoc::Parser::C < RDoc::Parser | |||
|   ## | ||||
|   # Find the C code corresponding to a Ruby method | ||||
| 
 | ||||
|   def find_body(class_name, meth_name, meth_obj, body, quiet = false) | ||||
|     case body | ||||
|   def find_body class_name, meth_name, meth_obj, file_content, quiet = false | ||||
|     case file_content | ||||
|     when %r%((?>/\*.*?\*/\s*)?) | ||||
|             ((?:(?:static|SWIGINTERN)\s+)? | ||||
|              (?:intern\s+)?VALUE\s+#{meth_name} | ||||
|              \s*(\([^)]*\))([^;]|$))%xm then | ||||
|              \s*(\(.*?\))([^;]|$))%xm then | ||||
|       comment = $1 | ||||
|       body_text = $2 | ||||
|       body = $2 | ||||
|       offset = $~.offset(2).first | ||||
| 
 | ||||
|       remove_private_comments comment if comment | ||||
| 
 | ||||
|       # see if we can find the whole body | ||||
| 
 | ||||
|       re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}' | ||||
|       body_text = $& if /#{re}/m =~ body | ||||
|       # try to find the whole body | ||||
|       body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content | ||||
| 
 | ||||
|       # The comment block may have been overridden with a 'Document-method' | ||||
|       # block. This happens in the interpreter when multiple methods are | ||||
|  | @ -399,38 +400,53 @@ class RDoc::Parser::C < RDoc::Parser | |||
|       #meth_obj.params = params | ||||
|       meth_obj.start_collecting_tokens | ||||
|       tk = RDoc::RubyToken::Token.new nil, 1, 1 | ||||
|       tk.set_text body_text | ||||
|       tk.set_text body | ||||
|       meth_obj.add_token tk | ||||
|       meth_obj.comment = strip_stars comment | ||||
|     when %r%((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))%m | ||||
|       meth_obj.offset  = offset | ||||
|       meth_obj.line    = file_content[0, offset].count("\n") + 1 | ||||
| 
 | ||||
|       body | ||||
|     when %r%((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))%m then | ||||
|       comment = $1 | ||||
|       body_text = $2 | ||||
|       find_body class_name, $3, meth_obj, body, true | ||||
|       body = $2 | ||||
|       offset = $~.offset(2).first | ||||
| 
 | ||||
|       find_body class_name, $3, meth_obj, file_content, true | ||||
|       find_modifiers comment, meth_obj | ||||
| 
 | ||||
|       meth_obj.start_collecting_tokens | ||||
|       tk = RDoc::RubyToken::Token.new nil, 1, 1 | ||||
|       tk.set_text body_text | ||||
|       tk.set_text body | ||||
|       meth_obj.add_token tk | ||||
|       meth_obj.comment = strip_stars(comment) + meth_obj.comment.to_s | ||||
|     when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m | ||||
|       unless find_body(class_name, $1, meth_obj, body, true) | ||||
|         warn "No definition for #{meth_name}" if @options.verbosity > 1 | ||||
|         return false | ||||
|       end | ||||
|       meth_obj.offset  = offset | ||||
|       meth_obj.line    = file_content[0, offset].count("\n") + 1 | ||||
| 
 | ||||
|       body | ||||
|     when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m then | ||||
|       # with no comment we hope the aliased definition has it and use it's | ||||
|       # definition | ||||
| 
 | ||||
|       body = find_body(class_name, $1, meth_obj, file_content, true) | ||||
| 
 | ||||
|       return body if body | ||||
| 
 | ||||
|       warn "No definition for #{meth_name}" if @options.verbosity > 1 | ||||
|       false | ||||
|     else # No body, but might still have an override comment | ||||
|       comment = find_override_comment class_name, meth_obj.name | ||||
| 
 | ||||
|       if comment | ||||
|       if comment then | ||||
|         find_modifiers comment, meth_obj | ||||
|         meth_obj.comment = strip_stars comment | ||||
| 
 | ||||
|         '' | ||||
|       else | ||||
|         warn "No definition for #{meth_name}" if @options.verbosity > 1 | ||||
|         return false | ||||
|         false | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     true | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -618,6 +634,7 @@ class RDoc::Parser::C < RDoc::Parser | |||
| 
 | ||||
|     attr = RDoc::Attr.new '', name, rw, comment | ||||
| 
 | ||||
|     attr.record_location @top_level | ||||
|     class_obj.add_attribute attr | ||||
|     @stats.add_attribute attr | ||||
|   end | ||||
|  | @ -732,6 +749,7 @@ class RDoc::Parser::C < RDoc::Parser | |||
|       con = RDoc::Constant.new const_name, definition, comment | ||||
|     end | ||||
| 
 | ||||
|     con.record_location @top_level | ||||
|     @stats.add_constant con | ||||
|     class_obj.add_constant con | ||||
|   end | ||||
|  | @ -748,7 +766,7 @@ class RDoc::Parser::C < RDoc::Parser | |||
|   # to +var_name+.  +type+ is the type of method definition function used. | ||||
|   # +singleton_method+ and +module_function+ create a singleton method. | ||||
| 
 | ||||
|   def handle_method(type, var_name, meth_name, meth_body, param_count, | ||||
|   def handle_method(type, var_name, meth_name, function, param_count, | ||||
|                     source_file = nil) | ||||
|     singleton = false | ||||
|     class_name = @known_classes[var_name] | ||||
|  | @ -770,33 +788,37 @@ class RDoc::Parser::C < RDoc::Parser | |||
|       end | ||||
| 
 | ||||
|       meth_obj = RDoc::AnyMethod.new '', meth_name | ||||
|       meth_obj.c_function = function | ||||
|       meth_obj.singleton = | ||||
|         singleton || %w[singleton_method module_function].include?(type) | ||||
| 
 | ||||
|       p_count = Integer(param_count) rescue -1 | ||||
| 
 | ||||
|       if p_count < 0 then | ||||
|         meth_obj.params = "(...)" | ||||
|       elsif p_count == 0 | ||||
|         meth_obj.params = "()" | ||||
|       else | ||||
|         meth_obj.params = "(" + (1..p_count).map{|i| "p#{i}"}.join(", ") + ")" | ||||
|       end | ||||
| 
 | ||||
|       if source_file then | ||||
|         file_name = File.join @file_dir, source_file | ||||
| 
 | ||||
|         if File.exist? file_name then | ||||
|           body = (@@known_bodies[file_name] ||= File.read(file_name)) | ||||
|           file_content = (@@known_bodies[file_name] ||= File.read(file_name)) | ||||
|         else | ||||
|           warn "unknown source #{source_file} for #{meth_name} in #{@file_name}" | ||||
|         end | ||||
|       else | ||||
|         body = @content | ||||
|         file_content = @content | ||||
|       end | ||||
| 
 | ||||
|       if find_body(class_name, meth_body, meth_obj, body) and | ||||
|          meth_obj.document_self then | ||||
|       body = find_body class_name, function, meth_obj, file_content | ||||
| 
 | ||||
|       if body and meth_obj.document_self then | ||||
|         meth_obj.params = if p_count < -1 then # -2 is Array | ||||
|                             '(*args)' | ||||
|                           elsif p_count == -1 then # argc, argv | ||||
|                             rb_scan_args body | ||||
|                           else | ||||
|                             "(#{(1..p_count).map { |i| "p#{i}" }.join ', '})" | ||||
|                           end | ||||
| 
 | ||||
| 
 | ||||
|         meth_obj.record_location @top_level | ||||
|         class_obj.add_method meth_obj | ||||
|         @stats.add_method meth_obj | ||||
|         meth_obj.visibility = :private if 'private_method' == type | ||||
|  | @ -856,6 +878,90 @@ class RDoc::Parser::C < RDoc::Parser | |||
|     comment | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Extracts parameters from the +method_body+ and returns a method | ||||
|   # parameter string.  Follows 1.9.3dev's scan-arg-spec, see README.EXT | ||||
| 
 | ||||
|   def rb_scan_args method_body | ||||
|     method_body =~ /rb_scan_args\((.*?)\)/m | ||||
|     return '(*args)' unless $1 | ||||
| 
 | ||||
|     $1.split(/,/)[2] =~ /"(.*?)"/ # format argument | ||||
|     format = $1.split(//) | ||||
| 
 | ||||
|     lead = opt = trail = 0 | ||||
| 
 | ||||
|     if format.first =~ /\d/ then | ||||
|       lead = $&.to_i | ||||
|       format.shift | ||||
|       if format.first =~ /\d/ then | ||||
|         opt = $&.to_i | ||||
|         format.shift | ||||
|         if format.first =~ /\d/ then | ||||
|           trail = $&.to_i | ||||
|           format.shift | ||||
|           block_arg = true | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     if format.first == '*' and not block_arg then | ||||
|       var = true | ||||
|       format.shift | ||||
|       if format.first =~ /\d/ then | ||||
|         trail = $&.to_i | ||||
|         format.shift | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     if format.first == ':' then | ||||
|       hash = true | ||||
|       format.shift | ||||
|     end | ||||
| 
 | ||||
|     if format.first == '&' then | ||||
|       block = true | ||||
|       format.shift | ||||
|     end | ||||
| 
 | ||||
|     # if the format string is not empty there's a bug in the C code, ignore it | ||||
| 
 | ||||
|     args = [] | ||||
|     position = 1 | ||||
| 
 | ||||
|     (1...(position + lead)).each do |index| | ||||
|       args << "p#{index}" | ||||
|     end | ||||
| 
 | ||||
|     position += lead | ||||
| 
 | ||||
|     (position...(position + opt)).each do |index| | ||||
|       args << "p#{index} = v#{index}" | ||||
|     end | ||||
| 
 | ||||
|     position += opt | ||||
| 
 | ||||
|     if var then | ||||
|       args << '*args' | ||||
|       position += 1 | ||||
|     end | ||||
| 
 | ||||
|     (position...(position + trail)).each do |index| | ||||
|       args << "p#{index}" | ||||
|     end | ||||
| 
 | ||||
|     position += trail | ||||
| 
 | ||||
|     if hash then | ||||
|       args << "p#{position} = {}" | ||||
|       position += 1 | ||||
|     end | ||||
| 
 | ||||
|     args << '&block' if block | ||||
| 
 | ||||
|     "(#{args.join ', '})" | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Removes lines that are commented out that might otherwise get picked up | ||||
|   # when scanning for classes and methods | ||||
|  |  | |||
|  | @ -174,6 +174,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|     @scanner.exception_on_syntax_error = false | ||||
|     @prev_seek = nil | ||||
| 
 | ||||
|     @encoding = nil | ||||
|     @encoding = @options.encoding if Object.const_defined? :Encoding | ||||
| 
 | ||||
|     reset | ||||
|   end | ||||
| 
 | ||||
|  | @ -183,6 +186,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   def collect_first_comment | ||||
|     skip_tkspace | ||||
|     comment = '' | ||||
|     comment.force_encoding @encoding if @encoding | ||||
|     first_line = true | ||||
| 
 | ||||
|     tk = get_tk | ||||
|  | @ -449,6 +453,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # +comment+. | ||||
| 
 | ||||
|   def parse_attr(context, single, tk, comment) | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     args = parse_symbol_arg 1 | ||||
|     if args.size > 0 then | ||||
|       name = args[0] | ||||
|  | @ -464,6 +471,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|       att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE | ||||
|       att.record_location @top_level | ||||
|       att.offset = offset | ||||
|       att.line   = line_no | ||||
| 
 | ||||
|       read_documentation_modifiers att, RDoc::ATTR_MODIFIERS | ||||
| 
 | ||||
|  | @ -480,6 +489,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # comment for each to +comment+. | ||||
| 
 | ||||
|   def parse_attr_accessor(context, single, tk, comment) | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     args = parse_symbol_arg | ||||
|     rw = "?" | ||||
| 
 | ||||
|  | @ -498,6 +510,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|     for name in args | ||||
|       att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE | ||||
|       att.record_location @top_level | ||||
|       att.offset = offset | ||||
|       att.line   = line_no | ||||
| 
 | ||||
|       context.add_attribute att | ||||
|       @stats.add_attribute att | ||||
|  | @ -508,6 +522,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # Parses an +alias+ in +context+ with +comment+ | ||||
| 
 | ||||
|   def parse_alias(context, single, tk, comment) | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     skip_tkspace | ||||
| 
 | ||||
|     if TkLPAREN === peek_tk then | ||||
|  | @ -534,6 +551,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|     al = RDoc::Alias.new(get_tkread, old_name, new_name, comment, | ||||
|                          single == SINGLE) | ||||
|     al.record_location @top_level | ||||
|     al.offset = offset | ||||
|     al.line   = line_no | ||||
| 
 | ||||
|     read_documentation_modifiers al, RDoc::ATTR_MODIFIERS | ||||
|     context.add_alias al if al.document_self | ||||
|  | @ -586,6 +605,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # Parses a class in +context+ with +comment+ | ||||
| 
 | ||||
|   def parse_class(container, single, tk, comment) | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     declaration_context = container | ||||
|     container, name_t, given_name = get_class_or_module container | ||||
| 
 | ||||
|  | @ -606,6 +628,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|       read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS | ||||
|       cls.record_location @top_level | ||||
|       cls.offset = offset | ||||
|       cls.line   = line_no | ||||
| 
 | ||||
|       cls.comment = comment if cls.document_self | ||||
| 
 | ||||
|       @top_level.add_to_classes_or_modules cls | ||||
|  | @ -622,6 +647,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|         unless other then | ||||
|           other = container.add_module RDoc::NormalModule, name | ||||
|           other.record_location @top_level | ||||
|           other.offset  = offset | ||||
|           other.line    = line_no | ||||
| 
 | ||||
|           other.comment = comment | ||||
|         end | ||||
| 
 | ||||
|  | @ -639,7 +667,6 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|         read_documentation_modifiers other, RDoc::CLASS_MODIFIERS | ||||
|         parse_statements(other, SINGLE) | ||||
|       end | ||||
| 
 | ||||
|     else | ||||
|       warn("Expected class name or '<<'. Got #{name_t.class}: #{name_t.text.inspect}") | ||||
|     end | ||||
|  | @ -649,6 +676,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # Parses a constant in +context+ with +comment+ | ||||
| 
 | ||||
|   def parse_constant(container, tk, comment) | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     name = tk.name | ||||
|     skip_tkspace false | ||||
| 
 | ||||
|  | @ -658,7 +688,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|     unless TkASSIGN === eq_tk then | ||||
|       unget_tk eq_tk | ||||
|       return | ||||
|       return false | ||||
|     end | ||||
| 
 | ||||
|     nest = 0 | ||||
|  | @ -669,7 +699,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|     if TkGT === tk then | ||||
|       unget_tk tk | ||||
|       unget_tk eq_tk | ||||
|       return | ||||
|       return false | ||||
|     end | ||||
| 
 | ||||
|     rhs_name = '' | ||||
|  | @ -698,7 +728,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|                   container.find_module_named rhs_name | ||||
|                 end | ||||
| 
 | ||||
|           container.add_module_alias mod, name if mod | ||||
|           container.add_module_alias mod, name, @top_level if mod | ||||
|           get_tk # TkNL | ||||
|           break | ||||
|         end | ||||
|  | @ -721,10 +751,13 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|     con = RDoc::Constant.new name, res, comment | ||||
|     con.record_location @top_level | ||||
|     con.offset = offset | ||||
|     con.line   = line_no | ||||
|     read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS | ||||
| 
 | ||||
|     @stats.add_constant con | ||||
|     container.add_constant con if con.document_self | ||||
|     true | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -732,8 +765,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # :method: or :attr: directives in +comment+. | ||||
| 
 | ||||
|   def parse_comment(container, tk, comment) | ||||
|     line_no = tk.line_no | ||||
|     column  = tk.char_no | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     singleton = !!comment.sub!(/(^# +:?)(singleton-)(method:)/, '\1\3') | ||||
| 
 | ||||
|  | @ -744,6 +778,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|       meth = RDoc::GhostMethod.new get_tkread, name | ||||
|       meth.record_location @top_level | ||||
|       meth.singleton = singleton | ||||
|       meth.offset    = offset | ||||
|       meth.line      = line_no | ||||
| 
 | ||||
|       meth.start_collecting_tokens | ||||
|       indent = TkSPACE.new nil, 1, 1 | ||||
|  | @ -764,7 +800,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|       meth.comment = comment | ||||
| 
 | ||||
|       @stats.add_method meth | ||||
|     elsif comment.sub!(/# +:?(attr(_reader|_writer|_accessor)?:) *(\S*).*?\n/i, '') then | ||||
|     elsif comment.sub!(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '') then | ||||
|       rw = case $1 | ||||
|            when 'attr_reader' then 'R' | ||||
|            when 'attr_writer' then 'W' | ||||
|  | @ -776,6 +812,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|       # TODO authorize 'singleton-attr...'? | ||||
|       att = RDoc::Attr.new get_tkread, name, rw, comment | ||||
|       att.record_location @top_level | ||||
|       att.offset    = offset | ||||
|       att.line      = line_no | ||||
| 
 | ||||
|       container.add_attribute att | ||||
| 
 | ||||
|  | @ -870,8 +908,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # Parses a meta-programmed method | ||||
| 
 | ||||
|   def parse_meta_method(container, single, tk, comment) | ||||
|     line_no = tk.line_no | ||||
|     column  = tk.char_no | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     start_collecting_tokens | ||||
|     add_token tk | ||||
|  | @ -903,6 +942,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|     meth = RDoc::MetaMethod.new get_tkread, name | ||||
|     meth.record_location @top_level | ||||
|     meth.offset = offset | ||||
|     meth.line   = line_no | ||||
|     meth.singleton = singleton | ||||
| 
 | ||||
|     remove_token_listener self | ||||
|  | @ -933,6 +974,10 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|           break unless last_tk and TkCOMMA === last_tk | ||||
|         when TkSPACE then | ||||
|           # expression continues | ||||
|         when TkDO then | ||||
|           unget_tk tk | ||||
|           parse_statements container, single, meth | ||||
|           break | ||||
|         else | ||||
|           last_tk = tk | ||||
|         end | ||||
|  | @ -951,8 +996,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|     added_container = nil | ||||
|     meth = nil | ||||
|     name = nil | ||||
|     line_no = tk.line_no | ||||
|     column  = tk.char_no | ||||
|     offset  = tk.seek | ||||
|     line_no = tk.line_no | ||||
| 
 | ||||
|     start_collecting_tokens | ||||
|     add_token tk | ||||
|  | @ -1044,6 +1090,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|     end | ||||
| 
 | ||||
|     meth.record_location @top_level | ||||
|     meth.offset = offset | ||||
|     meth.line   = line_no | ||||
| 
 | ||||
|     meth.start_collecting_tokens | ||||
|     indent = TkSPACE.new nil, 1, 1 | ||||
|  | @ -1216,6 +1264,8 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|   def parse_statements(container, single = NORMAL, current_method = nil, | ||||
|                        comment = '') | ||||
|     comment.force_encoding @encoding if @encoding | ||||
| 
 | ||||
|     nest = 1 | ||||
|     save_visibility = container.visibility | ||||
| 
 | ||||
|  | @ -1223,6 +1273,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|     while tk = get_tk do | ||||
|       keep_comment = false | ||||
|       try_parse_comment = false | ||||
| 
 | ||||
|       non_comment_seen = true unless TkCOMMENT === tk | ||||
| 
 | ||||
|  | @ -1238,6 +1289,7 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|               comment.empty? | ||||
| 
 | ||||
|             comment = '' | ||||
|             comment.force_encoding @encoding if @encoding | ||||
|           end | ||||
| 
 | ||||
|           while TkCOMMENT === tk do | ||||
|  | @ -1287,7 +1339,9 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
| 
 | ||||
|       when TkCONSTANT then | ||||
|         if container.document_self then | ||||
|           parse_constant container, tk, comment | ||||
|           if not parse_constant container, tk, comment then | ||||
|             try_parse_comment = true | ||||
|           end | ||||
|         end | ||||
| 
 | ||||
|       when TkALIAS then | ||||
|  | @ -1365,13 +1419,20 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|           return | ||||
|         end | ||||
|       else | ||||
|         try_parse_comment = nest == 1 | ||||
|       end | ||||
| 
 | ||||
|       if try_parse_comment then | ||||
|         non_comment_seen = parse_comment container, tk, comment unless | ||||
|           comment.empty? | ||||
| 
 | ||||
|         comment = '' | ||||
|         keep_comment = false | ||||
|       end | ||||
| 
 | ||||
|       comment = '' unless keep_comment | ||||
|       unless keep_comment then | ||||
|         comment = '' | ||||
|         comment.force_encoding @encoding if @encoding | ||||
|       end | ||||
| 
 | ||||
|       begin | ||||
|         get_tkread | ||||
|  | @ -1584,8 +1645,11 @@ class RDoc::Parser::Ruby < RDoc::Parser | |||
|   # Removes private comments from +comment+ | ||||
| 
 | ||||
|   def remove_private_comments(comment) | ||||
|     comment.gsub!(/^#--\n.*?^#\+\+\n?/m, '') | ||||
|     comment.sub!(/^#--\n.*\n?/m, '') | ||||
|     empty = '' | ||||
|     empty.force_encoding comment.encoding if Object.const_defined? :Encoding | ||||
| 
 | ||||
|     comment.gsub!(/^#--.*?^#\+\+\n?/m, empty) | ||||
|     comment.sub!(/^#--.*/m, '') | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  |  | |||
|  | @ -197,6 +197,7 @@ option) | |||
|       end unless @options.force_output | ||||
|     else | ||||
|       FileUtils.mkdir_p dir | ||||
|       FileUtils.touch output_flag_file dir | ||||
|     end | ||||
| 
 | ||||
|     last | ||||
|  | @ -206,7 +207,7 @@ option) | |||
|   # Update the flag file in an output directory. | ||||
| 
 | ||||
|   def update_output_dir(op_dir, time, last = {}) | ||||
|     return if @options.dry_run | ||||
|     return if @options.dry_run or not @options.update_output_dir | ||||
| 
 | ||||
|     open output_flag_file(op_dir), "w" do |f| | ||||
|       f.puts time.rfc2822 | ||||
|  | @ -353,12 +354,12 @@ The internal error was: | |||
| 
 | ||||
|   def parse_files files | ||||
|     file_list = gather_files files | ||||
|     @stats = RDoc::Stats.new file_list.size, @options.verbosity | ||||
| 
 | ||||
|     return [] if file_list.empty? | ||||
| 
 | ||||
|     file_info = [] | ||||
| 
 | ||||
|     @stats = RDoc::Stats.new file_list.size, @options.verbosity | ||||
|     @stats.begin_adding | ||||
| 
 | ||||
|     file_info = file_list.map do |filename| | ||||
|  | @ -381,21 +382,30 @@ The internal error was: | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Format up one or more files according to the given arguments. | ||||
|   # Generates documentation or a coverage report depending upon the settings | ||||
|   # in +options+. | ||||
|   # | ||||
|   # For simplicity, +argv+ is an array of strings, equivalent to the strings | ||||
|   # that would be passed on the command line. (This isn't a coincidence, as | ||||
|   # we _do_ pass in ARGV when running interactively). For a list of options, | ||||
|   # see <tt>rdoc --help</tt>. By default, output will be stored in a directory | ||||
|   # called +doc+ below the current directory, so make sure you're somewhere | ||||
|   # writable before invoking. | ||||
|   # +options+ can be either an RDoc::Options instance or an array of strings | ||||
|   # equivalent to the strings that would be passed on the command line like | ||||
|   # <tt>%w[-q -o doc -t My\ Doc\ Title]</tt>.  #document will automatically | ||||
|   # call RDoc::Options#finish if an options instance was given. | ||||
|   # | ||||
|   # For a list of options, see either RDoc::Options or <tt>rdoc --help</tt>. | ||||
|   # | ||||
|   # By default, output will be stored in a directory called "doc" below the | ||||
|   # current directory, so make sure you're somewhere writable before invoking. | ||||
| 
 | ||||
|   def document(argv) | ||||
|   def document options | ||||
|     RDoc::TopLevel.reset | ||||
|     RDoc::Parser::C.reset | ||||
| 
 | ||||
|     @options = RDoc::Options.new | ||||
|     @options.parse argv | ||||
|     if RDoc::Options === options then | ||||
|       @options = options | ||||
|       @options.finish | ||||
|     else | ||||
|       @options = RDoc::Options.new | ||||
|       @options.parse options | ||||
|     end | ||||
| 
 | ||||
|     if @options.pipe then | ||||
|       handle_pipe | ||||
|  | @ -416,10 +426,13 @@ The internal error was: | |||
| 
 | ||||
|     RDoc::TopLevel.complete @options.visibility | ||||
| 
 | ||||
|     @stats.coverage_level = @options.coverage_report | ||||
| 
 | ||||
|     if @options.coverage_report then | ||||
|       puts | ||||
| 
 | ||||
|       puts @stats.report | ||||
|     elsif file_info.empty? | ||||
|     elsif file_info.empty? then | ||||
|       $stderr.puts "\nNo newer files." unless @options.quiet | ||||
|     else | ||||
|       gen_klass = @options.generator | ||||
|  | @ -474,6 +487,7 @@ begin | |||
|         load extension | ||||
|       rescue => e | ||||
|         warn "error loading #{extension.inspect}: #{e.message} (#{e.class})" | ||||
|         warn "\t#{e.backtrace.join "\n\t"}" if $DEBUG | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  |  | |||
|  | @ -651,12 +651,14 @@ Options may also be set in the 'RI' environment variable. | |||
| 
 | ||||
|     raise NotFoundError, name if found.empty? | ||||
| 
 | ||||
|     filtered = filter_methods found, name | ||||
| 
 | ||||
|     out = RDoc::Markup::Document.new | ||||
| 
 | ||||
|     out << RDoc::Markup::Heading.new(1, name) | ||||
|     out << RDoc::Markup::BlankLine.new | ||||
| 
 | ||||
|     found.each do |store, methods| | ||||
|     filtered.each do |store, methods| | ||||
|       methods.each do |method| | ||||
|         out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") | ||||
| 
 | ||||
|  | @ -753,6 +755,21 @@ Options may also be set in the 'RI' environment variable. | |||
|     "#{expand_class klass}#{selector}#{method}" | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Filters the methods in +found+ trying to find a match for +name+. | ||||
| 
 | ||||
|   def filter_methods found, name | ||||
|     regexp = name_regexp name | ||||
| 
 | ||||
|     filtered = found.find_all do |store, methods| | ||||
|       methods.any? { |method| method.full_name =~ regexp } | ||||
|     end | ||||
| 
 | ||||
|     return filtered unless filtered.empty? | ||||
| 
 | ||||
|     found | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Yields items matching +name+ including the store they were found in, the | ||||
|   # class being searched for, the class they were found in (an ancestor) the | ||||
|  | @ -948,10 +965,10 @@ Options may also be set in the 'RI' environment variable. | |||
|       methods = [] | ||||
| 
 | ||||
|       methods << load_method(store, :class_methods, ancestor, '::',  method) if | ||||
|         types == :class or types == :both | ||||
|         [:class, :both].include? types | ||||
| 
 | ||||
|       methods << load_method(store, :instance_methods, ancestor, '#',  method) if | ||||
|         types == :instance or types == :both | ||||
|         [:instance, :both].include? types | ||||
| 
 | ||||
|       found << [store, methods.compact] | ||||
|     end | ||||
|  | @ -970,6 +987,21 @@ Options may also be set in the 'RI' environment variable. | |||
|     end | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Returns a regular expression for +name+ that will match an | ||||
|   # RDoc::AnyMethod's name. | ||||
| 
 | ||||
|   def name_regexp name | ||||
|     klass, type, name = parse_name name | ||||
| 
 | ||||
|     case type | ||||
|     when '#', '::' then | ||||
|       /^#{klass}#{type}#{name}$/ | ||||
|     else | ||||
|       /^#{klass}(#|::)#{name}$/ | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Paginates output through a pager program. | ||||
| 
 | ||||
|  | @ -996,7 +1028,7 @@ Options may also be set in the 'RI' environment variable. | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Extract the class, selector and method name parts from +name+ like | ||||
|   # Extracts the class, selector and method name parts from +name+ like | ||||
|   # Foo::Bar#baz. | ||||
|   # | ||||
|   # NOTE: Given Foo::Bar, Bar is considered a class even though it may be a | ||||
|  |  | |||
|  | @ -401,13 +401,15 @@ class RDoc::RubyLex | |||
|       |op, io| | ||||
|       @ltype = "=" | ||||
|       res = '' | ||||
|       until (ch = getc) == "\n" do res << ch end | ||||
|       nil until (ch = getc) == "\n" | ||||
| 
 | ||||
|       until peek_equal?("=end") && peek(4) =~ /\s/ do | ||||
|         until (ch = getc) == "\n" do res << ch end | ||||
|       end | ||||
|       res << gets | ||||
|       gets # consume =end | ||||
| 
 | ||||
|       @ltype = nil | ||||
|       Token(TkRD_COMMENT, res) | ||||
|       Token(TkCOMMENT, res) | ||||
|     end | ||||
| 
 | ||||
|     @OP.def_rule("\n") do |op, io| | ||||
|  |  | |||
|  | @ -5,10 +5,19 @@ require 'rdoc/class_module' | |||
| 
 | ||||
| class RDoc::SingleClass < RDoc::ClassModule | ||||
| 
 | ||||
|   ## | ||||
|   # Adds the superclass to the included modules. | ||||
| 
 | ||||
|   def ancestors | ||||
|     superclass ? super + [superclass] : super | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # The definition of this singleton class, <tt>class << MyClassName</tt> | ||||
| 
 | ||||
|   def definition | ||||
|     "class << #{full_name}" | ||||
|   end | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,6 +6,11 @@ require 'rdoc' | |||
| 
 | ||||
| class RDoc::Stats | ||||
| 
 | ||||
|   ## | ||||
|   # Output level for the coverage report | ||||
| 
 | ||||
|   attr_reader :coverage_level | ||||
| 
 | ||||
|   ## | ||||
|   # Count of files parsed during parsing | ||||
| 
 | ||||
|  | @ -23,10 +28,14 @@ class RDoc::Stats | |||
|   def initialize num_files, verbosity = 1 | ||||
|     @files_so_far = 0 | ||||
|     @num_files = num_files | ||||
|     @fully_documented = nil | ||||
|     @percent_doc = nil | ||||
| 
 | ||||
|     @coverage_level = 0 | ||||
|     @doc_items = nil | ||||
|     @fully_documented = nil | ||||
|     @num_params = 0 | ||||
|     @percent_doc = nil | ||||
|     @start = Time.now | ||||
|     @undoc_params = 0 | ||||
| 
 | ||||
|     @display = case verbosity | ||||
|                when 0 then Quiet.new   num_files | ||||
|  | @ -93,10 +102,11 @@ class RDoc::Stats | |||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Calculates documentation totals and percentages | ||||
|   # Calculates documentation totals and percentages for classes, modules, | ||||
|   # constants, attributes and methods. | ||||
| 
 | ||||
|   def calculate | ||||
|     return if @percent_doc | ||||
|     return if @doc_items | ||||
| 
 | ||||
|     ucm = RDoc::TopLevel.unique_classes_and_modules | ||||
|     constants = [] | ||||
|  | @ -119,20 +129,31 @@ class RDoc::Stats | |||
|       @num_classes + | ||||
|       @num_constants + | ||||
|       @num_methods + | ||||
|       @num_modules | ||||
|       @num_modules + | ||||
|       @num_params | ||||
| 
 | ||||
|     @undoc_items = | ||||
|       @undoc_attributes + | ||||
|       @undoc_classes + | ||||
|       @undoc_constants + | ||||
|       @undoc_methods + | ||||
|       @undoc_modules | ||||
|       @undoc_modules + | ||||
|       @undoc_params | ||||
| 
 | ||||
|     @doc_items = @num_items - @undoc_items | ||||
|   end | ||||
| 
 | ||||
|     @fully_documented = (@num_items - @doc_items) == 0 | ||||
|   ## | ||||
|   # Sets coverage report level.  Accepted values are: | ||||
|   # | ||||
|   # false or nil:: No report | ||||
|   # 0:: Classes, modules, constants, attributes, methods | ||||
|   # 1:: Level 0 + method parameters | ||||
| 
 | ||||
|     @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero? | ||||
|   def coverage_level= level | ||||
|     level = -1 unless level | ||||
| 
 | ||||
|     @coverage_level = level | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -159,97 +180,186 @@ class RDoc::Stats | |||
|     @fully_documented | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # A report that says you did a great job! | ||||
| 
 | ||||
|   def great_job | ||||
|     report = [] | ||||
|     report << '100% documentation!' | ||||
|     report << nil | ||||
|     report << 'Great Job!' | ||||
| 
 | ||||
|     report.join "\n" | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Calculates the percentage of items documented. | ||||
| 
 | ||||
|   def percent_doc | ||||
|     return @percent_doc if @percent_doc | ||||
| 
 | ||||
|     @fully_documented = (@num_items - @doc_items) == 0 | ||||
| 
 | ||||
|     @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero? | ||||
|     @percent_doc ||= 0 | ||||
| 
 | ||||
|     @percent_doc | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Returns a report on which items are not documented | ||||
| 
 | ||||
|   def report | ||||
|     report = [] | ||||
| 
 | ||||
|     calculate | ||||
| 
 | ||||
|     if @num_items == @doc_items then | ||||
|       report << '100% documentation!' | ||||
|       report << nil | ||||
|       report << 'Great Job!' | ||||
| 
 | ||||
|       return report.join "\n" | ||||
|     if @coverage_level > 0 then | ||||
|       require 'rdoc/markup/to_tt_only' | ||||
|       require 'rdoc/generator/markup' | ||||
|       require 'rdoc/text' | ||||
|       extend RDoc::Text | ||||
|     end | ||||
| 
 | ||||
|     report << 'The following items are not documented:' | ||||
|     report << nil | ||||
|     report = [] | ||||
| 
 | ||||
|     if @coverage_level.zero? then | ||||
|       calculate | ||||
| 
 | ||||
|       return great_job if @num_items == @doc_items | ||||
|     end | ||||
| 
 | ||||
|     ucm = RDoc::TopLevel.unique_classes_and_modules | ||||
| 
 | ||||
|     ucm.sort.each do |cm| | ||||
|       type = case cm # TODO #definition | ||||
|              when RDoc::NormalClass  then 'class' | ||||
|              when RDoc::SingleClass  then 'class <<' | ||||
|              when RDoc::NormalModule then 'module' | ||||
|              end | ||||
|       report << report_class_module(cm) { | ||||
|         [ | ||||
|           report_constants(cm), | ||||
|           report_attributes(cm), | ||||
|           report_methods(cm), | ||||
|         ].compact | ||||
|       } | ||||
|     end | ||||
| 
 | ||||
|       if cm.fully_documented? then | ||||
|         next | ||||
|       elsif cm.in_files.empty? or | ||||
|             (cm.constants.empty? and cm.method_list.empty?) then | ||||
|         report << "# #{type} #{cm.full_name} is referenced but empty." | ||||
|         report << '#' | ||||
|         report << '# It probably came from another project.  ' \ | ||||
|                   'I\'m sorry I\'m holding it against you.' | ||||
|         report << nil | ||||
|     if @coverage_level > 0 then | ||||
|       calculate | ||||
| 
 | ||||
|         next | ||||
|       elsif cm.documented? then | ||||
|         report << "#{type} #{cm.full_name} # is documented" | ||||
|       else | ||||
|         report << '# in files:' | ||||
|       return great_job if @num_items == @doc_items | ||||
|     end | ||||
| 
 | ||||
|         cm.in_files.each do |file| | ||||
|           report << "#   #{file.full_name}" | ||||
|         end | ||||
|     report.unshift nil | ||||
|     report.unshift 'The following items are not documented:' | ||||
| 
 | ||||
|         report << nil | ||||
|     report.join "\n" | ||||
|   end | ||||
| 
 | ||||
|         report << "#{type} #{cm.full_name}" | ||||
|   ## | ||||
|   # Returns a report on undocumented attributes in ClassModule +cm+ | ||||
| 
 | ||||
|   def report_attributes cm | ||||
|     return if cm.attributes.empty? | ||||
| 
 | ||||
|     report = [] | ||||
| 
 | ||||
|     cm.each_attribute do |attr| | ||||
|       next if attr.documented? | ||||
|       report << "  #{attr.definition} :#{attr.name} " \ | ||||
|         "# in file #{attr.file.full_name}" | ||||
|     end | ||||
| 
 | ||||
|     report | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Returns a report on undocumented items in ClassModule +cm+ | ||||
| 
 | ||||
|   def report_class_module cm | ||||
|     return if cm.fully_documented? and @coverage_level.zero? | ||||
| 
 | ||||
|     report = [] | ||||
| 
 | ||||
|     if cm.in_files.empty? then | ||||
|       report << "# #{cm.definition} is referenced but empty." | ||||
|       report << '#' | ||||
|       report << '# It probably came from another project.  ' \ | ||||
|         "I'm sorry I'm holding it against you." | ||||
|       report << nil | ||||
| 
 | ||||
|       return report | ||||
|     elsif cm.documented? then | ||||
|       documented = true | ||||
|       report << "#{cm.definition} # is documented" | ||||
|     else | ||||
|       report << '# in files:' | ||||
| 
 | ||||
|       cm.in_files.each do |file| | ||||
|         report << "#   #{file.full_name}" | ||||
|       end | ||||
| 
 | ||||
|       unless cm.constants.empty? then | ||||
|         report << nil | ||||
|       report << nil | ||||
| 
 | ||||
|         cm.each_constant do |constant| | ||||
|           # TODO constant aliases are listed in the summary but not reported | ||||
|           # figure out what to do here | ||||
|           next if constant.documented? || constant.is_alias_for | ||||
|           report << "  # in file #{constant.file.full_name}" | ||||
|           report << "  #{constant.name} = nil" | ||||
|       report << "#{cm.definition}" | ||||
|     end | ||||
| 
 | ||||
|     body = yield.flatten # HACK remove #flatten | ||||
| 
 | ||||
|     return if body.empty? and documented | ||||
| 
 | ||||
|     report << nil << body unless body.empty? | ||||
| 
 | ||||
|     report << 'end' | ||||
|     report << nil | ||||
| 
 | ||||
|     report | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Returns a report on undocumented constants in ClassModule +cm+ | ||||
| 
 | ||||
|   def report_constants cm | ||||
|     return if cm.constants.empty? | ||||
| 
 | ||||
|     report = [] | ||||
| 
 | ||||
|     cm.each_constant do |constant| | ||||
|       # TODO constant aliases are listed in the summary but not reported | ||||
|       # figure out what to do here | ||||
|       next if constant.documented? || constant.is_alias_for | ||||
|       report << "  # in file #{constant.file.full_name}" | ||||
|       report << "  #{constant.name} = nil" | ||||
|     end | ||||
| 
 | ||||
|     report | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Returns a report on undocumented methods in ClassModule +cm+ | ||||
| 
 | ||||
|   def report_methods cm | ||||
|     return if cm.method_list.empty? | ||||
| 
 | ||||
|     report = [] | ||||
| 
 | ||||
|     cm.each_method do |method| | ||||
|       next if method.documented? and @coverage_level.zero? | ||||
| 
 | ||||
|       if @coverage_level > 0 then | ||||
|         params, undoc = undoc_params method | ||||
| 
 | ||||
|         @num_params += params | ||||
| 
 | ||||
|         unless undoc.empty? then | ||||
|           @undoc_params += undoc.length | ||||
| 
 | ||||
|           undoc = undoc.map do |param| "+#{param}+" end | ||||
|           param_report = "  # #{undoc.join ', '} is not documented" | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       unless cm.attributes.empty? then | ||||
|         report << nil | ||||
| 
 | ||||
|         cm.each_attribute do |attr| | ||||
|           next if attr.documented? | ||||
|           report << "  #{attr.definition} #{attr.name} " \ | ||||
|                     "# in file #{attr.file.full_name}" | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       unless cm.method_list.empty? then | ||||
|         report << nil | ||||
| 
 | ||||
|         cm.each_method do |method| | ||||
|           next if method.documented? | ||||
|           report << "  # in file #{method.file.full_name}" | ||||
|           report << "  def #{method.name}#{method.params}; end" | ||||
|           report << nil | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       report << 'end' | ||||
|       next if method.documented? and not param_report | ||||
|       report << "  # in file #{method.file.full_name}" | ||||
|       report << param_report if param_report | ||||
|       report << "  def #{method.name}#{method.params}; end" | ||||
|       report << nil | ||||
|     end | ||||
| 
 | ||||
|     report.join "\n" | ||||
|     report | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -259,13 +369,14 @@ class RDoc::Stats | |||
|     calculate | ||||
| 
 | ||||
|     num_width = [@num_files, @num_items].max.to_s.length | ||||
|     nodoc_width = [ | ||||
|     undoc_width = [ | ||||
|       @undoc_attributes, | ||||
|       @undoc_classes, | ||||
|       @undoc_constants, | ||||
|       @undoc_items, | ||||
|       @undoc_methods, | ||||
|       @undoc_modules, | ||||
|       @undoc_params, | ||||
|     ].max.to_s.length | ||||
| 
 | ||||
|     report = [] | ||||
|  | @ -274,28 +385,51 @@ class RDoc::Stats | |||
|     report << nil | ||||
| 
 | ||||
|     report << 'Classes:    %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_classes, nodoc_width, @undoc_classes] | ||||
|       num_width, @num_classes, undoc_width, @undoc_classes] | ||||
|     report << 'Modules:    %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_modules, nodoc_width, @undoc_modules] | ||||
|       num_width, @num_modules, undoc_width, @undoc_modules] | ||||
|     report << 'Constants:  %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_constants, nodoc_width, @undoc_constants] | ||||
|       num_width, @num_constants, undoc_width, @undoc_constants] | ||||
|     report << 'Attributes: %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_attributes, nodoc_width, @undoc_attributes] | ||||
|       num_width, @num_attributes, undoc_width, @undoc_attributes] | ||||
|     report << 'Methods:    %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_methods, nodoc_width, @undoc_methods] | ||||
|       num_width, @num_methods, undoc_width, @undoc_methods] | ||||
|     report << 'Parameters: %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_params, undoc_width, @undoc_params] if | ||||
|         @coverage_level > 0 | ||||
| 
 | ||||
|     report << nil | ||||
| 
 | ||||
|     report << 'Total:      %*d (%*d undocumented)' % [ | ||||
|       num_width, @num_items, nodoc_width, @undoc_items] | ||||
|       num_width, @num_items, undoc_width, @undoc_items] | ||||
| 
 | ||||
|     report << '%6.2f%% documented' % @percent_doc if @percent_doc | ||||
|     report << '%6.2f%% documented' % percent_doc | ||||
|     report << nil | ||||
|     report << 'Elapsed: %0.1fs' % (Time.now - @start) | ||||
| 
 | ||||
|     report.join "\n" | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Determines which parameters in +method+ were not documented.  Returns a | ||||
|   # total parameter count and an Array of undocumented methods. | ||||
| 
 | ||||
|   def undoc_params method | ||||
|     @formatter ||= RDoc::Markup::ToTtOnly.new | ||||
| 
 | ||||
|     params = method.param_list | ||||
| 
 | ||||
|     return 0, [] if params.empty? | ||||
| 
 | ||||
|     document = parse method.comment | ||||
| 
 | ||||
|     tts = document.accept @formatter | ||||
| 
 | ||||
|     undoc = params - tts | ||||
| 
 | ||||
|     [params.length, undoc] | ||||
|   end | ||||
| 
 | ||||
|   autoload :Quiet,   'rdoc/stats/quiet' | ||||
|   autoload :Normal,  'rdoc/stats/normal' | ||||
|   autoload :Verbose, 'rdoc/stats/verbose' | ||||
|  |  | |||
|  | @ -149,17 +149,45 @@ class RDoc::Task < Rake::TaskLib | |||
|   # Create an RDoc task with the given name. See the RDoc::Task class overview | ||||
|   # for documentation. | ||||
| 
 | ||||
|   def initialize(name = :rdoc)  # :yield: self | ||||
|     if name.is_a? Hash then | ||||
|       invalid_options = name.keys.map { |k| k.to_sym } - | ||||
|         [:rdoc, :clobber_rdoc, :rerdoc] | ||||
|   def initialize name = :rdoc # :yield: self | ||||
|     defaults | ||||
| 
 | ||||
|       unless invalid_options.empty? then | ||||
|         raise ArgumentError, "invalid options: #{invalid_options.join(", ")}" | ||||
|       end | ||||
|     end | ||||
|     check_names name | ||||
| 
 | ||||
|     @name = name | ||||
| 
 | ||||
|     yield self if block_given? | ||||
| 
 | ||||
|     define | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Ensures that +names+ only includes names for the :rdoc, :clobber_rdoc and | ||||
|   # :rerdoc.  If other names are given an ArgumentError is raised. | ||||
| 
 | ||||
|   def check_names names | ||||
|     return unless Hash === names | ||||
| 
 | ||||
|     invalid_options = | ||||
|       names.keys.map { |k| k.to_sym } - [:rdoc, :clobber_rdoc, :rerdoc] | ||||
| 
 | ||||
|     unless invalid_options.empty? then | ||||
|       raise ArgumentError, "invalid options: #{invalid_options.join ', '}" | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Task description for the clobber rdoc task or its renamed equivalent | ||||
| 
 | ||||
|   def clobber_task_description | ||||
|     "Remove RDoc HTML files" | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Sets default task values | ||||
| 
 | ||||
|   def defaults | ||||
|     @name = :rdoc | ||||
|     @rdoc_files = Rake::FileList.new | ||||
|     @rdoc_dir = 'html' | ||||
|     @main = nil | ||||
|  | @ -167,14 +195,12 @@ class RDoc::Task < Rake::TaskLib | |||
|     @template = nil | ||||
|     @generator = nil | ||||
|     @options = [] | ||||
|     yield self if block_given? | ||||
|     define | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # All source is inline now.  This method is deprecated | ||||
| 
 | ||||
|   def inline_source() # :nodoc: | ||||
|   def inline_source # :nodoc: | ||||
|     warn "RDoc::Task#inline_source is deprecated" | ||||
|     true | ||||
|   end | ||||
|  | @ -190,13 +216,13 @@ class RDoc::Task < Rake::TaskLib | |||
|   # Create the tasks defined by this task lib. | ||||
| 
 | ||||
|   def define | ||||
|     desc "Build RDoc HTML files" | ||||
|     desc rdoc_task_description | ||||
|     task rdoc_task_name | ||||
| 
 | ||||
|     desc "Rebuild RDoc HTML files" | ||||
|     desc rerdoc_task_description | ||||
|     task rerdoc_task_name => [clobber_task_name, rdoc_task_name] | ||||
| 
 | ||||
|     desc "Remove RDoc HTML files" | ||||
|     desc clobber_task_description | ||||
|     task clobber_task_name do | ||||
|       rm_r @rdoc_dir rescue nil | ||||
|     end | ||||
|  | @ -215,11 +241,9 @@ class RDoc::Task < Rake::TaskLib | |||
|       @before_running_rdoc.call if @before_running_rdoc | ||||
|       args = option_list + @rdoc_files | ||||
| 
 | ||||
|       if Rake.application.options.trace then | ||||
|         $stderr.puts "rdoc #{args.join ' '}" | ||||
|       end | ||||
|       $stderr.puts "rdoc #{args.join ' '}" if Rake.application.options.trace | ||||
|       require 'rdoc/rdoc' | ||||
|       RDoc::RDoc.new.document(args) | ||||
|       RDoc::RDoc.new.document args | ||||
|     end | ||||
| 
 | ||||
|     self | ||||
|  | @ -247,6 +271,20 @@ class RDoc::Task < Rake::TaskLib | |||
|     @before_running_rdoc = block | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Task description for the rdoc task or its renamed equivalent | ||||
| 
 | ||||
|   def rdoc_task_description | ||||
|     'Build RDoc HTML files' | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Task description for the rerdoc task or its renamed description | ||||
| 
 | ||||
|   def rerdoc_task_description | ||||
|     "Rebuild RDoc HTML files" | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def rdoc_target | ||||
|  |  | |||
|  | @ -97,7 +97,8 @@ module RDoc::Text | |||
|     text = strip_hashes text | ||||
|     text = expand_tabs text | ||||
|     text = flush_left text | ||||
|     strip_newlines text | ||||
|     text = strip_newlines text | ||||
|     text | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  | @ -139,14 +140,18 @@ http://rubyforge.org/tracker/?atid=2472&group_id=627&func=browse | |||
| 
 | ||||
|   def strip_hashes text | ||||
|     return text if text =~ /^(?>\s*)[^\#]/ | ||||
|     text.gsub(/^\s*(#+)/) { $1.tr '#',' ' }.gsub(/^\s+$/, '') | ||||
| 
 | ||||
|     empty = '' | ||||
|     empty.force_encoding text.encoding if Object.const_defined? :Encoding | ||||
| 
 | ||||
|     text.gsub(/^\s*(#+)/) { $1.tr '#', ' ' }.gsub(/^\s+$/, empty) | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|   # Strips leading and trailing \n characters from +text+ | ||||
| 
 | ||||
|   def strip_newlines text | ||||
|     text.gsub(/\A\n*(.*?)\n*\z/m, '\1') | ||||
|     text.gsub(/\A\n*(.*?)\n*\z/m) do $1 end # block preserves String encoding | ||||
|   end | ||||
| 
 | ||||
|   ## | ||||
|  |  | |||
|  | @ -34,6 +34,12 @@ method(a, b) { |c, d| ... } | |||
|     assert_equal call_seq, m.arglists | ||||
|   end | ||||
| 
 | ||||
|   def test_c_function | ||||
|     @c1_m.c_function = 'my_c1_m' | ||||
| 
 | ||||
|     assert_equal 'my_c1_m', @c1_m.c_function | ||||
|   end | ||||
| 
 | ||||
|   def test_full_name | ||||
|     assert_equal 'C1::m', @c1.method_list.first.full_name | ||||
|   end | ||||
|  | @ -97,6 +103,48 @@ method(a, b) { |c, d| ... } | |||
|     assert_nil m.name | ||||
|   end | ||||
| 
 | ||||
|   def test_param_list_block_params | ||||
|     m = RDoc::AnyMethod.new nil, 'method' | ||||
|     m.parent = @c1 | ||||
| 
 | ||||
|     m.block_params = 'c, d' | ||||
| 
 | ||||
|     assert_equal %w[c d], m.param_list | ||||
|   end | ||||
| 
 | ||||
|   def test_param_list_call_seq | ||||
|     m = RDoc::AnyMethod.new nil, 'method' | ||||
|     m.parent = @c1 | ||||
| 
 | ||||
|     call_seq = <<-SEQ | ||||
| method(a) { |c| ... } | ||||
| method(a, b) { |c, d| ... } | ||||
|     SEQ | ||||
| 
 | ||||
|     m.call_seq = call_seq | ||||
| 
 | ||||
|     assert_equal %w[a b c d], m.param_list | ||||
|   end | ||||
| 
 | ||||
|   def test_param_list_params | ||||
|     m = RDoc::AnyMethod.new nil, 'method' | ||||
|     m.parent = @c1 | ||||
| 
 | ||||
|     m.params = '(a, b)' | ||||
| 
 | ||||
|     assert_equal %w[a b], m.param_list | ||||
|   end | ||||
| 
 | ||||
|   def test_param_list_params_block_params | ||||
|     m = RDoc::AnyMethod.new nil, 'method' | ||||
|     m.parent = @c1 | ||||
| 
 | ||||
|     m.params = '(a, b)' | ||||
|     m.block_params = 'c, d' | ||||
| 
 | ||||
|     assert_equal %w[a b c d], m.param_list | ||||
|   end | ||||
| 
 | ||||
|   def test_param_seq | ||||
|     m = RDoc::AnyMethod.new nil, 'method' | ||||
|     m.parent = @c1 | ||||
|  | @ -117,6 +165,21 @@ method(a, b) { |c, d| ... } | |||
|     assert_equal '(a, b) { |c, d| ... }', m.param_seq | ||||
|   end | ||||
| 
 | ||||
|   def test_param_seq_call_seq | ||||
|     m = RDoc::AnyMethod.new nil, 'method' | ||||
|     m.parent = @c1 | ||||
| 
 | ||||
|     call_seq = <<-SEQ | ||||
| method(a) { |c| ... } | ||||
| method(a, b) { |c, d| ... } | ||||
|     SEQ | ||||
| 
 | ||||
|     m.call_seq = call_seq | ||||
| 
 | ||||
|     assert_equal '(a, b) { |c, d| }', m.param_seq | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   def test_parent_name | ||||
|     assert_equal 'C1', @c1.method_list.first.parent_name | ||||
|     assert_equal 'C1', @c1.method_list.last.parent_name | ||||
|  |  | |||
|  | @ -114,7 +114,7 @@ class TestRDocClassModule < XrefTestCase | |||
|     n1 = @xref_data.add_module RDoc::NormalClass, 'N1' | ||||
|     n1_k2 = n1.add_module RDoc::NormalClass, 'N2' | ||||
| 
 | ||||
|     n1.add_module_alias n1_k2, 'A1' | ||||
|     n1.add_module_alias n1_k2, 'A1', @xref_data | ||||
| 
 | ||||
|     n1_a1_c = n1.constants.find { |c| c.name == 'A1' } | ||||
|     refute_nil n1_a1_c | ||||
|  | @ -138,7 +138,7 @@ class TestRDocClassModule < XrefTestCase | |||
|     n1 = @xref_data.add_module RDoc::NormalModule, 'N1' | ||||
|     n1_n2 = n1.add_module RDoc::NormalModule, 'N2' | ||||
| 
 | ||||
|     n1.add_module_alias n1_n2, 'A1' | ||||
|     n1.add_module_alias n1_n2, 'A1', @xref_data | ||||
| 
 | ||||
|     n1_a1_c = n1.constants.find { |c| c.name == 'A1' } | ||||
|     refute_nil n1_a1_c | ||||
|  | @ -163,7 +163,7 @@ class TestRDocClassModule < XrefTestCase | |||
|     l1_l2 = l1.add_module RDoc::NormalModule, 'L2' | ||||
|     o1 = @xref_data.add_module RDoc::NormalModule, 'O1' | ||||
| 
 | ||||
|     o1.add_module_alias l1_l2, 'A1' | ||||
|     o1.add_module_alias l1_l2, 'A1', @xref_data | ||||
| 
 | ||||
|     o1_a1_c = o1.constants.find { |c| c.name == 'A1' } | ||||
|     refute_nil o1_a1_c | ||||
|  |  | |||
|  | @ -30,6 +30,34 @@ class TestRDocCodeObject < XrefTestCase | |||
|     assert_equal 'I am a comment', @co.comment | ||||
|   end | ||||
| 
 | ||||
|   def test_comment_equals_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     refute_equal Encoding::UTF_8, ''.encoding, 'Encoding sanity check' | ||||
| 
 | ||||
|     input = 'text' | ||||
|     input.force_encoding Encoding::UTF_8 | ||||
| 
 | ||||
|     @co.comment = input | ||||
| 
 | ||||
|     assert_equal 'text', @co.comment | ||||
|     assert_equal Encoding::UTF_8, @co.comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_comment_equals_encoding_blank | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     refute_equal Encoding::UTF_8, ''.encoding, 'Encoding sanity check' | ||||
| 
 | ||||
|     input = '' | ||||
|     input.force_encoding Encoding::UTF_8 | ||||
| 
 | ||||
|     @co.comment = input | ||||
| 
 | ||||
|     assert_equal '', @co.comment | ||||
|     assert_equal Encoding::UTF_8, @co.comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_document_children_equals | ||||
|     @co.document_children = false | ||||
|     refute @co.document_children | ||||
|  | @ -101,6 +129,12 @@ class TestRDocCodeObject < XrefTestCase | |||
|     assert_nil @co.instance_variable_get(:@full_name) | ||||
|   end | ||||
| 
 | ||||
|   def test_line | ||||
|     @c1_m.line = 5 | ||||
| 
 | ||||
|     assert_equal 5, @c1_m.line | ||||
|   end | ||||
| 
 | ||||
|   def test_metadata | ||||
|     assert_empty @co.metadata | ||||
| 
 | ||||
|  | @ -113,6 +147,12 @@ class TestRDocCodeObject < XrefTestCase | |||
|     assert_equal 'not_rdoc', @co.metadata['markup'] | ||||
|   end | ||||
| 
 | ||||
|   def test_offset | ||||
|     @c1_m.offset = 5 | ||||
| 
 | ||||
|     assert_equal 5, @c1_m.offset | ||||
|   end | ||||
| 
 | ||||
|   def test_parent_file_name | ||||
|     assert_equal '(unknown)', @co.parent_file_name | ||||
|     assert_equal 'xref_data.rb', @c1.parent_file_name | ||||
|  |  | |||
|  | @ -174,9 +174,16 @@ class TestRDocContext < XrefTestCase | |||
|   end | ||||
| 
 | ||||
|   def test_add_module_alias | ||||
|     c3_c4 = @c2.add_module_alias @c2_c3, 'C4' | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
| 
 | ||||
|     assert_equal @c2.find_module_named('C4'), c3_c4 | ||||
|     c3_c4 = @c2.add_module_alias @c2_c3, 'C4', tl | ||||
| 
 | ||||
|     c4 = @c2.find_module_named('C4') | ||||
| 
 | ||||
|     alias_constant = @c2.constants.first | ||||
| 
 | ||||
|     assert_equal c4, c3_c4 | ||||
|     assert_equal tl, alias_constant.file | ||||
|   end | ||||
| 
 | ||||
|   def test_add_module_class | ||||
|  |  | |||
|  | @ -13,5 +13,11 @@ class TestRDocNormalClass < XrefTestCase | |||
|     assert_equal [incl.name, klass], sub_klass.ancestors | ||||
|   end | ||||
| 
 | ||||
|   def test_definition | ||||
|     c = RDoc::NormalClass.new 'C' | ||||
| 
 | ||||
|     assert_equal 'class C', c.definition | ||||
|   end | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,6 +23,12 @@ class TestRDocNormalModule < XrefTestCase | |||
|     assert_equal [mod2, incl.name], mod.ancestors | ||||
|   end | ||||
| 
 | ||||
|   def test_definition | ||||
|     m = RDoc::NormalModule.new 'M' | ||||
| 
 | ||||
|     assert_equal 'module M', m.definition | ||||
|   end | ||||
| 
 | ||||
|   def test_module_eh | ||||
|     assert @mod.module? | ||||
|   end | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ class TestRDocOptions < MiniTest::Unit::TestCase | |||
|   end | ||||
| 
 | ||||
|   def test_check_files | ||||
|     skip "assumes UNIX permition model" if /mswin|mingw/ =~ RUBY_PLATFORM | ||||
|     skip "assumes UNIX permission model" if /mswin|mingw/ =~ RUBY_PLATFORM | ||||
|     out, err = capture_io do | ||||
|       Dir.mktmpdir do |dir| | ||||
|         Dir.chdir dir do | ||||
|  | @ -67,6 +67,25 @@ file 'unreadable' not readable | |||
|     assert_equal expected, @options.generator_descriptions | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_coverage | ||||
|     @options.parse %w[--dcov] | ||||
| 
 | ||||
|     assert @options.coverage_report | ||||
|     assert @options.force_update | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_coverage_no | ||||
|     @options.parse %w[--no-dcov] | ||||
| 
 | ||||
|     refute @options.coverage_report | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_coverage_level_1 | ||||
|     @options.parse %w[--dcov=1] | ||||
| 
 | ||||
|     assert_equal 1, @options.coverage_report | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_dash_p | ||||
|     out, err = capture_io do | ||||
|       @options.parse %w[-p] | ||||
|  | @ -327,16 +346,46 @@ file 'unreadable' not readable | |||
|       def self.op() @op end | ||||
|     end | ||||
| 
 | ||||
|     RDoc::RDoc::GENERATORS['TestGenerator'] = test_generator | ||||
|     RDoc::RDoc::GENERATORS['test'] = test_generator | ||||
| 
 | ||||
|     @options.setup_generator 'TestGenerator' | ||||
|     @options.setup_generator 'test' | ||||
| 
 | ||||
|     assert_equal test_generator, @options.generator | ||||
|     assert_equal [test_generator], @options.generator_options | ||||
| 
 | ||||
|     assert_equal @options, test_generator.op | ||||
|   ensure | ||||
|     RDoc::RDoc::GENERATORS.delete 'TestGenerator' | ||||
|     RDoc::RDoc::GENERATORS.delete 'test' | ||||
|   end | ||||
| 
 | ||||
|   def test_setup_generator_no_option_parser | ||||
|     test_generator = Class.new do | ||||
|       def self.setup_options op | ||||
|         op.option_parser.separator nil | ||||
|         @op = op | ||||
|       end | ||||
| 
 | ||||
|       def self.op() @op end | ||||
|     end | ||||
| 
 | ||||
|     RDoc::RDoc::GENERATORS['test'] = test_generator | ||||
| 
 | ||||
|     @options.setup_generator 'test' | ||||
| 
 | ||||
|     assert_equal test_generator, @options.generator | ||||
|     assert_equal [test_generator], @options.generator_options | ||||
| 
 | ||||
|     assert_equal @options, test_generator.op | ||||
|   ensure | ||||
|     RDoc::RDoc::GENERATORS.delete 'test' | ||||
|   end | ||||
| 
 | ||||
|   def test_update_output_dir | ||||
|     assert @options.update_output_dir | ||||
| 
 | ||||
|     @options.update_output_dir = false | ||||
| 
 | ||||
|     refute @options.update_output_dir | ||||
|   end | ||||
| 
 | ||||
| end | ||||
|  |  | |||
|  | @ -101,6 +101,7 @@ void Init_Blah(void) { | |||
|     assert_equal 'accessor',            accessor.name | ||||
|     assert_equal 'RW',                  accessor.rw | ||||
|     assert_equal 'This is an accessor', accessor.comment | ||||
|     assert_equal @top_level,            accessor.file | ||||
| 
 | ||||
|     reader = attrs.shift | ||||
|     assert_equal 'reader',           reader.name | ||||
|  | @ -134,6 +135,7 @@ void Init_Blah(void) { | |||
|     assert_equal 'accessor',            accessor.name | ||||
|     assert_equal 'RW',                  accessor.rw | ||||
|     assert_equal 'This is an accessor', accessor.comment | ||||
|     assert_equal @top_level,            accessor.file | ||||
|   end | ||||
| 
 | ||||
|   def test_do_aliases | ||||
|  | @ -159,6 +161,9 @@ void Init_Blah(void) { | |||
|     assert_equal 2,      methods.length | ||||
|     assert_equal 'bleh', methods.last.name | ||||
|     assert_equal 'blah', methods.last.is_alias_for.name | ||||
| 
 | ||||
|     assert_equal @top_level, methods.last.is_alias_for.file | ||||
|     assert_equal @top_level, methods.last.file | ||||
|   end | ||||
| 
 | ||||
|   def test_do_aliases_singleton | ||||
|  | @ -339,6 +344,8 @@ void Init_foo(){ | |||
|     constants = klass.constants | ||||
|     assert !klass.constants.empty? | ||||
| 
 | ||||
|     assert_equal @top_level, constants.first.file | ||||
| 
 | ||||
|     constants = constants.map { |c| [c.name, c.value, c.comment] } | ||||
| 
 | ||||
|     assert_equal ['PERFECT', '300', 'The highest possible score in bowling   '], | ||||
|  | @ -529,7 +536,7 @@ Init_Foo(void) { | |||
| 
 | ||||
|     code = other_function.token_stream.first.text | ||||
| 
 | ||||
|     assert_equal "VALUE\nother_function() ", code | ||||
|     assert_equal "VALUE\nother_function() {\n}", code | ||||
|   end | ||||
| 
 | ||||
|   def test_find_body_2 | ||||
|  | @ -574,6 +581,41 @@ init_gi_repository (void) | |||
| 
 | ||||
|   def test_find_body_define | ||||
|     content = <<-EOF | ||||
| #define something something_else | ||||
| 
 | ||||
| #define other_function rb_other_function | ||||
| 
 | ||||
| /* | ||||
|  * a comment for rb_other_function | ||||
|  */ | ||||
| VALUE | ||||
| rb_other_function() { | ||||
| } | ||||
| 
 | ||||
| void | ||||
| Init_Foo(void) { | ||||
|     VALUE foo = rb_define_class("Foo", rb_cObject); | ||||
| 
 | ||||
|     rb_define_method(foo, "my_method", other_function, 0); | ||||
| } | ||||
|     EOF | ||||
| 
 | ||||
|     klass = util_get_class content, 'foo' | ||||
|     other_function = klass.method_list.first | ||||
| 
 | ||||
|     assert_equal 'my_method', other_function.name | ||||
|     assert_equal 'a comment for rb_other_function', other_function.comment | ||||
|     assert_equal '()', other_function.params | ||||
|     assert_equal 118, other_function.offset | ||||
|     assert_equal 8, other_function.line | ||||
| 
 | ||||
|     code = other_function.token_stream.first.text | ||||
| 
 | ||||
|     assert_equal "VALUE\nrb_other_function() {\n}", code | ||||
|   end | ||||
| 
 | ||||
|   def test_find_body_define_comment | ||||
|     content = <<-EOF | ||||
| /* | ||||
|  * a comment for other_function | ||||
|  */ | ||||
|  | @ -596,9 +638,10 @@ Init_Foo(void) { | |||
|     other_function = klass.method_list.first | ||||
| 
 | ||||
|     assert_equal 'my_method', other_function.name | ||||
|     assert_equal "a comment for other_function", | ||||
|                  other_function.comment | ||||
|     assert_equal 'a comment for other_function', other_function.comment | ||||
|     assert_equal '()', other_function.params | ||||
|     assert_equal 39, other_function.offset | ||||
|     assert_equal 4, other_function.line | ||||
| 
 | ||||
|     code = other_function.token_stream.first.text | ||||
| 
 | ||||
|  | @ -742,7 +785,51 @@ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9] | |||
|     assert_equal expected, comment | ||||
|   end | ||||
| 
 | ||||
|   def test_handle_method | ||||
|   def test_handle_method_args_minus_1 | ||||
|     parser = util_parser "Document-method: Object#m\n blah */" | ||||
| 
 | ||||
|     parser.content = <<-BODY | ||||
| VALUE | ||||
| rb_other(VALUE obj) { | ||||
|   rb_funcall(obj, rb_intern("other"), 0); | ||||
|   return rb_str_new2("blah, blah, blah"); | ||||
| } | ||||
| 
 | ||||
| VALUE | ||||
| rb_m(int argc, VALUE *argv, VALUE obj) { | ||||
|   VALUE o1, o2; | ||||
|   rb_scan_args(argc, argv, "1", &o1, &o2); | ||||
| } | ||||
|     BODY | ||||
| 
 | ||||
|     parser.handle_method 'method', 'rb_cObject', 'm', 'rb_m', -1 | ||||
| 
 | ||||
|     m = @top_level.find_module_named('Object').method_list.first | ||||
| 
 | ||||
|     assert_equal 'm', m.name | ||||
|     assert_equal @top_level, m.file | ||||
|     assert_equal 115, m.offset | ||||
|     assert_equal 7, m.line | ||||
| 
 | ||||
|     assert_equal '(p1)', m.params | ||||
|   end | ||||
| 
 | ||||
| 
 | ||||
|   def test_handle_method_args_0 | ||||
|     parser = util_parser "Document-method: BasicObject#==\n blah */" | ||||
| 
 | ||||
|     parser.handle_method 'method', 'rb_cBasicObject', '==', 'rb_obj_equal', 0 | ||||
| 
 | ||||
|     bo = @top_level.find_module_named 'BasicObject' | ||||
| 
 | ||||
|     assert_equal 1, bo.method_list.length | ||||
| 
 | ||||
|     equals2 = bo.method_list.first | ||||
| 
 | ||||
|     assert_equal '()', equals2.params | ||||
|   end | ||||
| 
 | ||||
|   def test_handle_method_args_1 | ||||
|     parser = util_parser "Document-method: BasicObject#==\n blah */" | ||||
| 
 | ||||
|     parser.handle_method 'method', 'rb_cBasicObject', '==', 'rb_obj_equal', 1 | ||||
|  | @ -753,7 +840,37 @@ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9] | |||
| 
 | ||||
|     equals2 = bo.method_list.first | ||||
| 
 | ||||
|     assert_equal '==', equals2.name | ||||
|     assert_equal '(p1)', equals2.params | ||||
|   end | ||||
| 
 | ||||
|   def test_handle_method_args_2 | ||||
|     parser = util_parser "Document-method: BasicObject#==\n blah */" | ||||
| 
 | ||||
|     parser.handle_method 'method', 'rb_cBasicObject', '==', 'rb_obj_equal', 2 | ||||
| 
 | ||||
|     bo = @top_level.find_module_named 'BasicObject' | ||||
| 
 | ||||
|     assert_equal 1, bo.method_list.length | ||||
| 
 | ||||
|     equals2 = bo.method_list.first | ||||
| 
 | ||||
|     assert_equal '(p1, p2)', equals2.params | ||||
|   end | ||||
| 
 | ||||
|   # test_handle_args_minus_1 handled by test_handle_method | ||||
| 
 | ||||
|   def test_handle_method_args_minus_2 | ||||
|     parser = util_parser "Document-method: BasicObject#==\n blah */" | ||||
| 
 | ||||
|     parser.handle_method 'method', 'rb_cBasicObject', '==', 'rb_obj_equal', -2 | ||||
| 
 | ||||
|     bo = @top_level.find_module_named 'BasicObject' | ||||
| 
 | ||||
|     assert_equal 1, bo.method_list.length | ||||
| 
 | ||||
|     equals2 = bo.method_list.first | ||||
| 
 | ||||
|     assert_equal '(*args)', equals2.params | ||||
|   end | ||||
| 
 | ||||
|   def test_handle_method_initialize | ||||
|  | @ -808,6 +925,7 @@ Init_IO(void) { | |||
|     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 | ||||
| 
 | ||||
|  | @ -898,6 +1016,65 @@ Init_IO(void) { | |||
|     assert read_method.singleton | ||||
|   end | ||||
| 
 | ||||
|   def test_rb_scan_args | ||||
|     parser = util_parser '' | ||||
| 
 | ||||
|     assert_equal '(p1)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "1",)') | ||||
|     assert_equal '(p1, p2)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "2",)') | ||||
| 
 | ||||
|     assert_equal '(p1 = v1)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "01",)') | ||||
|     assert_equal '(p1 = v1, p2 = v2)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "02",)') | ||||
| 
 | ||||
|     assert_equal '(p1, p2 = v2)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "11",)') | ||||
| 
 | ||||
|     assert_equal '(p1, *args)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "1*",)') | ||||
|     assert_equal '(p1, p2 = {})', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "1:",)') | ||||
|     assert_equal '(p1, &block)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "1&",)') | ||||
| 
 | ||||
|     assert_equal '(p1, p2)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "101",)') | ||||
| 
 | ||||
|     assert_equal '(p1, p2 = v2, p3)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "111",)') | ||||
| 
 | ||||
|     assert_equal '(p1, *args, p3)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "1*1",)') | ||||
| 
 | ||||
|     assert_equal '(p1, p2 = v2, *args)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "11*",)') | ||||
|     assert_equal '(p1, p2 = v2, p3 = {})', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "11:",)') | ||||
|     assert_equal '(p1, p2 = v2, &block)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "11&",)') | ||||
| 
 | ||||
|     assert_equal '(p1, p2 = v2, *args, p4, p5 = {}, &block)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "11*1:&",)') | ||||
| 
 | ||||
|     # The following aren't valid according to spec but are according to the | ||||
|     # implementation. | ||||
|     assert_equal '(*args)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "*",)') | ||||
|     assert_equal '(p1 = {})', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, ":",)') | ||||
|     assert_equal '(&block)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "&",)') | ||||
| 
 | ||||
|     assert_equal '(*args, p2 = {})', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "*:",)') | ||||
|     assert_equal '(p1 = {}, &block)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, ":&",)') | ||||
|     assert_equal '(*args, p2 = {}, &block)', | ||||
|                  parser.rb_scan_args('rb_scan_args(a, b, "*:&",)') | ||||
|   end | ||||
| 
 | ||||
|   def util_get_class(content, name) | ||||
|     @parser = util_parser content | ||||
|     @parser.scan | ||||
|  |  | |||
|  | @ -32,6 +32,36 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     @tempfile2.close | ||||
|   end | ||||
| 
 | ||||
|   def test_collect_first_comment | ||||
|     p = util_parser <<-CONTENT | ||||
| # first | ||||
| 
 | ||||
| # second | ||||
| class C; end | ||||
|     CONTENT | ||||
| 
 | ||||
|     comment = p.collect_first_comment | ||||
| 
 | ||||
|     assert_equal "# first\n", comment | ||||
|   end | ||||
| 
 | ||||
|   def test_collect_first_comment_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     @options.encoding = Encoding::CP852 | ||||
| 
 | ||||
|     p = util_parser <<-CONTENT | ||||
| # first | ||||
| 
 | ||||
| # second | ||||
| class C; end | ||||
|     CONTENT | ||||
| 
 | ||||
|     comment = p.collect_first_comment | ||||
| 
 | ||||
|     assert_equal Encoding::CP852, comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_extract_call_seq | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     p = util_parser '' | ||||
|  | @ -156,6 +186,42 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     assert_equal expected, comment | ||||
|   end | ||||
| 
 | ||||
|   def test_remove_private_comments_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     util_parser '' | ||||
| 
 | ||||
|     comment = <<-EOS | ||||
| # This is text | ||||
| #-- | ||||
| # this is private | ||||
|     EOS | ||||
|     comment.force_encoding Encoding::IBM437 | ||||
| 
 | ||||
|     @parser.remove_private_comments comment | ||||
| 
 | ||||
|     assert_equal Encoding::IBM437, comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_remove_private_comments_long | ||||
|     util_parser '' | ||||
| 
 | ||||
|     comment = <<-EOS | ||||
| #----- | ||||
| #++ | ||||
| # this is text | ||||
| #----- | ||||
|     EOS | ||||
| 
 | ||||
|     expected = <<-EOS | ||||
| # this is text | ||||
|     EOS | ||||
| 
 | ||||
|     @parser.remove_private_comments(comment) | ||||
| 
 | ||||
|     assert_equal expected, comment | ||||
|   end | ||||
| 
 | ||||
|   def test_remove_private_comments_rule | ||||
|     util_parser '' | ||||
| 
 | ||||
|  | @ -193,6 +259,45 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     assert_equal expected, comment | ||||
|   end | ||||
| 
 | ||||
|   def test_remove_private_comments_toggle_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     util_parser '' | ||||
| 
 | ||||
|     comment = <<-EOS | ||||
| # This is text | ||||
| #-- | ||||
| # this is private | ||||
| #++ | ||||
| # This is text again. | ||||
|     EOS | ||||
| 
 | ||||
|     comment.force_encoding Encoding::IBM437 | ||||
| 
 | ||||
|     @parser.remove_private_comments comment | ||||
| 
 | ||||
|     assert_equal Encoding::IBM437, comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_remove_private_comments_toggle_encoding_ruby_bug? | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     util_parser '' | ||||
| 
 | ||||
|     comment = <<-EOS | ||||
| #-- | ||||
| # this is private | ||||
| #++ | ||||
| # This is text again. | ||||
|     EOS | ||||
| 
 | ||||
|     comment.force_encoding Encoding::IBM437 | ||||
| 
 | ||||
|     @parser.remove_private_comments comment | ||||
| 
 | ||||
|     assert_equal Encoding::IBM437, comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_look_for_directives_in_commented | ||||
|     util_parser "" | ||||
| 
 | ||||
|  | @ -310,6 +415,8 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     assert_equal klass,      alas.parent | ||||
|     assert_equal 'comment',  alas.comment | ||||
|     assert_equal @top_level, alas.file | ||||
|     assert_equal 0,          alas.offset | ||||
|     assert_equal 1,          alas.line | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_alias_singleton | ||||
|  | @ -361,6 +468,8 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     assert_equal 'foo', foo.name | ||||
|     assert_equal 'my attr', foo.comment | ||||
|     assert_equal @top_level, foo.file | ||||
|     assert_equal 0, foo.offset | ||||
|     assert_equal 1, foo.line | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_attr_accessor | ||||
|  | @ -382,6 +491,8 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     assert_equal 'RW', foo.rw | ||||
|     assert_equal 'my attr', foo.comment | ||||
|     assert_equal @top_level, foo.file | ||||
|     assert_equal 0, foo.offset | ||||
|     assert_equal 1, foo.line | ||||
| 
 | ||||
|     bar = klass.attributes.last | ||||
|     assert_equal 'bar', bar.name | ||||
|  | @ -540,6 +651,9 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase | |||
|     foo = @top_level.classes.first | ||||
|     assert_equal 'Foo', foo.full_name | ||||
|     assert_equal 'my method', foo.comment | ||||
|     assert_equal [@top_level], foo.in_files | ||||
|     assert_equal 0, foo.offset | ||||
|     assert_equal 1, foo.line | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_class_ghost_method | ||||
|  | @ -592,6 +706,57 @@ end | |||
|     assert_equal 2, foo.method_list.length | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_multi_ghost_methods | ||||
|     util_parser <<-'CLASS' | ||||
| class Foo | ||||
|   ## | ||||
|   # :method: one | ||||
|   # | ||||
|   # my method | ||||
| 
 | ||||
|   ## | ||||
|   # :method: two | ||||
|   # | ||||
|   # my method | ||||
| 
 | ||||
|   [:one, :two].each do |t| | ||||
|     eval("def #{t}; \"#{t}\"; end") | ||||
|   end | ||||
| end | ||||
|     CLASS | ||||
| 
 | ||||
|     tk = @parser.get_tk | ||||
| 
 | ||||
|     @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, '' | ||||
| 
 | ||||
|     foo = @top_level.classes.first | ||||
|     assert_equal 'Foo', foo.full_name | ||||
| 
 | ||||
|     assert_equal 2, foo.method_list.length | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_const_fail_w_meta | ||||
|     util_parser <<-CLASS | ||||
| class ConstFailMeta | ||||
|   ## | ||||
|   # :attr: one | ||||
|   # | ||||
|   # an attribute | ||||
| 
 | ||||
|   OtherModule.define_attr(self, :one) | ||||
| end | ||||
|     CLASS | ||||
| 
 | ||||
|     tk = @parser.get_tk | ||||
| 
 | ||||
|     @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, '' | ||||
| 
 | ||||
|     const_fail_meta = @top_level.classes.first | ||||
|     assert_equal 'ConstFailMeta', const_fail_meta.full_name | ||||
| 
 | ||||
|     assert_equal 1, const_fail_meta.attributes.length | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_class_nested_superclass | ||||
|     util_top_level | ||||
|     foo = @top_level.add_module RDoc::NormalModule, 'Foo' | ||||
|  | @ -654,6 +819,10 @@ end | |||
|     assert_equal %w[A],    RDoc::TopLevel.classes.map { |c| c.full_name } | ||||
|     assert_equal %w[A::B A::d], RDoc::TopLevel.modules.map { |c| c.full_name } | ||||
| 
 | ||||
|     b = RDoc::TopLevel.modules.first | ||||
|     assert_equal 10, b.offset | ||||
|     assert_equal 2,  b.line | ||||
| 
 | ||||
|     # make sure method/alias was not added to enclosing class/module | ||||
|     a = RDoc::TopLevel.all_classes_hash['A'] | ||||
|     assert_empty a.method_list | ||||
|  | @ -792,6 +961,8 @@ EOF | |||
|     assert_equal 'RW',       foo.rw | ||||
|     assert_equal 'my attr',  foo.comment | ||||
|     assert_equal @top_level, foo.file | ||||
|     assert_equal 0,          foo.offset | ||||
|     assert_equal 1,          foo.line | ||||
| 
 | ||||
|     assert_equal nil,        foo.viewer | ||||
|     assert_equal true,       foo.document_children | ||||
|  | @ -821,6 +992,8 @@ EOF | |||
|     assert_equal 'foo',       foo.name | ||||
|     assert_equal 'my method', foo.comment | ||||
|     assert_equal @top_level,  foo.file | ||||
|     assert_equal 0,           foo.offset | ||||
|     assert_equal 1,           foo.line | ||||
| 
 | ||||
|     assert_equal [],        foo.aliases | ||||
|     assert_equal nil,       foo.block_params | ||||
|  | @ -848,6 +1021,25 @@ EOF | |||
|     assert_equal stream, foo.token_stream | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_constant | ||||
|     util_top_level | ||||
| 
 | ||||
|     klass = @top_level.add_class RDoc::NormalClass, 'Foo' | ||||
| 
 | ||||
|     util_parser "A = v" | ||||
| 
 | ||||
|     tk = @parser.get_tk | ||||
| 
 | ||||
|     @parser.parse_constant klass, tk, '' | ||||
| 
 | ||||
|     foo = klass.constants.first | ||||
| 
 | ||||
|     assert_equal 'A', foo.name | ||||
|     assert_equal @top_level, foo.file | ||||
|     assert_equal 0, foo.offset | ||||
|     assert_equal 1, foo.line | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_constant_attrasgn | ||||
|     util_top_level | ||||
| 
 | ||||
|  | @ -908,6 +1100,8 @@ EOF | |||
|     assert_equal 'foo',       foo.name | ||||
|     assert_equal 'my method', foo.comment | ||||
|     assert_equal @top_level,  foo.file | ||||
|     assert_equal 0,           foo.offset | ||||
|     assert_equal 1,           foo.line | ||||
| 
 | ||||
|     assert_equal [],      foo.aliases | ||||
|     assert_equal nil,     foo.block_params | ||||
|  | @ -942,6 +1136,27 @@ EOF | |||
|     assert_equal stream, foo.token_stream | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_meta_method_block | ||||
|     klass = RDoc::NormalClass.new 'Foo' | ||||
|     klass.parent = @top_level | ||||
| 
 | ||||
|     comment = "##\n# my method\n" | ||||
| 
 | ||||
|     content = <<-CONTENT | ||||
| inline(:my_method) do |*args| | ||||
|   "this method causes z to disappear" | ||||
| end | ||||
|     CONTENT | ||||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     tk = @parser.get_tk | ||||
| 
 | ||||
|     @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment | ||||
| 
 | ||||
|     assert_nil @parser.get_tk | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_meta_method_name | ||||
|     klass = RDoc::NormalClass.new 'Foo' | ||||
|     klass.parent = @top_level | ||||
|  | @ -1046,6 +1261,8 @@ EOF | |||
|     assert_equal 'foo',       foo.name | ||||
|     assert_equal 'my method', foo.comment | ||||
|     assert_equal @top_level,  foo.file | ||||
|     assert_equal 0,           foo.offset | ||||
|     assert_equal 1,           foo.line | ||||
| 
 | ||||
|     assert_equal [],        foo.aliases | ||||
|     assert_equal nil,       foo.block_params | ||||
|  | @ -1327,6 +1544,28 @@ end | |||
|     assert_equal 'my method', bar.comment | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_statements_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
|     @options.encoding = Encoding::CP852 | ||||
| 
 | ||||
|     content = <<-EOF | ||||
| class Foo | ||||
|   ## | ||||
|   # this is my method | ||||
|   add_my_method :foo | ||||
| end | ||||
|     EOF | ||||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.method_list.first | ||||
|     assert_equal 'foo', foo.name | ||||
|     assert_equal 'this is my method', foo.comment | ||||
|     assert_equal Encoding::CP852, foo.comment.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_parse_statements_identifier_meta_method | ||||
|     content = <<-EOF | ||||
| class Foo | ||||
|  | @ -1338,7 +1577,7 @@ end | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.method_list.first | ||||
|     assert_equal 'foo', foo.name | ||||
|  | @ -1354,7 +1593,7 @@ end | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.method_list[0] | ||||
|     assert_equal 'foo', foo.name | ||||
|  | @ -1387,7 +1626,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.method_list[0] | ||||
|     assert_equal 'foo', foo.name | ||||
|  | @ -1453,7 +1692,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     constants = @top_level.classes.first.constants | ||||
| 
 | ||||
|  | @ -1500,7 +1739,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.attributes.first | ||||
|     assert_equal 'foo', foo.name | ||||
|  | @ -1512,7 +1751,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.attributes.first | ||||
|     assert_equal 'foo', foo.name | ||||
|  | @ -1524,7 +1763,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first | ||||
|     assert_equal 'Foo', foo.name | ||||
|  | @ -1536,7 +1775,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo, s_foo = @top_level.modules.first.method_list | ||||
|     assert_equal 'foo',    foo.name,       'instance method name' | ||||
|  | @ -1553,7 +1792,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.classes.first.method_list.first | ||||
|     assert_equal 'foo', foo.name | ||||
|  | @ -1565,7 +1804,7 @@ EOF | |||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     assert_equal 1, @top_level.requires.length | ||||
|   end | ||||
|  | @ -1583,7 +1822,7 @@ class A | |||
| end | ||||
|     RUBY | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     c_a = @top_level.classes.first | ||||
|     assert_equal 'A', c_a.full_name | ||||
|  | @ -1691,8 +1930,77 @@ end | |||
|     while @parser.get_tk do end | ||||
|   end | ||||
| 
 | ||||
|   def test_stopdoc_after_comment | ||||
|   def test_scan_cr | ||||
|     content = <<-CONTENT | ||||
| class C\r | ||||
|   def m\r | ||||
|     a=\\\r | ||||
|       123\r | ||||
|   end\r | ||||
| end\r | ||||
|     CONTENT | ||||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.scan | ||||
| 
 | ||||
|     c = @top_level.classes.first | ||||
| 
 | ||||
|     assert_equal 1, c.method_list.length | ||||
|   end | ||||
| 
 | ||||
|   def test_scan_block_comment | ||||
|     content = <<-CONTENT | ||||
| =begin rdoc | ||||
| Foo comment | ||||
| =end | ||||
| 
 | ||||
| class Foo | ||||
| 
 | ||||
| =begin | ||||
| m comment | ||||
| =end | ||||
| 
 | ||||
|   def m() end | ||||
| end | ||||
|     CONTENT | ||||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.scan | ||||
| 
 | ||||
|     foo = @top_level.classes.first | ||||
| 
 | ||||
|     assert_equal 'Foo comment', foo.comment | ||||
| 
 | ||||
|     m = foo.method_list.first | ||||
| 
 | ||||
|     assert_equal 'm comment', m.comment | ||||
|   end | ||||
| 
 | ||||
|   def test_scan_meta_method_block | ||||
|     content = <<-CONTENT | ||||
| class C | ||||
| 
 | ||||
|   ## | ||||
|   #  my method | ||||
| 
 | ||||
|   inline(:my_method) do |*args| | ||||
|     "this method used to cause z to disappear" | ||||
|   end | ||||
| 
 | ||||
|   def z | ||||
|   end | ||||
|     CONTENT | ||||
| 
 | ||||
|     util_parser content | ||||
| 
 | ||||
|     @parser.scan | ||||
| 
 | ||||
|     assert_equal 2, @top_level.classes.first.method_list.length | ||||
|   end | ||||
| 
 | ||||
|   def test_stopdoc_after_comment | ||||
|     util_parser <<-EOS | ||||
|       module Bar | ||||
|         # hello | ||||
|  | @ -1706,7 +2014,7 @@ end | |||
|       end | ||||
|     EOS | ||||
| 
 | ||||
|     @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, '' | ||||
|     @parser.parse_statements @top_level | ||||
| 
 | ||||
|     foo = @top_level.modules.first.modules.first | ||||
|     assert_equal 'Foo', foo.name | ||||
|  |  | |||
|  | @ -9,6 +9,8 @@ require 'tmpdir' | |||
| class TestRDocRDoc < MiniTest::Unit::TestCase | ||||
| 
 | ||||
|   def setup | ||||
|     RDoc::TopLevel.reset | ||||
| 
 | ||||
|     @rdoc = RDoc::RDoc.new | ||||
|     @rdoc.options = RDoc::Options.new | ||||
| 
 | ||||
|  | @ -45,7 +47,7 @@ class TestRDocRDoc < MiniTest::Unit::TestCase | |||
|     assert_empty files | ||||
|   end | ||||
| 
 | ||||
|   def test_remove_unparsable | ||||
|   def test_remove_unparseable | ||||
|     file_list = %w[ | ||||
|       blah.class | ||||
|       blah.eps | ||||
|  | @ -62,13 +64,14 @@ class TestRDocRDoc < MiniTest::Unit::TestCase | |||
|     skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir | ||||
| 
 | ||||
|     Dir.mktmpdir {|d| | ||||
|       path = File.join(d, 'testdir') | ||||
|       path = File.join d, 'testdir' | ||||
| 
 | ||||
|       last = @rdoc.setup_output_dir path, false | ||||
| 
 | ||||
|       assert_empty last | ||||
| 
 | ||||
|       assert File.directory? path | ||||
|       assert File.exist? @rdoc.output_flag_file path | ||||
|     } | ||||
|   end | ||||
| 
 | ||||
|  | @ -149,6 +152,17 @@ class TestRDocRDoc < MiniTest::Unit::TestCase | |||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def test_update_output_dir_dont | ||||
|     skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir | ||||
| 
 | ||||
|     Dir.mktmpdir do |d| | ||||
|       @rdoc.options.update_output_dir = false | ||||
|       @rdoc.update_output_dir d, Time.now, {} | ||||
| 
 | ||||
|       refute File.exist? "#{d}/created.rid" | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def test_update_output_dir_dry_run | ||||
|     skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir | ||||
| 
 | ||||
|  |  | |||
|  | @ -390,6 +390,16 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase | |||
|     assert_match %r%^=== Implementation from Foo%, out | ||||
|   end | ||||
| 
 | ||||
|   def test_display_method_overriden | ||||
|     util_multi_store | ||||
| 
 | ||||
|     out, = capture_io do | ||||
|       @driver.display_method 'Bar#override' | ||||
|     end | ||||
| 
 | ||||
|     refute_match %r%must not be displayed%, out | ||||
|   end | ||||
| 
 | ||||
|   def test_display_name_not_found_class | ||||
|     util_store | ||||
| 
 | ||||
|  | @ -495,6 +505,32 @@ Foo::Bar#bother | |||
|     assert_equal expected, items | ||||
|   end | ||||
| 
 | ||||
|   def test_filter_methods | ||||
|     util_multi_store | ||||
| 
 | ||||
|     name = 'Bar#override' | ||||
| 
 | ||||
|     found = @driver.load_methods_matching name | ||||
| 
 | ||||
|     sorted = @driver.filter_methods found, name | ||||
| 
 | ||||
|     expected = [[@store2, [@override]]] | ||||
| 
 | ||||
|     assert_equal expected, sorted | ||||
|   end | ||||
| 
 | ||||
|   def test_filter_methods_not_found | ||||
|     util_multi_store | ||||
| 
 | ||||
|     name = 'Bar#inherit' | ||||
| 
 | ||||
|     found = @driver.load_methods_matching name | ||||
| 
 | ||||
|     sorted = @driver.filter_methods found, name | ||||
| 
 | ||||
|     assert_equal found, sorted | ||||
|   end | ||||
| 
 | ||||
|   def test_formatter | ||||
|     tty = Object.new | ||||
|     def tty.tty?() true; end | ||||
|  | @ -533,6 +569,16 @@ Foo::Bar#bother | |||
|     assert_equal :class,    @driver.method_type('::') | ||||
|   end | ||||
| 
 | ||||
|   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') | ||||
|   end | ||||
| 
 | ||||
|   def test_list_known_classes | ||||
|     util_store | ||||
| 
 | ||||
|  | @ -766,6 +812,7 @@ Foo::Bar#bother | |||
|     @mAmbiguous = RDoc::NormalModule.new 'Ambiguous' | ||||
| 
 | ||||
|     @cFoo = RDoc::NormalClass.new 'Foo' | ||||
| 
 | ||||
|     @cBar = RDoc::NormalClass.new 'Bar' | ||||
|     @cBar.superclass = 'Foo' | ||||
|     @cFoo_Baz = RDoc::NormalClass.new 'Baz' | ||||
|  | @ -774,10 +821,15 @@ Foo::Bar#bother | |||
|     @baz = RDoc::AnyMethod.new nil, 'baz' | ||||
|     @cBar.add_method @baz | ||||
| 
 | ||||
|     @override = RDoc::AnyMethod.new nil, 'override' | ||||
|     @override.comment = 'must be displayed' | ||||
|     @cBar.add_method @override | ||||
| 
 | ||||
|     @store2.save_class @mAmbiguous | ||||
|     @store2.save_class @cBar | ||||
|     @store2.save_class @cFoo_Baz | ||||
| 
 | ||||
|     @store2.save_method @cBar, @override | ||||
|     @store2.save_method @cBar, @baz | ||||
| 
 | ||||
|     @store2.save_cache | ||||
|  | @ -824,6 +876,11 @@ Foo::Bar#bother | |||
|     @inherit = RDoc::AnyMethod.new nil, 'inherit' | ||||
|     @cFoo.add_method @inherit | ||||
| 
 | ||||
|     # overriden by Bar in multi_store | ||||
|     @overriden = RDoc::AnyMethod.new nil, 'override' | ||||
|     @overriden.comment = 'must not be displayed' | ||||
|     @cFoo.add_method @overriden | ||||
| 
 | ||||
|     @store.save_class @cFoo | ||||
|     @store.save_class @cFoo_Bar | ||||
|     @store.save_class @cFoo_Baz | ||||
|  | @ -836,6 +893,7 @@ Foo::Bar#bother | |||
|     @store.save_method @cFoo_Bar, @attr | ||||
| 
 | ||||
|     @store.save_method @cFoo, @inherit | ||||
|     @store.save_method @cFoo, @overriden | ||||
| 
 | ||||
|     @store.save_cache | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,8 +13,78 @@ class TestRDocStats < MiniTest::Unit::TestCase | |||
|     @s = RDoc::Stats.new 0 | ||||
|   end | ||||
| 
 | ||||
|   def test_report_attr | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     a = RDoc::Attr.new nil, 'a', 'RW', nil | ||||
|     a.record_location tl | ||||
|     c.add_attribute a | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| class C # is documented | ||||
| 
 | ||||
|   attr_accessor :a # in file file.rb | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_attr_documented | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     a = RDoc::Attr.new nil, 'a', 'RW', 'a' | ||||
|     a.record_location tl | ||||
|     c.add_attribute a | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     assert_equal @s.great_job, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_constant | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     m = tl.add_module RDoc::NormalModule, 'M' | ||||
|     m.record_location tl | ||||
|     m.comment = 'M' | ||||
| 
 | ||||
|     c = RDoc::Constant.new 'C', nil, nil | ||||
|     c.record_location tl | ||||
|     m.add_constant c | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| module M # is documented | ||||
| 
 | ||||
|   # in file file.rb | ||||
|   C = nil | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_constant_alias | ||||
|     tl = RDoc::TopLevel.new 'fake.rb' | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     mod = tl.add_module RDoc::NormalModule, 'M' | ||||
| 
 | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|  | @ -34,5 +104,440 @@ class TestRDocStats < MiniTest::Unit::TestCase | |||
|     assert_match(/class Object/, report) | ||||
|   end | ||||
| 
 | ||||
|   def test_report_constant_documented | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     m = tl.add_module RDoc::NormalModule, 'M' | ||||
|     m.record_location tl | ||||
|     m.comment = 'M' | ||||
| 
 | ||||
|     c = RDoc::Constant.new 'C', nil, 'C' | ||||
|     c.record_location tl | ||||
|     m.add_constant c | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     assert_equal @s.great_job, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_class | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     c.add_method m | ||||
|     m.comment = 'm' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| # in files: | ||||
| #   file.rb | ||||
| 
 | ||||
| class C | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_class_documented | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     c.add_method m | ||||
|     m.comment = 'm' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     assert_equal @s.great_job, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_class_documented_level_1 | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c1 = tl.add_class RDoc::NormalClass, 'C1' | ||||
|     c1.record_location tl | ||||
|     c1.comment = 'C1' | ||||
| 
 | ||||
|     m1 = RDoc::AnyMethod.new nil, 'm1' | ||||
|     m1.record_location tl | ||||
|     c1.add_method m1 | ||||
|     m1.comment = 'm1' | ||||
| 
 | ||||
|     c2 = tl.add_class RDoc::NormalClass, 'C2' | ||||
|     c2.record_location tl | ||||
| 
 | ||||
|     m2 = RDoc::AnyMethod.new nil, 'm2' | ||||
|     m2.record_location tl | ||||
|     c2.add_method m2 | ||||
|     m2.comment = 'm2' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = 1 | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| 
 | ||||
| # in files: | ||||
| #   file.rb | ||||
| 
 | ||||
| class C2 | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_class_empty | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     tl.add_class RDoc::NormalClass, 'C' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| # class C is referenced but empty. | ||||
| # | ||||
| # It probably came from another project.  I'm sorry I'm holding it against you. | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_class_empty_2 | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c1 = tl.add_class RDoc::NormalClass, 'C1' | ||||
|     c1.record_location tl | ||||
| 
 | ||||
|     c2 = tl.add_class RDoc::NormalClass, 'C2' | ||||
|     c2.record_location tl | ||||
|     c2.comment = 'C2' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = 1 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| # in files: | ||||
| #   file.rb | ||||
| 
 | ||||
| class C1 | ||||
| end | ||||
| 
 | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_class_method_documented | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     c.add_method m | ||||
|     m.comment = 'm' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| # in files: | ||||
| #   file.rb | ||||
| 
 | ||||
| class C | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_empty | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     assert_equal @s.great_job, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_method | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m1 = RDoc::AnyMethod.new nil, 'm1' | ||||
|     m1.record_location tl | ||||
|     c.add_method m1 | ||||
| 
 | ||||
|     m2 = RDoc::AnyMethod.new nil, 'm2' | ||||
|     m2.record_location tl | ||||
|     c.add_method m2 | ||||
|     m2.comment = 'm2' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| class C # is documented | ||||
| 
 | ||||
|   # in file file.rb | ||||
|   def m1; end | ||||
| 
 | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_method_documented | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     c.add_method m | ||||
|     m.comment = 'm' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     assert_equal @s.great_job, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_method_parameters | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m1 = RDoc::AnyMethod.new nil, 'm1' | ||||
|     m1.record_location tl | ||||
|     m1.params = '(p1, p2)' | ||||
|     m1.comment = 'Stuff with +p1+' | ||||
|     c.add_method m1 | ||||
| 
 | ||||
|     m2 = RDoc::AnyMethod.new nil, 'm2' | ||||
|     m2.record_location tl | ||||
|     c.add_method m2 | ||||
|     m2.comment = 'm2' | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = 1 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| class C # is documented | ||||
| 
 | ||||
|   # in file file.rb | ||||
|   # +p2+ is not documented | ||||
|   def m1(p1, p2); end | ||||
| 
 | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_method_parameters_documented | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     m.params = '(p1)' | ||||
|     m.comment = 'Stuff with +p1+' | ||||
|     c.add_method m | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = 1 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     assert_equal @s.great_job, report | ||||
|   end | ||||
| 
 | ||||
|   def test_report_method_parameters_yield | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     m.call_seq = <<-SEQ | ||||
| m(a) { |c| ... } | ||||
| m(a, b) { |c, d| ... } | ||||
|     SEQ | ||||
|     m.comment = 'Stuff with +a+, yields +c+ for you to do stuff with' | ||||
|     c.add_method m | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = 1 | ||||
|     report = @s.report | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| The following items are not documented: | ||||
| 
 | ||||
| class C # is documented | ||||
| 
 | ||||
|   # in file file.rb | ||||
|   # +b+, +d+ is not documented | ||||
|   def m; end | ||||
| 
 | ||||
| end | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, report | ||||
|   end | ||||
| 
 | ||||
|   def test_summary | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
| 
 | ||||
|     m = tl.add_module RDoc::NormalModule, 'M' | ||||
|     m.record_location tl | ||||
| 
 | ||||
|     a = RDoc::Attr.new nil, 'a', 'RW', nil | ||||
|     a.record_location tl | ||||
|     c.add_attribute a | ||||
| 
 | ||||
|     c_c = RDoc::Constant.new 'C', nil, nil | ||||
|     c_c.record_location tl | ||||
|     c.add_constant c_c | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     c.add_method m | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     summary = @s.summary | ||||
|     summary.sub!(/Elapsed:.*/, '') | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| Files:      0 | ||||
| 
 | ||||
| Classes:    1 (1 undocumented) | ||||
| Modules:    1 (1 undocumented) | ||||
| Constants:  1 (1 undocumented) | ||||
| Attributes: 1 (1 undocumented) | ||||
| Methods:    1 (1 undocumented) | ||||
| 
 | ||||
| Total:      5 (5 undocumented) | ||||
|   0.00% documented | ||||
| 
 | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal summary, expected | ||||
|   end | ||||
| 
 | ||||
|   def test_summary_level_false | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = false | ||||
| 
 | ||||
|     summary = @s.summary | ||||
|     summary.sub!(/Elapsed:.*/, '') | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| Files:      0 | ||||
| 
 | ||||
| Classes:    1 (1 undocumented) | ||||
| Modules:    0 (0 undocumented) | ||||
| Constants:  0 (0 undocumented) | ||||
| Attributes: 0 (0 undocumented) | ||||
| Methods:    0 (0 undocumented) | ||||
| 
 | ||||
| Total:      1 (1 undocumented) | ||||
|   0.00% documented | ||||
| 
 | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal summary, expected | ||||
|   end | ||||
| 
 | ||||
|   def test_summary_level_1 | ||||
|     tl = RDoc::TopLevel.new 'file.rb' | ||||
|     c = tl.add_class RDoc::NormalClass, 'C' | ||||
|     c.record_location tl | ||||
|     c.comment = 'C' | ||||
| 
 | ||||
|     m = RDoc::AnyMethod.new nil, 'm' | ||||
|     m.record_location tl | ||||
|     m.params = '(p1, p2)' | ||||
|     m.comment = 'Stuff with +p1+' | ||||
|     c.add_method m | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|     @s.coverage_level = 1 | ||||
|     @s.report | ||||
| 
 | ||||
|     summary = @s.summary | ||||
|     summary.sub!(/Elapsed:.*/, '') | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| Files:      0 | ||||
| 
 | ||||
| Classes:    1 (0 undocumented) | ||||
| Modules:    0 (0 undocumented) | ||||
| Constants:  0 (0 undocumented) | ||||
| Attributes: 0 (0 undocumented) | ||||
| Methods:    1 (0 undocumented) | ||||
| Parameters: 2 (1 undocumented) | ||||
| 
 | ||||
| Total:      4 (1 undocumented) | ||||
|  75.00% documented | ||||
| 
 | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal summary, expected | ||||
|   end | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,25 +6,29 @@ class TestRDocTask < MiniTest::Unit::TestCase | |||
| 
 | ||||
|   def setup | ||||
|     Rake::Task.clear | ||||
| 
 | ||||
|     @t = RDoc::Task.new | ||||
|   end | ||||
| 
 | ||||
|   def test_clobber_task_description | ||||
|     assert_equal 'Remove RDoc HTML files', @t.clobber_task_description | ||||
|   end | ||||
| 
 | ||||
|   def test_inline_source | ||||
|     t = RDoc::Task.new | ||||
| 
 | ||||
|     _, err = capture_io do | ||||
|       assert t.inline_source | ||||
|       assert @t.inline_source | ||||
|     end | ||||
| 
 | ||||
|     assert_equal "RDoc::Task#inline_source is deprecated\n", err | ||||
| 
 | ||||
|     _, err = capture_io do | ||||
|       t.inline_source = false | ||||
|       @t.inline_source = false | ||||
|     end | ||||
| 
 | ||||
|     assert_equal "RDoc::Task#inline_source is deprecated\n", err | ||||
| 
 | ||||
|     capture_io do | ||||
|       assert t.inline_source | ||||
|       assert @t.inline_source | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  | @ -51,6 +55,14 @@ class TestRDocTask < MiniTest::Unit::TestCase | |||
|     assert_equal %w[-o html -f ri], rdoc_task.option_list | ||||
|   end | ||||
| 
 | ||||
|   def test_rdoc_task_description | ||||
|     assert_equal 'Build RDoc HTML files', @t.rdoc_task_description | ||||
|   end | ||||
| 
 | ||||
|   def test_rerdoc_task_description | ||||
|     assert_equal 'Rebuild RDoc HTML files', @t.rerdoc_task_description | ||||
|   end | ||||
| 
 | ||||
|   def test_tasks_creation_with_custom_name_string | ||||
|     rd = RDoc::Task.new("rdoc_dev") | ||||
|     assert Rake::Task[:rdoc_dev] | ||||
|  | @ -60,7 +72,14 @@ class TestRDocTask < MiniTest::Unit::TestCase | |||
|   end | ||||
| 
 | ||||
|   def test_tasks_creation_with_custom_name_hash | ||||
|     options = { :rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", :rerdoc => "rdoc:force" } | ||||
|     options = { | ||||
|       :rdoc => "rdoc", | ||||
|       :clobber_rdoc => "rdoc:clean", | ||||
|       :rerdoc => "rdoc:force" | ||||
|     } | ||||
| 
 | ||||
|     Rake::Task.clear | ||||
| 
 | ||||
|     rd = RDoc::Task.new(options) | ||||
|     assert Rake::Task[:"rdoc"] | ||||
|     assert Rake::Task[:"rdoc:clean"] | ||||
|  |  | |||
|  | @ -134,6 +134,31 @@ The comments associated with | |||
|     assert_equal expected, strip_hashes(text) | ||||
|   end | ||||
| 
 | ||||
|   def test_strip_hashes_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     text = <<-TEXT | ||||
| ## | ||||
| # we don't worry too much. | ||||
| # | ||||
| # The comments associated with | ||||
|     TEXT | ||||
| 
 | ||||
|     text.force_encoding Encoding::CP852 | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| 
 | ||||
|   we don't worry too much. | ||||
| 
 | ||||
|   The comments associated with | ||||
|     EXPECTED | ||||
| 
 | ||||
|     stripped = strip_hashes text | ||||
| 
 | ||||
|     assert_equal expected, stripped | ||||
|     assert_equal Encoding::CP852, stripped.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_strip_newlines | ||||
|     assert_equal ' ',  strip_newlines("\n \n") | ||||
| 
 | ||||
|  | @ -144,6 +169,21 @@ The comments associated with | |||
|     assert_equal 'hi', strip_newlines("\n\nhi\n\n") | ||||
|   end | ||||
| 
 | ||||
|   def test_strip_newlines_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     assert_equal Encoding::UTF_8, ''.encoding, 'Encoding sanity check' | ||||
| 
 | ||||
|     text = " \n" | ||||
|     text.force_encoding Encoding::US_ASCII | ||||
| 
 | ||||
|     stripped = strip_newlines text | ||||
| 
 | ||||
|     assert_equal ' ', stripped | ||||
| 
 | ||||
|     assert_equal Encoding::US_ASCII, stripped.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_strip_stars | ||||
|     text = <<-TEXT | ||||
| /* | ||||
|  | @ -163,6 +203,30 @@ The comments associated with | |||
|     assert_equal expected, strip_stars(text) | ||||
|   end | ||||
| 
 | ||||
|   def test_strip_stars_encoding | ||||
|     skip "Encoding not implemented" unless Object.const_defined? :Encoding | ||||
| 
 | ||||
|     text = <<-TEXT | ||||
| /* | ||||
|  * * we don't worry too much. | ||||
|  * | ||||
|  * The comments associated with | ||||
|  */ | ||||
|     TEXT | ||||
| 
 | ||||
|     text.force_encoding Encoding::CP852 | ||||
| 
 | ||||
|     expected = <<-EXPECTED | ||||
| 
 | ||||
|    * we don't worry too much. | ||||
| 
 | ||||
|    The comments associated with | ||||
|     EXPECTED | ||||
| 
 | ||||
|     assert_equal expected, strip_stars(text) | ||||
|     assert_equal Encoding::CP852, text.encoding | ||||
|   end | ||||
| 
 | ||||
|   def test_to_html_apostrophe | ||||
|     assert_equal '‘a', to_html("'a") | ||||
|     assert_equal 'a’', to_html("a'") | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ class TestRDocTopLevel < XrefTestCase | |||
|   end | ||||
| 
 | ||||
|   def test_class_complete | ||||
|     @c2.add_module_alias @c2_c3, 'A1' | ||||
|     @c2.add_module_alias @c2_c3, 'A1', @top_level | ||||
| 
 | ||||
|     RDoc::TopLevel.complete :public | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 drbrain
						drbrain