did_you_mean 1.3.0 → 1.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50bf04523f12cc4556ea28643d05f957a6ed95288d022716bbd32b325ea10feb
4
- data.tar.gz: eeb093d01d27dae887f7ecbc5e4c530db5230743de2c7280b19f139f56e11638
3
+ metadata.gz: '088f268582576b904e0d73ca3efc4d0f5b1f1b0502a215215e0d7a93d8e3fd27'
4
+ data.tar.gz: fa0582301402135a7ea58e974a9314ec4aeb0f4866d18233bbd8d68e2354d24b
5
5
  SHA512:
6
- metadata.gz: '0941cfdae93b66e3485c0850f2763c869971a1d7cff386fe66d51739d8869155d8ae868016210a0d2935f81aa8185477c9db162029d5a754240f210a2f3b9df8'
7
- data.tar.gz: fc53dbc6ae27025325d36084b5be82f0b462addc83a3fa7a0b0b780b6aed2b2dc5f40cc3a3ad7213eeb2a03476723f0ae36681a534d27b9991c95d5ab2197b66
6
+ metadata.gz: 176153acc0119212a3cff509cc5abefed1ae8ae0a99a92131882242b5a4f0dd7a5dcddf3da7aff492c0d00bfa3ea2c155f549c4430b36775ed7d66de0cf1dd9a
7
+ data.tar.gz: 24b2ae0af79e1a359e25174412a431d53a122a5cce658e02c1c511ebfeab17708b86e62fb8a9a66b79334d5ea6788ca3972ed2bc30a1b1a2092eb105d5fe6331
@@ -12,4 +12,12 @@ after_success:
12
12
 
13
13
  rvm:
14
14
  - 2.5.3
15
+ - 2.6.0
15
16
  - ruby-head
17
+ - jruby-9.2.5.0
18
+ - jruby-head
19
+
20
+ matrix:
21
+ allow_failures:
22
+ - rvm: jruby-9.2.5.0
23
+ - rvm: jruby-head
@@ -1,3 +1,41 @@
1
+ ## v1.4.0 (Next)
2
+
3
+ - Remove the empty `tmp/` directory to comply with `rpmlint` ([#122](https://github.com/yuki24/did_you_mean/issues/122))
4
+ - Fixes a bug where suggestions are not shown on subsequent errors ([#120](https://github.com/yuki24/did_you_mean/issues/120))
5
+
6
+ ## [v1.3.0](https://github.com/yuki24/did_you_mean/tree/v1.3.0)
7
+
8
+ _<sup>released at 2018-12-18 15:37:10 UTC</sup>_
9
+
10
+ **Starting version 1.3, the `did_you_mean` gem will be compatible with 2.6 and 2.5, and we will try to keep all subsequent versions compatible with Ruby 2.5 on an best-effort basis.**
11
+
12
+ - Version 1.2.0 only has support for Ruby 2.5.0 and later as it uses new features that are only available in 2.5.
13
+ - Versions earlier than 1.1.\* will still be maintained until Ruby 2.4 is deprecated.
14
+ - Versions earlier than 1.0.\* is still maintained, but are likely to be deprecated as Ruby 2.3 will (probably) be deprecated in 2019.
15
+ - Support for versions below 1.0 has already ended.
16
+
17
+ #### New features
18
+
19
+ - Suggest reserved words if there are close matches ([<tt>2a082a7</tt>](https://github.com/yuki24/did_you_mean/commit/2a082a71991f5afe2e27ce9538103eac4c428025))
20
+
21
+ ```ruby
22
+ results = yiedl
23
+ # NameError => undefined local variable or method `yiedl' for ...
24
+ # Did you mean? yield
25
+ ```
26
+
27
+ #### Bug fixes
28
+
29
+ - Fixes a bug where name errors can not be dumped ([#108](https://github.com/yuki24/did_you_mean/issues/108), [@jessebs](https://github.com/jessebs))
30
+
31
+ ## [v1.2.2](https://github.com/yuki24/did_you_mean/tree/v1.2.2)
32
+
33
+ _<sup>released at 2019-03-09 23:17:22 UTC</sup>_
34
+
35
+ #### Bug fixes
36
+
37
+ - Fixes a bug where name errors can not be dumped ([#108](https://github.com/yuki24/did_you_mean/issues/108), [@jessebs](https://github.com/jessebs))
38
+
1
39
  ## [v1.2.1](https://github.com/yuki24/did_you_mean/tree/v1.2.1)
2
40
 
3
41
  _<sup>released at 2018-04-03 04:44:47 UTC</sup>_
@@ -23,6 +61,15 @@ _<sup>released at 2018-01-02 20:49:35 UTC</sup>_
23
61
  - Now suggests `true`, `false` or `nil` if a NameError occurs because of a typo in these names ([#94](https://github.com/yuki24/did_you_mean/pull/94), [@styd](https://github.com/styd))
24
62
  - New Formatter API: This provides a clean way to customize DidYouMean’s formatter without overriding the default formatter. Please refer to [the built-in verbose formatter](https://github.com/yuki24/did_you_mean/blob/671cdff/lib/did_you_mean/verbose.rb) for how to use it
25
63
 
64
+ ## [v1.1.3](https://github.com/yuki24/did_you_mean/tree/v1.1.3)
65
+
66
+ _<sup>released at 2019-03-09 23:16:54 UTC</sup>_
67
+
68
+ #### Bug fixes
69
+
70
+ - Fixes a bug where name errors can not be dumped ([#108](https://github.com/yuki24/did_you_mean/issues/108), [@jessebs](https://github.com/jessebs))
71
+ - Fixed a bug where DYM suggests the same class name in the error message ([#102](https://github.com/yuki24/did_you_mean/issues/102), [@schneems](https://github.com/schneems))
72
+
26
73
  ## [v1.1.2](https://github.com/yuki24/did_you_mean/tree/v1.1.2)
27
74
 
28
75
  _<sup>released at 2017-09-24 07:28:48 UTC</sup>_
@@ -69,6 +116,15 @@ The version `1.1.0` only has support for Ruby 2.4.0 and later. Also, all patch r
69
116
 
70
117
  - Fixed a bug where private method names were added to the dictionary when an argument was passed in to a public method. Use the `NoMethodError#private_call?` method instead ([<tt>0a1b761</tt>](https://github.com/yuki24/did_you_mean/commit/0a1b7612252055e583a373b473932f789381ca0f))
71
118
 
119
+ ## [v1.0.4](https://github.com/yuki24/did_you_mean/tree/v1.0.4)
120
+
121
+ _<sup>released at 2019-03-09 23:16:38 UTC</sup>_
122
+
123
+ #### Bug fixes
124
+
125
+ - Fixes a bug where name errors can not be dumped ([#108](https://github.com/yuki24/did_you_mean/issues/108), [@jessebs](https://github.com/jessebs))
126
+ - Fixed a bug where DYM suggests the same class name in the error message ([#102](https://github.com/yuki24/did_you_mean/issues/102), [@schneems](https://github.com/schneems))
127
+
72
128
  ## [v1.0.3](https://github.com/yuki24/did_you_mean/tree/v1.0.3)
73
129
 
74
130
  _<sup>released at 2017-09-24 07:22:07 UTC</sup>_
data/Gemfile CHANGED
@@ -4,5 +4,6 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'benchmark-ips'
7
+ gem 'benchmark-driver'
7
8
  gem 'memory_profiler'
8
9
  gem 'jaro_winkler', '>= 1.4.0'
data/README.md CHANGED
@@ -108,6 +108,17 @@ OBject
108
108
  #
109
109
  ```
110
110
 
111
+ ## Using the `DidYouMean::SpellChecker`
112
+
113
+ If you need to programmatically find the closest matches to the user input, you could do so by re-using the `DidYouMean::SpellChecker` object.
114
+
115
+ ```ruby
116
+ spell_checker = DidYouMean::SpellChecker.new(dictionary: ['email', 'fail', 'eval'])
117
+
118
+ spell_checker.correct('meail') # => ['email']
119
+ spell_checker.correct('afil') # => ['fail']
120
+ ```
121
+
111
122
  ## Disabling `did_you_mean`
112
123
 
113
124
  Occasionally, you may want to disable the `did_you_mean` gem for e.g. debugging issues in the error object itself. You
@@ -147,6 +158,29 @@ no_method_error.original_message
147
158
  # => NoMethodError (undefined method `zeor?' for 1:Integer)
148
159
  ```
149
160
 
161
+ ## Benchmarking
162
+
163
+ Performance is very important as the `did_you_mean` gem attempts to find the closest matches on the fly right after an exception
164
+ is thrown. You could use the following rake tasks to get insights into how the gem performs:
165
+
166
+ ```bash
167
+ bundle exec rake benchmark:ips:jaro
168
+ bundle exec rake benchmark:ips:levenshtein
169
+ bundle exec rake benchmark:memory
170
+ bundle exec rake benchmark:memory:jaro
171
+ bundle exec rake benchmark:memory:levenshtein
172
+ ```
173
+
174
+ **Be sure to always use `bundle exec` otherwise it will activate the pre-installed version of the `did_you_mean`
175
+ gem rather than using what's in the `lib/`.**
176
+
177
+ You could also use the [`benchmark-driver`](https://github.com/benchmark-driver/benchmark-driver) gem to know how each
178
+ Ruby performs differently.
179
+
180
+ ```bash
181
+ bundle exec benchmark-driver benchmark/speed.yml --rbenv '2.6.0 --jit;2.6.0;2.5.3;truffleruby-1.0.0-rc10' --run-duration 30
182
+ ```
183
+
150
184
  ## Contributing
151
185
 
152
186
  1. Fork it (http://github.com/yuki24/did_you_mean/fork)
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ namespace :test do
27
27
  end
28
28
  end
29
29
 
30
- desc "Calculate accuracy of the gems' spell checker"
30
+ desc "Calculate accuracy of the gem's spell checker"
31
31
  task :accuracy do
32
32
  if !File.exist?("evaluation/dictionary.yml")
33
33
  puts 'Generating dictionary for evaluation:'
@@ -40,8 +40,32 @@ namespace :test do
40
40
  end
41
41
 
42
42
  namespace :benchmark do
43
- desc "Measure memory usage by the did_you_mean gem"
43
+ namespace :ips do
44
+ desc "Measure performance of the gem's Jaro distance implementation"
45
+ task :jaro do
46
+ sh "ruby benchmark/jaro_winkler/speed.rb"
47
+ end
48
+
49
+ desc "Benchmark performance of the gem's Levenshtein distance implementation"
50
+ task :levenshtein do
51
+ sh "ruby benchmark/levenshtein/speed.rb"
52
+ end
53
+ end
54
+
55
+ desc "Benchmark memory usage in the gem's spell checker"
44
56
  task :memory do
45
- sh 'ruby benchmark/memory_usage.rb'
57
+ sh "ruby benchmark/memory_usage.rb"
58
+ end
59
+
60
+ namespace :memory do
61
+ desc "Benchmark memory usage in the gem's Jaro distance implementation"
62
+ task :jaro do
63
+ sh "ruby benchmark/jaro_winkler/memory_usage.rb"
64
+ end
65
+
66
+ desc "Benchmark memory usage in the gem's Levenshtein distance implementation"
67
+ task :levenshtein do
68
+ sh "ruby benchmark/levenshtein/memory_usage.rb"
69
+ end
46
70
  end
47
71
  end
@@ -1,11 +1,11 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'memory_profiler'
2
4
  require 'did_you_mean/jaro_winkler'
3
5
 
4
- str1, str2 = "user_signed_in?", "user_logged_in?"
5
-
6
6
  report = MemoryProfiler.report do
7
- 80.times do
8
- DidYouMean::Jaro.distance str1, str2
7
+ 1000.times do
8
+ DidYouMean::Jaro.distance "user_signed_in?", "user_logged_in?"
9
9
  end
10
10
  end
11
11
 
@@ -1,14 +1,22 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'benchmark/ips'
2
- require 'did_you_mean'
4
+ require 'did_you_mean/jaro_winkler'
3
5
 
4
6
  Benchmark.ips do |x|
5
- x.report "before" do
6
- DidYouMean::Jaro.before_distance "user_signed_in?", "user_logged_in?"
7
+ x.report "original" do
8
+ DidYouMean::Jaro.distance "user_signed_in?", "user_logged_in?"
7
9
  end
8
10
 
9
- x.report "after" do
10
- DidYouMean::Jaro.after_distance "user_signed_in?", "user_logged_in?"
11
- end
11
+ # This #proposed method is not defined. Write your own method using this
12
+ # name so we can reliably run the benchmark and measure the difference.
13
+ #
14
+ # Alternatively, you could directly update the #distance method and remove
15
+ # this completely.
16
+ #
17
+ # x.report "proposed" do
18
+ # DidYouMean::Jaro.proposed "user_signed_in?", "user_logged_in?"
19
+ # end
12
20
 
13
21
  x.compare!
14
22
  end
@@ -1,11 +1,11 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'memory_profiler'
2
4
  require 'did_you_mean/levenshtein'
3
5
 
4
- str1, str2 = "user_signed_in?", "user_logged_in?"
5
-
6
6
  report = MemoryProfiler.report do
7
- 80.times do
8
- DidYouMean::Levenshtein.distance str1, str2
7
+ 1000.times do
8
+ DidYouMean::Levenshtein.distance "user_signed_in?", "user_logged_in?"
9
9
  end
10
10
  end
11
11
 
@@ -1,17 +1,22 @@
1
+ # frozen-string-literal: true
2
+
1
3
  require 'benchmark/ips'
2
- require 'did_you_mean'
3
4
  require 'did_you_mean/levenshtein'
4
5
 
5
- STR1, STR2 = "user_signed_in?", "user_logged_in?"
6
-
7
6
  Benchmark.ips do |x|
8
- x.report "enumerable" do
9
- DidYouMean::Levenshtein.before_distance STR1, STR2
7
+ x.report "original" do
8
+ DidYouMean::Levenshtein.distance "user_signed_in?", "user_logged_in?"
10
9
  end
11
10
 
12
- x.report "while" do
13
- DidYouMean::Levenshtein.after_distance STR1, STR2
14
- end
11
+ # This #proposed method is not defined. Write your own method using this
12
+ # name so we can reliably run the benchmark and measure the difference.
13
+ #
14
+ # Alternatively, you could directly update the #distance method and remove
15
+ # this completely.
16
+ #
17
+ # x.report "proposed" do
18
+ # DidYouMean::Levenshtein.proposed "user_signed_in?", "user_logged_in?"
19
+ # end
15
20
 
16
21
  x.compare!
17
22
  end
@@ -0,0 +1,13 @@
1
+ prelude: |
2
+ require 'did_you_mean/spell_checker'
3
+
4
+ str1, str2 = "user_signed_in?", "user_logged_in?"
5
+ METHODS = ''.methods
6
+ INPUT = 'starts_with?'
7
+ collection = DidYouMean::SpellChecker.new(dictionary: METHODS)
8
+
9
+ benchmark:
10
+ Jaro: DidYouMean::Jaro.distance(str1, str2)
11
+ Jaro Winkler: DidYouMean::JaroWinkler.distance(str1, str2)
12
+ Levenshtein: DidYouMean::Levenshtein.distance(str1, str2)
13
+ Spell checker: collection.correct(INPUT)
@@ -6,11 +6,9 @@ module DidYouMean
6
6
 
7
7
  def to_s
8
8
  msg = super.dup
9
+ suggestion = DidYouMean.formatter.message_for(corrections)
9
10
 
10
- if !cause.respond_to?(:corrections) || cause.corrections.empty?
11
- msg << DidYouMean.formatter.message_for(corrections)
12
- end
13
-
11
+ msg << suggestion if !msg.end_with?(suggestion)
14
12
  msg
15
13
  rescue
16
14
  super
@@ -38,13 +38,7 @@ module DidYouMean
38
38
  private
39
39
 
40
40
  def normalize(str_or_symbol) #:nodoc:
41
- str = if str_or_symbol.is_a?(String)
42
- str_or_symbol.dup
43
- else
44
- str_or_symbol.to_s
45
- end
46
-
47
- str.downcase!
41
+ str = str_or_symbol.to_s.downcase
48
42
  str.tr!("@", "")
49
43
  str
50
44
  end
@@ -9,7 +9,7 @@ module DidYouMean
9
9
 
10
10
  # +MethodNameChecker::RB_RESERVED_WORDS+ is the list of reserved words in
11
11
  # Ruby that take an argument. Unlike
12
- # +VariableNameChecker::RB_RESERVED_WORDS+, those reserved words reqquires
12
+ # +VariableNameChecker::RB_RESERVED_WORDS+, these reserved words require
13
13
  # an argument, and a +NoMethodError+ is raised due to the presence of the
14
14
  # argument.
15
15
  #
@@ -1,3 +1,3 @@
1
1
  module DidYouMean
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
@@ -39,13 +39,13 @@ class NameErrorExtensionTest < Minitest::Test
39
39
 
40
40
  def test_correctable_error_objects_are_dumpable
41
41
  error = begin
42
- File.open('./tmp/.keep').sizee
42
+ File.open('did_you_mean.gemspec').sizee
43
43
  rescue NoMethodError => e
44
44
  e
45
45
  end
46
46
 
47
47
  error.to_s
48
48
 
49
- assert_equal "undefined method `sizee' for #<File:./tmp/.keep>", Marshal.load(Marshal.dump(error)).original_message
49
+ assert_equal "undefined method `sizee' for #<File:did_you_mean.gemspec>", Marshal.load(Marshal.dump(error)).original_message
50
50
  end
51
51
  end
@@ -117,6 +117,18 @@ class MethodNameCheckTest < Minitest::Test
117
117
  assert_equal 1, error.to_s.scan(/Did you mean/).count
118
118
  end
119
119
 
120
+ def test_suggests_corrections_on_nested_error
121
+ error = assert_raises NoMethodError do
122
+ begin
123
+ @user.firstname
124
+ rescue NoMethodError
125
+ @user.firstname
126
+ end
127
+ end
128
+
129
+ assert_equal 1, error.to_s.scan(/Did you mean/).count
130
+ end
131
+
120
132
  def test_suggests_yield
121
133
  error = assert_raises(NoMethodError) { yeild(1) }
122
134
 
@@ -50,11 +50,13 @@ class VariableNameCheckTest < Minitest::Test
50
50
  end
51
51
 
52
52
  def test_corrections_include_local_variable_name
53
- person = person = nil
54
- error = (eprson rescue $!) # Do not use @assert_raises here as it changes a scope.
53
+ if RUBY_ENGINE != "jruby"
54
+ person = person = nil
55
+ error = (eprson rescue $!) # Do not use @assert_raises here as it changes a scope.
55
56
 
56
- assert_correction :person, error.corrections
57
- assert_match "Did you mean? person", error.to_s
57
+ assert_correction :person, error.corrections
58
+ assert_match "Did you mean? person", error.to_s
59
+ end
58
60
  end
59
61
 
60
62
  def test_corrections_include_ruby_predefined_objects
@@ -4,8 +4,7 @@ class VerboseFormatterTest < Minitest::Test
4
4
  def setup
5
5
  require 'did_you_mean/verbose'
6
6
 
7
- does_exist = does_exist = nil
8
- @error = assert_raises(NameError){ doesnt_exist }
7
+ @error = assert_raises(NameError){ 1.zeor? }
9
8
  end
10
9
 
11
10
  def teardown
@@ -14,9 +13,9 @@ class VerboseFormatterTest < Minitest::Test
14
13
 
15
14
  def test_message
16
15
  assert_equal <<~MESSAGE.chomp, @error.message
17
- undefined local variable or method `doesnt_exist' for #{to_s}
16
+ undefined method `zeor?' for 1:Integer
18
17
 
19
- Did you mean? does_exist
18
+ Did you mean? zero?
20
19
 
21
20
  MESSAGE
22
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: did_you_mean
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuki Nishijima
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-18 00:00:00.000000000 Z
11
+ date: 2019-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -60,7 +60,6 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
- - ".ruby-version"
64
63
  - ".travis.yml"
65
64
  - CHANGELOG.md
66
65
  - Gemfile
@@ -72,6 +71,7 @@ files:
72
71
  - benchmark/levenshtein/memory_usage.rb
73
72
  - benchmark/levenshtein/speed.rb
74
73
  - benchmark/memory_usage.rb
74
+ - benchmark/speed.yml
75
75
  - did_you_mean.gemspec
76
76
  - doc/CHANGELOG.md.erb
77
77
  - doc/changelog_generator.rb
@@ -106,7 +106,6 @@ files:
106
106
  - test/spell_checking/variable_name_check_test.rb
107
107
  - test/test_helper.rb
108
108
  - test/verbose_formatter_test.rb
109
- - tmp/.keep
110
109
  homepage: https://github.com/yuki24/did_you_mean
111
110
  licenses:
112
111
  - MIT
@@ -126,8 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
125
  - !ruby/object:Gem::Version
127
126
  version: '0'
128
127
  requirements: []
129
- rubyforge_project:
130
- rubygems_version: 2.7.4
128
+ rubygems_version: 3.0.3
131
129
  signing_key:
132
130
  specification_version: 4
133
131
  summary: '"Did you mean?" experience in Ruby'
@@ -1 +0,0 @@
1
- 2.5.0