did_you_mean 1.0.0.beta2 → 1.0.0.beta3
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/benchmark/memory_usage.rb +3 -1
- data/evaluation/calculator.rb +6 -4
- data/lib/did_you_mean.rb +2 -2
- data/lib/did_you_mean/formatter.rb +5 -3
- data/lib/did_you_mean/spell_checkable.rb +3 -4
- data/lib/did_you_mean/spell_checkers/method_name_checker.rb +1 -1
- data/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb +8 -17
- data/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb +3 -1
- data/lib/did_you_mean/version.rb +1 -1
- data/test/core_ext/name_error_extension_test.rb +1 -1
- data/test/spell_checker_test.rb +27 -37
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad488ff1d9e183f4789342bedca9e195be934b6a
|
4
|
+
data.tar.gz: 755225707c5e7ef906bba989dad41d4130c8b410
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecb0285487ed45ff04f470581b621a0d50681b62d6b4c099e04139b1082ca9ed92373bc3d2a6f1b4207172dfa62b90b112bd7df0d782ab43ffb4b0741608250a
|
7
|
+
data.tar.gz: 43ef649c7a45e82492938bf3ed90dad0c02337eb40f1873986cdd8bca8dc0c4b170495f277eed7b6b018f82f36f1ca954b46ecd8e5fc7cb6f16845665f7251c8
|
data/benchmark/memory_usage.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- frozen-string-literal: true -*-
|
2
|
+
|
1
3
|
require 'memory_profiler'
|
2
4
|
require 'did_you_mean'
|
3
5
|
|
@@ -12,7 +14,7 @@ class DidYouMean::WordCollection
|
|
12
14
|
@words = words
|
13
15
|
end
|
14
16
|
|
15
|
-
def similar_to(input, filter =
|
17
|
+
def similar_to(input, filter = '')
|
16
18
|
@corrections, @input = nil, input
|
17
19
|
corrections
|
18
20
|
end
|
data/evaluation/calculator.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- frozen-string-literal: true -*-
|
2
|
+
|
1
3
|
require 'benchmark'
|
2
4
|
|
3
5
|
def report(message, &block)
|
@@ -44,7 +46,7 @@ report "loading program" do
|
|
44
46
|
@words = words
|
45
47
|
end
|
46
48
|
|
47
|
-
def similar_to(input, filter =
|
49
|
+
def similar_to(input, filter = '')
|
48
50
|
@corrections, @input = nil, input
|
49
51
|
corrections
|
50
52
|
end
|
@@ -60,7 +62,7 @@ end
|
|
60
62
|
|
61
63
|
report "loading dictionary" do
|
62
64
|
yaml = open("evaluation/dictionary.yml").read
|
63
|
-
yaml = YAML.load(yaml).map{|word| word.downcase.tr(" "
|
65
|
+
yaml = YAML.load(yaml).map{|word| word.downcase.tr(" ", "_") }
|
64
66
|
|
65
67
|
DICTIONARY = Set.new(yaml)
|
66
68
|
end
|
@@ -92,8 +94,8 @@ report "calculating accuracy" do
|
|
92
94
|
correct_count += 1
|
93
95
|
else
|
94
96
|
words_not_corrected << {
|
95
|
-
correct
|
96
|
-
'result'
|
97
|
+
correct => incorrect,
|
98
|
+
'result' => corrections
|
97
99
|
}
|
98
100
|
end
|
99
101
|
end
|
data/lib/did_you_mean.rb
CHANGED
@@ -10,10 +10,10 @@ require "did_you_mean/formatter"
|
|
10
10
|
|
11
11
|
module DidYouMean
|
12
12
|
@@trace = TracePoint.new(:raise) do |tp|
|
13
|
-
e
|
13
|
+
e = tp.raised_exception
|
14
14
|
|
15
15
|
if SPELL_CHECKERS.include?(e.class.to_s) && !e.instance_variable_defined?(:@frame_binding)
|
16
|
-
e.instance_variable_set(:@frame_binding,
|
16
|
+
e.instance_variable_set(:@frame_binding, tp.binding)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
@@trace.enable
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# -*- frozen-string-literal: true -*-
|
2
|
+
|
1
3
|
module DidYouMean
|
2
4
|
class Formatter
|
3
5
|
def initialize(corrections = [])
|
@@ -5,10 +7,10 @@ module DidYouMean
|
|
5
7
|
end
|
6
8
|
|
7
9
|
def to_s
|
8
|
-
return ""
|
10
|
+
return "" if @corrections.empty?
|
9
11
|
|
10
|
-
output = "\nDid you mean? "
|
11
|
-
output << @corrections.join("\n"
|
12
|
+
output = "\nDid you mean? ".dup
|
13
|
+
output << @corrections.join("\n ")
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
+
# -*- frozen-string-literal: true -*-
|
2
|
+
|
1
3
|
require "did_you_mean/levenshtein"
|
2
4
|
require "did_you_mean/jaro_winkler"
|
3
5
|
|
4
6
|
module DidYouMean
|
5
7
|
module SpellCheckable
|
6
|
-
AT = "@".freeze
|
7
|
-
EMPTY = "".freeze
|
8
|
-
|
9
8
|
def corrections
|
10
9
|
@corrections ||= candidates.flat_map do |input, candidates|
|
11
10
|
input = normalize(input)
|
@@ -47,7 +46,7 @@ module DidYouMean
|
|
47
46
|
end
|
48
47
|
|
49
48
|
str.downcase!
|
50
|
-
str.tr!(
|
49
|
+
str.tr!("@", "")
|
51
50
|
str
|
52
51
|
end
|
53
52
|
end
|
@@ -12,7 +12,7 @@ module DidYouMean
|
|
12
12
|
@receiver = exception.receiver
|
13
13
|
@binding = exception.frame_binding
|
14
14
|
@location = exception.backtrace_locations.first
|
15
|
-
@ivar_names =
|
15
|
+
@ivar_names = @binding.receiver.instance_variables
|
16
16
|
end
|
17
17
|
|
18
18
|
def candidates
|
@@ -1,50 +1,41 @@
|
|
1
|
+
# -*- frozen-string-literal: true -*-
|
1
2
|
require 'delegate'
|
2
3
|
|
3
4
|
module DidYouMean
|
4
5
|
class ClassNameChecker
|
5
6
|
include SpellCheckable
|
6
|
-
attr_reader :class_name
|
7
|
+
attr_reader :class_name
|
7
8
|
|
8
9
|
def initialize(exception)
|
9
|
-
@class_name, @
|
10
|
+
@class_name, @receiver = exception.name, exception.receiver
|
10
11
|
end
|
11
12
|
|
12
13
|
def candidates
|
13
|
-
{
|
14
|
+
{class_name => class_names}
|
14
15
|
end
|
15
16
|
|
16
17
|
def class_names
|
17
18
|
scopes.flat_map do |scope|
|
18
19
|
scope.constants.map do |c|
|
19
|
-
ClassName.new(c, scope == Object ?
|
20
|
+
ClassName.new(c, scope == Object ? "" : "#{scope}::")
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
|
-
def name_from_message
|
25
|
-
class_name || /([A-Z]\w*$)/.match(original_message)[0]
|
26
|
-
end
|
27
|
-
|
28
25
|
def corrections
|
29
26
|
super.map(&:full_name)
|
30
27
|
end
|
31
28
|
|
32
29
|
def scopes
|
33
|
-
@scopes ||=
|
30
|
+
@scopes ||= @receiver.to_s.split("::").inject([Object]) do |_scopes, scope|
|
34
31
|
_scopes << _scopes.last.const_get(scope)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def scope_base
|
41
|
-
@scope_base ||= (/(([A-Z]\w*::)*)([A-Z]\w*)$/ =~ original_message ? $1 : EMPTY).split("::")
|
32
|
+
end.uniq
|
42
33
|
end
|
43
34
|
|
44
35
|
class ClassName < SimpleDelegator
|
45
36
|
attr :namespace
|
46
37
|
|
47
|
-
def initialize(name, namespace = ''
|
38
|
+
def initialize(name, namespace = '')
|
48
39
|
super(name)
|
49
40
|
@namespace = namespace
|
50
41
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# -*- frozen-string-literal: true -*-
|
2
|
+
|
1
3
|
module DidYouMean
|
2
4
|
class VariableNameChecker
|
3
5
|
include SpellCheckable
|
4
6
|
attr_reader :name, :method_names, :lvar_names, :ivar_names, :cvar_names
|
5
7
|
|
6
8
|
def initialize(exception)
|
7
|
-
@name = exception.name.to_s.tr(
|
9
|
+
@name = exception.name.to_s.tr("@", "")
|
8
10
|
@lvar_names = exception.frame_binding.local_variables
|
9
11
|
receiver = exception.frame_binding.receiver
|
10
12
|
|
data/lib/did_you_mean/version.rb
CHANGED
@@ -29,7 +29,7 @@ class NameErrorExtensionTest < Minitest::Test
|
|
29
29
|
|
30
30
|
def test_to_s_does_not_make_disruptive_changes_to_error_message
|
31
31
|
error = assert_raises(NameError) do
|
32
|
-
raise NameError, "uninitialized constant Object"
|
32
|
+
raise NameError, "uninitialized constant Object"
|
33
33
|
end
|
34
34
|
|
35
35
|
assert_equal 1, error.to_s.scan("Did you mean?").count
|
data/test/spell_checker_test.rb
CHANGED
@@ -1,40 +1,29 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class SpellCheckerTest < Minitest::Test
|
4
|
-
|
4
|
+
SpellChecker = Struct.new(:input, :words) do
|
5
5
|
include DidYouMean::SpellCheckable
|
6
6
|
|
7
|
-
def initialize(words)
|
8
|
-
@words = words
|
9
|
-
end
|
10
|
-
|
11
|
-
def similar_to(input)
|
12
|
-
@corrections, @input = nil, input
|
13
|
-
|
14
|
-
corrections
|
15
|
-
end
|
16
|
-
|
17
7
|
def candidates
|
18
|
-
{
|
8
|
+
{ input => words }
|
19
9
|
end
|
20
10
|
end
|
21
11
|
|
22
12
|
def test_similar_to_corrects_mistypes
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
assert_equal %w(
|
34
|
-
assert_equal %w(sub! sub gsub!), collection('sub', 'sub!', 'gsub', 'gsub!').similar_to('ssub!')
|
13
|
+
assert_spell 'foo', input: 'doo', dictionary: ['foo', 'fork']
|
14
|
+
assert_spell 'email', input: 'meail', dictionary: ['email', 'fail', 'eval']
|
15
|
+
assert_spell 'fail', input: 'fial', dictionary: ['email', 'fail', 'eval']
|
16
|
+
assert_spell 'fail', input: 'afil', dictionary: ['email', 'fail', 'eval']
|
17
|
+
assert_spell 'eval', input: 'eavl', dictionary: ['email', 'fail', 'eval']
|
18
|
+
assert_spell 'eval', input: 'veal', dictionary: ['email', 'fail', 'eval']
|
19
|
+
assert_spell 'sub!', input: 'suv!', dictionary: ['sub', 'gsub', 'sub!']
|
20
|
+
assert_spell 'sub', input: 'suv', dictionary: ['sub', 'gsub', 'sub!']
|
21
|
+
|
22
|
+
assert_equal %w(gsub! gsub), SpellChecker.new('gsuv!', %w(sub gsub gsub!)).corrections
|
23
|
+
assert_equal %w(sub! sub gsub!), SpellChecker.new('ssub!', %w(sub sub! gsub gsub!)).corrections
|
35
24
|
|
36
25
|
group_methods = %w(groups group_url groups_url group_path)
|
37
|
-
|
26
|
+
assert_spell 'groups', input: 'group', dictionary: group_methods
|
38
27
|
|
39
28
|
group_classes = %w(
|
40
29
|
GroupMembership
|
@@ -47,20 +36,20 @@ class SpellCheckerTest < Minitest::Test
|
|
47
36
|
NullGroupMembership
|
48
37
|
)
|
49
38
|
|
50
|
-
|
51
|
-
|
39
|
+
assert_spell 'GroupMembership', dictionary: group_classes, input: 'GroupMemberhip'
|
40
|
+
assert_spell 'GroupMembershipDecorator', dictionary: group_classes, input: 'GroupMemberhipDecorator'
|
52
41
|
|
53
42
|
names = %w(first_name_change first_name_changed? first_name_will_change!)
|
54
|
-
assert_equal names,
|
43
|
+
assert_equal names, SpellChecker.new('first_name_change!', names).corrections
|
55
44
|
|
56
|
-
assert_empty
|
57
|
-
assert_empty
|
45
|
+
assert_empty SpellChecker.new('product_path', ['proc']).corrections
|
46
|
+
assert_empty SpellChecker.new('fooo', ['fork']).corrections
|
58
47
|
end
|
59
48
|
|
60
49
|
def test_similar_to_corrects_misspells
|
61
|
-
|
62
|
-
|
63
|
-
|
50
|
+
assert_spell 'descendants', input: 'dependents', dictionary: ['descendants']
|
51
|
+
assert_spell 'drag_to', input: 'drag', dictionary: ['drag_to']
|
52
|
+
assert_spell 'set_result_count', input: 'set_result', dictionary: ['set_result_count']
|
64
53
|
end
|
65
54
|
|
66
55
|
def test_similar_to_sorts_results_by_simiarity
|
@@ -71,20 +60,21 @@ class SpellCheckerTest < Minitest::Test
|
|
71
60
|
name123
|
72
61
|
)
|
73
62
|
|
74
|
-
actual =
|
63
|
+
actual = SpellChecker.new("name123456", %w(
|
75
64
|
name12
|
76
65
|
name123
|
77
66
|
name1234
|
78
67
|
name12345
|
79
68
|
name123456
|
80
|
-
)).
|
69
|
+
)).corrections
|
81
70
|
|
82
71
|
assert_equal expected, actual
|
83
72
|
end
|
84
73
|
|
85
74
|
private
|
86
75
|
|
87
|
-
def
|
88
|
-
|
76
|
+
def assert_spell(expected, input: , dictionary: )
|
77
|
+
corrections = SpellChecker.new(input, dictionary).corrections
|
78
|
+
assert_equal [expected], corrections, "Expected to suggest #{expected}, but got #{corrections.inspect}"
|
89
79
|
end
|
90
80
|
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.0.0.
|
4
|
+
version: 1.0.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuki Nishijima
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09
|
11
|
+
date: 2015-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|