aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
authorGuillermo Iguaran <guilleiguaran@gmail.com>2018-03-29 11:05:47 -0500
committerGitHub <noreply@github.com>2018-03-29 11:05:47 -0500
commit480595e4919256ce692cb43f53ef05cb43d93cff (patch)
treee2ea880c72c1ce012a1ee2d6cbf85fb8fed65701 /railties
parent1765f09b10483f69fd13c238db7122179d8b4e6a (diff)
parentcb25f2c989588edf77f978820196b4446e01ffe8 (diff)
downloadrails-480595e4919256ce692cb43f53ef05cb43d93cff.tar.gz
rails-480595e4919256ce692cb43f53ef05cb43d93cff.tar.bz2
rails-480595e4919256ce692cb43f53ef05cb43d93cff.zip
Merge pull request #32289 from gsamokovarov/did-you-mean-suggestions
Use `did_you_mean` spell checker for option suggestions
Diffstat (limited to 'railties')
-rw-r--r--railties/lib/rails/command/spellchecker.rb46
-rw-r--r--railties/lib/rails/commands/server/server_command.rb4
-rw-r--r--railties/lib/rails/generators.rb11
-rw-r--r--railties/test/command/spellchecker_test.rb2
-rw-r--r--railties/test/commands/server_test.rb2
-rw-r--r--railties/test/generators_test.rb6
6 files changed, 14 insertions, 57 deletions
diff --git a/railties/lib/rails/command/spellchecker.rb b/railties/lib/rails/command/spellchecker.rb
index 59ccab4ea2..154358cd45 100644
--- a/railties/lib/rails/command/spellchecker.rb
+++ b/railties/lib/rails/command/spellchecker.rb
@@ -3,50 +3,8 @@
module Rails
module Command
module Spellchecker # :nodoc:
- class << self
- def suggest(word, from:, count: 3)
- from.sort_by { |w| levenshtein_distance(word, w) }.take(count)
- end
-
- private
- # This code is based directly on the Text gem implementation.
- # Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
- #
- # Returns a value representing the "cost" of transforming str1 into str2.
- def levenshtein_distance(str1, str2) # :doc:
- s = str1
- t = str2
- n = s.length
- m = t.length
-
- return m if (0 == n)
- return n if (0 == m)
-
- d = (0..m).to_a
- x = nil
-
- # avoid duplicating an enumerable object in the loop
- str2_codepoint_enumerable = str2.each_codepoint
-
- str1.each_codepoint.with_index do |char1, i|
- e = i + 1
-
- str2_codepoint_enumerable.with_index do |char2, j|
- cost = (char1 == char2) ? 0 : 1
- x = [
- d[j + 1] + 1, # insertion
- e + 1, # deletion
- d[j] + cost # substitution
- ].min
- d[j] = e
- e = x
- end
-
- d[m] = x
- end
-
- x
- end
+ def self.suggest(word, from:)
+ DidYouMean::SpellChecker.new(dictionary: from.map(&:to_s)).correct(word).first
end
end
end
diff --git a/railties/lib/rails/commands/server/server_command.rb b/railties/lib/rails/commands/server/server_command.rb
index 8588e2fd64..6da300e356 100644
--- a/railties/lib/rails/commands/server/server_command.rb
+++ b/railties/lib/rails/commands/server/server_command.rb
@@ -283,10 +283,10 @@ module Rails
Run `rails server --help` for more options.
MSG
else
- suggestions = Rails::Command::Spellchecker.suggest(server, from: RACK_SERVERS).map(&:inspect)
+ suggestions = Rails::Command::Spellchecker.suggest(server, from: RACK_SERVERS)
<<~MSG
- Could not find server "#{server}". Maybe you meant #{suggestions.first} or #{suggestions.second}?
+ Could not find server "#{server}". Maybe you meant #{suggestions.inspect}?
Run `rails server --help` for more options.
MSG
end
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 7248fbbc94..f468d82f14 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -276,12 +276,11 @@ module Rails
klass.start(args, config)
else
options = sorted_groups.flat_map(&:last)
- suggestions = Rails::Command::Spellchecker.suggest(namespace.to_s, from: options, count: 3)
- suggestions.map! { |s| "'#{s}'" }
- msg = "Could not find generator '#{namespace}'. ".dup
- msg << "Maybe you meant #{ suggestions[0...-1].join(', ')} or #{suggestions[-1]}\n"
- msg << "Run `rails generate --help` for more options."
- puts msg
+ suggestion = Rails::Command::Spellchecker.suggest(namespace.to_s, from: options)
+ puts <<~MSG
+ Could not find generator '#{namespace}'. Maybe you meant #{suggestion.inspect}?\n"
+ Run `rails generate --help` for more options."
+ MSG
end
end
diff --git a/railties/test/command/spellchecker_test.rb b/railties/test/command/spellchecker_test.rb
index aff50a3e73..e6a7a3957c 100644
--- a/railties/test/command/spellchecker_test.rb
+++ b/railties/test/command/spellchecker_test.rb
@@ -5,6 +5,6 @@ require "rails/command/spellchecker"
class Rails::Command::SpellcheckerTest < ActiveSupport::TestCase
test "suggests a word correction from dictionary" do
- assert_equal %w(thin cgi puma), Rails::Command::Spellchecker.suggest("tin", from: %w(puma thin cgi))
+ assert_equal "thin", Rails::Command::Spellchecker.suggest("tin", from: %w(puma thin cgi))
end
end
diff --git a/railties/test/commands/server_test.rb b/railties/test/commands/server_test.rb
index 467afe7cea..bdaab477f1 100644
--- a/railties/test/commands/server_test.rb
+++ b/railties/test/commands/server_test.rb
@@ -29,7 +29,7 @@ class Rails::Command::ServerCommandTest < ActiveSupport::TestCase
end
def test_using_server_mistype
- assert_match(/Could not find server "tin". Maybe you meant "thin" or "cgi"/, run_command("--using", "tin"))
+ assert_match(/Could not find server "tin". Maybe you meant "thin"?/, run_command("--using", "tin"))
end
def test_using_positional_argument_deprecation
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index 9f1f2a2289..a16a2d3f0a 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -33,7 +33,7 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_generator_suggestions
name = :migrationz
output = capture(:stdout) { Rails::Generators.invoke name }
- assert_match "Maybe you meant 'migration'", output
+ assert_match 'Maybe you meant "migration"?', output
end
def test_generator_suggestions_except_en_locale
@@ -43,7 +43,7 @@ class GeneratorsTest < Rails::Generators::TestCase
I18n.default_locale = :ja
name = :tas
output = capture(:stdout) { Rails::Generators.invoke name }
- assert_match "Maybe you meant 'task', 'job' or", output
+ assert_match 'Maybe you meant "task"?', output
ensure
I18n.available_locales = orig_available_locales
I18n.default_locale = orig_default_locale
@@ -52,7 +52,7 @@ class GeneratorsTest < Rails::Generators::TestCase
def test_generator_multiple_suggestions
name = :tas
output = capture(:stdout) { Rails::Generators.invoke name }
- assert_match "Maybe you meant 'task', 'job' or", output
+ assert_match 'Maybe you meant "task"?', output
end
def test_help_when_a_generator_with_required_arguments_is_invoked_without_arguments