did_you_mean 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/.travis.yml +0 -6
- data/CHANGELOG.md +28 -2
- data/Gemfile +1 -1
- data/README.md +12 -2
- data/Rakefile +3 -8
- data/benchmark/memory_usage.rb +1 -1
- data/did_you_mean.gemspec +3 -4
- data/evaluation/calculator.rb +4 -3
- data/evaluation/incorrect_words.yaml +1 -1
- data/lib/did_you_mean/core_ext/name_error.rb +3 -6
- data/lib/did_you_mean/experimental/initializer_name_correction.rb +1 -1
- data/lib/did_you_mean/formatter.rb +1 -1
- data/lib/did_you_mean/levenshtein.rb +2 -0
- data/lib/did_you_mean/spell_checker.rb +12 -14
- data/lib/did_you_mean/spell_checkers/method_name_checker.rb +8 -5
- data/lib/did_you_mean/spell_checkers/name_error_checkers.rb +4 -1
- data/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb +3 -6
- data/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb +5 -2
- data/lib/did_you_mean/verbose_formatter.rb +1 -1
- data/lib/did_you_mean/version.rb +1 -1
- data/test/core_ext/name_error_extension_test.rb +1 -13
- data/test/edit_distance/jaro_winkler_test.rb +1 -0
- data/test/spell_checker_test.rb +0 -1
- data/test/spell_checking/class_name_test.rb +0 -12
- data/test/spell_checking/method_name_test.rb +9 -24
- data/test/spell_checking/variable_name_test.rb +15 -6
- data/test/test_helper.rb +4 -2
- data/test/verbose_formatter_test.rb +4 -3
- metadata +10 -16
- data/lib/did_you_mean/extra_features.rb +0 -3
- data/test/experimental/deprecated_features_test.rb +0 -13
- data/test/fixtures/book.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70f21af56b6f4e14b5c5984d3ce5180a779c81c9
|
4
|
+
data.tar.gz: 1f73d774f056a90eadace8401876b6f35ea54177
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17fbd60b5fd5a951b241b1b0277b1888c3495849825fd699dd1da24a8ac9b4b0a7366505f3584a3a41c125e785b6be556ae0a7f736168e39cb3b6d6b36a3cfa5
|
7
|
+
data.tar.gz: 6a63b180eb98df8cfd4c59c209e9ff676d07e80b548d3d07c05e5e619cacd2725097d9f3da0037b34b517fcedb6c605229c0c4ab5c4fd68a68f124e03d85e9c1
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.0-dev
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
## [v1.0.2](https://github.com/yuki24/did_you_mean/tree/v1.0.2)
|
2
|
+
|
3
|
+
_<sup>released on 2016-06-20 18:03:07 UTC</sup>_
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
- Experimental features are officially available through `require 'did_you_mean/experimental'`
|
8
|
+
|
9
|
+
#### Deprecations
|
10
|
+
|
11
|
+
- `require 'did_you_mean/extra_features'` is now deprecated in favor of `require 'did_you_mean/experimental'`
|
12
|
+
|
13
|
+
#### Internal Changes
|
14
|
+
|
15
|
+
- Replaced the `DidYouMean::SpellCheckable` module with the `DidYouMean::SpellChecker` class. This is a slower implementation but close to the model explained in [this talk](https://speakerdeck.com/yuki24/saving-people-from-typos), more reusable and possibly makes it easier to expose the class as a public interface.
|
16
|
+
|
17
|
+
## [v1.0.1](https://github.com/yuki24/did_you_mean/tree/v1.0.1)
|
18
|
+
|
19
|
+
_<sup>released on 2016-05-15 05:17:22 UTC</sup>_
|
20
|
+
|
21
|
+
#### Bug Fixes
|
22
|
+
|
23
|
+
- Fixed a bug where the gem suggests what is actually typed by the user: [<tt>1c52c88</tt>](https://github.com/yuki24/did_you_mean/commit/1c52c887c62b0921e799f94bcc4a846dc7cbc057)
|
24
|
+
- Fixed features that didn't work on JRuby 9.1.0.0: [<tt>dc48dde</tt>](https://github.com/yuki24/did_you_mean/commit/dc48dde1b2a8f05aab1fcf897e1cb3075a206f53), [<tt>4de23f8</tt>](https://github.com/yuki24/did_you_mean/commit/4de23f880502c80c5f321371d39c08bb0fa34040), [<tt>00e3059</tt>](https://github.com/yuki24/did_you_mean/commit/00e305971060d150fae4817b5e895d6478b37579). The local variable name correction is still disabled. Also see: [jruby/jruby#3480](https://github.com/jruby/jruby/issues/3480)
|
25
|
+
|
26
|
+
|
1
27
|
## [v1.0.0](https://github.com/yuki24/did_you_mean/tree/v1.0.0)
|
2
28
|
|
3
29
|
_<sup>released on 2015-12-25 05:13:04 UTC</sup>_
|
@@ -9,7 +35,7 @@ _<sup>released on 2015-12-25 05:13:04 UTC</sup>_
|
|
9
35
|
|
10
36
|
#### Bug Fixes
|
11
37
|
|
12
|
-
- Fixed a bug where the Jaro-Winkler implementation returns the wrong distance when 2 identical strings are given
|
38
|
+
- Fixed a bug where the Jaro-Winkler implementation returns the wrong distance when 2 identical strings are given. fixes [#58](https://github.com/yuki24/did_you_mean/pull/58)
|
13
39
|
|
14
40
|
#### Internal Changes
|
15
41
|
|
@@ -29,7 +55,7 @@ _<sup>released on 2015-12-25 04:56:13 UTC</sup>_
|
|
29
55
|
|
30
56
|
#### Internal Changes
|
31
57
|
|
32
|
-
-
|
58
|
+
- Use the `frozen-string-literal` pragma rather than calling `.freeze` everywhere
|
33
59
|
- Use the `NameError#receiver` method in `DidYouMean:: ClassNameChecker` to know the namespace where the constant call is made
|
34
60
|
- Refactored the `SpellCheckerTest`
|
35
61
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Installation
|
4
4
|
|
5
|
-
Ruby 2.3 ships with this gem and it will automatically be `require`d when a Ruby process starts up. No special setup is required.
|
5
|
+
Ruby 2.3 and later ships with this gem and it will automatically be `require`d when a Ruby process starts up. No special setup is required.
|
6
6
|
|
7
7
|
## Examples
|
8
8
|
|
@@ -56,7 +56,7 @@ full_name.starts_with?("Y")
|
|
56
56
|
|
57
57
|
Aside from the basic features above, the `did_you_mean` gem comes with experimental features. They can be enabled by calling `require 'did_you_mean/experimental'`.
|
58
58
|
|
59
|
-
**Keep in mind that these experimental features should never be enabled in production as they would impact Ruby's performance and
|
59
|
+
**Keep in mind that these experimental features should never be enabled in production as they would impact Ruby's performance and use some unstable Ruby APIs.**
|
60
60
|
|
61
61
|
### Correcting an Instance Variable When It's Incorrectly Typed
|
62
62
|
|
@@ -69,7 +69,17 @@ require 'did_you_mean/experimental'
|
|
69
69
|
# Did you mean? @full_name
|
70
70
|
```
|
71
71
|
|
72
|
+
### Correcting a Hash Key Name
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
hash = {foo: 1, bar: 2, baz: 3}
|
76
|
+
hash.fetch(:fooo)
|
77
|
+
# KeyError: key not found: :fooo
|
78
|
+
# Did you mean? :foo
|
79
|
+
```
|
80
|
+
|
72
81
|
### Displaying a Warning When `initialize` is Incorrectly Typed
|
82
|
+
|
73
83
|
```ruby
|
74
84
|
require 'did_you_mean/experimental'
|
75
85
|
|
data/Rakefile
CHANGED
@@ -28,12 +28,7 @@ Rake::TestTask.new("test:experimental") do |task|
|
|
28
28
|
task.ruby_opts << "-rdid_you_mean/experimental"
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
task default: %i(test test:verbose_formatter test:experimental)
|
33
|
-
else
|
34
|
-
task default: %i(test test:verbose_formatter)
|
35
|
-
end
|
36
|
-
|
31
|
+
task default: %i(test test:verbose_formatter test:experimental)
|
37
32
|
|
38
33
|
namespace :test do
|
39
34
|
namespace :accuracy do
|
@@ -51,13 +46,13 @@ namespace :test do
|
|
51
46
|
puts "\n"
|
52
47
|
end
|
53
48
|
|
54
|
-
sh '
|
49
|
+
sh 'ruby evaluation/calculator.rb'
|
55
50
|
end
|
56
51
|
end
|
57
52
|
|
58
53
|
namespace :benchmark do
|
59
54
|
desc "Measure memory usage by the did_you_mean gem"
|
60
55
|
task :memory do
|
61
|
-
sh '
|
56
|
+
sh 'ruby benchmark/memory_usage.rb'
|
62
57
|
end
|
63
58
|
end
|
data/benchmark/memory_usage.rb
CHANGED
data/did_you_mean.gemspec
CHANGED
@@ -9,18 +9,17 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Yuki Nishijima"]
|
10
10
|
spec.email = ["mail@yukinishijima.net"]
|
11
11
|
spec.summary = '"Did you mean?" experience in Ruby'
|
12
|
-
spec.description = '
|
12
|
+
spec.description = 'The gem that has been saving people from typos since 2014.'
|
13
13
|
spec.homepage = "https://github.com/yuki24/did_you_mean"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
17
|
spec.test_files = spec.files.grep(%r{^(test)/})
|
19
18
|
spec.require_paths = ["lib"]
|
20
19
|
|
21
|
-
spec.required_ruby_version = '>= 2.
|
20
|
+
spec.required_ruby_version = '>= 2.4.0dev'
|
22
21
|
|
23
|
-
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "bundler"
|
24
23
|
spec.add_development_dependency "rake"
|
25
24
|
spec.add_development_dependency "minitest"
|
26
25
|
end
|
data/evaluation/calculator.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen-string-literal: true
|
2
2
|
|
3
3
|
require 'benchmark'
|
4
4
|
require 'did_you_mean'
|
@@ -36,7 +36,8 @@ report "loading program" do
|
|
36
36
|
::JaroWinkler.distance(str1, str2)
|
37
37
|
end if RUBY_ENGINE != 'jruby'
|
38
38
|
end
|
39
|
-
rescue LoadError, NameError
|
39
|
+
rescue LoadError, NameError => e
|
40
|
+
puts "couldn't load the jaro_winkler gem: #{e.message}\n\n"
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
@@ -47,7 +48,7 @@ report "loading dictionary" do
|
|
47
48
|
DICTIONARY = Set.new(yaml)
|
48
49
|
end
|
49
50
|
|
50
|
-
report "loading
|
51
|
+
report "loading correct/incorrect words" do
|
51
52
|
SPELL_CHECKER = DidYouMean::SpellChecker.new(dictionary: DICTIONARY)
|
52
53
|
INCORRECT_WORDS = YAML.load(open("evaluation/incorrect_words.yaml").read)
|
53
54
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# This data is based on Birkbeck Spelling Error Corpus: http://ota.ox.ac.uk/headers/0643.xml
|
2
|
-
# More specifically, this is a yaml version of the data in FAWTHROP1DAT.643 and
|
2
|
+
# More specifically, this is a yaml version of the data in FAWTHROP1DAT.643 and FAWTHROP2DAT.643.
|
3
3
|
---
|
4
4
|
abattoir: abbatoir
|
5
5
|
abhorrence: abhorence
|
@@ -10,21 +10,18 @@ module DidYouMean
|
|
10
10
|
msg = super.dup
|
11
11
|
bt = caller(1, 6)
|
12
12
|
|
13
|
-
if IGNORED_CALLERS.all? {|ignored| bt.grep(ignored).empty? }
|
14
|
-
msg << Formatter.new(corrections).to_s
|
15
|
-
end
|
16
|
-
|
13
|
+
msg << Formatter.new(corrections).to_s if IGNORED_CALLERS.all? {|ignored| bt.grep(ignored).empty? }
|
17
14
|
msg
|
18
15
|
rescue
|
19
16
|
super
|
20
17
|
end
|
21
18
|
|
22
19
|
def corrections
|
23
|
-
|
20
|
+
spell_checker.corrections
|
24
21
|
end
|
25
22
|
|
26
23
|
def spell_checker
|
27
|
-
SPELL_CHECKERS[self.class.to_s].new(self)
|
24
|
+
@spell_checker ||= SPELL_CHECKERS[self.class.to_s].new(self)
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module DidYouMean
|
2
2
|
module Levenshtein # :nodoc:
|
3
3
|
# This code is based directly on the Text gem implementation
|
4
|
+
# Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
|
5
|
+
#
|
4
6
|
# Returns a value representing the "cost" of transforming str1 into str2
|
5
7
|
def distance(str1, str2)
|
6
8
|
n = str1.length
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen-string-literal: true
|
2
2
|
|
3
3
|
require "did_you_mean/levenshtein"
|
4
4
|
require "did_you_mean/jaro_winkler"
|
@@ -13,24 +13,22 @@ module DidYouMean
|
|
13
13
|
input = normalize(input)
|
14
14
|
threshold = input.length > 3 ? 0.834 : 0.77
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
words = @dictionary.select {|word| JaroWinkler.distance(normalize(word), input) >= threshold }
|
17
|
+
words.reject! {|word| input == word.to_s }
|
18
|
+
words.sort_by! {|word| JaroWinkler.distance(word.to_s, input) }
|
19
|
+
words.reverse!
|
20
20
|
|
21
21
|
# Correct mistypes
|
22
22
|
threshold = (input.length * 0.25).ceil
|
23
|
-
|
23
|
+
corrections = words.select {|c| Levenshtein.distance(normalize(c), input) <= threshold }
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
candidate = normalize(candidate)
|
31
|
-
length = input.length < candidate.length ? input.length : candidate.length
|
25
|
+
# Correct misspells
|
26
|
+
if corrections.empty?
|
27
|
+
corrections = words.select do |word|
|
28
|
+
word = normalize(word)
|
29
|
+
length = input.length < word.length ? input.length : word.length
|
32
30
|
|
33
|
-
Levenshtein.distance(
|
31
|
+
Levenshtein.distance(word, input) < length
|
34
32
|
end.first(1)
|
35
33
|
end
|
36
34
|
|
@@ -2,19 +2,22 @@ module DidYouMean
|
|
2
2
|
class MethodNameChecker
|
3
3
|
attr_reader :method_name, :receiver
|
4
4
|
|
5
|
+
NAMES_TO_EXCLUDE = { NilClass => nil.methods }
|
6
|
+
NAMES_TO_EXCLUDE.default = []
|
7
|
+
|
5
8
|
def initialize(exception)
|
6
|
-
@method_name
|
7
|
-
@receiver
|
8
|
-
@
|
9
|
+
@method_name = exception.name
|
10
|
+
@receiver = exception.receiver
|
11
|
+
@private_call = exception.respond_to?(:private_call?) ? exception.private_call? : false
|
9
12
|
end
|
10
13
|
|
11
14
|
def corrections
|
12
|
-
@corrections ||= SpellChecker.new(dictionary: method_names).correct(method_name)
|
15
|
+
@corrections ||= SpellChecker.new(dictionary: method_names).correct(method_name) - NAMES_TO_EXCLUDE[@receiver.class]
|
13
16
|
end
|
14
17
|
|
15
18
|
def method_names
|
16
19
|
method_names = receiver.methods + receiver.singleton_methods
|
17
|
-
method_names += receiver.private_methods if @
|
20
|
+
method_names += receiver.private_methods if @private_call
|
18
21
|
method_names.uniq!
|
19
22
|
method_names
|
20
23
|
end
|
@@ -11,7 +11,10 @@ module DidYouMean
|
|
11
11
|
case exception.original_message
|
12
12
|
when /uninitialized constant/
|
13
13
|
ClassNameChecker
|
14
|
-
when /undefined local variable or method/,
|
14
|
+
when /undefined local variable or method/,
|
15
|
+
/undefined method/,
|
16
|
+
/uninitialized class variable/,
|
17
|
+
/no member '.*' in struct/
|
15
18
|
VariableNameChecker
|
16
19
|
else
|
17
20
|
NullChecker
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen-string-literal: true
|
2
2
|
require 'delegate'
|
3
3
|
|
4
4
|
module DidYouMean
|
@@ -6,14 +6,11 @@ module DidYouMean
|
|
6
6
|
attr_reader :class_name
|
7
7
|
|
8
8
|
def initialize(exception)
|
9
|
-
@class_name, @receiver
|
9
|
+
@class_name, @receiver = exception.name, exception.receiver
|
10
10
|
end
|
11
11
|
|
12
12
|
def corrections
|
13
|
-
@corrections ||= SpellChecker.new(dictionary: class_names)
|
14
|
-
.correct(class_name)
|
15
|
-
.map(&:full_name)
|
16
|
-
.reject {|qualified_name| @original_message.include?(qualified_name) }
|
13
|
+
@corrections ||= SpellChecker.new(dictionary: class_names).correct(class_name).map(&:full_name)
|
17
14
|
end
|
18
15
|
|
19
16
|
def class_names
|
@@ -1,9 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# frozen-string-literal: true
|
2
2
|
|
3
3
|
module DidYouMean
|
4
4
|
class VariableNameChecker
|
5
5
|
attr_reader :name, :method_names, :lvar_names, :ivar_names, :cvar_names
|
6
6
|
|
7
|
+
NAMES_TO_EXCLUDE = { 'foo' => [:fork] }
|
8
|
+
NAMES_TO_EXCLUDE.default = []
|
9
|
+
|
7
10
|
def initialize(exception)
|
8
11
|
@name = exception.name.to_s.tr("@", "")
|
9
12
|
@lvar_names = exception.respond_to?(:local_variables) ? exception.local_variables : []
|
@@ -18,7 +21,7 @@ module DidYouMean
|
|
18
21
|
def corrections
|
19
22
|
@corrections ||= SpellChecker
|
20
23
|
.new(dictionary: (lvar_names + method_names + ivar_names + cvar_names))
|
21
|
-
.correct(name)
|
24
|
+
.correct(name) - NAMES_TO_EXCLUDE[@name]
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
data/lib/did_you_mean/version.rb
CHANGED
@@ -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 #{to_s}
|
23
|
+
undefined local variable or method `doesnt_exist' for #{method(:to_s).super_method.call}
|
24
24
|
Did you mean? does_exist
|
25
25
|
MESSAGE
|
26
26
|
|
@@ -36,18 +36,6 @@ 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
|
-
|
40
|
-
def test_correctable_error_objects_are_dumpable
|
41
|
-
error = begin
|
42
|
-
File.open('/tmp/file').sizee
|
43
|
-
rescue NoMethodError => e
|
44
|
-
e
|
45
|
-
end
|
46
|
-
|
47
|
-
error.to_s
|
48
|
-
|
49
|
-
assert_equal "undefined method `sizee' for #<File:/tmp/file>", Marshal.load(Marshal.dump(error)).original_message
|
50
|
-
end
|
51
39
|
end
|
52
40
|
|
53
41
|
class IgnoreCallersTest < Minitest::Test
|
data/test/spell_checker_test.rb
CHANGED
@@ -13,7 +13,6 @@ class SpellCheckerTest < Minitest::Test
|
|
13
13
|
|
14
14
|
assert_spell %w(gsub! gsub), input: 'gsuv!', dictionary: %w(sub gsub gsub!)
|
15
15
|
assert_spell %w(sub! sub gsub!), input: 'ssub!', dictionary: %w(sub sub! gsub gsub!)
|
16
|
-
assert_spell %i(read rand), input: 'raed', dictionary: File.methods + File.private_methods
|
17
16
|
|
18
17
|
group_methods = %w(groups group_url groups_url group_path)
|
19
18
|
assert_spell 'groups', input: 'group', dictionary: group_methods
|
@@ -62,16 +62,4 @@ 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
|
77
65
|
end
|
@@ -9,12 +9,6 @@ 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
|
-
|
18
12
|
protected
|
19
13
|
def the_protected_method; end
|
20
14
|
|
@@ -78,27 +72,18 @@ class MethodNameTest < Minitest::Test
|
|
78
72
|
assert_match "Did you mean? raise", error.to_s
|
79
73
|
end
|
80
74
|
|
81
|
-
def
|
82
|
-
error = assert_raises
|
83
|
-
|
84
|
-
@user.firstname
|
85
|
-
rescue NoMethodError => e
|
86
|
-
raise e, e.message, e.backtrace
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
assert_equal 1, error.to_s.scan(/Did you mean/).count
|
75
|
+
def test_exclude_methods_on_nil
|
76
|
+
error = assert_raises(NoMethodError){ nil.map }
|
77
|
+
assert_empty error.corrections
|
91
78
|
end
|
92
79
|
|
93
|
-
def
|
94
|
-
|
95
|
-
begin
|
96
|
-
@user.raise_no_method_error
|
97
|
-
rescue NoMethodError => e
|
98
|
-
raise e, e.message, e.backtrace
|
99
|
-
end
|
80
|
+
def test_does_not_exclude_custom_methods_on_nil
|
81
|
+
def nil.empty?
|
100
82
|
end
|
101
83
|
|
102
|
-
|
84
|
+
error = assert_raises(NoMethodError){ nil.empty }
|
85
|
+
assert_correction :empty?, error.corrections
|
86
|
+
ensure
|
87
|
+
NilClass.class_eval { undef empty? }
|
103
88
|
end
|
104
89
|
end
|
@@ -53,12 +53,8 @@ class VariableNameTest < Minitest::Test
|
|
53
53
|
person = person = nil
|
54
54
|
error = (eprson rescue $!) # Do not use @assert_raises here as it changes a scope.
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
assert_match "Did you mean? person", error.to_s
|
59
|
-
else
|
60
|
-
assert_empty error.corrections
|
61
|
-
end
|
56
|
+
assert_correction :person, error.corrections
|
57
|
+
assert_match "Did you mean? person", error.to_s
|
62
58
|
end
|
63
59
|
|
64
60
|
def test_corrections_include_instance_variable_name
|
@@ -85,4 +81,17 @@ class VariableNameTest < Minitest::Test
|
|
85
81
|
assert_correction :@@does_exist, error.corrections
|
86
82
|
assert_match "Did you mean? @@does_exist", error.to_s
|
87
83
|
end
|
84
|
+
|
85
|
+
def test_struct_name_error
|
86
|
+
value = Struct.new(:does_exist).new
|
87
|
+
error = assert_raises(NameError){ value[:doesnt_exist] }
|
88
|
+
|
89
|
+
assert_correction [:does_exist, :does_exist=], error.corrections
|
90
|
+
assert_match "Did you mean? does_exist", error.to_s
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_exclude_typical_incorrect_suggestions
|
94
|
+
error = assert_raises(NameError){ foo }
|
95
|
+
assert_empty error.corrections
|
96
|
+
end
|
88
97
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
|
-
require 'minitest/
|
2
|
+
require 'minitest/pride'
|
3
3
|
require 'did_you_mean'
|
4
4
|
|
5
|
+
puts "DidYouMean version: #{DidYouMean::VERSION}"
|
6
|
+
|
5
7
|
module DidYouMean::TestHelper
|
6
8
|
def assert_correction(expected, array)
|
7
|
-
assert_equal
|
9
|
+
assert_equal Array(expected), array, "Expected #{array.inspect} to only include #{expected.inspect}"
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -2,14 +2,15 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class VerboseFormatterTest < Minitest::Test
|
4
4
|
def setup
|
5
|
-
|
5
|
+
does_exist = does_exist = nil
|
6
|
+
@error = assert_raises(NameError){ doesnt_exist }
|
6
7
|
end
|
7
8
|
|
8
9
|
def test_message
|
9
10
|
assert_equal <<~MESSAGE.chomp, @error.message
|
10
|
-
undefined method `
|
11
|
+
undefined local variable or method `doesnt_exist' for #{method(:to_s).super_method.call}
|
11
12
|
|
12
|
-
Did you mean?
|
13
|
+
Did you mean? does_exist
|
13
14
|
|
14
15
|
MESSAGE
|
15
16
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: did_you_mean
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuki Nishijima
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,8 +52,7 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description:
|
56
|
-
the right one when you misspelled something.'
|
55
|
+
description: The gem that has been saving people from typos since 2014.
|
57
56
|
email:
|
58
57
|
- mail@yukinishijima.net
|
59
58
|
executables: []
|
@@ -61,6 +60,7 @@ extensions: []
|
|
61
60
|
extra_rdoc_files: []
|
62
61
|
files:
|
63
62
|
- ".gitignore"
|
63
|
+
- ".ruby-version"
|
64
64
|
- ".travis.yml"
|
65
65
|
- CHANGELOG.md
|
66
66
|
- Gemfile
|
@@ -84,7 +84,6 @@ files:
|
|
84
84
|
- lib/did_you_mean/experimental/initializer_name_correction.rb
|
85
85
|
- lib/did_you_mean/experimental/ivar_name_correction.rb
|
86
86
|
- lib/did_you_mean/experimental/key_error_name_correction.rb
|
87
|
-
- lib/did_you_mean/extra_features.rb
|
88
87
|
- lib/did_you_mean/formatter.rb
|
89
88
|
- lib/did_you_mean/jaro_winkler.rb
|
90
89
|
- lib/did_you_mean/levenshtein.rb
|
@@ -98,11 +97,9 @@ files:
|
|
98
97
|
- lib/did_you_mean/version.rb
|
99
98
|
- test/core_ext/name_error_extension_test.rb
|
100
99
|
- test/edit_distance/jaro_winkler_test.rb
|
101
|
-
- test/experimental/deprecated_features_test.rb
|
102
100
|
- test/experimental/initializer_name_correction_test.rb
|
103
101
|
- test/experimental/key_error_test.rb
|
104
102
|
- test/experimental/method_name_checker_test.rb
|
105
|
-
- test/fixtures/book.rb
|
106
103
|
- test/spell_checker_test.rb
|
107
104
|
- test/spell_checking/class_name_test.rb
|
108
105
|
- test/spell_checking/method_name_test.rb
|
@@ -110,7 +107,6 @@ files:
|
|
110
107
|
- test/spell_checking/variable_name_test.rb
|
111
108
|
- test/test_helper.rb
|
112
109
|
- test/verbose_formatter_test.rb
|
113
|
-
- tmp/.keep
|
114
110
|
homepage: https://github.com/yuki24/did_you_mean
|
115
111
|
licenses:
|
116
112
|
- MIT
|
@@ -123,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
119
|
requirements:
|
124
120
|
- - ">="
|
125
121
|
- !ruby/object:Gem::Version
|
126
|
-
version: 2.
|
122
|
+
version: 2.4.0dev
|
127
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
124
|
requirements:
|
129
125
|
- - ">="
|
@@ -131,18 +127,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
127
|
version: '0'
|
132
128
|
requirements: []
|
133
129
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.
|
130
|
+
rubygems_version: 2.6.8
|
135
131
|
signing_key:
|
136
132
|
specification_version: 4
|
137
133
|
summary: '"Did you mean?" experience in Ruby'
|
138
134
|
test_files:
|
139
135
|
- test/core_ext/name_error_extension_test.rb
|
140
136
|
- test/edit_distance/jaro_winkler_test.rb
|
141
|
-
- test/experimental/deprecated_features_test.rb
|
142
137
|
- test/experimental/initializer_name_correction_test.rb
|
143
138
|
- test/experimental/key_error_test.rb
|
144
139
|
- test/experimental/method_name_checker_test.rb
|
145
|
-
- test/fixtures/book.rb
|
146
140
|
- test/spell_checker_test.rb
|
147
141
|
- test/spell_checking/class_name_test.rb
|
148
142
|
- test/spell_checking/method_name_test.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class DeprecatedExtraFeaturesTest < Minitest::Test
|
4
|
-
def test_message
|
5
|
-
message = "The file 'did_you_mean/extra_features.rb' has been moved to " \
|
6
|
-
"'did_you_mean/experimental.rb'. Please `require 'did_you_mean/experimental'` " \
|
7
|
-
"instead.\n"
|
8
|
-
|
9
|
-
assert_output nil, message do
|
10
|
-
require 'did_you_mean/extra_features'
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
data/test/fixtures/book.rb
DELETED