Skip to content

Commit a3e34f5

Browse files
committed
implementation of inexact match feature
1 parent 5a92e4f commit a3e34f5

File tree

3 files changed

+23
-61
lines changed

3 files changed

+23
-61
lines changed

lib/optimist.rb

+8-8
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def self.registry_getopttype(type)
8585
attr_accessor :ignore_invalid_options
8686

8787
DEFAULT_SETTINGS = { suggestions: true, exact_match: false }
88-
88+
8989
## Initializes the parser, and instance-evaluates any block given.
9090
def initialize(*a, &b)
9191
@version = nil
@@ -264,9 +264,9 @@ def perform_inexact_match(arg, partial_match) # :nodoc:
264264
def handle_unknown_argument(arg, candidates, suggestions)
265265
errstring = "unknown argument '#{arg}'"
266266
if (suggestions &&
267-
Module::const_defined?("DidYouMean") &&
268-
Module::const_defined?("DidYouMean::JaroWinkler") &&
269-
Module::const_defined?("DidYouMean::Levenshtein"))
267+
Module::const_defined?("DidYouMean") &&
268+
Module::const_defined?("DidYouMean::JaroWinkler") &&
269+
Module::const_defined?("DidYouMean::Levenshtein"))
270270
input = arg.sub(/^[-]*/,'')
271271

272272
# Code borrowed from did_you_mean gem
@@ -331,13 +331,13 @@ def parse(cmdline = ARGV)
331331
else raise CommandlineError, "invalid argument syntax: '#{arg}'"
332332
end
333333

334-
sym = nil if arg =~ /--no-/ # explicitly invalidate --no-no- arguments
335-
334+
if arg =~ /--no-/ # explicitly invalidate --no-no- arguments
335+
sym = nil
336336
## Support inexact matching of long-arguments like perl's Getopt::Long
337-
if !sym && !@settings[:exact_match] && arg.match(/^--(\S*)$/)
337+
elsif !sym && !@settings[:exact_match] && arg.match(/^--(\S*)$/)
338338
sym = perform_inexact_match(arg, $1)
339339
end
340-
340+
341341
next nil if ignore_invalid_options && !sym
342342
handle_unknown_argument(arg, @long.keys, @settings[:suggestions]) unless sym
343343

test/optimist/parser_test.rb

+9-53
Original file line numberDiff line numberDiff line change
@@ -46,56 +46,11 @@ def test_synopsis
4646

4747
def test_unknown_arguments
4848
err = assert_raises(CommandlineError) { @p.parse(%w(--arg)) }
49-
assert_match(/unknown argument '--arg'$/, err.message)
49+
assert_match(/unknown argument '--arg'/, err.message)
5050
@p.opt "arg"
5151
@p.parse(%w(--arg))
5252
err = assert_raises(CommandlineError) { @p.parse(%w(--arg2)) }
53-
assert_match(/unknown argument '--arg2'$/, err.message)
54-
end
55-
56-
def test_unknown_arguments_with_suggestions
57-
sugp = Parser.new(:suggestions => true)
58-
err = assert_raises(CommandlineError) { sugp.parse(%w(--bone)) }
59-
assert_match(/unknown argument '--bone'$/, err.message)
60-
61-
if (Module::const_defined?("DidYouMean") &&
62-
Module::const_defined?("DidYouMean::JaroWinkler") &&
63-
Module::const_defined?("DidYouMean::Levenshtein"))
64-
sugp.opt "cone"
65-
sugp.parse(%w(--cone))
66-
67-
# single letter mismatch
68-
err = assert_raises(CommandlineError) { sugp.parse(%w(--bone)) }
69-
assert_match(/unknown argument '--bone'. Did you mean: \[--cone\] \?$/, err.message)
70-
71-
# transposition
72-
err = assert_raises(CommandlineError) { sugp.parse(%w(--ocne)) }
73-
assert_match(/unknown argument '--ocne'. Did you mean: \[--cone\] \?$/, err.message)
74-
75-
# extra letter at end
76-
err = assert_raises(CommandlineError) { sugp.parse(%w(--cones)) }
77-
assert_match(/unknown argument '--cones'. Did you mean: \[--cone\] \?$/, err.message)
78-
79-
# too big of a mismatch to suggest (extra letters in front)
80-
err = assert_raises(CommandlineError) { sugp.parse(%w(--snowcone)) }
81-
assert_match(/unknown argument '--snowcone'$/, err.message)
82-
83-
# too big of a mismatch to suggest (nothing close)
84-
err = assert_raises(CommandlineError) { sugp.parse(%w(--clown-nose)) }
85-
assert_match(/unknown argument '--clown-nose'$/, err.message)
86-
87-
sugp.opt "zippy"
88-
sugp.opt "zapzy"
89-
# single letter mismatch, matches two
90-
err = assert_raises(CommandlineError) { sugp.parse(%w(--zipzy)) }
91-
assert_match(/unknown argument '--zipzy'. Did you mean: \[--zippy, --zapzy\] \?$/, err.message)
92-
93-
sugp.opt "big_bug"
94-
# suggest common case of dash versus underscore in argnames
95-
err = assert_raises(CommandlineError) { sugp.parse(%w(--big_bug)) }
96-
assert_match(/unknown argument '--big_bug'. Did you mean: \[--big-bug\] \?$/, err.message)
97-
end
98-
53+
assert_match(/unknown argument '--arg2'/, err.message)
9954
end
10055

10156
def test_unknown_arguments_with_suggestions
@@ -825,13 +780,13 @@ def test_arguments_passed_through_block
825780
end
826781
assert_equal @goat, boat
827782
end
828-
783+
829784
## test-only access reader method so that we dont have to
830785
## expose settings in the public API.
831786
class Optimist::Parser
832787
def get_settings_for_testing ; return @settings ;end
833788
end
834-
789+
835790
def test_two_arguments_passed_through_block
836791
newp = Parser.new(:abcd => 123, :efgh => "other" ) do |i|
837792
end
@@ -1229,7 +1184,7 @@ def test_inexact_match
12291184
opts = newp.parse %w(--lib 5 --ev bar)
12301185
assert_equal 5, opts[:liberation]
12311186
assert_equal 'bar', opts[:evaluate]
1232-
assert_equal nil, opts[:eval]
1187+
assert_nil opts[:eval]
12331188
end
12341189

12351190
def test_exact_match
@@ -1440,9 +1395,10 @@ def test_options_takes_hashy_settings
14401395
settings_copy = @settings
14411396
end
14421397
assert_equal [], passargs_copy
1443-
assert_equal({:fizz=>:buzz, :bear=>:cat}, settings_copy)
1398+
assert_equal settings_copy[:fizz], :buzz
1399+
assert_equal settings_copy[:bear], :cat
14441400
end
1445-
1401+
14461402
def test_options_takes_some_other_data
14471403
passargs_copy = []
14481404
settings_copy = []
@@ -1453,7 +1409,7 @@ def test_options_takes_some_other_data
14531409
settings_copy = @settings
14541410
end
14551411
assert_equal [1,2,3], passargs_copy
1456-
assert_equal({}, settings_copy)
1412+
assert_equal(Optimist::Parser::DEFAULT_SETTINGS, settings_copy)
14571413
end
14581414
end
14591415

test/support/assert_helpers.rb

+6
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,11 @@ def assert_system_exit *exp
4242
end
4343
flunk "#{msg}#{mu_pp(exp)} SystemExit expected but nothing was raised."
4444
end
45+
46+
# wrapper around common assertion checking pattern
47+
def assert_raises_errmatch(err_klass, err_regexp, &b)
48+
err = assert_raises(err_klass, &b)
49+
assert_match(err_regexp, err.message)
50+
end
4551
end
4652

0 commit comments

Comments
 (0)