Skip to content
Browse files

Added line and column information for misspellings

Fixed pollution of test results with private wordlists
  • Loading branch information...
1 parent 117be4d commit 5f50f07a0e33241c74d54db8db8eb1309dcf2601 @drbrain drbrain committed Apr 6, 2012
Showing with 176 additions and 62 deletions.
  1. +54 −7 lib/rdoc/generator/spellcheck.rb
  2. +122 −55 test/test_rdoc_generator_spellcheck.rb
View
61 lib/rdoc/generator/spellcheck.rb
@@ -256,9 +256,10 @@ class RDoc::Generator::Spellcheck
def self.setup_options options
default_language, = ENV['LANG'].split '.'
- options.spell_add_words = false
- options.spell_language = default_language
- options.quiet = true # suppress statistics
+ options.spell_add_words = false
+ options.spell_language = default_language
+ options.spell_source_dir = Dir.pwd
+ options.quiet = true # suppress statistics
op = options.option_parser
@@ -308,10 +309,12 @@ def self.setup_options options
def initialize options # :not-new:
@options = options
+ @encoding = @options.encoding
+ @source_dir = @options.spell_source_dir
+
@misspellings = Hash.new 0
- encoding_name = @options.encoding.name
- @spell = Aspell.new @options.spell_language, nil, nil, encoding_name
+ @spell = Aspell.new @options.spell_language, nil, nil, @encoding.name
@spell.suggestion_mode = Aspell::NORMAL
@spell.set_option 'run-together', 'true'
@@ -427,6 +430,32 @@ def generate files
end
##
+ # Determines the line and column of the misspelling in +comment+ at +offset+
+ # in the +file+.
+
+ def location_of text, offset, file
+ last_newline = text[0, offset].rindex "\n"
+ start_of_line = last_newline ? last_newline + 1 : 0
+
+ line_text = text[start_of_line..offset]
+
+ full_path = File.expand_path file.absolute_name, @source_dir
+
+ file_content = RDoc::Encoding.read_file full_path, @encoding
+
+ raise "[bug] Unable to read #{full_path}" unless file_content
+
+ file_content.each_line.with_index do |line, index|
+ if line =~ /#{Regexp.escape line_text}/ then
+ column = $`.length + line_text.length
+ return index, column
+ end
+ end
+
+ raise "[bug] Unable to find #{line_text} in #{file.absolute_name}"
+ end
+
+ ##
# Returns a report of misspellings the +comment+ at +location+ for
# documentation item +name+
@@ -444,9 +473,15 @@ def misspellings_for name, comment, location
else
out << "In #{location.full_name}:"
end
+
out << nil
- out.concat misspelled.map { |word, offset|
- suggestion_text comment.text, word, offset
+
+ out.concat misspelled.flat_map { |word, offset|
+ line, column = location_of word, offset, location
+ [
+ "#{location.absolute_name}:#{line}:#{column}",
+ suggestion_text(comment.text, word, offset),
+ ]
}
out
@@ -520,6 +555,13 @@ def suggestion_text text, word, offset
\t#{suggestions.join ', '}
TEXT
+ rescue => e
+ $stderr.puts "[bug] #{e.class}: #{e.message}"
+ $stderr.puts
+ $stderr.puts "word: #{word}"
+ $stderr.puts "offset: #{offset}"
+ $stderr.puts ">>>> start text <<<<\n#{text}\n>>>>> end text <<<<<"
+ raise
end
end
@@ -537,5 +579,10 @@ class RDoc::Options
attr_accessor :spell_language
+ ##
+ # The directory spellcheck was run from which contains all the source files.
+
+ attr_accessor :spell_source_dir
+
end
View
177 test/test_rdoc_generator_spellcheck.rb
@@ -15,16 +15,33 @@ class TestRDocGeneratorSpellcheck < RDoc::TestCase
def setup
super
- @top_level = RDoc::TopLevel.new 'funkify_thingus.rb'
- @top_level.comment = comment 'funkify_thingus'
-
@SC = RDoc::Generator::Spellcheck
@options = RDoc::Options.new
@options.spell_language = 'en_US'
@sc = @SC.new @options
@text = 'Hello, this class has real gud spelling!'
+
+ @tempfile = Tempfile.new __name__
+ @tempfile.puts "# #{@text}"
+ @tempfile.puts
+ @tempfile.puts "# funkify thingus"
+ @tempfile.flush
+
+ @escaped_path = Regexp.escape @tempfile.path
+
+ @top_level = RDoc::TopLevel.new @tempfile.path
+ @top_level.comment = comment 'funkify_thingus'
+
+ method = RDoc::AnyMethod.new nil, 'funkify_thingus'
+ @top_level.add_method method
+ end
+
+ def teardown
+ @tempfile.close
+
+ super
end
def test_add_name
@@ -44,6 +61,7 @@ def test_class_setup_options_default
refute options.spell_add_words
assert_equal 'en_US', options.spell_language
+ assert_equal Dir.pwd, options.spell_source_dir
assert options.quiet
ensure
ENV['LANG'] = orig_lang
@@ -107,23 +125,16 @@ def test_class_setup_options_spell_language
end
def test_initialize_add_words
- orig_aspell_conf = ENV['ASPELL_CONF']
+ private_wordlist do
+ @options.spell_add_words = %w[funkify thingus]
- Tempfile.open 'personal_wordlist' do |wordlist|
- Tempfile.open 'personal_repl' do |repl|
- ENV['ASPELL_CONF'] = "personal #{wordlist.path};repl #{repl.path}"
- @options.spell_add_words = %w[funkify thingus]
+ sc = @SC.new @options
- sc = @SC.new @options
+ spell = Aspell.new 'en_US'
- spell = Aspell.new 'en_US'
-
- assert spell.check('funkify'), 'funkify not added to personal wordlist'
- assert spell.check('thingus'), 'thingus not added to personal wordlist'
- end
+ assert spell.check('funkify'), 'funkify not added to personal wordlist'
+ assert spell.check('thingus'), 'thingus not added to personal wordlist'
end
- ensure
- ENV['ASPELL_CONF'] = orig_aspell_conf
end
def test_add_name
@@ -139,14 +150,16 @@ def test_add_name_utf_8
end
def test_find_misspelled
- c = comment @text
+ private_wordlist do
+ c = comment @text
- report = @sc.find_misspelled c
+ report = @sc.find_misspelled c
- word, offset = report.shift
+ word, offset = report.shift
- assert_equal 'gud', word
- assert_equal 28, offset
+ assert_equal 'gud', word
+ assert_equal 28, offset
+ end
end
def test_find_misspelled_quote
@@ -170,22 +183,26 @@ def test_find_misspelled_quote
end
def test_find_misspelled_underscore
- c = comment 'gud_method'
+ private_wordlist do
+ c = comment 'gud_method'
- report = @sc.find_misspelled c
+ report = @sc.find_misspelled c
- word, offset = report.shift
+ word, offset = report.shift
- assert_equal 'gud', word
- assert_equal 0, offset
+ assert_equal 'gud', word
+ assert_equal 0, offset
+ end
end
def test_find_misspelled_utf_8
- c = comment 'Marvin Gülker'
+ private_wordlist do
+ c = comment 'Marvin Gülker'
- report = @sc.find_misspelled c
+ report = @sc.find_misspelled c
- assert_empty report
+ assert_empty report
+ end
end
def test_generate_alias
@@ -207,8 +224,8 @@ def test_generate_alias
assert_empty err
- assert_match %r%^Object alias old new in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^Object alias old new in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_attribute
@@ -225,8 +242,8 @@ def test_generate_attribute
assert_empty err
- assert_match %r%^Object\.attr_accessor :attr in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^Object\.attr_accessor :attr in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_class
@@ -241,8 +258,8 @@ def test_generate_class
assert_empty err
- assert_match %r%^class Object in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^class Object in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_constant
@@ -259,8 +276,8 @@ def test_generate_constant
assert_empty err
- assert_match %r%^Object::CONSTANT in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^Object::CONSTANT in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_correct
@@ -287,8 +304,8 @@ def test_generate_file
assert_empty err
- assert_match %r%^In funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^In #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_include
@@ -305,8 +322,8 @@ def test_generate_include
assert_empty err
- assert_match %r%^Object\.include INCLUDE in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^Object\.include INCLUDE in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_method
@@ -324,8 +341,8 @@ def test_generate_method
assert_empty err
- assert_match %r%^Object#method in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ assert_match %r%^Object#method in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
end
def test_generate_multiple
@@ -345,18 +362,54 @@ def test_generate_multiple
assert_empty err
- assert_match %r%^Object#method in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
- assert_match %r%^2 gud%, out
+ assert_match %r%^Object#method in #{@escaped_path}:%, out
+ assert_match %r%^"gud"%, out
+ assert_match %r%^2 gud%, out
+ end
+
+ def test_location_of
+ Tempfile.open 'location_of' do |io|
+ io.puts "##"
+ io.puts "# Here is some text with proper spelling"
+ io.puts "#"
+ io.puts "# #{@text}"
+ io.flush
+
+ tl = RDoc::TopLevel.new io.path
+ text = "Here is some text with proper spelling\n\n#{@text}"
+ offset = text.index "gud"
+
+ line, column = @sc.location_of text, offset, tl
+
+ assert_equal 3, line
+ assert_equal 30, column
+ end
+ end
+
+ def test_location_of_first_line
+ Tempfile.open 'location_of' do |io|
+ io.puts "# #{@text}"
+ io.flush
+
+ tl = RDoc::TopLevel.new io.path
+ offset = @text.index "gud"
+
+ line, column = @sc.location_of @text, offset, tl
+
+ assert_equal 0, line
+ assert_equal 30, column
+ end
end
def test_misspellings_for
out = @sc.misspellings_for 'class Object', comment(@text), @top_level
out = out.join "\n"
- assert_match %r%^class Object in funkify_thingus\.rb:%, out
- assert_match %r%^"gud"%, out
+ location = Regexp.escape @top_level.absolute_name
+ assert_match %r%^class Object in #{location}%, out
+ assert_match %r%^#{location}:0:32%, out
+ assert_match %r%^"gud"%, out
end
def test_misspellings_for_empty
@@ -458,7 +511,7 @@ def test_setup_dictionary_include
def test_setup_dictionary_method
klass = @top_level.add_class RDoc::NormalClass, 'Object'
- meth = RDoc::AnyMethod.new nil, 'funkify_thingus'
+ meth = RDoc::AnyMethod.new nil, 'bagas_methd'
meth.block_params = 'foo, bar'
meth.params = 'baz, hoge'
meth.record_location @top_level
@@ -468,13 +521,13 @@ def test_setup_dictionary_method
@sc.setup_dictionary
- assert @sc.spell.check('funkify'), 'funkify not added to wordlist'
- assert @sc.spell.check('thingus'), 'thingus not added to wordlist'
+ assert @sc.spell.check('bagas'), 'bagas not added to wordlist'
+ assert @sc.spell.check('methd'), 'methd not added to wordlist'
- assert @sc.spell.check('foo'), 'foo not added to wordlist'
- assert @sc.spell.check('bar'), 'bar not added to wordlist'
- assert @sc.spell.check('baz'), 'baz not added to wordlist'
- assert @sc.spell.check('hoge'), 'hoge not added to wordlist'
+ assert @sc.spell.check('foo'), 'foo not added to wordlist'
+ assert @sc.spell.check('bar'), 'bar not added to wordlist'
+ assert @sc.spell.check('baz'), 'baz not added to wordlist'
+ assert @sc.spell.check('hoge'), 'hoge not added to wordlist'
end
def test_suggestion_text
@@ -542,6 +595,20 @@ def test_suggestion_text_start
assert_equal expected, out
end
+ def private_wordlist
+ orig_aspell_conf = ENV['ASPELL_CONF']
+
+ Tempfile.open 'personal_wordlist' do |wordlist|
+ Tempfile.open 'personal_repl' do |repl|
+ ENV['ASPELL_CONF'] = "personal #{wordlist.path};repl #{repl.path}"
+
+ yield
+ end
+ end
+ ensure
+ ENV['ASPELL_CONF'] = orig_aspell_conf
+ end
+
def suggest word
Aspell.new('en_US').suggest(word).first 5
end

0 comments on commit 5f50f07

Please sign in to comment.
Something went wrong with that request. Please try again.