diff options
Diffstat (limited to 'v_windows/v/vlib/flag/flag_test.v')
-rw-r--r-- | v_windows/v/vlib/flag/flag_test.v | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/v_windows/v/vlib/flag/flag_test.v b/v_windows/v/vlib/flag/flag_test.v new file mode 100644 index 0000000..8326193 --- /dev/null +++ b/v_windows/v/vlib/flag/flag_test.v @@ -0,0 +1,412 @@ +import flag + +fn test_if_flag_not_given_return_default_values() { + mut fp := flag.new_flag_parser([]) + assert false == fp.bool('a_bool', 0, false, '') + assert 42 == fp.int('an_int', 0, 42, '') + assert 1.0 == fp.float('a_float', 0, 1.0, '') + assert 'stuff' == fp.string('a_string', 0, 'stuff', '') +} + +fn test_could_define_application_name_and_version() { + mut fp := flag.new_flag_parser([]) + fp.application('test app') + fp.version('0.0.42') + fp.description('some text') + assert fp.application_name == 'test app' + assert fp.application_version == '0.0.42' + assert fp.application_description == 'some text' +} + +fn test_bool_flags_do_not_need_an_value() { + mut fp := flag.new_flag_parser(['--a_bool']) + assert true == fp.bool('a_bool', 0, false, '') +} + +fn test_flags_could_be_defined_with_eq() { + mut fp := flag.new_flag_parser([ + '--an_int=42', + '--a_float=2.0', + '--bool_without', + '--a_string=stuff', + '--a_bool=true', + ]) + assert 42 == fp.int('an_int', 0, 0o666, '') + assert true == fp.bool('a_bool', 0, false, '') + assert true == fp.bool('bool_without', 0, false, '') + assert 2.0 == fp.float('a_float', 0, 1.0, '') + assert 'stuff' == fp.string('a_string', 0, 'not_stuff', '') +} + +fn test_values_could_be_defined_without_eq() { + mut fp := flag.new_flag_parser([ + '--an_int', + '42', + '--a_float', + '2.0', + '--bool_without', + '--a_string', + 'stuff', + '--a_bool', + 'true', + ]) + assert 42 == fp.int('an_int', 0, 0o666, '') + assert true == fp.bool('a_bool', 0, false, '') + assert true == fp.bool('bool_without', 0, false, '') + assert 2.0 == fp.float('a_float', 0, 1.0, '') + assert 'stuff' == fp.string('a_string', 0, 'not_stuff', '') +} + +fn test_values_could_be_defined_mixed() { + mut fp := flag.new_flag_parser([ + '--an_int', + '42', + '--a_float=2.0', + '--bool_without', + '--a_string', + 'stuff', + '--a_bool=true', + ]) + assert 42 == fp.int('an_int', 0, 0o666, '') + assert true == fp.bool('a_bool', 0, false, '') + assert true == fp.bool('bool_without', 0, false, '') + assert 2.0 == fp.float('a_float', 0, 1.0, '') + assert 'stuff' == fp.string('a_string', 0, 'not_stuff', '') +} + +fn test_beaware_for_argument_names_with_same_prefix() { + mut fp := flag.new_flag_parser([ + '--short', + '5', + '--shorter=7', + ]) + assert 5 == fp.int('short', 0, 0o666, '') + assert 7 == fp.int('shorter', 0, 0o666, '') +} + +fn test_beaware_for_argument_names_with_same_prefix_inverse() { + mut fp := flag.new_flag_parser([ + '--shorter=7', + '--short', + '5', + ]) + assert 5 == fp.int('short', 0, 0o666, '') + assert 7 == fp.int('shorter', 0, 0o666, '') +} + +fn test_allow_to_skip_executable_path() { + mut fp := flag.new_flag_parser(['./path/to/execuable']) + fp.skip_executable() + args := fp.finalize() or { + assert false + return + } + assert !args.contains('./path/to/execuable') +} + +fn test_none_flag_arguments_are_allowed() { + mut fp := flag.new_flag_parser([ + 'file1', + '--an_int=2', + 'file2', + 'file3', + '--bool_without', + 'file4', + '--outfile', + 'outfile', + ]) + assert 2 == fp.int('an_int', 0, 0o666, '') + assert 'outfile' == fp.string('outfile', 0, 'bad', '') + assert true == fp.bool('bool_without', 0, false, '') +} + +fn test_finalize_returns_none_flag_arguments_ordered() { + mut fp := flag.new_flag_parser(['d', 'b', 'x', 'a', '--outfile', 'outfile']) + fp.string('outfile', 0, 'bad', '') + finalized := fp.finalize() or { + assert false + return + } + expected := ['d', 'b', 'x', 'a'] + for i, v in finalized { + assert v == expected[i] + } +} + +fn test_finalize_returns_error_for_unknown_flags_long() { + mut fp := flag.new_flag_parser(['--known', '--unknown']) + fp.bool('known', 0, false, '') + finalized := fp.finalize() or { + assert err.msg == 'Unknown flag `--unknown`' + return + } + assert finalized.len < 0 // expect error to be returned +} + +fn test_finalize_returns_error_for_unknown_flags_short() { + mut fp := flag.new_flag_parser(['--known', '-x']) + fp.bool('known', 0, false, '') + finalized := fp.finalize() or { + assert err.msg == 'Unknown flag `-x`' + return + } + assert finalized.len < 0 // expect error to be returned +} + +fn test_allow_to_build_usage_message() { + mut fp := flag.new_flag_parser([]) + fp.limit_free_args(1, 4) + fp.application('flag_tool') + fp.version('v0.0.0') + fp.description('some short information about this tool') + fp.int('an_int', 0, 0o666, 'some int to define') + fp.bool('a_bool', 0, false, 'some bool to define') + fp.bool('bool_without_but_really_big', 0, false, 'this should appear on the next line') + fp.float('a_float', 0, 1.0, 'some float as well') + fp.string('a_string', 0, 'not_stuff', 'your credit card number') + usage := fp.usage() + mut all_strings_found := true + for s in ['flag_tool', 'v0.0.0', 'an_int <int>', 'a_bool', 'bool_without', 'a_float <float>', + 'a_string <string>', 'some int to define', 'some bool to define', + 'this should appear on the next line', 'some float as well', 'your credit card number', + 'The arguments should be at least 1 and at most 4 in number.', 'Usage', 'Options:', + 'Description:', 'some short information about this tool'] { + if !usage.contains(s) { + eprintln(" missing '$s' in usage message") + all_strings_found = false + } + } + assert all_strings_found +} + +fn test_if_no_description_given_usage_message_does_not_contain_descpription() { + mut fp := flag.new_flag_parser([]) + fp.application('flag_tool') + fp.version('v0.0.0') + fp.bool('a_bool', 0, false, '') + assert !fp.usage().contains('Description:') +} + +fn test_if_no_options_given_usage_message_does_not_contain_options() { + mut fp := flag.new_flag_parser([]) + fp.application('flag_tool') + fp.version('v0.0.0') + assert !fp.usage().contains('Options:') +} + +fn test_free_args_could_be_limited() { + mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) + fp1.limit_free_args(1, 4) + args := fp1.finalize() or { + assert false + return + } + assert args[0] == 'a' + assert args[1] == 'b' + assert args[2] == 'c' +} + +fn test_error_for_to_few_free_args() { + mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) + fp1.limit_free_args(5, 6) + args := fp1.finalize() or { + assert err.msg.starts_with('Expected at least 5 arguments') + return + } + assert args.len < 0 // expect an error and need to use args +} + +fn test_error_for_to_much_free_args() { + mut fp1 := flag.new_flag_parser(['a', 'b', 'c']) + fp1.limit_free_args(1, 2) + args := fp1.finalize() or { + assert err.msg.starts_with('Expected at most 2 arguments') + return + } + assert args.len < 0 // expect an error and need to use args +} + +fn test_could_expect_no_free_args() { + mut fp1 := flag.new_flag_parser(['a']) + fp1.limit_free_args(0, 0) + args := fp1.finalize() or { + assert err.msg.starts_with('Expected no arguments') + return + } + assert args.len < 0 // expect an error and need to use args +} + +fn test_allow_abreviations() { + mut fp := flag.new_flag_parser(['-v', '-o', 'some_file', '-i', '42', '-f', '2.0']) + v := fp.bool('version', `v`, false, '') + o := fp.string('output', `o`, 'empty', '') + i := fp.int('count', `i`, 0, '') + f := fp.float('value', `f`, 0.0, '') + assert v == true + assert o == 'some_file' + assert i == 42 + assert f == 2.0 + u := fp.usage() + assert u.contains(' -v') + assert u.contains(' -o') + assert u.contains(' -i') + assert u.contains(' -f') + assert u.contains(' -o, --output <string>') + assert u.contains(' -i, --count <int>') + assert u.contains(' -f, --value <float>') +} + +fn test_allow_kebab_options() { + default_value := 'this_is_the_default_value_of_long_option' + long_option_value := 'this_is_a_long_option_value_as_argument' + mut fp := flag.new_flag_parser(['--my-long-flag', 'true', '--my-long-option', long_option_value]) + my_flag := fp.bool('my-long-flag', 0, false, 'flag with long-kebab-name') + my_option := fp.string('my-long-option', 0, default_value, 'string with long-kebab-name') + assert my_flag == true + assert my_option == long_option_value + u := fp.usage() + assert u.contains(' --my-long-flag') + assert u.contains(' --my-long-option') +} + +fn test_not_provided_option_is_not_returned() { + mut fp := flag.new_flag_parser([]) + fp.bool_opt('some-flag', `a`, '') or { + fp.int_opt('some-flag', `a`, '') or { + fp.float_opt('some-flag', `a`, '') or { + fp.string_opt('some-flag', `a`, '') or { + // Everything should not return + return + } + return + } + return + } + return + } + // If we reach here, one of them returned a value. + assert false +} + +fn test_provided_option_is_returned() { + mut fp := flag.new_flag_parser(['-a', '-b', '3', '-c', 'hello', '-d', '3.14']) + a := fp.bool_opt('some-flag', `a`, '') or { panic('bool_opt did not return a bool') } + b := fp.int_opt('some-flag', `b`, '') or { panic('int_opt did not return an int') } + c := fp.string_opt('some-flag', `c`, '') or { panic('string_opt did not return a string') } + d := fp.float_opt('some-flag', `d`, '') or { panic('float_opt did not return a float') } + assert true == a + assert b == 3 + assert c == 'hello' + assert d == 3.14 +} + +fn test_multiple_arguments() { + mut fp := flag.new_flag_parser([ + '-a', + '2', + '-a', + '3', + '-a', + '5', + '-b', + 'a', + '-b', + 'c', + '-b', + 'b', + '-c', + '1.23', + '-c', + '2.34', + '-c', + '3.45', + ]) + // TODO Move to array comparison once it's implemented + // assert fp.int_multi('some-flag', `a`, '') == [2, 3, 5] && + // fp.string_multi('some-flag', `b`, '') == ['a', 'c', 'b'] && + // fp.float_multi('some-flag', `c`, '') == [1.23, 2.34, 3.45] + a := fp.int_multi('some-flag', `a`, '') + b := fp.string_multi('some-flag', `b`, '') + c := fp.float_multi('some-flag', `c`, '') + assert a.len == 3 + assert b.len == 3 + assert c.len == 3 + assert a[0] == 2 + assert a[1] == 3 + assert a[2] == 5 + assert b[0] == 'a' + assert b[1] == 'c' + assert b[2] == 'b' + assert c[0] == 1.23 + assert c[1] == 2.34 + assert c[2] == 3.45 +} + +fn test_long_options_that_start_with_the_same_letter_as_another_short_option() { + mut fp := flag.new_flag_parser([ + '--vabc', + '/abc', + ]) + verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') + vabc := fp.string('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') + assert verbose == false + assert vabc == '/abc' +} + +fn test_long_options_that_start_with_the_same_letter_as_another_short_option_both_set() { + mut fp := flag.new_flag_parser([ + '-v', + '--vabc', + '/abc', + ]) + verbose := fp.bool('verbose', `v`, false, 'Be more verbose.') + vabc := fp.string('vabc', `x`, 'default', 'Another option that *may* conflict with v, but *should not*') + assert verbose == true + assert vabc == '/abc' +} + +fn test_single_dash() { + mut fp := flag.new_flag_parser([ + '-', + ]) + flag_update := fp.bool('update', `u`, false, 'Update tools') + assert flag_update == false +} + +fn test_optional_flags() { + mut fp := flag.new_flag_parser(['-a', '10', '-b']) + fp.int_opt('some-flag', `a`, '') or { + assert false + return + } + b := fp.string_opt('another-flag', `b`, '') or { 'some_default_value' } + assert b == 'some_default_value' +} + +fn test_dashdash_acts_as_parser_full_stop() ? { + mut fp := flag.new_flag_parser(['-b', '5', '--', '-d', '-x', '-b', '4', '-a', '-c', 'hello', + 'some', 'other', 'parameters']) + a := fp.bool_opt('a-bool-flag', `a`, '') or { false } + b := fp.int_opt('an-int-flag', `b`, '') or { -1 } + c := fp.string_opt('a-string-flag', `c`, '') or { 'default' } + assert a == false + assert b == 5 + assert c == 'default' + args := fp.finalize() ? + assert args.len > 0 + assert args[0] != '--' + assert args == ['-d', '-x', '-b', '4', '-a', '-c', 'hello', 'some', 'other', 'parameters'] +} + +fn test_dashdash_acts_as_parser_full_stop_dashdash_at_end() ? { + mut fp := flag.new_flag_parser(['-b', '5', '-b', '4', 'other', 'params', '--']) + b := fp.int_multi('an-int-flag', `b`, '') + assert b == [5, 4] + args := fp.finalize() ? + assert args.len > 0 +} + +fn test_empty_string_with_flag() { + mut fp := flag.new_flag_parser(['']) + s := fp.string('something', `s`, 'default', 'Hey parse me') +} |