Skip to content

Commit

Permalink
Suggest instance variable names in case "@" is missing
Browse files Browse the repository at this point in the history
closes #12, but class/module variable name suggestion should also be
implemented.
  • Loading branch information
yuki24 committed Oct 28, 2014
1 parent dbc8f49 commit 39d1e2b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
19 changes: 17 additions & 2 deletions lib/did_you_mean/finders/name_error_finders/similar_name_finder.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
module DidYouMean
class SimilarNameFinder
include BaseFinder
attr_reader :name, :_methods, :_local_variables
attr_reader :name, :_methods, :_local_variables, :_instance_variables

def initialize(exception)
@name = exception.name
@_methods = exception.frame_binding.eval("methods")
@_local_variables = exception.frame_binding.eval("local_variables")
@_instance_variables = exception.frame_binding.eval("instance_variables").map do |name|
name.to_s.tr("@", "")
end
end

def words
local_variable_names + method_names
local_variable_names + method_names + instance_variable_names
end

alias target_word name
Expand All @@ -31,6 +34,14 @@ def similar_methods
similar_words.select{|word| word.is_a?(MethodName) }
end

def instance_variable_names
_instance_variables.map {|word| InstanceVariableName.new(word.to_s) }
end

def similar_instance_variables
similar_words.select {|word| word.is_a?(InstanceVariableName) }
end

def format(word)
"#{word.prefix}#{word}"
end
Expand All @@ -42,5 +53,9 @@ def prefix; "#"; end
class LocalVariableName < String
def prefix; ""; end
end

class InstanceVariableName < String
def prefix; "@"; end
end
end
end
14 changes: 14 additions & 0 deletions test/similar_name_finder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@

class SimilarNameFinderTest < Minitest::Test
class User
def initialize(options = {})
@email = options[:email]
end

def call_flrst_name; f1rst_name; end
def call_fr0m_module; fr0m_module; end
def first_name; end
def to_s
"#{@first_name} #{@last_name} <#{email}>"
end
end

module UserModule
Expand All @@ -16,6 +23,7 @@ def setup

@error_from_instance_method = assert_raises(NameError){ user.call_flrst_name }
@error_from_module_method = assert_raises(NameError){ user.call_fr0m_module }
@error_from_missing_at_sign = assert_raises(NameError){ user.to_s }

# Use begin + rescue as #assert_raises changes a scope.
@error_from_local_variable = begin
Expand All @@ -29,6 +37,7 @@ def test_similar_words
assert_includes @error_from_instance_method.finder.similar_words, "first_name"
assert_includes @error_from_module_method.finder.similar_words, "from_module"
assert_includes @error_from_local_variable.finder.similar_words, "user"
assert_includes @error_from_missing_at_sign.finder.similar_words, "email"
end

def test_similar_instance_methods
Expand All @@ -40,9 +49,14 @@ def test_similar_local_variables
assert_includes @error_from_local_variable.finder.similar_local_variables, "user"
end

def test_similar_instance_variables
assert_includes @error_from_missing_at_sign.finder.similar_instance_variables, "email"
end

def test_did_you_mean?
assert_match "Did you mean? #first_name", @error_from_instance_method.did_you_mean?
assert_match "Did you mean? #from_module", @error_from_module_method.did_you_mean?
assert_match "Did you mean? user", @error_from_local_variable.did_you_mean?
assert_match "Did you mean? @email", @error_from_missing_at_sign.did_you_mean?
end
end

0 comments on commit 39d1e2b

Please sign in to comment.