did_you_mean 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +110 -28
  5. data/README.md +52 -13
  6. data/Rakefile +4 -15
  7. data/did_you_mean.gemspec +2 -2
  8. data/doc/CHANGELOG.md.erb +1 -1
  9. data/lib/did_you_mean/core_ext/name_error.rb +6 -6
  10. data/lib/did_you_mean/experimental/initializer_name_correction.rb +2 -0
  11. data/lib/did_you_mean/experimental/ivar_name_correction.rb +36 -9
  12. data/lib/did_you_mean/experimental.rb +0 -15
  13. data/lib/did_you_mean/formatters/plain_formatter.rb +33 -0
  14. data/lib/did_you_mean/formatters/verbose_formatter.rb +49 -0
  15. data/lib/did_you_mean/spell_checkers/key_error_checker.rb +14 -0
  16. data/lib/did_you_mean/spell_checkers/method_name_checker.rb +32 -1
  17. data/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb +6 -2
  18. data/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb +57 -2
  19. data/lib/did_you_mean/spell_checkers/name_error_checkers.rb +2 -6
  20. data/lib/did_you_mean/verbose.rb +4 -0
  21. data/lib/did_you_mean/version.rb +1 -1
  22. data/lib/did_you_mean.rb +94 -4
  23. data/test/core_ext/name_error_extension_test.rb +9 -31
  24. data/test/edit_distance/jaro_winkler_test.rb +6 -1
  25. data/test/fixtures/book.rb +4 -0
  26. data/test/spell_checking/{class_name_test.rb → class_name_check_test.rb} +13 -1
  27. data/test/spell_checking/key_name_check_test.rb +44 -0
  28. data/test/spell_checking/{method_name_test.rb → method_name_check_test.rb} +38 -1
  29. data/test/spell_checking/{uncorrectable_name_test.rb → uncorrectable_name_check_test.rb} +1 -1
  30. data/test/spell_checking/{variable_name_test.rb → variable_name_check_test.rb} +40 -1
  31. data/test/verbose_formatter_test.rb +7 -1
  32. data/tmp/.keep +0 -0
  33. metadata +21 -20
  34. data/evaluation/calculator.rb +0 -105
  35. data/evaluation/dictionary_generator.rb +0 -37
  36. data/evaluation/incorrect_words.yaml +0 -1159
  37. data/lib/did_you_mean/experimental/key_error_name_correction.rb +0 -32
  38. data/lib/did_you_mean/formatter.rb +0 -16
  39. data/lib/did_you_mean/verbose_formatter.rb +0 -16
  40. data/test/experimental/key_error_test.rb +0 -15
@@ -0,0 +1,49 @@
1
+ # frozen-string-literal: true
2
+
3
+ module DidYouMean
4
+ # The +DidYouMean::VerboseFormatter+ uses extra empty lines to make the
5
+ # suggestion stand out more in the error message.
6
+ #
7
+ # In order to activate the verbose formatter,
8
+ #
9
+ # @example
10
+ #
11
+ # OBject
12
+ # # => NameError: uninitialized constant OBject
13
+ # # Did you mean? Object
14
+ #
15
+ # require 'did_you_mean/verbose'
16
+ #
17
+ # OBject
18
+ # # => NameError: uninitialized constant OBject
19
+ # #
20
+ # # Did you mean? Object
21
+ # #
22
+ #
23
+ class VerboseFormatter
24
+
25
+ # Returns a human readable string that contains +corrections+. This
26
+ # formatter is designed to be less verbose to not take too much screen
27
+ # space while being helpful enough to the user.
28
+ #
29
+ # @example
30
+ #
31
+ # formatter = DidYouMean::PlainFormatter.new
32
+ #
33
+ # puts formatter.message_for(["methods", "method"])
34
+ #
35
+ #
36
+ # Did you mean? methods
37
+ # method
38
+ #
39
+ # # => nil
40
+ #
41
+ def message_for(corrections)
42
+ return "" if corrections.empty?
43
+
44
+ output = "\n\n Did you mean? ".dup
45
+ output << corrections.join("\n ")
46
+ output << "\n "
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ require "did_you_mean/spell_checker"
2
+
3
+ module DidYouMean
4
+ class KeyErrorChecker
5
+ def initialize(key_error)
6
+ @key = key_error.key
7
+ @keys = key_error.receiver.keys
8
+ end
9
+
10
+ def corrections
11
+ @corrections ||= SpellChecker.new(dictionary: @keys).correct(@key).map(&:inspect)
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,5 @@
1
+ require "did_you_mean/spell_checker"
2
+
1
3
  module DidYouMean
2
4
  class MethodNameChecker
3
5
  attr_reader :method_name, :receiver
@@ -5,6 +7,35 @@ module DidYouMean
5
7
  NAMES_TO_EXCLUDE = { NilClass => nil.methods }
6
8
  NAMES_TO_EXCLUDE.default = []
7
9
 
10
+ # +MethodNameChecker::RB_RESERVED_WORDS+ is the list of reserved words in
11
+ # Ruby that take an argument. Unlike
12
+ # +VariableNameChecker::RB_RESERVED_WORDS+, those reserved words reqquires
13
+ # an argument, and a +NoMethodError+ is raised due to the presence of the
14
+ # argument.
15
+ #
16
+ # The +MethodNameChecker+ will use this list to suggest a reversed word if
17
+ # a +NoMethodError+ is raised and found closest matches.
18
+ #
19
+ # Also see +VariableNameChecker::RB_RESERVED_WORDS+.
20
+ RB_RESERVED_WORDS = %i(
21
+ alias
22
+ case
23
+ def
24
+ defined?
25
+ elsif
26
+ end
27
+ ensure
28
+ for
29
+ rescue
30
+ super
31
+ undef
32
+ unless
33
+ until
34
+ when
35
+ while
36
+ yield
37
+ )
38
+
8
39
  def initialize(exception)
9
40
  @method_name = exception.name
10
41
  @receiver = exception.receiver
@@ -12,7 +43,7 @@ module DidYouMean
12
43
  end
13
44
 
14
45
  def corrections
15
- @corrections ||= SpellChecker.new(dictionary: method_names).correct(method_name) - NAMES_TO_EXCLUDE[@receiver.class]
46
+ @corrections ||= SpellChecker.new(dictionary: RB_RESERVED_WORDS + method_names).correct(method_name) - NAMES_TO_EXCLUDE[@receiver.class]
16
47
  end
17
48
 
18
49
  def method_names
@@ -1,16 +1,20 @@
1
1
  # frozen-string-literal: true
2
2
  require 'delegate'
3
+ require "did_you_mean/spell_checker"
3
4
 
4
5
  module DidYouMean
5
6
  class ClassNameChecker
6
7
  attr_reader :class_name
7
8
 
8
9
  def initialize(exception)
9
- @class_name, @receiver = exception.name, exception.receiver
10
+ @class_name, @receiver, @original_message = exception.name, exception.receiver, exception.original_message
10
11
  end
11
12
 
12
13
  def corrections
13
- @corrections ||= SpellChecker.new(dictionary: class_names).correct(class_name).map(&:full_name)
14
+ @corrections ||= SpellChecker.new(dictionary: class_names)
15
+ .correct(class_name)
16
+ .map(&:full_name)
17
+ .reject {|qualified_name| @original_message.include?(qualified_name) }
14
18
  end
15
19
 
16
20
  def class_names
@@ -1,12 +1,67 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ require "did_you_mean/spell_checker"
4
+
3
5
  module DidYouMean
4
6
  class VariableNameChecker
5
7
  attr_reader :name, :method_names, :lvar_names, :ivar_names, :cvar_names
6
8
 
7
- NAMES_TO_EXCLUDE = { 'foo' => [:fork] }
9
+ NAMES_TO_EXCLUDE = { 'foo' => [:fork, :for] }
8
10
  NAMES_TO_EXCLUDE.default = []
9
11
 
12
+ # +VariableNameChecker::RB_RESERVED_WORDS+ is the list of all reserved
13
+ # words in Ruby. They could be declared like methods are, and a typo would
14
+ # cause Ruby to raise a +NameError+ because of the way they are declared.
15
+ #
16
+ # The +:VariableNameChecker+ will use this list to suggest a reversed word
17
+ # if a +NameError+ is raised and found closest matches, excluding:
18
+ #
19
+ # * +do+
20
+ # * +if+
21
+ # * +in+
22
+ # * +or+
23
+ #
24
+ # Also see +MethodNameChecker::RB_RESERVED_WORDS+.
25
+ RB_RESERVED_WORDS = %i(
26
+ BEGIN
27
+ END
28
+ alias
29
+ and
30
+ begin
31
+ break
32
+ case
33
+ class
34
+ def
35
+ defined?
36
+ else
37
+ elsif
38
+ end
39
+ ensure
40
+ false
41
+ for
42
+ module
43
+ next
44
+ nil
45
+ not
46
+ redo
47
+ rescue
48
+ retry
49
+ return
50
+ self
51
+ super
52
+ then
53
+ true
54
+ undef
55
+ unless
56
+ until
57
+ when
58
+ while
59
+ yield
60
+ __LINE__
61
+ __FILE__
62
+ __ENCODING__
63
+ )
64
+
10
65
  def initialize(exception)
11
66
  @name = exception.name.to_s.tr("@", "")
12
67
  @lvar_names = exception.respond_to?(:local_variables) ? exception.local_variables : []
@@ -20,7 +75,7 @@ module DidYouMean
20
75
 
21
76
  def corrections
22
77
  @corrections ||= SpellChecker
23
- .new(dictionary: (lvar_names + method_names + ivar_names + cvar_names))
78
+ .new(dictionary: (RB_RESERVED_WORDS + lvar_names + method_names + ivar_names + cvar_names))
24
79
  .correct(name) - NAMES_TO_EXCLUDE[@name]
25
80
  end
26
81
  end
@@ -2,12 +2,8 @@ require 'did_you_mean/spell_checkers/name_error_checkers/class_name_checker'
2
2
  require 'did_you_mean/spell_checkers/name_error_checkers/variable_name_checker'
3
3
 
4
4
  module DidYouMean
5
- module NameErrorCheckers
6
- def self.included(*)
7
- raise "Do not include this module since it overrides Class.new method."
8
- end
9
-
10
- def self.new(exception)
5
+ class << (NameErrorCheckers = Object.new)
6
+ def new(exception)
11
7
  case exception.original_message
12
8
  when /uninitialized constant/
13
9
  ClassNameChecker
@@ -0,0 +1,4 @@
1
+ require 'did_you_mean'
2
+ require 'did_you_mean/formatters/verbose_formatter'
3
+
4
+ DidYouMean.formatter = DidYouMean::VerboseFormatter.new
@@ -1,3 +1,3 @@
1
1
  module DidYouMean
2
- VERSION = "1.1.0"
2
+ VERSION = "1.3.0"
3
3
  end
data/lib/did_you_mean.rb CHANGED
@@ -4,16 +4,106 @@ require "did_you_mean/core_ext/name_error"
4
4
  require "did_you_mean/spell_checker"
5
5
  require 'did_you_mean/spell_checkers/name_error_checkers'
6
6
  require 'did_you_mean/spell_checkers/method_name_checker'
7
+ require 'did_you_mean/spell_checkers/key_error_checker'
7
8
  require 'did_you_mean/spell_checkers/null_checker'
8
9
 
9
- require "did_you_mean/formatter"
10
+ require "did_you_mean/formatters/plain_formatter"
10
11
 
12
+ # The +DidYouMean+ gem adds functionality to suggest possible method/class
13
+ # names upon errors such as +NameError+ and +NoMethodError+. In Ruby 2.3 or
14
+ # later, it is automatically activated during startup.
15
+ #
16
+ # @example
17
+ #
18
+ # methosd
19
+ # # => NameError: undefined local variable or method `methosd' for main:Object
20
+ # # Did you mean? methods
21
+ # # method
22
+ #
23
+ # OBject
24
+ # # => NameError: uninitialized constant OBject
25
+ # # Did you mean? Object
26
+ #
27
+ # @full_name = "Yuki Nishijima"
28
+ # first_name, last_name = full_name.split(" ")
29
+ # # => NameError: undefined local variable or method `full_name' for main:Object
30
+ # # Did you mean? @full_name
31
+ #
32
+ # @@full_name = "Yuki Nishijima"
33
+ # @@full_anme
34
+ # # => NameError: uninitialized class variable @@full_anme in Object
35
+ # # Did you mean? @@full_name
36
+ #
37
+ # full_name = "Yuki Nishijima"
38
+ # full_name.starts_with?("Y")
39
+ # # => NoMethodError: undefined method `starts_with?' for "Yuki Nishijima":String
40
+ # # Did you mean? start_with?
41
+ #
42
+ # hash = {foo: 1, bar: 2, baz: 3}
43
+ # hash.fetch(:fooo)
44
+ # # => KeyError: key not found: :fooo
45
+ # # Did you mean? :foo
46
+ #
47
+ #
48
+ # == Disabling +did_you_mean+
49
+ #
50
+ # Occasionally, you may want to disable the +did_you_mean+ gem for e.g.
51
+ # debugging issues in the error object itself. You can disable it entirely by
52
+ # specifying +--disable-did_you_mean+ option to the +ruby+ command:
53
+ #
54
+ # $ ruby --disable-did_you_mean -e "1.zeor?"
55
+ # -e:1:in `<main>': undefined method `zeor?' for 1:Integer (NameError)
56
+ #
57
+ # When you do not have direct access to the +ruby+ command (e.g.
58
+ # +rails console+, +irb+), you could applyoptions using the +RUBYOPT+
59
+ # environment variable:
60
+ #
61
+ # $ RUBYOPT='--disable-did_you_mean' irb
62
+ # irb:0> 1.zeor?
63
+ # # => NoMethodError (undefined method `zeor?' for 1:Integer)
64
+ #
65
+ #
66
+ # == Getting the original error message
67
+ #
68
+ # Sometimes, you do not want to disable the gem entirely, but need to get the
69
+ # original error message without suggestions (e.g. testing). In this case, you
70
+ # could use the +#original_message+ method on the error object:
71
+ #
72
+ # no_method_error = begin
73
+ # 1.zeor?
74
+ # rescue NoMethodError => error
75
+ # error
76
+ # end
77
+ #
78
+ # no_method_error.message
79
+ # # => NoMethodError (undefined method `zeor?' for 1:Integer)
80
+ # # Did you mean? zero?
81
+ #
82
+ # no_method_error.original_message
83
+ # # => NoMethodError (undefined method `zeor?' for 1:Integer)
84
+ #
11
85
  module DidYouMean
12
- IGNORED_CALLERS = []
13
-
86
+ # Map of error types and spell checker objects.
14
87
  SPELL_CHECKERS = Hash.new(NullChecker)
88
+
15
89
  SPELL_CHECKERS.merge!({
16
90
  "NameError" => NameErrorCheckers,
17
- "NoMethodError" => MethodNameChecker
91
+ "NoMethodError" => MethodNameChecker,
92
+ "KeyError" => KeyErrorChecker
18
93
  })
94
+
95
+ NameError.prepend DidYouMean::Correctable
96
+ KeyError.prepend DidYouMean::Correctable
97
+
98
+ # Returns the currenctly set formatter. By default, it is set to +DidYouMean::Formatter+.
99
+ def self.formatter
100
+ @@formatter
101
+ end
102
+
103
+ # Updates the primary formatter used to format the suggestions.
104
+ def self.formatter=(formatter)
105
+ @@formatter = formatter
106
+ end
107
+
108
+ self.formatter = PlainFormatter.new
19
109
  end
@@ -20,7 +20,7 @@ class NameErrorExtensionTest < Minitest::Test
20
20
 
21
21
  def test_message
22
22
  message = <<~MESSAGE.chomp
23
- undefined local variable or method `doesnt_exist' for #{method(:to_s).super_method.call}
23
+ undefined local variable or method `doesnt_exist' for #{to_s}
24
24
  Did you mean? does_exist
25
25
  MESSAGE
26
26
 
@@ -36,38 +36,16 @@ class NameErrorExtensionTest < Minitest::Test
36
36
  error.to_s
37
37
  assert_equal 1, error.to_s.scan("Did you mean?").count
38
38
  end
39
- end
40
-
41
- class IgnoreCallersTest < Minitest::Test
42
- SPELL_CHECKERS = DidYouMean::SPELL_CHECKERS
43
-
44
- class Boomer
45
- def initialize(*)
46
- raise Exception, "spell checker was created when it shouldn't!"
47
- end
48
- end
49
-
50
- def setup
51
- @org, SPELL_CHECKERS['NameError'] = SPELL_CHECKERS['NameError'], Boomer
52
- DidYouMean::IGNORED_CALLERS << /( |`)do_not_correct_typo'/
53
-
54
- @error = assert_raises(NameError){ doesnt_exist }
55
- end
56
-
57
- def teardown
58
- SPELL_CHECKERS['NameError'] = @org
59
- DidYouMean::IGNORED_CALLERS.clear
60
- end
61
-
62
- def test_ignore
63
- assert_nothing_raised { do_not_correct_typo }
64
- end
65
39
 
66
- private
40
+ def test_correctable_error_objects_are_dumpable
41
+ error = begin
42
+ File.open('./tmp/.keep').sizee
43
+ rescue NoMethodError => e
44
+ e
45
+ end
67
46
 
68
- def do_not_correct_typo; @error.message end
47
+ error.to_s
69
48
 
70
- def assert_nothing_raised
71
- yield
49
+ assert_equal "undefined method `sizee' for #<File:./tmp/.keep>", Marshal.load(Marshal.dump(error)).original_message
72
50
  end
73
51
  end
@@ -1,6 +1,11 @@
1
- # -*- coding: utf-8 -*-
2
1
  require 'test_helper'
3
2
 
3
+ # These tests were originally written by Jian Weihang (簡煒航) as part of his work
4
+ # on the jaro_winkler gem. The original code could be found here:
5
+ # https://github.com/tonytonyjan/jaro_winkler/blob/9bd12421/spec/jaro_winkler_spec.rb
6
+ #
7
+ # Copyright (c) 2014 Jian Weihang
8
+
4
9
  class JaroWinklerTest < Minitest::Test
5
10
  def test_jaro_winkler_distance
6
11
  assert_distance 0.9667, 'henka', 'henkan'
@@ -0,0 +1,4 @@
1
+ class Book
2
+ class Cover
3
+ end
4
+ end
@@ -27,7 +27,7 @@ class Book
27
27
  end
28
28
  end
29
29
 
30
- class ClassNameTest < Minitest::Test
30
+ class ClassNameCheckTest < Minitest::Test
31
31
  def test_corrections
32
32
  error = assert_raises(NameError) { ::Bo0k }
33
33
  assert_correction "Book", error.corrections
@@ -62,4 +62,16 @@ class ClassNameTest < Minitest::Test
62
62
  error = assert_raises(NameError) { ::Book::Page.new.tableof_contents }
63
63
  assert_correction "Book::TableOfContents", error.corrections
64
64
  end
65
+
66
+ def test_does_not_suggest_user_input
67
+ error = assert_raises(NameError) { ::Book::Cover }
68
+
69
+ # This is a weird require, but in a multi-threaded condition, a constant may
70
+ # be loaded between when a NameError occurred and when the spell checker
71
+ # attemps to find a possible suggestion. The manual require here simulates
72
+ # a race condition a single test.
73
+ require_relative '../fixtures/book'
74
+
75
+ assert_empty error.corrections
76
+ end
65
77
  end
@@ -0,0 +1,44 @@
1
+ require "test_helper"
2
+
3
+ class KeyNameCheckTest < Minitest::Test
4
+ def test_corrects_hash_key_name_with_fetch
5
+ hash = { "foo" => 1, bar: 2 }
6
+
7
+ error = assert_raises(KeyError) { hash.fetch(:bax) }
8
+ assert_correction ":bar", error.corrections
9
+ assert_match "Did you mean? :bar", error.to_s
10
+
11
+ error = assert_raises(KeyError) { hash.fetch("fooo") }
12
+ assert_correction %("foo"), error.corrections
13
+ assert_match %(Did you mean? "foo"), error.to_s
14
+ end
15
+
16
+ def test_corrects_hash_key_name_with_fetch_values
17
+ hash = { "foo" => 1, bar: 2 }
18
+
19
+ error = assert_raises(KeyError) { hash.fetch_values("foo", :bar, :bax) }
20
+ assert_correction ":bar", error.corrections
21
+ assert_match "Did you mean? :bar", error.to_s
22
+
23
+ error = assert_raises(KeyError) { hash.fetch_values("foo", :bar, "fooo") }
24
+ assert_correction %("foo"), error.corrections
25
+ assert_match %(Did you mean? "foo"), error.to_s
26
+ end
27
+
28
+ def test_corrects_sprintf_key_name
29
+ error = assert_raises(KeyError) { sprintf("%<foo>d", {fooo: 1}) }
30
+ assert_correction ":fooo", error.corrections
31
+ assert_match "Did you mean? :fooo", error.to_s
32
+ end
33
+
34
+ def test_corrects_env_key_name
35
+ ENV["FOO"] = "1"
36
+ ENV["BAR"] = "2"
37
+ error = assert_raises(KeyError) { ENV.fetch("BAX") }
38
+ assert_correction %("BAR"), error.corrections
39
+ assert_match %(Did you mean? "BAR"), error.to_s
40
+ ensure
41
+ ENV.delete("FOO")
42
+ ENV.delete("BAR")
43
+ end
44
+ end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class MethodNameTest < Minitest::Test
3
+ class MethodNameCheckTest < Minitest::Test
4
4
  class User
5
5
  def friends; end
6
6
  def first_name; end
@@ -9,6 +9,12 @@ class MethodNameTest < Minitest::Test
9
9
  raiae NoMethodError
10
10
  end
11
11
 
12
+ def raise_no_method_error
13
+ self.firstname
14
+ rescue NoMethodError => e
15
+ raise e, e.message, e.backtrace
16
+ end
17
+
12
18
  protected
13
19
  def the_protected_method; end
14
20
 
@@ -86,4 +92,35 @@ class MethodNameTest < Minitest::Test
86
92
  ensure
87
93
  NilClass.class_eval { undef empty? }
88
94
  end
95
+
96
+ def test_does_not_append_suggestions_twice
97
+ error = assert_raises NoMethodError do
98
+ begin
99
+ @user.firstname
100
+ rescue NoMethodError => e
101
+ raise e, e.message, e.backtrace
102
+ end
103
+ end
104
+
105
+ assert_equal 1, error.to_s.scan(/Did you mean/).count
106
+ end
107
+
108
+ def test_does_not_append_suggestions_three_times
109
+ error = assert_raises NoMethodError do
110
+ begin
111
+ @user.raise_no_method_error
112
+ rescue NoMethodError => e
113
+ raise e, e.message, e.backtrace
114
+ end
115
+ end
116
+
117
+ assert_equal 1, error.to_s.scan(/Did you mean/).count
118
+ end
119
+
120
+ def test_suggests_yield
121
+ error = assert_raises(NoMethodError) { yeild(1) }
122
+
123
+ assert_correction :yield, error.corrections
124
+ assert_match "Did you mean? yield", error.to_s
125
+ end
89
126
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class UncorrectableNameTest < Minitest::Test
3
+ class UncorrectableNameCheckTest < Minitest::Test
4
4
  class FirstNameError < NameError; end
5
5
 
6
6
  def setup
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class VariableNameTest < Minitest::Test
3
+ class VariableNameCheckTest < Minitest::Test
4
4
  class User
5
5
  def initialize
6
6
  @email_address = 'email_address@address.net'
@@ -57,6 +57,45 @@ class VariableNameTest < Minitest::Test
57
57
  assert_match "Did you mean? person", error.to_s
58
58
  end
59
59
 
60
+ def test_corrections_include_ruby_predefined_objects
61
+ some_var = nil
62
+
63
+ false_error = assert_raises(NameError) do
64
+ some_var = fals
65
+ end
66
+
67
+ true_error = assert_raises(NameError) do
68
+ some_var = treu
69
+ end
70
+
71
+ nil_error = assert_raises(NameError) do
72
+ some_var = nul
73
+ end
74
+
75
+ file_error = assert_raises(NameError) do
76
+ __FIEL__
77
+ end
78
+
79
+ assert_correction :false, false_error.corrections
80
+ assert_match "Did you mean? false", false_error.to_s
81
+
82
+ assert_correction :true, true_error.corrections
83
+ assert_match "Did you mean? true", true_error.to_s
84
+
85
+ assert_correction :nil, nil_error.corrections
86
+ assert_match "Did you mean? nil", nil_error.to_s
87
+
88
+ assert_correction :__FILE__, file_error.corrections
89
+ assert_match "Did you mean? __FILE__", file_error.to_s
90
+ end
91
+
92
+ def test_suggests_yield
93
+ error = assert_raises(NameError) { yeild }
94
+
95
+ assert_correction :yield, error.corrections
96
+ assert_match "Did you mean? yield", error.to_s
97
+ end
98
+
60
99
  def test_corrections_include_instance_variable_name
61
100
  error = assert_raises(NameError){ @user.to_s }
62
101
 
@@ -2,13 +2,19 @@ require 'test_helper'
2
2
 
3
3
  class VerboseFormatterTest < Minitest::Test
4
4
  def setup
5
+ require 'did_you_mean/verbose'
6
+
5
7
  does_exist = does_exist = nil
6
8
  @error = assert_raises(NameError){ doesnt_exist }
7
9
  end
8
10
 
11
+ def teardown
12
+ DidYouMean.formatter = DidYouMean::PlainFormatter.new
13
+ end
14
+
9
15
  def test_message
10
16
  assert_equal <<~MESSAGE.chomp, @error.message
11
- undefined local variable or method `doesnt_exist' for #{method(:to_s).super_method.call}
17
+ undefined local variable or method `doesnt_exist' for #{to_s}
12
18
 
13
19
  Did you mean? does_exist
14
20
 
data/tmp/.keep ADDED
File without changes