did_you_mean 1.3.1 → 1.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/.github/workflows/ruby.yml +48 -0
- data/CHANGELOG.md +75 -75
- data/Gemfile +2 -1
- data/README.md +2 -32
- data/Rakefile +4 -5
- data/appveyor.yml +25 -0
- data/did_you_mean.gemspec +6 -4
- data/documentation/CHANGELOG.md.erb +8 -0
- data/documentation/changelog_generator.rb +34 -0
- data/documentation/human_typo_api.md +20 -0
- data/documentation/tree_spell_algorithm.md +82 -0
- data/documentation/tree_spell_checker_api.md +24 -0
- data/lib/did_you_mean.rb +17 -16
- data/lib/did_you_mean/experimental.rb +2 -2
- data/lib/did_you_mean/experimental/initializer_name_correction.rb +1 -1
- data/lib/did_you_mean/experimental/ivar_name_correction.rb +3 -1
- data/lib/did_you_mean/levenshtein.rb +1 -1
- data/lib/did_you_mean/spell_checker.rb +7 -7
- data/lib/did_you_mean/spell_checkers/key_error_checker.rb +8 -2
- data/lib/did_you_mean/spell_checkers/method_name_checker.rb +14 -6
- data/lib/did_you_mean/spell_checkers/name_error_checkers.rb +2 -2
- data/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb +5 -5
- data/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb +1 -1
- data/lib/did_you_mean/tree_spell_checker.rb +137 -0
- data/lib/did_you_mean/verbose.rb +2 -2
- data/lib/did_you_mean/version.rb +1 -1
- data/test/core_ext/test_name_error_extension.rb +48 -0
- data/test/edit_distance/{jaro_winkler_test.rb → test_jaro_winkler.rb} +2 -2
- data/test/fixtures/mini_dir.yml +15 -0
- data/test/fixtures/rspec_dir.yml +112 -0
- data/test/helper.rb +29 -0
- data/test/spell_checking/{class_name_check_test.rb → test_class_name_check.rb} +12 -10
- data/test/spell_checking/{key_name_check_test.rb → test_key_name_check.rb} +18 -8
- data/test/spell_checking/{method_name_check_test.rb → test_method_name_check.rb} +17 -15
- data/test/spell_checking/{uncorrectable_name_check_test.rb → test_uncorrectable_name_check.rb} +3 -3
- data/test/spell_checking/{variable_name_check_test.rb → test_variable_name_check.rb} +18 -16
- data/test/{spell_checker_test.rb → test_spell_checker.rb} +2 -2
- data/test/test_tree_spell_checker.rb +173 -0
- data/test/test_verbose_formatter.rb +21 -0
- data/test/tree_spell/change_word.rb +61 -0
- data/test/tree_spell/human_typo.rb +89 -0
- data/test/tree_spell/test_change_word.rb +38 -0
- data/test/tree_spell/test_explore.rb +128 -0
- data/test/tree_spell/test_human_typo.rb +24 -0
- metadata +47 -58
- data/.travis.yml +0 -23
- data/test/core_ext/name_error_extension_test.rb +0 -51
- data/test/experimental/initializer_name_correction_test.rb +0 -15
- data/test/experimental/method_name_checker_test.rb +0 -13
- data/test/test_helper.rb +0 -13
- data/test/verbose_formatter_test.rb +0 -22
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative "../spell_checker"
|
2
2
|
|
3
3
|
module DidYouMean
|
4
4
|
class MethodNameChecker
|
@@ -43,14 +43,22 @@ module DidYouMean
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def corrections
|
46
|
-
@corrections ||= SpellChecker.new(dictionary: RB_RESERVED_WORDS + method_names).correct(method_name) -
|
46
|
+
@corrections ||= SpellChecker.new(dictionary: RB_RESERVED_WORDS + method_names).correct(method_name) - names_to_exclude
|
47
47
|
end
|
48
48
|
|
49
49
|
def method_names
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
if Object === receiver
|
51
|
+
method_names = receiver.methods + receiver.singleton_methods
|
52
|
+
method_names += receiver.private_methods if @private_call
|
53
|
+
method_names.uniq!
|
54
|
+
method_names
|
55
|
+
else
|
56
|
+
[]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def names_to_exclude
|
61
|
+
Object === receiver ? NAMES_TO_EXCLUDE[receiver.class] : []
|
54
62
|
end
|
55
63
|
end
|
56
64
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative 'name_error_checkers/class_name_checker'
|
2
|
+
require_relative 'name_error_checkers/variable_name_checker'
|
3
3
|
|
4
4
|
module DidYouMean
|
5
5
|
class << (NameErrorCheckers = Object.new)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
|
-
|
3
|
-
|
2
|
+
|
3
|
+
require_relative "../../spell_checker"
|
4
4
|
|
5
5
|
module DidYouMean
|
6
6
|
class ClassNameChecker
|
@@ -31,16 +31,16 @@ module DidYouMean
|
|
31
31
|
end.uniq
|
32
32
|
end
|
33
33
|
|
34
|
-
class ClassName <
|
34
|
+
class ClassName < String
|
35
35
|
attr :namespace
|
36
36
|
|
37
37
|
def initialize(name, namespace = '')
|
38
|
-
super(name)
|
38
|
+
super(name.to_s)
|
39
39
|
@namespace = namespace
|
40
40
|
end
|
41
41
|
|
42
42
|
def full_name
|
43
|
-
self.class.new("#{namespace}#{
|
43
|
+
self.class.new("#{namespace}#{self}")
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module DidYouMean
|
2
|
+
# spell checker for a dictionary that has a tree
|
3
|
+
# structure, see doc/tree_spell_checker_api.md
|
4
|
+
class TreeSpellChecker
|
5
|
+
attr_reader :dictionary, :dimensions, :separator, :augment
|
6
|
+
|
7
|
+
def initialize(dictionary:, separator: '/', augment: nil)
|
8
|
+
@dictionary = dictionary
|
9
|
+
@separator = separator
|
10
|
+
@augment = augment
|
11
|
+
@dimensions = parse_dimensions
|
12
|
+
end
|
13
|
+
|
14
|
+
def correct(input)
|
15
|
+
plausibles = plausible_dimensions input
|
16
|
+
return no_idea(input) if plausibles.empty?
|
17
|
+
suggestions = find_suggestions input, plausibles
|
18
|
+
return no_idea(input) if suggestions.empty?
|
19
|
+
suggestions
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def parse_dimensions
|
25
|
+
ParseDimensions.new(dictionary, separator).call
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_suggestions(input, plausibles)
|
29
|
+
states = plausibles[0].product(*plausibles[1..-1])
|
30
|
+
paths = possible_paths states
|
31
|
+
leaf = input.split(separator).last
|
32
|
+
ideas = find_ideas(paths, leaf)
|
33
|
+
ideas.compact.flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def no_idea(input)
|
37
|
+
return [] unless augment
|
38
|
+
::DidYouMean::SpellChecker.new(dictionary: dictionary).correct(input)
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_ideas(paths, leaf)
|
42
|
+
paths.map do |path|
|
43
|
+
names = find_leaves(path)
|
44
|
+
ideas = CorrectElement.new.call names, leaf
|
45
|
+
ideas_to_paths ideas, leaf, names, path
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def ideas_to_paths(ideas, leaf, names, path)
|
50
|
+
return nil if ideas.empty?
|
51
|
+
return [path + separator + leaf] if names.include? leaf
|
52
|
+
ideas.map { |str| path + separator + str }
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_leaves(path)
|
56
|
+
dictionary.map do |str|
|
57
|
+
next unless str.include? "#{path}#{separator}"
|
58
|
+
str.gsub("#{path}#{separator}", '')
|
59
|
+
end.compact
|
60
|
+
end
|
61
|
+
|
62
|
+
def possible_paths(states)
|
63
|
+
states.map do |state|
|
64
|
+
state.join separator
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def plausible_dimensions(input)
|
69
|
+
elements = input.split(separator)[0..-2]
|
70
|
+
elements.each_with_index.map do |element, i|
|
71
|
+
next if dimensions[i].nil?
|
72
|
+
CorrectElement.new.call dimensions[i], element
|
73
|
+
end.compact
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# parses the elements in each dimension
|
78
|
+
class ParseDimensions
|
79
|
+
def initialize(dictionary, separator)
|
80
|
+
@dictionary = dictionary
|
81
|
+
@separator = separator
|
82
|
+
end
|
83
|
+
|
84
|
+
def call
|
85
|
+
leafless = remove_leaves
|
86
|
+
dimensions = find_elements leafless
|
87
|
+
dimensions.map do |elements|
|
88
|
+
elements.to_set.to_a
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def remove_leaves
|
95
|
+
dictionary.map do |a|
|
96
|
+
elements = a.split(separator)
|
97
|
+
elements[0..-2]
|
98
|
+
end.to_set.to_a
|
99
|
+
end
|
100
|
+
|
101
|
+
def find_elements(leafless)
|
102
|
+
max_elements = leafless.map(&:size).max
|
103
|
+
dimensions = Array.new(max_elements) { [] }
|
104
|
+
(0...max_elements).each do |i|
|
105
|
+
leafless.each do |elements|
|
106
|
+
dimensions[i] << elements[i] unless elements[i].nil?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
dimensions
|
110
|
+
end
|
111
|
+
|
112
|
+
attr_reader :dictionary, :separator
|
113
|
+
end
|
114
|
+
|
115
|
+
# identifies the elements close to element
|
116
|
+
class CorrectElement
|
117
|
+
def initialize
|
118
|
+
end
|
119
|
+
|
120
|
+
def call(names, element)
|
121
|
+
return names if names.size == 1
|
122
|
+
str = normalize element
|
123
|
+
return [str] if names.include? str
|
124
|
+
checker = ::DidYouMean::SpellChecker.new(dictionary: names)
|
125
|
+
checker.correct(str)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def normalize(leaf)
|
131
|
+
str = leaf.dup
|
132
|
+
str.downcase!
|
133
|
+
return str unless str.include? '@'
|
134
|
+
str.tr!('@', ' ')
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/did_you_mean/verbose.rb
CHANGED
data/lib/did_you_mean/version.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
class NameErrorExtensionTest < Test::Unit::TestCase
|
4
|
+
SPELL_CHECKERS = DidYouMean::SPELL_CHECKERS
|
5
|
+
|
6
|
+
class TestSpellChecker
|
7
|
+
def initialize(*); end
|
8
|
+
def corrections; ["does_exist"]; end
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@org, SPELL_CHECKERS['NameError'] = SPELL_CHECKERS['NameError'], TestSpellChecker
|
13
|
+
|
14
|
+
@error = assert_raise(NameError){ doesnt_exist }
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
SPELL_CHECKERS['NameError'] = @org
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_message
|
22
|
+
assert_match(/Did you mean\? does_exist/, @error.to_s)
|
23
|
+
assert_match(/Did you mean\? does_exist/, @error.message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_to_s_does_not_make_disruptive_changes_to_error_message
|
27
|
+
error = assert_raise(NameError) do
|
28
|
+
raise NameError, "uninitialized constant Object"
|
29
|
+
end
|
30
|
+
|
31
|
+
error.to_s
|
32
|
+
assert_equal 1, error.to_s.scan("Did you mean?").count
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_correctable_error_objects_are_dumpable
|
36
|
+
error =
|
37
|
+
begin
|
38
|
+
Dir.chdir(__dir__) { File.open('test_name_error_extension.rb') { |f| f.sizee } }
|
39
|
+
rescue NoMethodError => e
|
40
|
+
e
|
41
|
+
end
|
42
|
+
|
43
|
+
error.to_s
|
44
|
+
|
45
|
+
assert_equal "undefined method `sizee' for #<File:test_name_error_extension.rb (closed)>",
|
46
|
+
Marshal.load(Marshal.dump(error)).original_message
|
47
|
+
end
|
48
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
3
|
# These tests were originally written by Jian Weihang (簡煒航) as part of his work
|
4
4
|
# on the jaro_winkler gem. The original code could be found here:
|
@@ -6,7 +6,7 @@ require 'test_helper'
|
|
6
6
|
#
|
7
7
|
# Copyright (c) 2014 Jian Weihang
|
8
8
|
|
9
|
-
class JaroWinklerTest <
|
9
|
+
class JaroWinklerTest < Test::Unit::TestCase
|
10
10
|
def test_jaro_winkler_distance
|
11
11
|
assert_distance 0.9667, 'henka', 'henkan'
|
12
12
|
assert_distance 1.0, 'al', 'al'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
- test/core_ext/name_error_extension_test.rb
|
3
|
+
- test/edit_distance/jaro_winkler_test.rb
|
4
|
+
- test/fixtures/book.rb
|
5
|
+
- test/spell_checker_test.rb
|
6
|
+
- test/spell_checking/class_name_check_test.rb
|
7
|
+
- test/spell_checking/key_name_check_test.rb
|
8
|
+
- test/spell_checking/method_name_check_test.rb
|
9
|
+
- test/spell_checking/uncorrectable_name_check_test.rb
|
10
|
+
- test/spell_checking/variable_name_check_test.rb
|
11
|
+
- test/test_helper.rb
|
12
|
+
- test/tree_spell_checker_test.rb
|
13
|
+
- test/tree_spell_explore_test.rb
|
14
|
+
- test/tree_spell_human_typo_test.rb
|
15
|
+
- test/verbose_formatter_test.rb
|
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
- spec/spec_helper.rb
|
3
|
+
- spec/integration/suite_hooks_errors_spec.rb
|
4
|
+
- spec/integration/filtering_spec.rb
|
5
|
+
- spec/integration/spec_file_load_errors_spec.rb
|
6
|
+
- spec/integration/failed_line_detection_spec.rb
|
7
|
+
- spec/integration/persistence_failures_spec.rb
|
8
|
+
- spec/integration/bisect_runners_spec.rb
|
9
|
+
- spec/integration/order_spec.rb
|
10
|
+
- spec/integration/fail_if_no_examples_spec.rb
|
11
|
+
- spec/integration/bisect_spec.rb
|
12
|
+
- spec/integration/output_stream_spec.rb
|
13
|
+
- spec/support/sandboxing.rb
|
14
|
+
- spec/support/spec_files.rb
|
15
|
+
- spec/support/fake_libs/json.rb
|
16
|
+
- spec/support/fake_libs/open3.rb
|
17
|
+
- spec/support/fake_libs/drb/acl.rb
|
18
|
+
- spec/support/fake_libs/drb/drb.rb
|
19
|
+
- spec/support/fake_libs/mocha/api.rb
|
20
|
+
- spec/support/fake_libs/test/unit/assertions.rb
|
21
|
+
- spec/support/fake_libs/flexmock/rspec.rb
|
22
|
+
- spec/support/fake_libs/rake/tasklib.rb
|
23
|
+
- spec/support/fake_libs/coderay.rb
|
24
|
+
- spec/support/fake_libs/rr.rb
|
25
|
+
- spec/support/fake_libs/rake.rb
|
26
|
+
- spec/support/fake_libs/erb.rb
|
27
|
+
- spec/support/fake_libs/rspec/mocks.rb
|
28
|
+
- spec/support/fake_libs/rspec/expectations.rb
|
29
|
+
- spec/support/fake_libs/minitest/assertions.rb
|
30
|
+
- spec/support/fake_libs/minitest.rb
|
31
|
+
- spec/support/matchers.rb
|
32
|
+
- spec/support/runner_support.rb
|
33
|
+
- spec/support/isolated_home_directory.rb
|
34
|
+
- spec/support/config_options_helper.rb
|
35
|
+
- spec/support/mathn_integration_support.rb
|
36
|
+
- spec/support/helper_methods.rb
|
37
|
+
- spec/support/formatter_support.rb
|
38
|
+
- spec/support/fake_bisect_runner.rb
|
39
|
+
- spec/support/shared_example_groups.rb
|
40
|
+
- spec/support/aruba_support.rb
|
41
|
+
- spec/rspec/core/runner_spec.rb
|
42
|
+
- spec/rspec/core/did_you_mean_spec.rb
|
43
|
+
- spec/rspec/core/drb_spec.rb
|
44
|
+
- spec/rspec/core/metadata_spec.rb
|
45
|
+
- spec/rspec/core/example_group_spec.rb
|
46
|
+
- spec/rspec/core/configuration/only_failures_support_spec.rb
|
47
|
+
- spec/rspec/core/rake_task_spec.rb
|
48
|
+
- spec/rspec/core/memoized_helpers_spec.rb
|
49
|
+
- spec/rspec/core/ordering_spec.rb
|
50
|
+
- spec/rspec/core/option_parser_spec.rb
|
51
|
+
- spec/rspec/core/example_execution_result_spec.rb
|
52
|
+
- spec/rspec/core/suite_hooks_spec.rb
|
53
|
+
- spec/rspec/core/set_spec.rb
|
54
|
+
- spec/rspec/core/configuration_spec.rb
|
55
|
+
- spec/rspec/core/rspec_matchers_spec.rb
|
56
|
+
- spec/rspec/core/hooks_filtering_spec.rb
|
57
|
+
- spec/rspec/core/bisect/shell_command_spec.rb
|
58
|
+
- spec/rspec/core/bisect/server_spec.rb
|
59
|
+
- spec/rspec/core/bisect/example_minimizer_spec.rb
|
60
|
+
- spec/rspec/core/bisect/shell_runner_spec.rb
|
61
|
+
- spec/rspec/core/bisect/utilities_spec.rb
|
62
|
+
- spec/rspec/core/bisect/coordinator_spec.rb
|
63
|
+
- spec/rspec/core/resources/a_foo.rb
|
64
|
+
- spec/rspec/core/resources/formatter_specs.rb
|
65
|
+
- spec/rspec/core/resources/inconsistently_ordered_specs.rb
|
66
|
+
- spec/rspec/core/resources/a_bar.rb
|
67
|
+
- spec/rspec/core/resources/utf8_encoded.rb
|
68
|
+
- spec/rspec/core/resources/a_spec.rb
|
69
|
+
- spec/rspec/core/resources/acceptance/bar.rb
|
70
|
+
- spec/rspec/core/resources/acceptance/foo_spec.rb
|
71
|
+
- spec/rspec/core/resources/custom_example_group_runner.rb
|
72
|
+
- spec/rspec/core/failed_example_notification_spec.rb
|
73
|
+
- spec/rspec/core/hooks_spec.rb
|
74
|
+
- spec/rspec/core/formatters/profile_formatter_spec.rb
|
75
|
+
- spec/rspec/core/formatters/deprecation_formatter_spec.rb
|
76
|
+
- spec/rspec/core/formatters/syntax_highlighter_spec.rb
|
77
|
+
- spec/rspec/core/formatters/base_text_formatter_spec.rb
|
78
|
+
- spec/rspec/core/formatters/snippet_extractor_spec.rb
|
79
|
+
- spec/rspec/core/formatters/progress_formatter_spec.rb
|
80
|
+
- spec/rspec/core/formatters/html_snippet_extractor_spec.rb
|
81
|
+
- spec/rspec/core/formatters/helpers_spec.rb
|
82
|
+
- spec/rspec/core/formatters/html_formatter_spec.rb
|
83
|
+
- spec/rspec/core/formatters/json_formatter_spec.rb
|
84
|
+
- spec/rspec/core/formatters/documentation_formatter_spec.rb
|
85
|
+
- spec/rspec/core/formatters/exception_presenter_spec.rb
|
86
|
+
- spec/rspec/core/formatters/console_codes_spec.rb
|
87
|
+
- spec/rspec/core/formatters/fallback_message_formatter_spec.rb
|
88
|
+
- spec/rspec/core/invocations_spec.rb
|
89
|
+
- spec/rspec/core/configuration_options_spec.rb
|
90
|
+
- spec/rspec/core/pending_spec.rb
|
91
|
+
- spec/rspec/core/profiler_spec.rb
|
92
|
+
- spec/rspec/core/project_initializer_spec.rb
|
93
|
+
- spec/rspec/core/aggregate_failures_spec.rb
|
94
|
+
- spec/rspec/core/dsl_spec.rb
|
95
|
+
- spec/rspec/core/ruby_project_spec.rb
|
96
|
+
- spec/rspec/core/formatters_spec.rb
|
97
|
+
- spec/rspec/core/metadata_filter_spec.rb
|
98
|
+
- spec/rspec/core/example_group_constants_spec.rb
|
99
|
+
- spec/rspec/core/world_spec.rb
|
100
|
+
- spec/rspec/core/shared_context_spec.rb
|
101
|
+
- spec/rspec/core/pending_example_spec.rb
|
102
|
+
- spec/rspec/core/filter_manager_spec.rb
|
103
|
+
- spec/rspec/core/shared_example_group_spec.rb
|
104
|
+
- spec/rspec/core/example_status_persister_spec.rb
|
105
|
+
- spec/rspec/core/backtrace_formatter_spec.rb
|
106
|
+
- spec/rspec/core/output_wrapper_spec.rb
|
107
|
+
- spec/rspec/core/example_spec.rb
|
108
|
+
- spec/rspec/core/reporter_spec.rb
|
109
|
+
- spec/rspec/core/filterable_item_repository_spec.rb
|
110
|
+
- spec/rspec/core/notifications_spec.rb
|
111
|
+
- spec/rspec/core/warnings_spec.rb
|
112
|
+
- spec/rspec/core_spec.rb
|
data/test/helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
module DidYouMean
|
4
|
+
module TestHelper
|
5
|
+
class << self
|
6
|
+
attr_reader :root
|
7
|
+
end
|
8
|
+
|
9
|
+
if File.file?(File.expand_path('../lib/did_you_mean.rb', __dir__))
|
10
|
+
# In this case we're being run from inside the gem, so we just want to
|
11
|
+
# require the root of the library
|
12
|
+
|
13
|
+
@root = File.expand_path('../lib/did_you_mean', __dir__)
|
14
|
+
require_relative @root
|
15
|
+
else
|
16
|
+
# In this case we're being run from inside ruby core, and we want to
|
17
|
+
# include the experimental features in the test suite
|
18
|
+
|
19
|
+
@root = File.expand_path('../../lib/did_you_mean', __dir__)
|
20
|
+
require_relative @root
|
21
|
+
# We are excluding experimental features for now.
|
22
|
+
# require_relative File.join(@root, 'experimental')
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_correction(expected, array)
|
26
|
+
assert_equal Array(expected), array, "Expected #{array.inspect} to only include #{expected.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|