1 // Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 use structopt::StructOpt;
10
11 #[derive(StructOpt, PartialEq, Debug)]
12 struct Opt {
13 #[structopt(short, long)]
14 force: bool,
15 #[structopt(short, long, parse(from_occurrences))]
16 verbose: u64,
17 #[structopt(subcommand)]
18 cmd: Sub,
19 }
20
21 #[derive(StructOpt, PartialEq, Debug)]
22 enum Sub {
23 Fetch {},
24 Add {},
25 }
26
27 #[derive(StructOpt, PartialEq, Debug)]
28 struct Opt2 {
29 #[structopt(short, long)]
30 force: bool,
31 #[structopt(short, long, parse(from_occurrences))]
32 verbose: u64,
33 #[structopt(subcommand)]
34 cmd: Option<Sub>,
35 }
36
37 #[test]
test_no_cmd()38 fn test_no_cmd() {
39 let result = Opt::clap().get_matches_from_safe(&["test"]);
40 assert!(result.is_err());
41
42 assert_eq!(
43 Opt2 {
44 force: false,
45 verbose: 0,
46 cmd: None
47 },
48 Opt2::from_clap(&Opt2::clap().get_matches_from(&["test"]))
49 );
50 }
51
52 #[test]
test_fetch()53 fn test_fetch() {
54 assert_eq!(
55 Opt {
56 force: false,
57 verbose: 3,
58 cmd: Sub::Fetch {}
59 },
60 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-vvv", "fetch"]))
61 );
62 assert_eq!(
63 Opt {
64 force: true,
65 verbose: 0,
66 cmd: Sub::Fetch {}
67 },
68 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "--force", "fetch"]))
69 );
70 }
71
72 #[test]
test_add()73 fn test_add() {
74 assert_eq!(
75 Opt {
76 force: false,
77 verbose: 0,
78 cmd: Sub::Add {}
79 },
80 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "add"]))
81 );
82 assert_eq!(
83 Opt {
84 force: false,
85 verbose: 2,
86 cmd: Sub::Add {}
87 },
88 Opt::from_clap(&Opt::clap().get_matches_from(&["test", "-vv", "add"]))
89 );
90 }
91
92 #[test]
test_badinput()93 fn test_badinput() {
94 let result = Opt::clap().get_matches_from_safe(&["test", "badcmd"]);
95 assert!(result.is_err());
96 let result = Opt::clap().get_matches_from_safe(&["test", "add", "--verbose"]);
97 assert!(result.is_err());
98 let result = Opt::clap().get_matches_from_safe(&["test", "--badopt", "add"]);
99 assert!(result.is_err());
100 let result = Opt::clap().get_matches_from_safe(&["test", "add", "--badopt"]);
101 assert!(result.is_err());
102 }
103
104 #[derive(StructOpt, PartialEq, Debug)]
105 struct Opt3 {
106 #[structopt(short, long)]
107 all: bool,
108 #[structopt(subcommand)]
109 cmd: Sub2,
110 }
111
112 #[derive(StructOpt, PartialEq, Debug)]
113 enum Sub2 {
114 Foo {
115 file: String,
116 #[structopt(subcommand)]
117 cmd: Sub3,
118 },
119 Bar {},
120 }
121
122 #[derive(StructOpt, PartialEq, Debug)]
123 enum Sub3 {
124 Baz {},
125 Quux {},
126 }
127
128 #[test]
test_subsubcommand()129 fn test_subsubcommand() {
130 assert_eq!(
131 Opt3 {
132 all: true,
133 cmd: Sub2::Foo {
134 file: "lib.rs".to_string(),
135 cmd: Sub3::Quux {}
136 }
137 },
138 Opt3::from_clap(
139 &Opt3::clap().get_matches_from(&["test", "--all", "foo", "lib.rs", "quux"])
140 )
141 );
142 }
143
144 #[derive(StructOpt, PartialEq, Debug)]
145 enum SubSubCmdWithOption {
146 Remote {
147 #[structopt(subcommand)]
148 cmd: Option<Remote>,
149 },
150 Stash {
151 #[structopt(subcommand)]
152 cmd: Stash,
153 },
154 }
155 #[derive(StructOpt, PartialEq, Debug)]
156 enum Remote {
157 Add { name: String, url: String },
158 Remove { name: String },
159 }
160
161 #[derive(StructOpt, PartialEq, Debug)]
162 enum Stash {
163 Save,
164 Pop,
165 }
166
167 #[test]
sub_sub_cmd_with_option()168 fn sub_sub_cmd_with_option() {
169 fn make(args: &[&str]) -> Option<SubSubCmdWithOption> {
170 SubSubCmdWithOption::clap()
171 .get_matches_from_safe(args)
172 .ok()
173 .map(|m| SubSubCmdWithOption::from_clap(&m))
174 }
175 assert_eq!(
176 Some(SubSubCmdWithOption::Remote { cmd: None }),
177 make(&["", "remote"])
178 );
179 assert_eq!(
180 Some(SubSubCmdWithOption::Remote {
181 cmd: Some(Remote::Add {
182 name: "origin".into(),
183 url: "http".into()
184 })
185 }),
186 make(&["", "remote", "add", "origin", "http"])
187 );
188 assert_eq!(
189 Some(SubSubCmdWithOption::Stash { cmd: Stash::Save }),
190 make(&["", "stash", "save"])
191 );
192 assert_eq!(None, make(&["", "stash"]));
193 }
194