Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file test_validate_command.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633open!Coreopen!Importletgroupsubcommands=Command.group~summary:""subcommandsletbasicparam=Command.basic~summary:""paramletexecpath_to_exechild_subcommand=Command.exec~summary:""~path_to_exe~child_subcommand();;letget_output_or_errorcommandargs~f=(matchfcommandargswith|Ok()->()|Errorerror->print_s[%sexp(error:Error.t)]|exceptionexn->print_s[%sexp"Raised",(exn:exn)]);expect_test_output[%here];;(* Opam cannot distinguish between dependencies of the implementation and dependencies of
the tests, so [core > patdiff -> core tests] would be a dependency cycle at the opam
package level.
Instead we approximate a diff as a shared prefix, a shared suffix, and one big
substitution in between. Good enough for the simple diffs in this test file. *)lethacky_diff_because_patdiff_breaks_the_public_release~prev~next=letshared_prefix=String.common_prefix2prevnextinletshared_suffix=String.common_suffix2prevnextinletget_unshared_lines_and_prependstr~prepend=String.substr~pos:(String.lengthshared_prefix)~len:String.(lengthstr-lengthshared_prefix-lengthshared_suffix)|>String.split_lines|>List.map~f:(funs->prepend^s)in[String.split_linesshared_prefix;get_unshared_lines_and_prependprev~prepend:"-|";get_unshared_lines_and_prependnext~prepend:"+|";String.split_linesshared_suffix]|>List.concat|>String.concat~sep:"\n";;lettestcommandargs=letvalidate_command_line=get_output_or_errorcommandargs~f:(funcommandargs->Command_test_helpers.validate_command_line(Command_unix.shapecommand)|>Or_error.bind~f:(funf->fargs))inletvalidate_command=get_output_or_errorcommandargs~f:Command_test_helpers.validate_commandinmatchString.(=)validate_command_linevalidate_commandwith|true->print_endlinevalidate_command(* either would work, since they're the same *)|false->print_endline"Diff of validate_command (-) vs validate_command_line (+):";hacky_diff_because_patdiff_breaks_the_public_release~prev:validate_command~next:validate_command_line|>print_endline;;module_=structlettest=letcommand=basic(Command.Param.returnFn.id)ingroup["foo1",group["bar1",command;"qux",command];"foo2",command]|>test;;let%expect_test"subcommand__missing_subcommand"=test["foo1"];[%expect{|
CMD foo1 SUBCOMMAND
=== subcommands ===
bar1 .
qux .
help . explain a given subcommand (perhaps recursively)
missing subcommand for command CMD foo1
(command.ml.Exit_called (status 1)) |}];;let%expect_test"subcommand__present_subcommand"=test["foo1";"bar1"];[%expect{| |}];;let%expect_test"subcommand__ambiguous_prefix"=test["foo"];[%expect{|
CMD SUBCOMMAND
=== subcommands ===
foo1 .
foo2 .
version . print version information
help . explain a given subcommand (perhaps recursively)
subcommand foo is an ambiguous prefix: foo1, foo2
(command.ml.Exit_called (status 1)) |}];;let%expect_test"subcommand__unambiguous_prefix"=test["foo1";"q"];[%expect{| |}];;endmodule_=structlet%expect_test"misc__check_command_doesn't_actually_run"=letcommand=basic(let%map_open.Commands=flag"-print"(requiredstring)~doc:""infun()->print_endlines)intestcommand["-print";"don't print me"];[%expect{| |}];;let%expect_test"misc__cannot_validate_exec_commands"=letexec_dev_null=exec(`Absolute"/dev/null")[]intestexec_dev_null[];[%expect{|
("[Exec _] commands are not validated to avoid unexpected external dependencies."
(exec_info (
(summary "")
(working_dir ELIDED-IN-TEST)
(path_to_exe /dev/null)
(child_subcommand ())))) |}];;endmodule_=structopenCommand.Paramletunit_flag?aliases?full_flag_requirednamearg_type=flag?aliases?full_flag_requirednamearg_type~doc:""|>map~f:ignore;;lettestparamsargs=letparam=List.foldparams~init:(return())~f:(map2~f:const)intest(basic(mapparam~f:const))args;;let%expect_test"params__full_flag_required"=lettest_full_flag_requiredargs=test[unit_flag"-foo"(requiredint)~full_flag_required:()]argsin(* Validating by reconstruction cannot test full-flag-required *)test_full_flag_required["-f";"1"];[%expect{|
Diff of validate_command (-) vs validate_command_line (+):
-|Error parsing command line:
-|
-| unknown flag -f
-|
-|For usage information, run
-|
-| CMD -help
-|
-|(command.ml.Exit_called (status 1)) |}];;module_=structlettest_prefix=test[unit_flag"-foobar"no_arg;unit_flag"-fubar"no_arg]let%expect_test"params_prefixes__unambiguous_prefix"=test_prefix["-fo"];[%expect{| |}];;let%expect_test"params_prefixes__ambiguous_prefix"=test_prefix["-f"];[%expect{|
Error parsing command line:
flag -f is an ambiguous prefix: -foobar, -fubar
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;endmodule_=structlettest_flagsargs=test[unit_flag"-a"no_arg;unit_flag"-b"(listedint)]argslet%expect_test"params_arg_types__not_passing_nonrequired_flags"=test_flags["-a"];[%expect{| |}];;let%expect_test"params_arg_types__passing_invalid_anonymous_args"=test_flags["-a";"_"];[%expect{|
Error parsing command line:
too many anonymous arguments
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_arg_types__passing_wrong_arg_type"=(* Validating by reconstruction cannot test arg type, only arity *)test_flags["-b";"_"];[%expect{|
Diff of validate_command (-) vs validate_command_line (+):
-|Error parsing command line:
-|
-| failed to parse -b value "_".
-| (Failure "Int.of_string: \"_\"")
-|
-|For usage information, run
-|
-| CMD -help
-|
-|(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_arg_types__passing_correct_arg_type"=test_flags["-b";"1"];[%expect{||}];;let%expect_test"params_arg_types__passing_flag_but_no_arg"=test_flags["-b"];[%expect{|
Error parsing command line:
missing argument for flag -b
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_arg_types__passing_arg_which_looks_like_a_flag"=(* Validating by reconstruction cannot test arg type, only arity *)test_flags["-b";"-b"];[%expect{|
Diff of validate_command (-) vs validate_command_line (+):
-|Error parsing command line:
-|
-| failed to parse -b value "-b".
-| (Failure "Int.of_string: \"-b\"")
-|
-|For usage information, run
-|
-| CMD -help
-|
-|(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_arg_types__passing_flag_twice_but_arg_once"=test_flags["-b";"-b";"_"];(* Wrong error raised: Validating by reconstruction cannot
test arg type, only arity *)[%expect{|
Diff of validate_command (-) vs validate_command_line (+):
Error parsing command line:
-|failed to parse -b value "-b".
-| (Failure "Int.of_string: \"-b\"")
+|too many anonymous arguments
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;endmodule_=structlettest_alias=test[unit_flag"-a"no_arg~aliases:["-b"]]let%expect_test"params_aliases__original_flag_passed"=test_alias["-a"];[%expect{| |}];;let%expect_test"params_aliases__alias_passed"=test_alias["-b"];[%expect{| |}];;let%expect_test"params_aliases__non_alias_passed"=test_alias["-c"];[%expect{|
Error parsing command line:
unknown flag -c
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_aliases__internal_alias_exluded_from_help"=test[]["--help"];[%expect{|
CMD
=== flags ===
[-build-info] . print info about this build and exit
[-version] . print the version of this build and exit
[-help], -? . print this help text and exit
(command.ml.Exit_called (status 0)) |}];;endmodule_=structlettest_anons_vs_flag_args=letunit_anonf=anon(f("A"%:int)|>map_anons~f:ignore)intest[unit_anonFn.id;unit_flag"-a"(optionalint);unit_flag"-b"no_arg];;let%expect_test"params_anonymous_flags_and_args__just_anon"=test_anons_vs_flag_args["1"];[%expect{| |}];;let%expect_test"params_anonymous_flags_and_args__anon_and_arg"=test_anons_vs_flag_args["1";"-a";"2"];[%expect{| |}];;let%expect_test"params_anonymous_flags_and_args__no_required_anon"=test_anons_vs_flag_args["-a";"2"];[%expect{|
Error parsing command line:
missing anonymous argument: A
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_anonymous_flags_and_args__anon_and_no-arg_flag"=test_anons_vs_flag_args["-b";"3"];[%expect{| |}];;endmodule_=structlettest_escapeargs=letescape=[flag~doc:"""--"escape|>map~f:(Option.map~f:(List.map~f:Int.of_string))]intestescapeargs;;let%expect_test"params_escape__incorrect_escaped_arg_type"=test_escape["--";"foo"];(* Wrong error raised: Validation by reconstruction cannot
handle side-effects like escape args *)[%expect{|
Diff of validate_command (-) vs validate_command_line (+):
Error parsing command line:
-|(Failure "Int.of_string: \"foo\"")
+|too many anonymous arguments
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_escape__correct_escaped_arg_type"=(* Validation by reconstruction cannot handle side-effects like escape args *)test_escape["--";"1"];[%expect{|
Diff of validate_command (-) vs validate_command_line (+):
+|Error parsing command line:
+|
+| too many anonymous arguments
+|
+|For usage information, run
+|
+| CMD -help
+|
+|(command.ml.Exit_called (status 1)) |}];;endmodule_=structletprint~make_argsnresult="$ CMD"::make_argsn|>String.concat~sep:" "|>print_endline;print_endlineresult;;lettest_param_typesparamargs=test[(let%map_open.Command_=paraminFn.id)]args;;module_=structletmake_args=List.init~f:(const["-a";"1"])>>List.concatletprint=print~make_argslettestfn=letparam=unit_flag"-a"(fint)inletargs=make_argsnintest_param_typesparamargs;;let%expect_test"params_counting_flags__listed"=lettestn=testlistedn;printn[%expect.output]intest0;[%expect{| $ CMD |}];test1;[%expect{| $ CMD -a 1 |}];test2;[%expect{| $ CMD -a 1 -a 1 |}];;let%expect_test"params_counting_flags__optional"=lettestn=testoptionaln;printn[%expect.output]intest0;[%expect{| $ CMD |}];test1;[%expect{| $ CMD -a 1 |}];test2;[%expect{|
$ CMD -a 1 -a 1
Error parsing command line:
flag -a passed more than once
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_counting_flags__required"=lettestn=testrequiredn;printn[%expect.output]intest0;[%expect{|
$ CMD
Error parsing command line:
missing required flag: -a
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];test1;[%expect{| $ CMD -a 1 |}];test2;[%expect{|
$ CMD -a 1 -a 1
Error parsing command line:
flag -a passed more than once
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;endmodule_=structletmake_args=List.init~f:(Int.succ>>Int.to_string)letprint=print~make_argslettestfn=letparam=anon(f("A"%:int))inletargs=make_argsnintest_param_typesparamargs;;let%expect_test"params_counting_anonymous_args__sequence"=lettestn=testsequencen;printn[%expect.output]intest0;[%expect{| $ CMD |}];test1;[%expect{| $ CMD 1 |}];test2;[%expect{| $ CMD 1 2 |}];;let%expect_test"params_counting_anonymous_args__maybe"=lettestn=testmayben;printn[%expect.output]intest0;[%expect{| $ CMD |}];test1;[%expect{| $ CMD 1 |}];test2;[%expect{|
$ CMD 1 2
Error parsing command line:
too many anonymous arguments
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_counting_anonymous_args__required"=lettestn=testFn.idn;printn[%expect.output]intest0;[%expect{|
$ CMD
Error parsing command line:
missing anonymous argument: A
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];test1;[%expect{| $ CMD 1 |}];test2;[%expect{|
$ CMD 1 2
Error parsing command line:
too many anonymous arguments
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];;let%expect_test"params_counting_anonymous_args__required_and_maybe"=lettestn=test_param_types(let%map_open.Command_=anon("A"%:int)and_=anon(maybe("B"%:int))inFn.id)(make_argsn);printn[%expect.output]intest0;[%expect{|
$ CMD
Error parsing command line:
missing anonymous argument: A
For usage information, run
CMD -help
(command.ml.Exit_called (status 1)) |}];test1;[%expect{| $ CMD 1 |}];test2;[%expect{| $ CMD 1 2 |}];;endendend