did_you_mean 1.0.0.beta2 → 1.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b34cbc0ccdd5f3ad3b8edce86667a3cc74b5378
4
- data.tar.gz: 876c524186e3e5874bd5e481e18aaa94287dad63
3
+ metadata.gz: ad488ff1d9e183f4789342bedca9e195be934b6a
4
+ data.tar.gz: 755225707c5e7ef906bba989dad41d4130c8b410
5
5
  SHA512:
6
- metadata.gz: 76ad432f1fe5a9d346d415a5c09b47f7563c4e176a8b522272a426b7baabbf38b149cfad7c7bf846a991f7599e535a9c6781d8661a7c65f09a638f84edb298e0
7
- data.tar.gz: 8b52260010d946d8e341a11cf0969570e3c590da11f65d3c7f920a418714b382e6da7acb30e398ddc55727cee848135c42b338caafd0aced87766357f22b1061
6
+ metadata.gz: ecb0285487ed45ff04f470581b621a0d50681b62d6b4c099e04139b1082ca9ed92373bc3d2a6f1b4207172dfa62b90b112bd7df0d782ab43ffb4b0741608250a
7
+ data.tar.gz: 43ef649c7a45e82492938bf3ed90dad0c02337eb40f1873986cdd8bca8dc0c4b170495f277eed7b6b018f82f36f1ca954b46ecd8e5fc7cb6f16845665f7251c8
@@ -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 = EMPTY)
17
+ def similar_to(input, filter = '')
16
18
  @corrections, @input = nil, input
17
19
  corrections
18
20
  end
@@ -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 = EMPTY)
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(" ".freeze, "_".freeze) }
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 => incorrect,
96
- 'result'.freeze => corrections
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, b = tp.raised_exception, tp.binding
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, b)
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 "".freeze if @corrections.empty?
10
+ return "" if @corrections.empty?
9
11
 
10
- output = "\nDid you mean? "
11
- output << @corrections.join("\n" << ' '.freeze * 15)
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!(AT, EMPTY)
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 = VariableNameChecker.new(exception).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, :original_message
7
+ attr_reader :class_name
7
8
 
8
9
  def initialize(exception)
9
- @class_name, @original_message = exception.name, exception.original_message
10
+ @class_name, @receiver = exception.name, exception.receiver
10
11
  end
11
12
 
12
13
  def candidates
13
- {name_from_message => class_names}
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 ? EMPTY : "#{scope}::")
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 ||= scope_base.inject([Object]) do |_scopes, scope|
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 = ''.freeze)
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(AT, EMPTY)
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
 
@@ -1,3 +1,3 @@
1
1
  module DidYouMean
2
- VERSION = "1.0.0.beta2"
2
+ VERSION = "1.0.0.beta3"
3
3
  end
@@ -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".freeze
32
+ raise NameError, "uninitialized constant Object"
33
33
  end
34
34
 
35
35
  assert_equal 1, error.to_s.scan("Did you mean?").count
@@ -1,40 +1,29 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class SpellCheckerTest < Minitest::Test
4
- class WordCollection
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
- { @input => @words }
8
+ { input => words }
19
9
  end
20
10
  end
21
11
 
22
12
  def test_similar_to_corrects_mistypes
23
-
24
- assert_correction 'foo', collection('foo', 'fork') .similar_to('doo')
25
- assert_correction 'email', collection('email', 'fail', 'eval').similar_to('meail')
26
- assert_correction 'fail', collection('email', 'fail', 'eval').similar_to('fial')
27
- assert_correction 'fail', collection('email', 'fail', 'eval').similar_to('afil')
28
- assert_correction 'eval', collection('email', 'fail', 'eval').similar_to('eavl')
29
- assert_correction 'eval', collection('email', 'fail', 'eval').similar_to('veal')
30
- assert_correction 'sub!', collection('sub', 'gsub', 'sub!') .similar_to('suv!')
31
- assert_correction 'sub', collection('sub', 'gsub', 'sub!') .similar_to('suv')
32
-
33
- assert_equal %w(gsub! gsub), collection('sub', 'gsub', 'gsub!').similar_to('gsuv!')
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
- assert_correction 'groups', collection(group_methods).similar_to('group')
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
- assert_correction 'GroupMembership', collection(group_classes).similar_to('GroupMemberhip')
51
- assert_correction 'GroupMembershipDecorator', collection(group_classes).similar_to('GroupMemberhipDecorator')
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, collection(names).similar_to('first_name_change!')
43
+ assert_equal names, SpellChecker.new('first_name_change!', names).corrections
55
44
 
56
- assert_empty collection('proc').similar_to 'product_path'
57
- assert_empty collection('fork').similar_to 'fooo'
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
- assert_correction 'descendants', collection('descendants') .similar_to('dependents')
62
- assert_correction 'drag_to', collection('drag_to') .similar_to('drag')
63
- assert_correction 'set_result_count', collection('set_result_count').similar_to('set_result')
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 = WordCollection.new(%w(
63
+ actual = SpellChecker.new("name123456", %w(
75
64
  name12
76
65
  name123
77
66
  name1234
78
67
  name12345
79
68
  name123456
80
- )).similar_to("name123456")
69
+ )).corrections
81
70
 
82
71
  assert_equal expected, actual
83
72
  end
84
73
 
85
74
  private
86
75
 
87
- def collection(*args)
88
- WordCollection.new(args.flatten)
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.beta2
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-08 00:00:00.000000000 Z
11
+ date: 2015-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler