Repository: kbknapp/clap-rs
Pull request #1136 (2017-12-26 16:20:01)

Test for Issue 1135
It looks like `required_unless_one` has incorrect behavior if the
argument it applies to also has a short form. This adds a failing test, but I could use help fixing the issue.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/kbknapp/clap-rs/1136)
<!-- Reviewable:end -->



Patch:
diff --git a/src/args/arg_builder/flag.rs b/src/args/arg_builder/flag.rs
index 4e378210..641e7777 100644
--- a/src/args/arg_builder/flag.rs
+++ b/src/args/arg_builder/flag.rs
@@ -67,7 +67,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
         self.b.requires.as_ref().map(|o| &o[..])
     }
     fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
-    fn required_unless(&self) -> Option<&[&'e str]> { None }
+    fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
     fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
     fn has_switch(&self) -> bool { true }
     fn takes_value(&self) -> bool { false }


Test patch:
diff --git a/tests/require.rs b/tests/require.rs
index 9d289134..5dbf2dc1 100644
--- a/tests/require.rs
+++ b/tests/require.rs
@@ -320,6 +320,62 @@ fn required_unless_one_2() {
     assert!(!m.is_present("cfg"));
 }
 
+#[test]
+fn required_unless_one_works_with_short() {
+    // GitHub issue: https://github.com/kbknapp/clap-rs/issues/1135
+    let res = App::new("unlessone")
+        .arg(Arg::with_name("a").conflicts_with("b").short("a"))
+        .arg(Arg::with_name("b").short("b"))
+        .arg(
+            Arg::with_name("x")
+                .short("x")
+                .required_unless_one(&["a", "b"])
+        ).get_matches_from_safe(vec!["unlessone", "-a"]);
+
+    assert!(res.is_ok());
+}
+
+#[test]
+fn required_unless_one_works_with_short_err() {
+    let res = App::new("unlessone")
+        .arg(Arg::with_name("a").conflicts_with("b").short("a"))
+        .arg(Arg::with_name("b").short("b"))
+        .arg(
+            Arg::with_name("x")
+                .short("x")
+                .required_unless_one(&["a", "b"])
+        ).get_matches_from_safe(vec!["unlessone"]);
+
+    assert!(!res.is_ok());
+}
+
+#[test]
+fn required_unless_one_works_without() {
+    let res = App::new("unlessone")
+        .arg(Arg::with_name("a").conflicts_with("b").short("a"))
+        .arg(Arg::with_name("b").short("b"))
+        .arg(
+            Arg::with_name("x")
+                .required_unless_one(&["a", "b"])
+        ).get_matches_from_safe(vec!["unlessone", "-a"]);
+
+    assert!(res.is_ok());
+}
+
+#[test]
+fn required_unless_one_works_with_long() {
+    let res = App::new("unlessone")
+        .arg(Arg::with_name("a").conflicts_with("b").short("a"))
+        .arg(Arg::with_name("b").short("b"))
+        .arg(
+            Arg::with_name("x")
+                .long("x_is_the_option")
+                .required_unless_one(&["a", "b"])
+        ).get_matches_from_safe(vec!["unlessone", "-a"]);
+
+    assert!(res.is_ok());
+}
+
 #[test]
 fn required_unless_one_1() {
     let res = App::new("unlessone")