1use clap::{error::ErrorKind, ArgAction, Command}; 2 3use crate::utils; 4 5fn common() -> Command { 6 Command::new("foo").help_template(utils::FULL_TEMPLATE) 7} 8 9fn with_version() -> Command { 10 common().version("3.0") 11} 12 13fn with_long_version() -> Command { 14 common().long_version("3.0 (abcdefg)") 15} 16 17fn with_both() -> Command { 18 common().version("3.0").long_version("3.0 (abcdefg)") 19} 20 21fn with_subcommand() -> Command { 22 with_version().subcommand(Command::new("bar").subcommand(Command::new("baz"))) 23} 24 25#[test] 26fn version_short_flag_no_version() { 27 let res = common().try_get_matches_from("foo -V".split(' ')); 28 29 assert!(res.is_err()); 30 let err = res.unwrap_err(); 31 assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument); 32} 33 34#[test] 35fn version_long_flag_no_version() { 36 let res = common().try_get_matches_from("foo --version".split(' ')); 37 38 assert!(res.is_err()); 39 let err = res.unwrap_err(); 40 assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument); 41} 42 43#[test] 44fn version_short_flag_with_version() { 45 let res = with_version().try_get_matches_from("foo -V".split(' ')); 46 47 assert!(res.is_err()); 48 let err = res.unwrap_err(); 49 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 50 assert_eq!(err.to_string(), "foo 3.0\n"); 51} 52 53#[test] 54fn version_long_flag_with_version() { 55 let res = with_version().try_get_matches_from("foo --version".split(' ')); 56 57 assert!(res.is_err()); 58 let err = res.unwrap_err(); 59 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 60 assert_eq!(err.to_string(), "foo 3.0\n"); 61} 62 63#[test] 64fn version_short_flag_with_long_version() { 65 let res = with_long_version().try_get_matches_from("foo -V".split(' ')); 66 67 assert!(res.is_err()); 68 let err = res.unwrap_err(); 69 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 70 assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n"); 71} 72 73#[test] 74fn version_long_flag_with_long_version() { 75 let res = with_long_version().try_get_matches_from("foo --version".split(' ')); 76 77 assert!(res.is_err()); 78 let err = res.unwrap_err(); 79 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 80 assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n"); 81} 82 83#[test] 84fn version_short_flag_with_both() { 85 let res = with_both().try_get_matches_from("foo -V".split(' ')); 86 87 assert!(res.is_err()); 88 let err = res.unwrap_err(); 89 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 90 assert_eq!(err.to_string(), "foo 3.0\n"); 91} 92 93#[test] 94fn version_long_flag_with_both() { 95 let res = with_both().try_get_matches_from("foo --version".split(' ')); 96 97 assert!(res.is_err()); 98 let err = res.unwrap_err(); 99 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 100 assert_eq!(err.to_string(), "foo 3.0 (abcdefg)\n"); 101} 102 103#[test] 104fn help_short_flag_no_version() { 105 static EXPECTED: &str = "\ 106foo 107 108Usage: foo 109 110Options: 111 -h, --help Print help 112"; 113 let cmd = common(); 114 utils::assert_output(cmd, "foo -h", EXPECTED, false); 115} 116 117#[test] 118fn help_long_flag_no_version() { 119 static EXPECTED: &str = "\ 120foo 121 122Usage: foo 123 124Options: 125 -h, --help Print help 126"; 127 let cmd = common(); 128 utils::assert_output(cmd, "foo --help", EXPECTED, false); 129} 130 131#[test] 132fn help_short_flag_with_version() { 133 static EXPECTED: &str = "\ 134foo 3.0 135 136Usage: foo 137 138Options: 139 -h, --help Print help 140 -V, --version Print version 141"; 142 let cmd = with_version(); 143 utils::assert_output(cmd, "foo -h", EXPECTED, false); 144} 145 146#[test] 147fn help_long_flag_with_version() { 148 static EXPECTED: &str = "\ 149foo 3.0 150 151Usage: foo 152 153Options: 154 -h, --help Print help 155 -V, --version Print version 156"; 157 let cmd = with_version(); 158 utils::assert_output(cmd, "foo --help", EXPECTED, false); 159} 160 161#[test] 162fn help_short_flag_with_long_version() { 163 static EXPECTED: &str = "\ 164foo 3.0 (abcdefg) 165 166Usage: foo 167 168Options: 169 -h, --help Print help 170 -V, --version Print version 171"; 172 let cmd = with_long_version(); 173 utils::assert_output(cmd, "foo -h", EXPECTED, false); 174} 175 176#[test] 177fn help_long_flag_with_long_version() { 178 static EXPECTED: &str = "\ 179foo 3.0 (abcdefg) 180 181Usage: foo 182 183Options: 184 -h, --help Print help 185 -V, --version Print version 186"; 187 let cmd = with_long_version(); 188 utils::assert_output(cmd, "foo --help", EXPECTED, false); 189} 190 191#[test] 192fn help_short_flag_with_both() { 193 static EXPECTED: &str = "\ 194foo 3.0 195 196Usage: foo 197 198Options: 199 -h, --help Print help 200 -V, --version Print version 201"; 202 let cmd = with_both(); 203 utils::assert_output(cmd, "foo -h", EXPECTED, false); 204} 205 206#[test] 207fn help_long_flag_with_both() { 208 static EXPECTED: &str = "\ 209foo 3.0 210 211Usage: foo 212 213Options: 214 -h, --help Print help 215 -V, --version Print version 216"; 217 let cmd = with_both(); 218 utils::assert_output(cmd, "foo --help", EXPECTED, false); 219} 220 221#[test] 222#[cfg(debug_assertions)] 223#[should_panic = "Command foo: Long option names must be unique for each argument, but '--version' is in use by both 'ver' and 'version' (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)"] 224fn override_version_long_with_user_flag() { 225 with_version() 226 .arg( 227 clap::Arg::new("ver") 228 .long("version") 229 .action(ArgAction::SetTrue), 230 ) 231 .debug_assert(); 232} 233 234#[test] 235#[cfg(debug_assertions)] 236#[should_panic = "Command foo: Short option names must be unique for each argument, but '-V' is in use by both 'ver' and 'version' (call `cmd.disable_version_flag(true)` to remove the auto-generated `--version`)"] 237fn override_version_short_with_user_flag() { 238 with_version() 239 .arg(clap::Arg::new("ver").short('V').action(ArgAction::SetTrue)) 240 .debug_assert(); 241} 242 243#[test] 244fn no_propagation_by_default_long() { 245 // Version Flag should not be propagated to subcommands 246 let res = with_subcommand().try_get_matches_from("foo bar --version".split(' ')); 247 248 assert!(res.is_err()); 249 let err = res.unwrap_err(); 250 assert_eq!(err.kind(), ErrorKind::UnknownArgument); 251} 252 253#[test] 254fn no_propagation_by_default_short() { 255 let res = with_subcommand().try_get_matches_from("foo bar -V".split(' ')); 256 257 assert!(res.is_err()); 258 let err = res.unwrap_err(); 259 assert_eq!(err.kind(), ErrorKind::UnknownArgument); 260} 261 262#[test] 263fn propagate_version_long() { 264 let res = with_subcommand() 265 .propagate_version(true) 266 .try_get_matches_from("foo bar --version".split(' ')); 267 268 assert!(res.is_err()); 269 let err = res.unwrap_err(); 270 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 271} 272 273#[test] 274fn propagate_version_short() { 275 let res = with_subcommand() 276 .propagate_version(true) 277 .try_get_matches_from("foo bar -V".split(' ')); 278 279 assert!(res.is_err()); 280 let err = res.unwrap_err(); 281 assert_eq!(err.kind(), ErrorKind::DisplayVersion); 282} 283 284#[cfg(debug_assertions)] 285#[test] 286#[should_panic = "`ArgAction::Version` used without providing Command::version or Command::long_version"] 287fn version_required() { 288 let _res = common() 289 .arg(clap::arg!(--version).action(ArgAction::Version)) 290 .try_get_matches_from("foo -z".split(' ')); 291} 292 293#[test] 294#[should_panic = "Argument `version` is undefined"] 295fn mut_arg_version_no_auto_version() { 296 let _ = common().mut_arg("version", |v| v.short('z').action(ArgAction::SetTrue)); 297} 298 299#[cfg(debug_assertions)] 300#[test] 301#[should_panic = "No version information via Command::version or Command::long_version to propagate"] 302fn propagate_version_no_version_info() { 303 let _res = common() 304 .propagate_version(true) 305 .subcommand(Command::new("bar")) 306 .try_get_matches_from("foo".split(' ')); 307} 308