@@ -45,10 +45,57 @@ def test_synopsis
4545
4646
4747 def test_unknown_arguments
48- assert_raises ( CommandlineError ) { @p . parse ( %w( --arg ) ) }
48+ err = assert_raises ( CommandlineError ) { @p . parse ( %w( --arg ) ) }
49+ assert_match ( /unknown argument '--arg'$/ , err . message )
4950 @p . opt "arg"
5051 @p . parse ( %w( --arg ) )
51- assert_raises ( CommandlineError ) { @p . parse ( %w( --arg2 ) ) }
52+ 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+
5299 end
53100
54101 def test_unknown_arguments_with_suggestions
@@ -778,6 +825,20 @@ def test_arguments_passed_through_block
778825 end
779826 assert_equal @goat , boat
780827 end
828+
829+ ## test-only access reader method so that we dont have to
830+ ## expose settings in the public API.
831+ class Optimist ::Parser
832+ def get_settings_for_testing ; return @settings ; end
833+ end
834+
835+ def test_two_arguments_passed_through_block
836+ newp = Parser . new ( :abcd => 123 , :efgh => "other" ) do |i |
837+ end
838+ assert_equal newp . get_settings_for_testing [ :abcd ] , 123
839+ assert_equal newp . get_settings_for_testing [ :efgh ] , "other"
840+ end
841+
781842
782843 def test_version_and_help_override_errors
783844 @p . opt :asdf , "desc" , :type => String
@@ -1161,6 +1222,54 @@ def test_default_shorts_assigned_only_after_user_shorts
11611222 assert opts [ :ccd ]
11621223 end
11631224
1225+ def test_inexact_match
1226+ newp = Parser . new ( )
1227+ newp . opt :liberation , "liberate something" , :type => :int
1228+ newp . opt :evaluate , "evaluate something" , :type => :string
1229+ opts = newp . parse %w( --lib 5 --ev bar )
1230+ assert_equal 5 , opts [ :liberation ]
1231+ assert_equal 'bar' , opts [ :evaluate ]
1232+ assert_equal nil , opts [ :eval ]
1233+ end
1234+
1235+ def test_exact_match
1236+ newp = Parser . new ( exact_match : true )
1237+ newp . opt :liberation , "liberate something" , :type => :int
1238+ newp . opt :evaluate , "evaluate something" , :type => :string
1239+ assert_raises ( CommandlineError , /unknown argument '--lib'/ ) do
1240+ newp . parse %w( --lib 5 )
1241+ end
1242+ assert_raises_errmatch ( CommandlineError , /unknown argument '--ev'/ ) do
1243+ newp . parse %w( --ev bar )
1244+ end
1245+ end
1246+
1247+ def test_inexact_collision
1248+ newp = Parser . new ( )
1249+ newp . opt :bookname , "name of a book" , :type => :string
1250+ newp . opt :bookcost , "cost of the book" , :type => :string
1251+ opts = newp . parse %w( --bookn hairy_potsworth --bookc 10 )
1252+ assert_equal 'hairy_potsworth' , opts [ :bookname ]
1253+ assert_equal '10' , opts [ :bookcost ]
1254+ assert_raises ( CommandlineError ) do
1255+ newp . parse %w( --book 5 ) # ambiguous
1256+ end
1257+ ## partial match causes 'specified multiple times' error
1258+ assert_raises ( CommandlineError , /specified multiple times/ ) do
1259+ newp . parse %w( --bookc 17 --bookcost 22 )
1260+ end
1261+ end
1262+
1263+ def test_inexact_collision_with_exact
1264+ newp = Parser . new ( )
1265+ newp . opt :book , "name of a book" , :type => :string , :default => "ABC"
1266+ newp . opt :bookcost , "cost of the book" , :type => :int , :default => 5
1267+ opts = newp . parse %w( --book warthog --bookc 3 )
1268+ assert_equal 'warthog' , opts [ :book ]
1269+ assert_equal 3 , opts [ :bookcost ]
1270+
1271+ end
1272+
11641273 def test_accepts_arguments_with_spaces
11651274 @p . opt :arg1 , "arg" , :type => String
11661275 @p . opt :arg2 , "arg2" , :type => String
@@ -1316,6 +1425,36 @@ def test_ignore_invalid_options_stop_on_unknown_partial_mid_short
13161425 assert opts [ :arg1 ]
13171426 assert_equal %w{ -bu potato } , @p . leftovers
13181427 end
1428+
1429+ # Due to strangeness in how the cloaker works, there were
1430+ # cases where Optimist.parse would work, but Optimist.options
1431+ # did not, depending on arguments given to the function.
1432+ # These serve to validate different args given to Optimist.options
1433+ def test_options_takes_hashy_settings
1434+ passargs_copy = [ ]
1435+ settings_copy = [ ]
1436+ ::Optimist . options ( %w( --wig --pig ) , :fizz => :buzz , :bear => :cat ) do |*passargs |
1437+ opt :wig
1438+ opt :pig
1439+ passargs_copy = passargs . dup
1440+ settings_copy = @settings
1441+ end
1442+ assert_equal [ ] , passargs_copy
1443+ assert_equal ( { :fizz => :buzz , :bear => :cat } , settings_copy )
1444+ end
1445+
1446+ def test_options_takes_some_other_data
1447+ passargs_copy = [ ]
1448+ settings_copy = [ ]
1449+ ::Optimist . options ( %w( --nose --close ) , 1 , 2 , 3 ) do |*passargs |
1450+ opt :nose
1451+ opt :close
1452+ passargs_copy = passargs . dup
1453+ settings_copy = @settings
1454+ end
1455+ assert_equal [ 1 , 2 , 3 ] , passargs_copy
1456+ assert_equal ( { } , settings_copy )
1457+ end
13191458end
13201459
13211460end
0 commit comments