119625d8cSopenharmony_ci// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>,
219625d8cSopenharmony_ci// Kevin Knapp (@kbknapp) <kbknapp@gmail.com>, and
319625d8cSopenharmony_ci// Ana Hobden (@hoverbear) <operator@hoverbear.org>
419625d8cSopenharmony_ci//
519625d8cSopenharmony_ci// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
619625d8cSopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
719625d8cSopenharmony_ci// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
819625d8cSopenharmony_ci// option. This file may not be copied, modified, or distributed
919625d8cSopenharmony_ci// except according to those terms.
1019625d8cSopenharmony_ci//
1119625d8cSopenharmony_ci// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
1219625d8cSopenharmony_ci// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
1319625d8cSopenharmony_ci// MIT/Apache 2.0 license.
1419625d8cSopenharmony_ci
1519625d8cSopenharmony_ciuse clap::{Parser, Subcommand};
1619625d8cSopenharmony_ci
1719625d8cSopenharmony_ci#[derive(Parser, PartialEq, Debug)]
1819625d8cSopenharmony_cistruct Opt {
1919625d8cSopenharmony_ci    #[arg(short, long)]
2019625d8cSopenharmony_ci    force: bool,
2119625d8cSopenharmony_ci    #[arg(short, long, action = clap::ArgAction::Count)]
2219625d8cSopenharmony_ci    verbose: u8,
2319625d8cSopenharmony_ci    #[command(subcommand)]
2419625d8cSopenharmony_ci    cmd: Sub,
2519625d8cSopenharmony_ci}
2619625d8cSopenharmony_ci
2719625d8cSopenharmony_ci#[derive(Subcommand, PartialEq, Debug)]
2819625d8cSopenharmony_cienum Sub {
2919625d8cSopenharmony_ci    Fetch {},
3019625d8cSopenharmony_ci    Add {},
3119625d8cSopenharmony_ci}
3219625d8cSopenharmony_ci
3319625d8cSopenharmony_ci#[derive(Parser, PartialEq, Debug)]
3419625d8cSopenharmony_cistruct Opt2 {
3519625d8cSopenharmony_ci    #[arg(short, long)]
3619625d8cSopenharmony_ci    force: bool,
3719625d8cSopenharmony_ci    #[arg(short, long, action = clap::ArgAction::Count)]
3819625d8cSopenharmony_ci    verbose: u8,
3919625d8cSopenharmony_ci    #[command(subcommand)]
4019625d8cSopenharmony_ci    cmd: Option<Sub>,
4119625d8cSopenharmony_ci}
4219625d8cSopenharmony_ci
4319625d8cSopenharmony_ci#[test]
4419625d8cSopenharmony_cifn test_no_cmd() {
4519625d8cSopenharmony_ci    let result = Opt::try_parse_from(["test"]);
4619625d8cSopenharmony_ci    assert!(result.is_err());
4719625d8cSopenharmony_ci
4819625d8cSopenharmony_ci    assert_eq!(
4919625d8cSopenharmony_ci        Opt2 {
5019625d8cSopenharmony_ci            force: false,
5119625d8cSopenharmony_ci            verbose: 0,
5219625d8cSopenharmony_ci            cmd: None
5319625d8cSopenharmony_ci        },
5419625d8cSopenharmony_ci        Opt2::try_parse_from(["test"]).unwrap()
5519625d8cSopenharmony_ci    );
5619625d8cSopenharmony_ci}
5719625d8cSopenharmony_ci
5819625d8cSopenharmony_ci#[test]
5919625d8cSopenharmony_cifn test_fetch() {
6019625d8cSopenharmony_ci    assert_eq!(
6119625d8cSopenharmony_ci        Opt {
6219625d8cSopenharmony_ci            force: false,
6319625d8cSopenharmony_ci            verbose: 3,
6419625d8cSopenharmony_ci            cmd: Sub::Fetch {}
6519625d8cSopenharmony_ci        },
6619625d8cSopenharmony_ci        Opt::try_parse_from(["test", "-vvv", "fetch"]).unwrap()
6719625d8cSopenharmony_ci    );
6819625d8cSopenharmony_ci    assert_eq!(
6919625d8cSopenharmony_ci        Opt {
7019625d8cSopenharmony_ci            force: true,
7119625d8cSopenharmony_ci            verbose: 0,
7219625d8cSopenharmony_ci            cmd: Sub::Fetch {}
7319625d8cSopenharmony_ci        },
7419625d8cSopenharmony_ci        Opt::try_parse_from(["test", "--force", "fetch"]).unwrap()
7519625d8cSopenharmony_ci    );
7619625d8cSopenharmony_ci}
7719625d8cSopenharmony_ci
7819625d8cSopenharmony_ci#[test]
7919625d8cSopenharmony_cifn test_add() {
8019625d8cSopenharmony_ci    assert_eq!(
8119625d8cSopenharmony_ci        Opt {
8219625d8cSopenharmony_ci            force: false,
8319625d8cSopenharmony_ci            verbose: 0,
8419625d8cSopenharmony_ci            cmd: Sub::Add {}
8519625d8cSopenharmony_ci        },
8619625d8cSopenharmony_ci        Opt::try_parse_from(["test", "add"]).unwrap()
8719625d8cSopenharmony_ci    );
8819625d8cSopenharmony_ci    assert_eq!(
8919625d8cSopenharmony_ci        Opt {
9019625d8cSopenharmony_ci            force: false,
9119625d8cSopenharmony_ci            verbose: 2,
9219625d8cSopenharmony_ci            cmd: Sub::Add {}
9319625d8cSopenharmony_ci        },
9419625d8cSopenharmony_ci        Opt::try_parse_from(["test", "-vv", "add"]).unwrap()
9519625d8cSopenharmony_ci    );
9619625d8cSopenharmony_ci}
9719625d8cSopenharmony_ci
9819625d8cSopenharmony_ci#[test]
9919625d8cSopenharmony_cifn test_badinput() {
10019625d8cSopenharmony_ci    let result = Opt::try_parse_from(["test", "badcmd"]);
10119625d8cSopenharmony_ci    assert!(result.is_err());
10219625d8cSopenharmony_ci    let result = Opt::try_parse_from(["test", "add", "--verbose"]);
10319625d8cSopenharmony_ci    assert!(result.is_err());
10419625d8cSopenharmony_ci    let result = Opt::try_parse_from(["test", "--badopt", "add"]);
10519625d8cSopenharmony_ci    assert!(result.is_err());
10619625d8cSopenharmony_ci    let result = Opt::try_parse_from(["test", "add", "--badopt"]);
10719625d8cSopenharmony_ci    assert!(result.is_err());
10819625d8cSopenharmony_ci}
10919625d8cSopenharmony_ci
11019625d8cSopenharmony_ci#[derive(Parser, PartialEq, Debug)]
11119625d8cSopenharmony_cistruct Opt3 {
11219625d8cSopenharmony_ci    #[arg(short, long)]
11319625d8cSopenharmony_ci    all: bool,
11419625d8cSopenharmony_ci    #[command(subcommand)]
11519625d8cSopenharmony_ci    cmd: Sub2,
11619625d8cSopenharmony_ci}
11719625d8cSopenharmony_ci
11819625d8cSopenharmony_ci#[derive(Subcommand, PartialEq, Debug)]
11919625d8cSopenharmony_cienum Sub2 {
12019625d8cSopenharmony_ci    Foo {
12119625d8cSopenharmony_ci        file: String,
12219625d8cSopenharmony_ci        #[command(subcommand)]
12319625d8cSopenharmony_ci        cmd: Sub3,
12419625d8cSopenharmony_ci    },
12519625d8cSopenharmony_ci    Bar {},
12619625d8cSopenharmony_ci}
12719625d8cSopenharmony_ci
12819625d8cSopenharmony_ci#[derive(Subcommand, PartialEq, Debug)]
12919625d8cSopenharmony_cienum Sub3 {
13019625d8cSopenharmony_ci    Baz {},
13119625d8cSopenharmony_ci    Quux {},
13219625d8cSopenharmony_ci}
13319625d8cSopenharmony_ci
13419625d8cSopenharmony_ci#[test]
13519625d8cSopenharmony_cifn test_subsubcommand() {
13619625d8cSopenharmony_ci    assert_eq!(
13719625d8cSopenharmony_ci        Opt3 {
13819625d8cSopenharmony_ci            all: true,
13919625d8cSopenharmony_ci            cmd: Sub2::Foo {
14019625d8cSopenharmony_ci                file: "lib.rs".to_string(),
14119625d8cSopenharmony_ci                cmd: Sub3::Quux {}
14219625d8cSopenharmony_ci            }
14319625d8cSopenharmony_ci        },
14419625d8cSopenharmony_ci        Opt3::try_parse_from(["test", "--all", "foo", "lib.rs", "quux"]).unwrap()
14519625d8cSopenharmony_ci    );
14619625d8cSopenharmony_ci}
14719625d8cSopenharmony_ci
14819625d8cSopenharmony_ci#[derive(Parser, PartialEq, Debug)]
14919625d8cSopenharmony_cienum SubSubCmdWithOption {
15019625d8cSopenharmony_ci    Remote {
15119625d8cSopenharmony_ci        #[command(subcommand)]
15219625d8cSopenharmony_ci        cmd: Option<Remote>,
15319625d8cSopenharmony_ci    },
15419625d8cSopenharmony_ci    Stash {
15519625d8cSopenharmony_ci        #[command(subcommand)]
15619625d8cSopenharmony_ci        cmd: Stash,
15719625d8cSopenharmony_ci    },
15819625d8cSopenharmony_ci}
15919625d8cSopenharmony_ci#[derive(Subcommand, PartialEq, Debug)]
16019625d8cSopenharmony_cienum Remote {
16119625d8cSopenharmony_ci    Add { name: String, url: String },
16219625d8cSopenharmony_ci    Remove { name: String },
16319625d8cSopenharmony_ci}
16419625d8cSopenharmony_ci
16519625d8cSopenharmony_ci#[derive(Subcommand, PartialEq, Debug)]
16619625d8cSopenharmony_cienum Stash {
16719625d8cSopenharmony_ci    Save,
16819625d8cSopenharmony_ci    Pop,
16919625d8cSopenharmony_ci}
17019625d8cSopenharmony_ci
17119625d8cSopenharmony_ci#[test]
17219625d8cSopenharmony_cifn sub_sub_cmd_with_option() {
17319625d8cSopenharmony_ci    fn make(args: &[&str]) -> Option<SubSubCmdWithOption> {
17419625d8cSopenharmony_ci        SubSubCmdWithOption::try_parse_from(args).ok()
17519625d8cSopenharmony_ci    }
17619625d8cSopenharmony_ci    assert_eq!(
17719625d8cSopenharmony_ci        Some(SubSubCmdWithOption::Remote { cmd: None }),
17819625d8cSopenharmony_ci        make(&["", "remote"])
17919625d8cSopenharmony_ci    );
18019625d8cSopenharmony_ci    assert_eq!(
18119625d8cSopenharmony_ci        Some(SubSubCmdWithOption::Remote {
18219625d8cSopenharmony_ci            cmd: Some(Remote::Add {
18319625d8cSopenharmony_ci                name: "origin".into(),
18419625d8cSopenharmony_ci                url: "http".into()
18519625d8cSopenharmony_ci            })
18619625d8cSopenharmony_ci        }),
18719625d8cSopenharmony_ci        make(&["", "remote", "add", "origin", "http"])
18819625d8cSopenharmony_ci    );
18919625d8cSopenharmony_ci    assert_eq!(
19019625d8cSopenharmony_ci        Some(SubSubCmdWithOption::Stash { cmd: Stash::Save }),
19119625d8cSopenharmony_ci        make(&["", "stash", "save"])
19219625d8cSopenharmony_ci    );
19319625d8cSopenharmony_ci    assert_eq!(None, make(&["", "stash"]));
19419625d8cSopenharmony_ci}
195