159 lines
5.4 KiB
OCaml
159 lines
5.4 KiB
OCaml
(*---------------------------------------------------------------------------
|
|
Copyright (c) 2025 The cmdliner programmers. All rights reserved.
|
|
SPDX-License-Identifier: ISC
|
|
---------------------------------------------------------------------------*)
|
|
|
|
open B0_std
|
|
open B0_testing
|
|
open Cmdliner
|
|
open Cmdliner.Term.Syntax
|
|
|
|
(* The tests have the following structure:
|
|
|
|
let test =
|
|
let cmd = … (* A command definition *) in
|
|
(* A few snapshots of valid cli parses *)
|
|
parse …
|
|
(* A few snapshots of invalid cli parses *)
|
|
error …
|
|
(* A snapshot of a plain text version of the manual *)
|
|
Testing_cmdliner.snap_man … *)
|
|
|
|
let test_with_used_args =
|
|
Test.test "Term.with_used_args" @@ fun () ->
|
|
let cmd =
|
|
Cmd.make (Cmd.info "test_with_used_args" ~doc:"Test cli arg capture") @@
|
|
let args =
|
|
let+ a = Arg.(value & flag & info ["a"; "aaa"])
|
|
and+ b = Arg.(value & opt (some string) None & info ["b"; "bbb"])
|
|
and+ c = Arg.(value & pos_all string [] & info []) in
|
|
(a, b, c)
|
|
in
|
|
let+ parse, args = Term.with_used_args args in
|
|
args, parse
|
|
in
|
|
let t = Test.T.(t2 (list string) (t3 bool (option string) (list string))) in
|
|
let parse = Testing_cmdliner.snap_parse t cmd in
|
|
let error err = Testing_cmdliner.snap_eval_error err cmd in
|
|
parse [] @@ __POS_OF__
|
|
([], (false, None, []));
|
|
(* Note some of these are bugs, see issue #204 *)
|
|
parse ["--"] @@ __POS_OF__
|
|
([], (false, None, []));
|
|
parse ["hoho"; "-a"; "-bmsg"] @@ __POS_OF__
|
|
(["-a"; "-b"; "msg"; "hoho"], (true, Some "msg", ["hoho"]));
|
|
parse ["hoho"; "-a"; "-bmsg"; "hihi"] @@ __POS_OF__
|
|
(["-a"; "-b"; "msg"; "hoho"; "hihi"], (true, Some "msg", ["hoho"; "hihi"]));
|
|
parse ["--"; "hoho"; "-a"; "-bbla"; "hihi"] @@ __POS_OF__
|
|
(["hoho"; "-a"; "-bbla"; "hihi"],
|
|
(false, None, ["hoho"; "-a"; "-bbla"; "hihi"]));
|
|
parse ["hoho"; "-a"; "--bbb=msg"; "hihi"] @@ __POS_OF__
|
|
(["-a"; "--bbb"; "msg"; "hoho"; "hihi"],
|
|
(true, Some "msg", ["hoho"; "hihi"]));
|
|
(**)
|
|
error `Term ["--opt"] @@ __POS_OF__
|
|
"Usage: \u{001B}[01mtest_with_used_args\u{001B}[m [\u{001B}[01m--help\u{001B}[m] [\u{001B}[01m--aaa\u{001B}[m] [\u{001B}[01m--bbb\u{001B}[m=\u{001B}[04mVAL\u{001B}[m] [\u{001B}[04mOPTION\u{001B}[m]… [\u{001B}[04mARG\u{001B}[m]…\n\
|
|
test_with_used_args: \u{001B}[31munknown\u{001B}[m option \u{001B}[01m--opt\u{001B}[m\n";
|
|
(**)
|
|
Testing_cmdliner.snap_man cmd @@ __POS_OF__
|
|
{|NAME
|
|
test_with_used_args - Test cli arg capture
|
|
|
|
SYNOPSIS
|
|
test_with_used_args [--aaa] [--bbb=VAL] [OPTION]… [ARG]…
|
|
|
|
OPTIONS
|
|
-a, --aaa
|
|
|
|
-b VAL, --bbb=VAL
|
|
|
|
COMMON OPTIONS
|
|
--help[=FMT] (default=auto)
|
|
Show this help in format FMT. The value FMT must be one of auto,
|
|
pager, groff or plain. With auto, the format is pager or plain
|
|
whenever the TERM env var is dumb or undefined.
|
|
|
|
EXIT STATUS
|
|
test_with_used_args exits with:
|
|
|
|
0 on success.
|
|
|
|
123 on indiscriminate errors reported on standard error.
|
|
|
|
124 on command line parsing errors.
|
|
|};
|
|
()
|
|
|
|
let term_duplication =
|
|
Test.test "Term.app duplicates" @@ fun () ->
|
|
let cmd =
|
|
Cmd.make (Cmd.info "test_term_dups" ~doc:"Test multiple term usage") @@
|
|
let+ p =
|
|
let doc = "First pos argument should show up only once in the docs" in
|
|
Arg.(value & pos 0 string "popopo" & info [] ~doc ~docv:"POS")
|
|
and+ o =
|
|
let doc = "This should show up only once in the docs" in
|
|
Arg.(value & flag & info ["f"; "flag"] ~doc)
|
|
in
|
|
(p, p, o, o)
|
|
in
|
|
let t = Test.T.(t4 string string bool bool) in
|
|
let parse = Testing_cmdliner.snap_parse t cmd in
|
|
let error err = Testing_cmdliner.snap_eval_error err cmd in
|
|
parse [] @@ __POS_OF__ ("popopo", "popopo", false, false);
|
|
parse ["0"] @@ __POS_OF__ ("0", "0", false, false);
|
|
parse ["0"; "-f"] @@ __POS_OF__ ("0", "0", true, true);
|
|
(**)
|
|
error `Term ["0"; "1"] @@ __POS_OF__
|
|
"Usage: \u{001B}[01mtest_term_dups\u{001B}[m [\u{001B}[01m--help\u{001B}[m] [\u{001B}[01m--flag\u{001B}[m] [\u{001B}[04mOPTION\u{001B}[m]… [\u{001B}[04mPOS\u{001B}[m]\n\
|
|
test_term_dups: \u{001B}[31mtoo many arguments\u{001B}[m, don't know what to do with \u{001B}[01m1\u{001B}[m\n";
|
|
(**)
|
|
Testing_cmdliner.snap_man cmd @@ __POS_OF__
|
|
{|NAME
|
|
test_term_dups - Test multiple term usage
|
|
|
|
SYNOPSIS
|
|
test_term_dups [--flag] [OPTION]… [POS]
|
|
|
|
ARGUMENTS
|
|
POS (absent=popopo)
|
|
First pos argument should show up only once in the docs
|
|
|
|
OPTIONS
|
|
-f, --flag
|
|
This should show up only once in the docs
|
|
|
|
COMMON OPTIONS
|
|
--help[=FMT] (default=auto)
|
|
Show this help in format FMT. The value FMT must be one of auto,
|
|
pager, groff or plain. With auto, the format is pager or plain
|
|
whenever the TERM env var is dumb or undefined.
|
|
|
|
EXIT STATUS
|
|
test_term_dups exits with:
|
|
|
|
0 on success.
|
|
|
|
123 on indiscriminate errors reported on standard error.
|
|
|
|
124 on command line parsing errors.
|
|
|};
|
|
()
|
|
|
|
let test_env =
|
|
Test.test "Term.env" @@ fun () ->
|
|
let env = function "HEYHO" -> Some "Let's go" | _ -> None in
|
|
let cmd =
|
|
Cmd.make (Cmd.info "test_env" ~doc:"Test Term.env") @@
|
|
let+ env = Term.env in
|
|
Test.(option T.string) (env "HEYHO") (Some "Let's go")
|
|
in
|
|
Testing_cmdliner.test_eval_result ~env Test.T.unit cmd [] (Ok (`Ok ()));
|
|
()
|
|
|
|
|
|
let main () =
|
|
let doc = "Test term specifications" in
|
|
Test.main ~doc @@ fun () -> Test.autorun ()
|
|
|
|
let () = if !Sys.interactive then () else exit (main ())
|