1use clap::{arg, error::ErrorKind, Arg, ArgAction, Command}; 2 3#[test] 4fn flag_overrides_itself() { 5 let res = Command::new("posix") 6 .arg( 7 arg!(--flag "some flag" 8 ) 9 .action(ArgAction::SetTrue) 10 .overrides_with("flag"), 11 ) 12 .try_get_matches_from(vec!["", "--flag", "--flag"]); 13 assert!(res.is_ok(), "{}", res.unwrap_err()); 14 let m = res.unwrap(); 15 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 16} 17 18#[test] 19fn option_overrides_itself() { 20 let res = Command::new("posix") 21 .arg( 22 arg!(--opt <val> "some option") 23 .required(false) 24 .overrides_with("opt"), 25 ) 26 .try_get_matches_from(vec!["", "--opt=some", "--opt=other"]); 27 assert!(res.is_ok(), "{}", res.unwrap_err()); 28 let m = res.unwrap(); 29 assert!(m.contains_id("opt")); 30 assert_eq!( 31 m.get_one::<String>("opt").map(|v| v.as_str()), 32 Some("other") 33 ); 34} 35 36#[test] 37fn posix_compatible_flags_long() { 38 let m = Command::new("posix") 39 .arg( 40 arg!(--flag "some flag") 41 .overrides_with("color") 42 .action(ArgAction::SetTrue), 43 ) 44 .arg(arg!(--color "some other flag").action(ArgAction::SetTrue)) 45 .try_get_matches_from(vec!["", "--flag", "--color"]) 46 .unwrap(); 47 assert!(*m.get_one::<bool>("color").expect("defaulted by clap")); 48 assert!(!*m.get_one::<bool>("flag").expect("defaulted by clap")); 49} 50 51#[test] 52fn posix_compatible_flags_long_rev() { 53 let m = Command::new("posix") 54 .arg( 55 arg!(--flag "some flag") 56 .overrides_with("color") 57 .action(ArgAction::SetTrue), 58 ) 59 .arg(arg!(--color "some other flag").action(ArgAction::SetTrue)) 60 .try_get_matches_from(vec!["", "--color", "--flag"]) 61 .unwrap(); 62 assert!(!*m.get_one::<bool>("color").expect("defaulted by clap")); 63 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 64} 65 66#[test] 67fn posix_compatible_flags_short() { 68 let m = Command::new("posix") 69 .arg( 70 arg!(-f --flag "some flag") 71 .overrides_with("color") 72 .action(ArgAction::SetTrue), 73 ) 74 .arg(arg!(-c --color "some other flag").action(ArgAction::SetTrue)) 75 .try_get_matches_from(vec!["", "-f", "-c"]) 76 .unwrap(); 77 assert!(*m.get_one::<bool>("color").expect("defaulted by clap")); 78 assert!(!*m.get_one::<bool>("flag").expect("defaulted by clap")); 79} 80 81#[test] 82fn posix_compatible_flags_short_rev() { 83 let m = Command::new("posix") 84 .arg( 85 arg!(-f --flag "some flag") 86 .overrides_with("color") 87 .action(ArgAction::SetTrue), 88 ) 89 .arg(arg!(-c --color "some other flag").action(ArgAction::SetTrue)) 90 .try_get_matches_from(vec!["", "-c", "-f"]) 91 .unwrap(); 92 assert!(!*m.get_one::<bool>("color").expect("defaulted by clap")); 93 assert!(*m.get_one::<bool>("flag").expect("defaulted by clap")); 94} 95 96#[test] 97fn posix_compatible_opts_long() { 98 let m = Command::new("posix") 99 .arg(arg!(--flag <flag> "some flag").overrides_with("color")) 100 .arg(arg!(--color <color> "some other flag")) 101 .try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]) 102 .unwrap(); 103 assert!(m.contains_id("color")); 104 assert_eq!( 105 m.get_one::<String>("color").map(|v| v.as_str()).unwrap(), 106 "other" 107 ); 108 assert!(!m.contains_id("flag")); 109} 110 111#[test] 112fn posix_compatible_opts_long_rev() { 113 let m = Command::new("posix") 114 .arg(arg!(--flag <flag> "some flag").overrides_with("color")) 115 .arg(arg!(--color <color> "some other flag")) 116 .try_get_matches_from(vec!["", "--color", "some", "--flag", "other"]) 117 .unwrap(); 118 assert!(!m.contains_id("color")); 119 assert!(m.contains_id("flag")); 120 assert_eq!( 121 m.get_one::<String>("flag").map(|v| v.as_str()).unwrap(), 122 "other" 123 ); 124} 125 126#[test] 127fn posix_compatible_opts_long_equals() { 128 let m = Command::new("posix") 129 .arg(arg!(--flag <flag> "some flag").overrides_with("color")) 130 .arg(arg!(--color <color> "some other flag")) 131 .try_get_matches_from(vec!["", "--flag=some", "--color=other"]) 132 .unwrap(); 133 assert!(m.contains_id("color")); 134 assert_eq!( 135 m.get_one::<String>("color").map(|v| v.as_str()).unwrap(), 136 "other" 137 ); 138 assert!(!m.contains_id("flag")); 139} 140 141#[test] 142fn posix_compatible_opts_long_equals_rev() { 143 let m = Command::new("posix") 144 .arg(arg!(--flag <flag> "some flag").overrides_with("color")) 145 .arg(arg!(--color <color> "some other flag")) 146 .try_get_matches_from(vec!["", "--color=some", "--flag=other"]) 147 .unwrap(); 148 assert!(!m.contains_id("color")); 149 assert!(m.contains_id("flag")); 150 assert_eq!( 151 m.get_one::<String>("flag").map(|v| v.as_str()).unwrap(), 152 "other" 153 ); 154} 155 156#[test] 157fn posix_compatible_opts_short() { 158 let m = Command::new("posix") 159 .arg(arg!(f: -f <flag> "some flag").overrides_with("c")) 160 .arg(arg!(c: -c <color> "some other flag")) 161 .try_get_matches_from(vec!["", "-f", "some", "-c", "other"]) 162 .unwrap(); 163 assert!(m.contains_id("c")); 164 assert_eq!( 165 m.get_one::<String>("c").map(|v| v.as_str()).unwrap(), 166 "other" 167 ); 168 assert!(!m.contains_id("f")); 169} 170 171#[test] 172fn posix_compatible_opts_short_rev() { 173 let m = Command::new("posix") 174 .arg(arg!(f: -f <flag> "some flag").overrides_with("c")) 175 .arg(arg!(c: -c <color> "some other flag")) 176 .try_get_matches_from(vec!["", "-c", "some", "-f", "other"]) 177 .unwrap(); 178 assert!(!m.contains_id("c")); 179 assert!(m.contains_id("f")); 180 assert_eq!( 181 m.get_one::<String>("f").map(|v| v.as_str()).unwrap(), 182 "other" 183 ); 184} 185 186#[test] 187fn conflict_overridden() { 188 let m = Command::new("conflict_overridden") 189 .arg( 190 arg!(-f --flag "some flag") 191 .conflicts_with("debug") 192 .action(ArgAction::SetTrue), 193 ) 194 .arg(arg!(-d --debug "other flag").action(ArgAction::SetTrue)) 195 .arg( 196 arg!(-c --color "third flag") 197 .overrides_with("flag") 198 .action(ArgAction::SetTrue), 199 ) 200 .try_get_matches_from(vec!["", "-f", "-c", "-d"]) 201 .unwrap(); 202 assert!(*m.get_one::<bool>("color").expect("defaulted by clap")); 203 assert!(!*m.get_one::<bool>("flag").expect("defaulted by clap")); 204 assert!(*m.get_one::<bool>("debug").expect("defaulted by clap")); 205} 206 207#[test] 208fn conflict_overridden_2() { 209 let result = Command::new("conflict_overridden") 210 .arg( 211 arg!(-f --flag "some flag") 212 .conflicts_with("debug") 213 .action(ArgAction::SetTrue), 214 ) 215 .arg(arg!(-d --debug "other flag").action(ArgAction::SetTrue)) 216 .arg( 217 arg!(-c --color "third flag") 218 .overrides_with("flag") 219 .action(ArgAction::SetTrue), 220 ) 221 .try_get_matches_from(vec!["", "-f", "-d", "-c"]); 222 assert!(result.is_ok(), "{}", result.unwrap_err()); 223 let m = result.unwrap(); 224 assert!(*m.get_one::<bool>("color").expect("defaulted by clap")); 225 assert!(*m.get_one::<bool>("debug").expect("defaulted by clap")); 226 assert!(!*m.get_one::<bool>("flag").expect("defaulted by clap")); 227} 228 229#[test] 230fn conflict_overridden_3() { 231 let result = Command::new("conflict_overridden") 232 .arg(arg!(-f --flag "some flag").conflicts_with("debug")) 233 .arg(arg!(-d --debug "other flag")) 234 .arg(arg!(-c --color "third flag").overrides_with("flag")) 235 .try_get_matches_from(vec!["", "-d", "-c", "-f"]); 236 assert!(result.is_err()); 237 let err = result.err().unwrap(); 238 assert_eq!(err.kind(), ErrorKind::ArgumentConflict); 239} 240 241#[test] 242fn conflict_overridden_4() { 243 let m = Command::new("conflict_overridden") 244 .arg( 245 arg!(-f --flag "some flag") 246 .conflicts_with("debug") 247 .action(ArgAction::SetTrue), 248 ) 249 .arg(arg!(-d --debug "other flag").action(ArgAction::SetTrue)) 250 .arg( 251 arg!(-c --color "third flag") 252 .overrides_with("flag") 253 .action(ArgAction::SetTrue), 254 ) 255 .try_get_matches_from(vec!["", "-d", "-f", "-c"]) 256 .unwrap(); 257 assert!(*m.get_one::<bool>("color").expect("defaulted by clap")); 258 assert!(!*m.get_one::<bool>("flag").expect("defaulted by clap")); 259 assert!(*m.get_one::<bool>("debug").expect("defaulted by clap")); 260} 261 262#[test] 263fn pos_required_overridden_by_flag() { 264 let result = Command::new("require_overridden") 265 .arg(Arg::new("pos").index(1).required(true)) 266 .arg(arg!(-c --color "some flag").overrides_with("pos")) 267 .try_get_matches_from(vec!["", "test", "-c"]); 268 assert!(result.is_ok(), "{:?}", result.unwrap_err()); 269} 270 271#[test] 272fn require_overridden_2() { 273 let m = Command::new("require_overridden") 274 .arg(Arg::new("req_pos").required(true)) 275 .arg( 276 arg!(-c --color "other flag") 277 .overrides_with("req_pos") 278 .action(ArgAction::SetTrue), 279 ) 280 .try_get_matches_from(vec!["", "-c", "req_pos"]) 281 .unwrap(); 282 assert!(!*m.get_one::<bool>("color").expect("defaulted by clap")); 283 assert!(m.contains_id("req_pos")); 284} 285 286#[test] 287fn require_overridden_3() { 288 let m = Command::new("require_overridden") 289 .arg( 290 arg!(-f --flag "some flag") 291 .requires("debug") 292 .action(ArgAction::SetTrue), 293 ) 294 .arg(arg!(-d --debug "other flag").action(ArgAction::SetTrue)) 295 .arg( 296 arg!(-c --color "third flag") 297 .overrides_with("flag") 298 .action(ArgAction::SetTrue), 299 ) 300 .try_get_matches_from(vec!["", "-f", "-c"]) 301 .unwrap(); 302 assert!(*m.get_one::<bool>("color").expect("defaulted by clap")); 303 assert!(!*m.get_one::<bool>("flag").expect("defaulted by clap")); 304 assert!(!*m.get_one::<bool>("debug").expect("defaulted by clap")); 305} 306 307#[test] 308fn require_overridden_4() { 309 let result = Command::new("require_overridden") 310 .arg(arg!(-f --flag "some flag").requires("debug")) 311 .arg(arg!(-d --debug "other flag")) 312 .arg(arg!(-c --color "third flag").overrides_with("flag")) 313 .try_get_matches_from(vec!["", "-c", "-f"]); 314 assert!(result.is_err()); 315 let err = result.err().unwrap(); 316 assert_eq!(err.kind(), ErrorKind::MissingRequiredArgument); 317} 318 319#[test] 320fn incremental_override() { 321 let mut cmd = Command::new("test") 322 .arg(arg!(--name <NAME> ...).required(true)) 323 .arg( 324 arg!(--"no-name") 325 .overrides_with("name") 326 .action(ArgAction::SetTrue), 327 ); 328 let m = cmd 329 .try_get_matches_from_mut(["test", "--name=ahmed", "--no-name", "--name=ali"]) 330 .unwrap(); 331 assert_eq!( 332 m.get_many::<String>("name") 333 .unwrap() 334 .map(|v| v.as_str()) 335 .collect::<Vec<_>>(), 336 ["ali"] 337 ); 338 assert!(!*m.get_one::<bool>("no-name").expect("defaulted by clap")); 339} 340 341#[cfg(debug_assertions)] 342#[test] 343#[should_panic = "Argument or group 'extra' specified in 'overrides_with*' for 'config' does not exist"] 344fn overrides_with_invalid_arg() { 345 let _ = Command::new("prog") 346 .arg(Arg::new("config").long("config").overrides_with("extra")) 347 .try_get_matches_from(vec!["", "--config"]); 348} 349