did_you_mean 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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