| 1 | import flag |
| 2 | |
| 3 | fn test_if_flag_not_given_return_default_values() { |
| 4 | mut fp := flag.new_flag_parser([]) |
| 5 | assert false == fp.bool('a_bool', 0, false, '') |
| 6 | assert 42 == fp.int('an_int', 0, 42, '') |
| 7 | assert 1.0 == fp.float('a_float', 0, 1.0, '') |
| 8 | assert 'stuff' == fp.string('a_string', 0, 'stuff', '') |
| 9 | } |
| 10 | |
| 11 | fn test_if_flag_not_given_can_return_option_defaults() { |
| 12 | mut fp := flag.new_flag_parser([]) |
| 13 | assert fp.bool_val('a_bool', 0, ?bool(none), '') == none |
| 14 | assert fp.int_val('an_int', 0, ?int(none), '') == none |
| 15 | assert fp.float_val('a_float', 0, ?f64(none), '') == none |
| 16 | assert fp.string_val('a_string', 0, ?string(none), '') == none |
| 17 | } |
| 18 | |
| 19 | fn test_if_flag_not_given_preserves_typed_option_defaults() { |
| 20 | mut fp := flag.new_flag_parser([]) |
| 21 | a_bool := fp.bool_val('a_bool', 0, ?bool(true), '') |
| 22 | an_int := fp.int_val('an_int', 0, ?int(42), '') |
| 23 | a_float := fp.float_val('a_float', 0, ?f64(1.5), '') |
| 24 | a_string := fp.string_val('a_string', 0, ?string('stuff'), '') |
| 25 | if value := a_bool { |
| 26 | assert value |
| 27 | } else { |
| 28 | assert false |
| 29 | } |
| 30 | if value := an_int { |
| 31 | assert value == 42 |
| 32 | } else { |
| 33 | assert false |
| 34 | } |
| 35 | if value := a_float { |
| 36 | assert value == 1.5 |
| 37 | } else { |
| 38 | assert false |
| 39 | } |
| 40 | if value := a_string { |
| 41 | assert value == 'stuff' |
| 42 | } else { |
| 43 | assert false |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | fn test_could_define_application_name_and_version() { |
| 48 | mut fp := flag.new_flag_parser([]) |
| 49 | fp.application('test app') |
| 50 | fp.version('0.0.42') |
| 51 | fp.description('some text') |
| 52 | assert fp.application_name == 'test app' |
| 53 | assert fp.application_version == '0.0.42' |
| 54 | assert fp.application_description == 'some text' |
| 55 | } |
| 56 | |
| 57 | fn test_bool_flags_do_not_need_an_value() { |
| 58 | mut fp := flag.new_flag_parser(['--a_bool']) |
| 59 | assert true == fp.bool('a_bool', 0, false, '') |
| 60 | } |
| 61 | |
| 62 | fn test_flag_values_can_be_returned_as_options() { |
| 63 | mut fp := flag.new_flag_parser([ |
| 64 | '--an_int', |
| 65 | '42', |
| 66 | '--a_float=2.0', |
| 67 | '--a_string', |
| 68 | 'stuff', |
| 69 | '--a_bool=false', |
| 70 | ]) |
| 71 | a_bool := fp.bool_val('a_bool', 0, ?bool(none), '') |
| 72 | an_int := fp.int_val('an_int', 0, ?int(none), '') |
| 73 | a_float := fp.float_val('a_float', 0, ?f64(none), '') |
| 74 | a_string := fp.string_val('a_string', 0, ?string(none), '') |
| 75 | if value := a_bool { |
| 76 | assert !value |
| 77 | } else { |
| 78 | assert false |
| 79 | } |
| 80 | if value := an_int { |
| 81 | assert value == 42 |
| 82 | } else { |
| 83 | assert false |
| 84 | } |
| 85 | if value := a_float { |
| 86 | assert value == 2.0 |
| 87 | } else { |
| 88 | assert false |
| 89 | } |
| 90 | if value := a_string { |
| 91 | assert value == 'stuff' |
| 92 | } else { |
| 93 | assert false |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | fn test_flags_could_be_defined_with_eq() { |
| 98 | mut fp := flag.new_flag_parser([ |
| 99 | '--an_int=42', |
| 100 | '--a_float=2.0', |
| 101 | '--bool_without', |
| 102 | '--a_string=stuff', |
| 103 | '--a_bool=true', |
| 104 | ]) |
| 105 | assert 42 == fp.int('an_int', 0, 0o666, '') |
| 106 | assert true == fp.bool('a_bool', 0, false, '') |
| 107 | assert true == fp.bool('bool_without', 0, false, '') |
| 108 | assert 2.0 == fp.float('a_float', 0, 1.0, '') |
| 109 | assert 'stuff' == fp.string('a_string', 0, 'not_stuff', '') |
| 110 | } |
| 111 | |
| 112 | fn test_values_could_be_defined_without_eq() { |
| 113 | mut fp := flag.new_flag_parser([ |
| 114 | '--an_int', |
| 115 | '42', |
| 116 | '--a_float', |
| 117 | '2.0', |
| 118 | '--bool_without', |
| 119 | '--a_string', |
| 120 | 'stuff', |
| 121 | '--a_bool', |
| 122 | 'true', |
| 123 | ]) |
| 124 | assert 42 == fp.int('an_int', 0, 0o666, '') |
| 125 | assert true == fp.bool('a_bool', 0, false, '') |
| 126 | assert true == fp.bool('bool_without', 0, false, '') |
| 127 | assert 2.0 == fp.float('a_float', 0, 1.0, '') |
| 128 | assert 'stuff' == fp.string('a_string', 0, 'not_stuff', '') |
| 129 | } |
| 130 | |
| 131 | fn test_values_could_be_defined_mixed() { |
| 132 | mut fp := flag.new_flag_parser([ |
| 133 | '--an_int', |
| 134 | '42', |
| 135 | '--a_float=2.0', |
| 136 | '--bool_without', |
| 137 | '--a_string', |
| 138 | 'stuff', |
| 139 | '--a_bool=true', |
| 140 | ]) |
| 141 | assert 42 == fp.int('an_int', 0, 0o666, '') |
| 142 | assert true == fp.bool('a_bool', 0, false, '') |
| 143 | assert true == fp.bool('bool_without', 0, false, '') |
| 144 | assert 2.0 == fp.float('a_float', 0, 1.0, '') |
| 145 | assert 'stuff' == fp.string('a_string', 0, 'not_stuff', '') |
| 146 | } |
| 147 | |
| 148 | fn test_beaware_for_argument_names_with_same_prefix() { |
| 149 | mut fp := flag.new_flag_parser([ |
| 150 | '--short', |
| 151 | '5', |
| 152 | '--shorter=7', |
| 153 | ]) |
| 154 | assert 5 == fp.int('short', 0, 0o666, '') |
| 155 | assert 7 == fp.int('shorter', 0, 0o666, '') |
| 156 | } |
| 157 | |
| 158 | fn test_beaware_for_argument_names_with_same_prefix_inverse() { |
| 159 | mut fp := flag.new_flag_parser([ |
| 160 | '--shorter=7', |
| 161 | '--short', |
| 162 | '5', |
| 163 | ]) |
| 164 | assert 5 == fp.int('short', 0, 0o666, '') |
| 165 | assert 7 == fp.int('shorter', 0, 0o666, '') |
| 166 | } |
| 167 | |
| 168 | fn test_allow_to_skip_executable_path() { |
| 169 | mut fp := flag.new_flag_parser(['./path/to/execuable']) |
| 170 | fp.skip_executable() |
| 171 | args := fp.finalize() or { |
| 172 | assert false |
| 173 | return |
| 174 | } |
| 175 | assert !args.contains('./path/to/execuable') |
| 176 | } |
| 177 | |
| 178 | fn test_none_flag_arguments_are_allowed() { |
| 179 | mut fp := flag.new_flag_parser([ |
| 180 | 'file1', |
| 181 | '--an_int=2', |
| 182 | 'file2', |
| 183 | 'file3', |
| 184 | '--bool_without', |
| 185 | 'file4', |
| 186 | '--outfile', |
| 187 | 'outfile', |
| 188 | ]) |
| 189 | assert 2 == fp.int('an_int', 0, 0o666, '') |
| 190 | assert 'outfile' == fp.string('outfile', 0, 'bad', '') |
| 191 | assert true == fp.bool('bool_without', 0, false, '') |
| 192 | } |
| 193 | |
| 194 | fn test_finalize_returns_none_flag_arguments_ordered() { |
| 195 | mut fp := flag.new_flag_parser(['d', 'b', 'x', 'a', '--outfile', 'outfile']) |
| 196 | fp.string('outfile', 0, 'bad', '') |
| 197 | finalized := fp.finalize() or { |
| 198 | assert false |
| 199 | return |
| 200 | } |
| 201 | expected := ['d', 'b', 'x', 'a'] |
| 202 | for i, v in finalized { |
| 203 | assert v == expected[i] |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | fn test_finalize_returns_error_for_unknown_flags_long() { |
| 208 | mut fp := flag.new_flag_parser(['--known', '--unknown']) |
| 209 | fp.bool('known', 0, false, '') |
| 210 | finalized := fp.finalize() or { |
| 211 | assert err.msg() == 'Unknown flag `--unknown`' |
| 212 | return |
| 213 | } |
| 214 | assert finalized.len < 0 // expect error to be returned |
| 215 | } |
| 216 | |
| 217 | fn test_finalize_returns_error_for_unknown_flags_short() { |
| 218 | mut fp := flag.new_flag_parser(['--known', '-x']) |
| 219 | fp.bool('known', 0, false, '') |
| 220 | finalized := fp.finalize() or { |
| 221 | assert err.msg() == 'Unknown flag `-x`' |
| 222 | return |
| 223 | } |
| 224 | assert finalized.len < 0 // expect error to be returned |
| 225 | } |
| 226 | |
| 227 | fn test_allow_to_build_usage_message() { |
| 228 | mut fp := flag.new_flag_parser([]) |
| 229 | fp.limit_free_args(1, 4)! |
| 230 | fp.application('flag_tool') |
| 231 | fp.version('v0.0.0') |
| 232 | fp.description('some short information about this tool') |
| 233 | fp.int('an_int', 0, 0o666, 'some int to define') |
| 234 | fp.bool('a_bool', 0, false, 'some bool to define') |
| 235 | fp.bool('bool_without_but_really_big', 0, false, 'this should appear on the next line') |
| 236 | fp.float('a_float', 0, 1.0, 'some float as well') |
| 237 | fp.string('a_string', 0, 'not_stuff', 'your credit card number') |
| 238 | usage := fp.usage() |
| 239 | mut all_strings_found := true |
| 240 | for s in ['flag_tool', 'v0.0.0', 'an_int <int>', 'a_bool', 'bool_without', 'a_float <float>', |
| 241 | 'a_string <string>', 'some int to define', 'some bool to define', |
| 242 | 'this should appear on the next line', 'some float as well', 'your credit card number', |
| 243 | 'The arguments should be at least 1 and at most 4 in number.', 'Usage', 'Options:', |
| 244 | 'Description:', 'some short information about this tool'] { |
| 245 | if !usage.contains(s) { |
| 246 | eprintln(" missing '${s}' in usage message") |
| 247 | all_strings_found = false |
| 248 | } |
| 249 | } |
| 250 | assert all_strings_found |
| 251 | } |
| 252 | |
| 253 | fn test_usage_shows_default_values_for_defaulted_options() { |
| 254 | mut fp := flag.new_flag_parser([]) |
| 255 | fp.int('count', `c`, 34, 'My parameter') |
| 256 | fp.float('ratio', `r`, 1.25, 'My ratio') |
| 257 | fp.string('name', `n`, 'guest', 'My name') |
| 258 | fp.string('empty', 0, '', 'Empty string') |
| 259 | fp.bool('verbose', `v`, false, 'Be chatty') |
| 260 | usage := fp.usage() |
| 261 | assert usage.contains('My parameter (default 34)') |
| 262 | assert usage.contains('My ratio (default 1.25)') |
| 263 | assert usage.contains('My name (default "guest")') |
| 264 | assert usage.contains('Empty string (default "")') |
| 265 | assert usage.contains('Be chatty (default false)') |
| 266 | } |
| 267 | |
| 268 | fn test_builtin_flags_do_not_show_default_values_in_usage() { |
| 269 | mut fp := flag.new_flag_parser([]) |
| 270 | fp.finalize() or { panic(err) } |
| 271 | usage := fp.usage() |
| 272 | assert !usage.contains('display this help and exit (default false)') |
| 273 | assert !usage.contains('output version information and exit (default false)') |
| 274 | } |
| 275 | |
| 276 | fn test_if_app_name_given_but_no_show_usage_message_still_contain_version() { |
| 277 | mut fp := flag.new_flag_parser([]) |
| 278 | fp.application('flag_tool') |
| 279 | fp.version('v0.0.0') |
| 280 | fp.description('a description') |
| 281 | fp.bool('a_bool', 0, false, '') |
| 282 | fp.options.show.clear(.name) |
| 283 | assert fp.usage().contains('v0.0.0\n---') |
| 284 | } |
| 285 | |
| 286 | fn test_if_version_given_but_no_show_usage_message_does_not_contain_banner() { |
| 287 | mut fp := flag.new_flag_parser([]) |
| 288 | fp.application('flag_tool') |
| 289 | fp.version('v0.0.0') |
| 290 | fp.description('a description') |
| 291 | fp.bool('a_bool', 0, false, '') |
| 292 | fp.options.show.clear(.version) |
| 293 | assert !fp.usage().contains('v0.0.0\n---') |
| 294 | } |
| 295 | |
| 296 | fn test_if_no_description_given_usage_message_does_not_contain_description() { |
| 297 | mut fp := flag.new_flag_parser([]) |
| 298 | fp.application('flag_tool') |
| 299 | fp.version('v0.0.0') |
| 300 | fp.bool('a_bool', 0, false, '') |
| 301 | assert !fp.usage().contains('Description:') |
| 302 | } |
| 303 | |
| 304 | fn test_if_description_given_but_no_show_usage_message_does_not_contain_description() { |
| 305 | mut fp := flag.new_flag_parser([]) |
| 306 | fp.application('flag_tool') |
| 307 | fp.version('v0.0.0') |
| 308 | fp.description('a description') |
| 309 | fp.bool('a_bool', 0, false, '') |
| 310 | fp.options.show.clear(.description) |
| 311 | assert !fp.usage().contains('Description:') |
| 312 | } |
| 313 | |
| 314 | fn test_if_no_options_given_usage_message_does_not_contain_options() { |
| 315 | mut fp := flag.new_flag_parser([]) |
| 316 | fp.application('flag_tool') |
| 317 | fp.version('v0.0.0') |
| 318 | assert !fp.usage().contains('Options:') |
| 319 | } |
| 320 | |
| 321 | fn test_if_options_given_but_no_show_flag_header_usage_message_does_not_contain_flag_header() { |
| 322 | mut fp := flag.new_flag_parser([]) |
| 323 | fp.application('flag_tool') |
| 324 | fp.version('v0.0.0') |
| 325 | fp.int('abc', `a`, 1, '') |
| 326 | fp.options.show.clear(.flags_header) |
| 327 | assert !fp.usage().contains('Options:') |
| 328 | } |
| 329 | |
| 330 | fn test_if_options_given_but_no_show_usage_message_does_not_contain_options() { |
| 331 | mut fp := flag.new_flag_parser([]) |
| 332 | fp.application('flag_tool') |
| 333 | fp.version('v0.0.0') |
| 334 | fp.int('abc', `a`, 1, '') |
| 335 | fp.options.show.clear(.flags) |
| 336 | assert !fp.usage().contains('Options:') |
| 337 | } |
| 338 | |
| 339 | fn test_if_footer_given_but_no_show_usage_message_does_not_contain_footer() { |
| 340 | mut fp := flag.new_flag_parser([]) |
| 341 | fp.application('flag_tool') |
| 342 | fp.version('v0.0.0') |
| 343 | fp.int('abc', `a`, 1, '') |
| 344 | fp.footers << 'footer1' |
| 345 | fp.options.show.clear(.footer) |
| 346 | assert !fp.usage().contains('footer1') |
| 347 | } |
| 348 | |
| 349 | fn test_default_val_descriptions_for_bools() { |
| 350 | mut fp := flag.new_flag_parser([]) |
| 351 | fp.bool('a_bool', `b`, true, '') |
| 352 | |
| 353 | // by default, boolean flags contain no value description |
| 354 | assert !fp.usage().contains('<bool>') |
| 355 | } |
| 356 | |
| 357 | fn test_custom_val_descriptions_for_bools() { |
| 358 | mut fp := flag.new_flag_parser([]) |
| 359 | fp.bool('a_bool', `b`, true, '', val_desc: '<custom bool>') |
| 360 | |
| 361 | // a custom boolean value description will be output |
| 362 | assert fp.usage().contains('<custom bool>') |
| 363 | } |
| 364 | |
| 365 | fn test_default_val_descriptions_for_ints() { |
| 366 | mut fp := flag.new_flag_parser([]) |
| 367 | fp.int_multi('a_int', `a`, '') |
| 368 | fp.int('b_int', `i`, 0, '') |
| 369 | |
| 370 | assert fp.usage().contains('<multiple ints>') |
| 371 | assert fp.usage().contains('<int>') |
| 372 | } |
| 373 | |
| 374 | fn test_custom_val_descriptions_for_ints() { |
| 375 | mut fp := flag.new_flag_parser([]) |
| 376 | fp.int_multi('a_int', `a`, '', val_desc: '<multi custom int>') |
| 377 | fp.int('b_int', `i`, 0, '', val_desc: '<custom int>') |
| 378 | |
| 379 | assert fp.usage().contains('<multi custom int>') |
| 380 | assert fp.usage().contains('<custom int>') |
| 381 | } |
| 382 | |
| 383 | fn test_default_val_descriptions_for_floats() { |
| 384 | mut fp := flag.new_flag_parser([]) |
| 385 | fp.float_multi('a_float', `a`, '') |
| 386 | fp.float('b_float', `f`, 0.0, '') |
| 387 | |
| 388 | assert fp.usage().contains('<multiple floats>') |
| 389 | assert fp.usage().contains('<float>') |
| 390 | } |
| 391 | |
| 392 | fn test_custom_val_descriptions_for_floats() { |
| 393 | mut fp := flag.new_flag_parser([]) |
| 394 | fp.float_multi('a_float', `a`, '', val_desc: '<multi custom float>') |
| 395 | fp.float('b_float', `f`, 0.0, '', val_desc: '<custom float>') |
| 396 | |
| 397 | assert fp.usage().contains('<multi custom float>') |
| 398 | assert fp.usage().contains('<custom float>') |
| 399 | } |
| 400 | |
| 401 | fn test_default_val_descriptions_for_strings() { |
| 402 | mut fp := flag.new_flag_parser([]) |
| 403 | fp.string_multi('a_string', `a`, '') |
| 404 | fp.string('b_string', `s`, '', '') |
| 405 | |
| 406 | assert fp.usage().contains('<multiple strings>') |
| 407 | assert fp.usage().contains('<string>') |
| 408 | } |
| 409 | |
| 410 | fn test_custom_val_descriptions_for_strings() { |
| 411 | mut fp := flag.new_flag_parser([]) |
| 412 | fp.string_multi('a_string', `a`, '', val_desc: '<multi custom string>') |
| 413 | fp.string('b_string', `s`, '', '', val_desc: '<custom string>') |
| 414 | |
| 415 | assert fp.usage().contains('<multi custom string>') |
| 416 | assert fp.usage().contains('<custom string>') |
| 417 | } |
| 418 | |
| 419 | fn test_free_args_could_be_limited() { |
| 420 | mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) |
| 421 | fp1.limit_free_args(1, 4)! |
| 422 | args := fp1.finalize() or { |
| 423 | assert false |
| 424 | return |
| 425 | } |
| 426 | assert args[0] == 'a' |
| 427 | assert args[1] == 'b' |
| 428 | assert args[2] == 'c' |
| 429 | |
| 430 | mut fp2 := flag.new_flag_parser(['--', 'a']) |
| 431 | fp2.limit_free_args_to_at_least(1)! |
| 432 | args2 := fp2.finalize() or { |
| 433 | assert false |
| 434 | return |
| 435 | } |
| 436 | assert args2[0] == 'a' |
| 437 | } |
| 438 | |
| 439 | fn test_error_for_to_few_free_args() { |
| 440 | mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) |
| 441 | fp1.limit_free_args(5, 6)! |
| 442 | args := fp1.finalize() or { |
| 443 | assert err.msg().starts_with('Expected at least 5 arguments') |
| 444 | return |
| 445 | } |
| 446 | assert args.len < 0 // expect an error and need to use args |
| 447 | } |
| 448 | |
| 449 | fn test_error_for_to_much_free_args() { |
| 450 | mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) |
| 451 | fp1.limit_free_args(1, 2)! |
| 452 | args := fp1.finalize() or { |
| 453 | assert err.msg().starts_with('Expected at most 2 arguments') |
| 454 | return |
| 455 | } |
| 456 | assert args.len < 0 // expect an error and need to use args |
| 457 | } |
| 458 | |
| 459 | fn test_could_expect_no_free_args() { |
| 460 | mut fp1 := flag.new_flag_parser(['a']) |
| 461 | fp1.limit_free_args(0, 0)! |
| 462 | args := fp1.finalize() or { |
| 463 | assert err.msg().starts_with('Expected no arguments') |
| 464 | return |
| 465 | } |
| 466 | assert args.len < 0 // expect an error and need to use args |
| 467 | } |
| 468 | |
| 469 | fn test_allow_abbreviations() { |
| 470 | mut fp := flag.new_flag_parser(['-v', '-o', 'some_file', '-i', '42', '-f', '2.0']) |
| 471 | v := fp.bool('version', `v`, false, '') |
| 472 | o := fp.string('output', `o`, 'empty', '') |
| 473 | i := fp.int('count', `i`, 0, '') |
| 474 | f := fp.float('value', `f`, 0.0, '') |
| 475 | assert v == true |
| 476 | assert o == 'some_file' |
| 477 | assert i == 42 |
| 478 | assert f == 2.0 |
| 479 | u := fp.usage() |
| 480 | assert u.contains(' -v') |
| 481 | assert u.contains(' -o') |
| 482 | assert u.contains(' -i') |
| 483 | assert u.contains(' -f') |
| 484 | assert u.contains(' -o, --output <string>') |
| 485 | assert u.contains(' -i, --count <int>') |
| 486 | assert u.contains(' -f, --value <float>') |
| 487 | } |
| 488 | |
| 489 | fn test_allow_kebab_options() { |
| 490 | default_value := 'this_is_the_default_value_of_long_option' |
| 491 | long_option_value := 'this_is_a_long_option_value_as_argument' |
| 492 | mut fp := |
| 493 | flag.new_flag_parser(['--my-long-flag', 'true', '--my-long-option', long_option_value]) |
| 494 | my_flag := fp.bool('my-long-flag', 0, false, 'flag with long-kebab-name') |
| 495 | my_option := fp.string('my-long-option', 0, default_value, 'string with long-kebab-name') |
| 496 | assert my_flag == true |
| 497 | assert my_option == long_option_value |
| 498 | u := fp.usage() |
| 499 | assert u.contains(' --my-long-flag') |
| 500 | assert u.contains(' --my-long-option') |
| 501 | } |
| 502 | |
| 503 | fn test_not_provided_option_is_not_returned() { |
| 504 | mut fp := flag.new_flag_parser([]) |
| 505 | fp.bool_opt('some-flag', `a`, '') or { |
| 506 | fp.int_opt('some-flag', `a`, '') or { |
| 507 | fp.float_opt('some-flag', `a`, '') or { |
| 508 | fp.string_opt('some-flag', `a`, '') or { |
| 509 | // Everything should not return |
| 510 | return |
| 511 | } |
| 512 | return |
| 513 | } |
| 514 | return |
| 515 | } |
| 516 | return |
| 517 | } |
| 518 | // If we reach here, one of them returned a value. |
| 519 | assert false |
| 520 | } |
| 521 | |
| 522 | fn test_provided_option_is_returned() { |
| 523 | mut fp := flag.new_flag_parser(['-a', '-b', '3', '-c', 'hello', '-d', '3.14']) |
| 524 | a := fp.bool_opt('some-flag', `a`, '') or { panic('bool_opt did not return a bool') } |
| 525 | b := fp.int_opt('some-flag', `b`, '') or { panic('int_opt did not return an int') } |
| 526 | c := fp.string_opt('some-flag', `c`, '') or { panic('string_opt did not return a string') } |
| 527 | d := fp.float_opt('some-flag', `d`, '') or { panic('float_opt did not return a float') } |
| 528 | assert true == a |
| 529 | assert b == 3 |
| 530 | assert c == 'hello' |
| 531 | assert d == 3.14 |
| 532 | } |
| 533 | |
| 534 | fn test_multiple_arguments() { |
| 535 | mut fp := flag.new_flag_parser([ |
| 536 | '-a', |
| 537 | '2', |
| 538 | '-a', |
| 539 | '3', |
| 540 | '-a', |
| 541 | '5', |
| 542 | '-b', |
| 543 | 'a', |
| 544 | '-b', |
| 545 | 'c', |
| 546 | '-b', |
| 547 | 'b', |
| 548 | '-c', |
| 549 | '1.23', |
| 550 | '-c', |
| 551 | '2.34', |
| 552 | '-c', |
| 553 | '3.45', |
| 554 | ]) |
| 555 | // TODO: Move to array comparison once it's implemented |
| 556 | // assert fp.int_multi('some-flag', `a`, '') == [2, 3, 5] && |
| 557 | // fp.string_multi('some-flag', `b`, '') == ['a', 'c', 'b'] && |
| 558 | // fp.float_multi('some-flag', `c`, '') == [1.23, 2.34, 3.45] |
| 559 | a := fp.int_multi('some-flag', `a`, '') |
| 560 | b := fp.string_multi('some-flag', `b`, '') |
| 561 | c := fp.float_multi('some-flag', `c`, '') |
| 562 | assert a.len == 3 |
| 563 | assert b.len == 3 |
| 564 | assert c.len == 3 |
| 565 | assert a[0] == 2 |
| 566 | assert a[1] == 3 |
| 567 | assert a[2] == 5 |
| 568 | assert b[0] == 'a' |
| 569 | assert b[1] == 'c' |
| 570 | assert b[2] == 'b' |
| 571 | assert c[0] == 1.23 |
| 572 | assert c[1] == 2.34 |
| 573 | assert c[2] == 3.45 |
| 574 | } |
| 575 | |
| 576 | fn test_long_options_that_start_with_the_same_letter_as_another_short_option() { |
| 577 | mut fp := flag.new_flag_parser([ |
| 578 | '--vabc', |
| 579 | '/abc', |
| 580 | ]) |
| 581 | verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') |
| 582 | vabc := fp.string('vabc', `x`, 'default', |
| 583 | 'Another option that *may* conflict with v, but *should not*') |
| 584 | assert verbose == false |
| 585 | assert vabc == '/abc' |
| 586 | } |
| 587 | |
| 588 | fn test_long_options_that_start_with_the_same_letter_as_another_short_option_both_set() { |
| 589 | mut fp := flag.new_flag_parser([ |
| 590 | '-v', |
| 591 | '--vabc', |
| 592 | '/abc', |
| 593 | ]) |
| 594 | verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') |
| 595 | vabc := fp.string('vabc', `x`, 'default', |
| 596 | 'Another option that *may* conflict with v, but *should not*') |
| 597 | assert verbose == true |
| 598 | assert vabc == '/abc' |
| 599 | } |
| 600 | |
| 601 | fn test_single_dash() { |
| 602 | mut fp := flag.new_flag_parser([ |
| 603 | '-', |
| 604 | ]) |
| 605 | flag_update := fp.bool('update', `u`, false, 'Update tools') |
| 606 | assert flag_update == false |
| 607 | } |
| 608 | |
| 609 | fn test_optional_flags() { |
| 610 | mut fp := flag.new_flag_parser(['-a', '10', '-b']) |
| 611 | fp.int_opt('some-flag', `a`, '') or { |
| 612 | assert false |
| 613 | return |
| 614 | } |
| 615 | b := fp.string_opt('another-flag', `b`, '') or { 'some_default_value' } |
| 616 | assert b == 'some_default_value' |
| 617 | } |
| 618 | |
| 619 | fn test_dashdash_acts_as_parser_full_stop() { |
| 620 | mut fp := flag.new_flag_parser(['-b', '5', '--', '-d', '-x', '-b', '4', '-a', '-c', 'hello', |
| 621 | 'some', 'other', 'parameters']) |
| 622 | a := fp.bool_opt('a-bool-flag', `a`, '') or { false } |
| 623 | b := fp.int_opt('an-int-flag', `b`, '') or { -1 } |
| 624 | c := fp.string_opt('a-string-flag', `c`, '') or { 'default' } |
| 625 | assert a == false |
| 626 | assert b == 5 |
| 627 | assert c == 'default' |
| 628 | args := fp.finalize()! |
| 629 | assert args.len > 0 |
| 630 | assert args[0] != '--' |
| 631 | assert args == ['-d', '-x', '-b', '4', '-a', '-c', 'hello', 'some', 'other', 'parameters'] |
| 632 | } |
| 633 | |
| 634 | fn test_dashdash_acts_as_parser_full_stop_dashdash_at_end() { |
| 635 | mut fp := flag.new_flag_parser(['-b', '5', '-b', '4', 'other', 'params', '--']) |
| 636 | b := fp.int_multi('an-int-flag', `b`, '') |
| 637 | assert b == [5, 4] |
| 638 | args := fp.finalize()! |
| 639 | assert args.len > 0 |
| 640 | } |
| 641 | |
| 642 | fn test_empty_string_with_flag() { |
| 643 | mut fp := flag.new_flag_parser(['']) |
| 644 | s := fp.string('something', `s`, 'default', 'Hey parse me') |
| 645 | } |
| 646 | |
| 647 | fn test_finalize_with_multi_shortargs() { |
| 648 | mut fp := flag.new_flag_parser(['-ab', '-c']) |
| 649 | a_bool := fp.bool('a_bool', `a`, false, '') |
| 650 | assert a_bool |
| 651 | b_bool := fp.bool('b_bool', `b`, false, '') |
| 652 | assert b_bool |
| 653 | c_bool := fp.bool('c_bool', `c`, false, '') |
| 654 | assert c_bool |
| 655 | additional_args := fp.finalize()! |
| 656 | println(additional_args.join_lines()) |
| 657 | assert additional_args == [] |
| 658 | } |
| 659 | |
| 660 | fn test_finalize_with_multi_shortargs_different_order() { |
| 661 | mut fp := flag.new_flag_parser(['-ba', '-c']) |
| 662 | a_bool := fp.bool('a_bool', `a`, false, '') |
| 663 | assert a_bool |
| 664 | b_bool := fp.bool('b_bool', `b`, false, '') |
| 665 | assert b_bool |
| 666 | c_bool := fp.bool('c_bool', `c`, false, '') |
| 667 | assert c_bool |
| 668 | additional_args := fp.finalize()! |
| 669 | println(additional_args.join_lines()) |
| 670 | assert additional_args == [] |
| 671 | } |
| 672 | |