did_you_mean 0.3.1 → 0.4.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/.gitignore +1 -0
- data/.travis.yml +12 -1
- data/Appraisals +25 -0
- data/Rakefile +9 -0
- data/did_you_mean.gemspec +3 -4
- data/gemfiles/activerecord_30.gemfile +7 -0
- data/gemfiles/activerecord_31.gemfile +7 -0
- data/gemfiles/activerecord_32.gemfile +7 -0
- data/gemfiles/activerecord_40.gemfile +7 -0
- data/gemfiles/activerecord_41.gemfile +7 -0
- data/gemfiles/activerecord_edge.gemfile +9 -0
- data/lib/did_you_mean.rb +1 -1
- data/lib/did_you_mean/core_ext/name_error.rb +10 -36
- data/lib/did_you_mean/method_finder.rb +1 -1
- data/lib/did_you_mean/strategies.rb +23 -0
- data/lib/did_you_mean/strategies/similar_attribute_finder.rb +41 -0
- data/lib/did_you_mean/strategies/similar_method_finder.rb +46 -0
- data/lib/did_you_mean/strategies/similar_name_finder.rb +57 -0
- data/lib/did_you_mean/version.rb +1 -1
- data/test.sh +18 -0
- data/test/all_test.rb +3 -2
- data/test/similar_attribute_finder_test.rb +21 -0
- data/test/{no_method_error_extension_test.rb → similar_method_finder_test.rb} +21 -11
- data/test/{name_error_extension_test.rb → similar_name_finder_test.rb} +6 -6
- data/test/test_helper.rb +24 -1
- metadata +62 -7
- data/lib/did_you_mean/core_ext/no_method_error.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7304160d0a724a77cd37f5c0ad3068f6469117ea
|
4
|
+
data.tar.gz: 398c18be7e4768cb7bab4a1e5c335a70d2b005dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bc3de404cf9341f59d6068e9c768c6592735e7152b3c6e0698c34d73a6c2b72ea7e9c87a0b2de8b4f6bef84ea1b2eb3f5205af8e4e3d2d4ecbb3bc2824771e5
|
7
|
+
data.tar.gz: f48fc7b6ba5fbeb05f8994f0892eeeedf62b3270424e0001d9a232a03c1111bce626c77804ae3ebbc14fdc3e7c40a2f36700c6391d6701943b93d3a8f0f0ade0
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
script: "rake test"
|
1
|
+
script: "bundle install && bundle exec rake test"
|
2
2
|
|
3
3
|
rvm:
|
4
4
|
- 1.9.3
|
@@ -6,3 +6,14 @@ rvm:
|
|
6
6
|
- 2.1.0
|
7
7
|
- 2.1.1
|
8
8
|
- ruby-head
|
9
|
+
|
10
|
+
gemfile:
|
11
|
+
- gemfiles/activerecord_30.gemfile
|
12
|
+
- gemfiles/activerecord_31.gemfile
|
13
|
+
- gemfiles/activerecord_32.gemfile
|
14
|
+
- gemfiles/activerecord_40.gemfile
|
15
|
+
- gemfiles/activerecord_41.gemfile
|
16
|
+
- gemfiles/activerecord_edge.gemfile
|
17
|
+
|
18
|
+
matrix:
|
19
|
+
fast_finish: true
|
data/Appraisals
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
appraise "activerecord_30" do
|
2
|
+
gem "activerecord", "~> 3.0.0"
|
3
|
+
end
|
4
|
+
|
5
|
+
appraise "activerecord_31" do
|
6
|
+
gem "activerecord", "~> 3.1.0"
|
7
|
+
end
|
8
|
+
|
9
|
+
appraise "activerecord_32" do
|
10
|
+
gem "activerecord", "~> 3.2.0"
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise "activerecord_40" do
|
14
|
+
gem "activerecord", "~> 4.0.0"
|
15
|
+
end
|
16
|
+
|
17
|
+
appraise "activerecord_41" do
|
18
|
+
gem "activerecord", "~> 4.1.0"
|
19
|
+
end
|
20
|
+
|
21
|
+
appraise "activerecord_edge" do
|
22
|
+
git 'git://github.com/rails/rails.git' do
|
23
|
+
gem 'activerecord', require: 'activerecord'
|
24
|
+
end
|
25
|
+
end
|
data/Rakefile
CHANGED
@@ -25,3 +25,12 @@ task :test do
|
|
25
25
|
|
26
26
|
Rake::Task['clobber'].execute
|
27
27
|
end
|
28
|
+
|
29
|
+
namespace :test do
|
30
|
+
desc "Run tests without re-compiling extensions"
|
31
|
+
task :without_compile do
|
32
|
+
$stdout.puts("\033[33m")
|
33
|
+
sh "bundle exec ruby test/all_test.rb"
|
34
|
+
$stdout.puts("\033[0m")
|
35
|
+
end
|
36
|
+
end
|
data/did_you_mean.gemspec
CHANGED
@@ -25,8 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.5"
|
26
26
|
spec.add_development_dependency "rake"
|
27
27
|
spec.add_development_dependency "rake-compiler"
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
28
|
+
spec.add_development_dependency "appraisal"
|
29
|
+
spec.add_development_dependency "sqlite3"
|
30
|
+
spec.add_development_dependency "minitest"
|
32
31
|
end
|
data/lib/did_you_mean.rb
CHANGED
@@ -40,48 +40,22 @@ class NameError
|
|
40
40
|
@__did_you_mean_bindings_stack || []
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
alias original_to_s to_s
|
48
|
-
alias to_s to_s_with_did_you_mean
|
49
|
-
alias original_message original_to_s
|
50
|
-
|
51
|
-
def did_you_mean?
|
52
|
-
return if !undefined_local_variable_or_method? || (similar_methods.empty? && similar_local_variables.empty?)
|
53
|
-
|
54
|
-
output = "\n\n"
|
55
|
-
output << " Did you mean?\n"
|
56
|
-
|
57
|
-
unless similar_methods.empty?
|
58
|
-
output << " instance methods: ##{similar_methods.first}\n"
|
59
|
-
output << similar_methods[1..-1].map{|word| "#{' ' * 23}##{word}\n" }.join
|
60
|
-
end
|
61
|
-
|
62
|
-
output << "\n" if !similar_methods.empty? && !similar_local_variables.empty?
|
63
|
-
|
64
|
-
unless similar_local_variables.empty?
|
65
|
-
output << " local variables: #{similar_local_variables.map.first}\n"
|
66
|
-
output << similar_local_variables[1..-1].map{|word| "#{' ' * 23}##{word}\n" }.join
|
67
|
-
end
|
68
|
-
|
69
|
-
output
|
43
|
+
def frame_binding
|
44
|
+
@frame_binding ||= __did_you_mean_bindings_stack.first
|
70
45
|
end
|
71
46
|
|
72
|
-
def
|
73
|
-
|
47
|
+
def to_s_with_did_you_mean
|
48
|
+
original_message + did_you_mean?.to_s
|
74
49
|
end
|
75
50
|
|
76
|
-
|
77
|
-
|
78
|
-
end
|
51
|
+
alias original_message to_s
|
52
|
+
alias to_s to_s_with_did_you_mean
|
79
53
|
|
80
|
-
def
|
81
|
-
|
54
|
+
def did_you_mean?
|
55
|
+
method_finder.did_you_mean? if not method_finder.empty?
|
82
56
|
end
|
83
57
|
|
84
|
-
def
|
85
|
-
@
|
58
|
+
def method_finder
|
59
|
+
@method_finder ||= DidYouMean.strategies[self.class.to_s].build(self)
|
86
60
|
end
|
87
61
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DidYouMean
|
2
|
+
class NullFinder
|
3
|
+
def self.build(*)
|
4
|
+
new
|
5
|
+
end
|
6
|
+
|
7
|
+
def did_you_mean?; end
|
8
|
+
|
9
|
+
def empty?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
@@strategies = Hash.new(NullFinder)
|
15
|
+
|
16
|
+
def self.strategies
|
17
|
+
@@strategies
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'did_you_mean/strategies/similar_name_finder'
|
22
|
+
require 'did_you_mean/strategies/similar_method_finder'
|
23
|
+
require 'did_you_mean/strategies/similar_attribute_finder'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module DidYouMean
|
2
|
+
class SimilarAttributeFinder
|
3
|
+
attr_reader :columns, :attribute_name
|
4
|
+
|
5
|
+
def self.build(exception)
|
6
|
+
columns = exception.frame_binding.eval("self.class").columns
|
7
|
+
attribute_name = exception.original_message.gsub("unknown attribute: ", "")
|
8
|
+
|
9
|
+
new(attribute_name, columns)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(attribute_name, columns)
|
13
|
+
@attribute_name, @columns = attribute_name, columns
|
14
|
+
end
|
15
|
+
|
16
|
+
def did_you_mean?
|
17
|
+
return if empty?
|
18
|
+
|
19
|
+
output = "\n\n"
|
20
|
+
output << " Did you mean? #{format(similar_columns.first)}\n"
|
21
|
+
output << similar_columns[1..-1].map{|word| "#{' ' * 18}#{format(word)}\n" }.join
|
22
|
+
output
|
23
|
+
end
|
24
|
+
|
25
|
+
def empty?
|
26
|
+
similar_columns.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
def similar_columns
|
30
|
+
@similar_columns ||= MethodMatcher.new(columns.map(&:name), attribute_name).similar_methods
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def format(name)
|
36
|
+
"%s: %s" % [name, columns.detect{|c| c.name == name }.type]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
strategies["ActiveRecord::UnknownAttributeError"] = SimilarAttributeFinder
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module DidYouMean
|
2
|
+
class SimilarMethodFinder
|
3
|
+
attr_reader :name, :receiver
|
4
|
+
|
5
|
+
def self.build(exception)
|
6
|
+
new(exception.name, exception.args.first)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(name, receiver)
|
10
|
+
@name, @receiver = name, receiver
|
11
|
+
end
|
12
|
+
|
13
|
+
def did_you_mean?
|
14
|
+
return if empty?
|
15
|
+
|
16
|
+
output = "\n\n"
|
17
|
+
output << " Did you mean? #{separator}#{similar_methods.first}\n"
|
18
|
+
output << similar_methods[1..-1].map{|word| "#{' ' * 17}#{separator}#{word}\n" }.join
|
19
|
+
output
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
similar_methods.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def similar_methods
|
27
|
+
@similar_methods ||= MethodMatcher.new(receiver.methods + receiver.singleton_methods, name).similar_methods
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def receiver_name
|
33
|
+
class_method? ? receiver.name : receiver.class.name
|
34
|
+
end
|
35
|
+
|
36
|
+
def separator
|
37
|
+
class_method? ? "." : "#"
|
38
|
+
end
|
39
|
+
|
40
|
+
def class_method?
|
41
|
+
receiver.is_a? Class
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
strategies["NoMethodError"] = SimilarMethodFinder
|
46
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module DidYouMean
|
2
|
+
class SimilarNameFinder
|
3
|
+
attr_reader :name, :_methods, :_local_variables, :original_message
|
4
|
+
|
5
|
+
def self.build(exception)
|
6
|
+
methods = exception.frame_binding.eval("methods")
|
7
|
+
local_variables = exception.frame_binding.eval("local_variables")
|
8
|
+
original_message = exception.original_message
|
9
|
+
|
10
|
+
new(exception.name, methods, local_variables, original_message)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(name, methods, local_variables, original_message)
|
14
|
+
@name, @_methods, @_local_variables, @original_message =
|
15
|
+
name, methods, local_variables, original_message
|
16
|
+
end
|
17
|
+
|
18
|
+
def did_you_mean?
|
19
|
+
return if empty?
|
20
|
+
|
21
|
+
output = "\n\n"
|
22
|
+
output << " Did you mean?\n"
|
23
|
+
|
24
|
+
unless similar_methods.empty?
|
25
|
+
output << " instance methods: ##{similar_methods.first}\n"
|
26
|
+
output << similar_methods[1..-1].map{|word| "#{' ' * 23}##{word}\n" }.join
|
27
|
+
end
|
28
|
+
|
29
|
+
output << "\n" if !similar_methods.empty? && !similar_local_variables.empty?
|
30
|
+
|
31
|
+
unless similar_local_variables.empty?
|
32
|
+
output << " local variables: #{similar_local_variables.map.first}\n"
|
33
|
+
output << similar_local_variables[1..-1].map{|word| "#{' ' * 23}##{word}\n" }.join
|
34
|
+
end
|
35
|
+
|
36
|
+
output
|
37
|
+
end
|
38
|
+
|
39
|
+
def empty?
|
40
|
+
!undefined_local_variable_or_method? || (similar_methods.empty? && similar_local_variables.empty?)
|
41
|
+
end
|
42
|
+
|
43
|
+
def similar_methods
|
44
|
+
@similar_methods ||= DidYouMean::MethodMatcher.new(_methods, name).similar_methods
|
45
|
+
end
|
46
|
+
|
47
|
+
def similar_local_variables
|
48
|
+
@similar_local_variables ||= DidYouMean::MethodMatcher.new(_local_variables, name).similar_methods
|
49
|
+
end
|
50
|
+
|
51
|
+
def undefined_local_variable_or_method?
|
52
|
+
original_message.include?("undefined local variable or method")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
strategies["NameError"] = SimilarNameFinder
|
57
|
+
end
|
data/lib/did_you_mean/version.rb
CHANGED
data/test.sh
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
for ruby_version in 1.9.3-p545 2.0.0-p451 2.1.0 2.1.1 head
|
4
|
+
do
|
5
|
+
echo -e "\e[32mTesting did_you_mean for Ruby $ruby_version\e[39m"
|
6
|
+
|
7
|
+
source ~/.rvm/environments/ruby-$ruby_version
|
8
|
+
ruby -v
|
9
|
+
|
10
|
+
bundle install
|
11
|
+
appraisal install
|
12
|
+
|
13
|
+
rake compile
|
14
|
+
appraisal rake test:without_compile
|
15
|
+
rake clobber
|
16
|
+
|
17
|
+
echo ""
|
18
|
+
done
|
data/test/all_test.rb
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
1
|
+
require_relative 'similar_name_finder_test'
|
2
|
+
require_relative 'similar_method_finder_test'
|
3
|
+
require_relative 'similar_attribute_finder_test'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class SimilarAttributeFinderTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@error = assert_raises(ActiveRecord::UnknownAttributeError) do
|
6
|
+
User.new(flrst_name: "wrong flrst name")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_similar_columns
|
11
|
+
assert @error.method_finder.similar_columns.include?("first_name")
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_did_you_mean?
|
15
|
+
assert_match "Did you mean? first_name: string", @error.did_you_mean?
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_message
|
19
|
+
assert_match @error.did_you_mean?, @error.message
|
20
|
+
end
|
21
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class SimilarMethodFinderTest < Minitest::Test
|
4
4
|
class User
|
5
5
|
def friends; end
|
6
6
|
def first_name; end
|
@@ -23,23 +23,33 @@ class NoMethodErrorExtensionTest < Test::Unit::TestCase
|
|
23
23
|
user = User.new.extend(UserModule)
|
24
24
|
|
25
25
|
@errors = {
|
26
|
-
from_instance_method:
|
27
|
-
from_private_method:
|
28
|
-
from_module_method:
|
29
|
-
from_class_method:
|
26
|
+
from_instance_method: assert_raises(NoMethodError){ user.flrst_name },
|
27
|
+
from_private_method: assert_raises(NoMethodError){ user.friend },
|
28
|
+
from_module_method: assert_raises(NoMethodError){ user.fr0m_module },
|
29
|
+
from_class_method: assert_raises(NoMethodError){ User.l0ad }
|
30
30
|
}
|
31
31
|
end
|
32
32
|
|
33
|
+
def test_unknown_attribute_error_with_did_you_mean
|
34
|
+
error = assert_raises(ActiveRecord::UnknownAttributeError) do
|
35
|
+
::User.new(flrst_name: "wrong flrst name")
|
36
|
+
end
|
37
|
+
|
38
|
+
assert error.method_finder.similar_columns.include?("first_name")
|
39
|
+
assert_match "Did you mean? first_name", error.did_you_mean?
|
40
|
+
assert_match error.did_you_mean?, error.message
|
41
|
+
end
|
42
|
+
|
33
43
|
def test_similar_methods
|
34
|
-
assert @errors[:from_instance_method].similar_methods.include?(:first_name)
|
35
|
-
assert @errors[:from_private_method].similar_methods.include?(:friends)
|
36
|
-
assert @errors[:from_module_method].similar_methods.include?(:from_module)
|
37
|
-
assert @errors[:from_class_method].similar_methods.include?(:load)
|
44
|
+
assert @errors[:from_instance_method].method_finder.similar_methods.include?(:first_name)
|
45
|
+
assert @errors[:from_private_method].method_finder.similar_methods.include?(:friends)
|
46
|
+
assert @errors[:from_module_method].method_finder.similar_methods.include?(:from_module)
|
47
|
+
assert @errors[:from_class_method].method_finder.similar_methods.include?(:load)
|
38
48
|
end
|
39
49
|
|
40
50
|
def test_similar_methods_for_long_method_name
|
41
|
-
error =
|
42
|
-
assert error.similar_methods.include?(:descendants)
|
51
|
+
error = assert_raises(NoMethodError){ User.new.dependents }
|
52
|
+
assert error.method_finder.similar_methods.include?(:descendants)
|
43
53
|
end
|
44
54
|
|
45
55
|
def test_did_you_mean?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class SimilarNameFinderTest < Minitest::Test
|
4
4
|
class User
|
5
5
|
def call_flrst_name; f1rst_name; end
|
6
6
|
def call_fr0m_module; fr0m_module; end
|
@@ -15,8 +15,8 @@ class NameErrorExtensionTest < Test::Unit::TestCase
|
|
15
15
|
user = User.new.extend(UserModule)
|
16
16
|
|
17
17
|
@errors = {
|
18
|
-
from_instance_method:
|
19
|
-
from_module_method:
|
18
|
+
from_instance_method: assert_raises(NameError){ user.call_flrst_name },
|
19
|
+
from_module_method: assert_raises(NameError){ user.call_fr0m_module }
|
20
20
|
}
|
21
21
|
|
22
22
|
begin
|
@@ -27,12 +27,12 @@ class NameErrorExtensionTest < Test::Unit::TestCase
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def test_similar_methods
|
30
|
-
assert @errors[:from_instance_method].similar_methods.include?(:first_name)
|
31
|
-
assert @errors[:from_module_method].similar_methods.include?(:from_module)
|
30
|
+
assert @errors[:from_instance_method].method_finder.similar_methods.include?(:first_name)
|
31
|
+
assert @errors[:from_module_method].method_finder.similar_methods.include?(:from_module)
|
32
32
|
end
|
33
33
|
|
34
34
|
def test_similar_local_variables
|
35
|
-
assert @instance_variable_error.similar_local_variables.include?(:user)
|
35
|
+
assert @instance_variable_error.method_finder.similar_local_variables.include?(:user)
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_did_you_mean?
|
data/test/test_helper.rb
CHANGED
@@ -1,2 +1,25 @@
|
|
1
|
-
require '
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'minitest/unit'
|
2
3
|
require 'did_you_mean'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
begin
|
7
|
+
MiniTest::Test
|
8
|
+
rescue NameError
|
9
|
+
MiniTest::Test = MiniTest::Unit::TestCase
|
10
|
+
end
|
11
|
+
|
12
|
+
# database
|
13
|
+
ActiveRecord::Base.configurations = {'test' => {adapter: 'sqlite3', database: ':memory:'}}
|
14
|
+
ActiveRecord::Base.establish_connection('test')
|
15
|
+
|
16
|
+
# models
|
17
|
+
class User < ActiveRecord::Base; end
|
18
|
+
|
19
|
+
class CreateAllTables < ActiveRecord::Migration
|
20
|
+
def self.up
|
21
|
+
create_table(:users) {|t| t.string :first_name; t.integer :last_name }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
ActiveRecord::Migration.verbose = false
|
25
|
+
CreateAllTables.up
|
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: 0.
|
4
|
+
version: 0.4.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: 2014-
|
11
|
+
date: 2014-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: text
|
@@ -80,6 +80,48 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: appraisal
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sqlite3
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: minitest
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
83
125
|
description: It adds "did you mean?" experience on NoMethodError and NameError because
|
84
126
|
of a typo.
|
85
127
|
email:
|
@@ -91,6 +133,7 @@ extra_rdoc_files: []
|
|
91
133
|
files:
|
92
134
|
- ".gitignore"
|
93
135
|
- ".travis.yml"
|
136
|
+
- Appraisals
|
94
137
|
- Gemfile
|
95
138
|
- LICENSE.txt
|
96
139
|
- README.md
|
@@ -231,14 +274,25 @@ files:
|
|
231
274
|
- ext/did_you_mean/ruby_headers/220/vm_insnhelper.h
|
232
275
|
- ext/did_you_mean/ruby_headers/220/vm_opts.h
|
233
276
|
- ext/did_you_mean/vm_method.c
|
277
|
+
- gemfiles/activerecord_30.gemfile
|
278
|
+
- gemfiles/activerecord_31.gemfile
|
279
|
+
- gemfiles/activerecord_32.gemfile
|
280
|
+
- gemfiles/activerecord_40.gemfile
|
281
|
+
- gemfiles/activerecord_41.gemfile
|
282
|
+
- gemfiles/activerecord_edge.gemfile
|
234
283
|
- lib/did_you_mean.rb
|
235
284
|
- lib/did_you_mean/core_ext/name_error.rb
|
236
|
-
- lib/did_you_mean/core_ext/no_method_error.rb
|
237
285
|
- lib/did_you_mean/method_finder.rb
|
286
|
+
- lib/did_you_mean/strategies.rb
|
287
|
+
- lib/did_you_mean/strategies/similar_attribute_finder.rb
|
288
|
+
- lib/did_you_mean/strategies/similar_method_finder.rb
|
289
|
+
- lib/did_you_mean/strategies/similar_name_finder.rb
|
238
290
|
- lib/did_you_mean/version.rb
|
291
|
+
- test.sh
|
239
292
|
- test/all_test.rb
|
240
|
-
- test/
|
241
|
-
- test/
|
293
|
+
- test/similar_attribute_finder_test.rb
|
294
|
+
- test/similar_method_finder_test.rb
|
295
|
+
- test/similar_name_finder_test.rb
|
242
296
|
- test/test_helper.rb
|
243
297
|
homepage: https://github.com/yuki24/did_you_mean
|
244
298
|
licenses:
|
@@ -266,6 +320,7 @@ specification_version: 4
|
|
266
320
|
summary: '"Did you mean?" experience in Ruby'
|
267
321
|
test_files:
|
268
322
|
- test/all_test.rb
|
269
|
-
- test/
|
270
|
-
- test/
|
323
|
+
- test/similar_attribute_finder_test.rb
|
324
|
+
- test/similar_method_finder_test.rb
|
325
|
+
- test/similar_name_finder_test.rb
|
271
326
|
- test/test_helper.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class NoMethodError
|
2
|
-
def receiver
|
3
|
-
args.first
|
4
|
-
end
|
5
|
-
|
6
|
-
def did_you_mean?
|
7
|
-
return if similar_methods.empty?
|
8
|
-
|
9
|
-
output = "\n\n"
|
10
|
-
output << " Did you mean? #{separator}#{similar_methods.first}\n"
|
11
|
-
output << similar_methods[1..-1].map{|word| "#{' ' * 17}#{separator}#{word}\n" }.join
|
12
|
-
end
|
13
|
-
|
14
|
-
def similar_methods
|
15
|
-
@similar_methods ||= DidYouMean::MethodFinder.new(receiver.methods + receiver.singleton_methods, name).similar_methods
|
16
|
-
end
|
17
|
-
|
18
|
-
def receiver_name
|
19
|
-
class_method? ? receiver.name : receiver.class.name
|
20
|
-
end
|
21
|
-
|
22
|
-
def separator
|
23
|
-
class_method? ? "." : "#"
|
24
|
-
end
|
25
|
-
|
26
|
-
def class_method?
|
27
|
-
receiver.is_a? Class
|
28
|
-
end
|
29
|
-
end
|