aboutsummaryrefslogtreecommitdiff
path: root/mingling_picker/test
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_picker/test')
-rw-r--r--mingling_picker/test/src/test.rs1
-rw-r--r--mingling_picker/test/src/test/basic_test.rs52
-rw-r--r--mingling_picker/test/src/test/route_test.rs44
-rw-r--r--mingling_picker/test/src/test/style_test.rs123
-rw-r--r--mingling_picker/test/src/test/value_flag_test.rs174
5 files changed, 328 insertions, 66 deletions
diff --git a/mingling_picker/test/src/test.rs b/mingling_picker/test/src/test.rs
index d3e19b3..29d52ec 100644
--- a/mingling_picker/test/src/test.rs
+++ b/mingling_picker/test/src/test.rs
@@ -1,3 +1,4 @@
mod basic_test;
mod route_test;
mod style_test;
+mod value_flag_test;
diff --git a/mingling_picker/test/src/test/basic_test.rs b/mingling_picker/test/src/test/basic_test.rs
index 5929e75..78b154e 100644
--- a/mingling_picker/test/src/test/basic_test.rs
+++ b/mingling_picker/test/src/test/basic_test.rs
@@ -1,4 +1,4 @@
-use mingling_picker::{IntoPicker, macros::flag};
+use mingling_picker::{IntoPicker, macros::arg};
// Basic bool flag — present / absent
@@ -7,7 +7,7 @@ fn test_bool_flag_present() {
let args = vec!["--verbose"];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.unwrap();
assert_eq!(parsed, true);
@@ -18,7 +18,7 @@ fn test_bool_flag_absent() {
let args: Vec<&str> = vec![];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.unwrap();
assert_eq!(parsed, false);
@@ -31,7 +31,7 @@ fn test_bool_short_flag_present() {
let args = vec!["-v"];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool, 'v'])
+ .pick(&arg![verbose: bool, 'v'])
.or_default()
.unwrap();
assert_eq!(parsed, true);
@@ -41,13 +41,13 @@ fn test_bool_short_flag_present() {
#[test]
fn test_two_bool_flags_both_present() {
- // The `flag!` macro expands the identifier `flag_a` into the string "flag_a" → --flag_a
- let args = vec!["--flag_a", "--flag_b"];
+ // UNIX_STYLE now uses Kebab naming: `flag_a` → "flag-a" → --flag-a
+ let args = vec!["--flag-a", "--flag-b"];
let (a, b) = args
.to_picker()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
.or_default()
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_default()
.unwrap();
assert_eq!(a, true);
@@ -56,12 +56,12 @@ fn test_two_bool_flags_both_present() {
#[test]
fn test_two_bool_flags_one_present() {
- let args = vec!["--flag_a"];
+ let args = vec!["--flag-a"];
let (a, b) = args
.to_picker()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
.or_default()
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_default()
.unwrap();
assert_eq!(a, true);
@@ -73,9 +73,9 @@ fn test_two_bool_flags_neither_present() {
let args: Vec<&str> = vec![];
let (a, b) = args
.to_picker()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
.or_default()
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_default()
.unwrap();
assert_eq!(a, false);
@@ -86,12 +86,12 @@ fn test_two_bool_flags_neither_present() {
#[test]
fn test_short_and_long_flags() {
- let args = vec!["-a", "--long_b"];
+ let args = vec!["-a", "--long-b"];
let (a, b) = args
.to_picker()
- .pick(&flag![flag_a: bool, 'a'])
+ .pick(&arg![flag_a: bool, 'a'])
.or_default()
- .pick(&flag![long_b: bool])
+ .pick(&arg![long_b: bool])
.or_default()
.unwrap();
assert_eq!(a, true);
@@ -105,7 +105,7 @@ fn test_flag_after_end_of_options() {
let args = vec!["--", "--verbose"];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.unwrap();
assert_eq!(parsed, false);
@@ -118,7 +118,7 @@ fn test_bool_flag_with_alias() {
let args = vec!["--cfg"];
let parsed = args
.to_picker()
- .pick(&flag![config: bool, "cfg"])
+ .pick(&arg![config: bool, "cfg"])
.or_default()
.unwrap();
assert_eq!(parsed, true);
@@ -129,7 +129,7 @@ fn test_bool_flag_primary_name() {
let args = vec!["--config"];
let parsed = args
.to_picker()
- .pick(&flag![config: bool, "cfg"])
+ .pick(&arg![config: bool, "cfg"])
.or_default()
.unwrap();
assert_eq!(parsed, true);
@@ -142,7 +142,7 @@ fn test_bool_flag_short_and_alias() {
let args = vec!["-v"];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool, 'v', "cfg"])
+ .pick(&arg![verbose: bool, 'v', "cfg"])
.or_default()
.unwrap();
assert_eq!(parsed, true);
@@ -155,7 +155,7 @@ fn test_or_default_without_args() {
let args: Vec<&str> = vec![];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.unwrap();
assert_eq!(parsed, false);
@@ -166,7 +166,7 @@ fn test_or_custom_default() {
let args: Vec<&str> = vec![];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or(|| true)
.unwrap();
assert_eq!(parsed, true);
@@ -179,7 +179,7 @@ fn test_to_result_ok() {
let args = vec!["--verbose"];
let result = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.to_result();
assert_eq!(result, Ok(true));
@@ -190,7 +190,7 @@ fn test_to_option_some() {
let args = vec!["--verbose"];
let opt = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.to_option();
assert_eq!(opt, Some(true));
@@ -203,7 +203,7 @@ fn test_with_route_chain() {
let args = vec!["--flag"];
let parsed = args
.with_route::<String>()
- .pick(&flag![flag: bool])
+ .pick(&arg![flag: bool])
.or_default()
.unwrap();
assert_eq!(parsed, true);
@@ -216,7 +216,7 @@ fn test_unrelated_flag_does_not_match() {
let args = vec!["--other"];
let parsed = args
.to_picker()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.unwrap();
assert_eq!(parsed, false);
diff --git a/mingling_picker/test/src/test/route_test.rs b/mingling_picker/test/src/test/route_test.rs
index ca07cc0..9261db1 100644
--- a/mingling_picker/test/src/test/route_test.rs
+++ b/mingling_picker/test/src/test/route_test.rs
@@ -1,4 +1,4 @@
-use mingling_picker::{IntoPicker, macros::flag};
+use mingling_picker::{IntoPicker, macros::arg};
// Route mechanism — or_route
@@ -8,7 +8,7 @@ fn test_or_route_triggered_to_result() {
let args: Vec<&str> = vec![];
let result: Result<bool, &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "missing_verbose")
.to_result();
assert_eq!(result, Err("missing_verbose"));
@@ -20,7 +20,7 @@ fn test_or_route_not_triggered_when_flag_present() {
let args = vec!["--verbose"];
let result: Result<bool, &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "missing_verbose")
.to_result();
assert_eq!(result, Ok(true));
@@ -33,7 +33,7 @@ fn test_or_default_priority_over_or_route() {
let args: Vec<&str> = vec![];
let result: Result<bool, &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_default()
.or_route(|| "should_not_reach")
.to_result();
@@ -46,7 +46,7 @@ fn test_or_route_to_option_returns_none() {
let args: Vec<&str> = vec![];
let opt: Option<bool> = args
.with_route::<&'static str>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "missing")
.to_option();
assert_eq!(opt, None);
@@ -57,7 +57,7 @@ fn test_or_route_to_option_returns_none() {
fn test_or_route_unwrap_panics() {
let args: Vec<&str> = vec![];
args.with_route::<&'static str>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "missing")
.unwrap();
}
@@ -68,7 +68,7 @@ fn test_or_route_with_string_route() {
let args: Vec<&str> = vec![];
let result: Result<bool, String> = args
.with_route::<String>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "route_hit".to_string())
.to_result();
assert_eq!(result, Err("route_hit".to_string()));
@@ -87,7 +87,7 @@ fn test_or_route_with_custom_enum() {
let args: Vec<&str> = vec![];
let result: Result<bool, Redirect> = args
.with_route::<Redirect>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| Redirect::Help)
.to_result();
assert_eq!(result, Err(Redirect::Help));
@@ -102,9 +102,9 @@ fn test_two_flags_first_missing_triggers_route() {
let args: Vec<&str> = vec![];
let result: Result<(bool, bool), &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
.or_route(|| "first_missing")
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_route(|| "second_missing")
.to_result();
assert_eq!(result, Err("first_missing"));
@@ -116,9 +116,9 @@ fn test_two_flags_second_missing_triggers_route() {
let args: Vec<&str> = vec![];
let result: Result<(bool, bool), &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
.or_default()
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_route(|| "second_missing")
.to_result();
assert_eq!(result, Err("second_missing"));
@@ -127,12 +127,12 @@ fn test_two_flags_second_missing_triggers_route() {
#[test]
fn test_two_flags_both_present_route_not_triggered() {
// Both flags present → route not triggered → Ok((true, true))
- let args = vec!["--flag_a", "--flag_b"];
+ let args = vec!["--flag-a", "--flag-b"];
let result: Result<(bool, bool), &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
.or_route(|| "first_missing")
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_route(|| "second_missing")
.to_result();
assert_eq!(result, Ok((true, true)));
@@ -145,9 +145,9 @@ fn test_two_flags_first_missing_no_route_second_has_route() {
let args: Vec<&str> = vec![];
let result: Result<(bool, bool), &'static str> = args
.with_route::<&'static str>()
- .pick(&flag![flag_a: bool])
+ .pick(&arg![flag_a: bool])
// No or_default, no or_route either
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_b: bool])
.or_route(|| "second_missing")
.to_result();
assert_eq!(result, Err("second_missing"));
@@ -160,8 +160,8 @@ fn test_two_flags_only_second_has_default() {
let args: Vec<&str> = vec![];
let (a, b) = args
.to_picker()
- .pick(&flag![flag_a: bool])
- .pick(&flag![flag_b: bool])
+ .pick(&arg![flag_a: bool])
+ .pick(&arg![flag_b: bool])
.or_default()
.unpack();
assert_eq!(a, None);
@@ -176,7 +176,7 @@ fn test_with_route_and_or_route() {
let args: Vec<&str> = vec![];
let result: Result<bool, String> = args
.with_route::<String>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "redirected".to_string())
.to_result();
assert_eq!(result, Err("redirected".to_string()));
@@ -188,10 +188,10 @@ fn test_with_route_type_switch() {
let args: Vec<&str> = vec![];
let result: Result<(bool, bool), i32> = args
.with_route::<String>()
- .pick(&flag![verbose: bool])
+ .pick(&arg![verbose: bool])
.or_route(|| "string_route".to_string())
.with_route::<i32>()
- .pick(&flag![other: bool])
+ .pick(&arg![other: bool])
.or_route(|| -1)
.to_result();
// The first flag is missing, but its or_route is cleared when with_route switches (route_$ = None)
diff --git a/mingling_picker/test/src/test/style_test.rs b/mingling_picker/test/src/test/style_test.rs
index 795c4ab..efb2185 100644
--- a/mingling_picker/test/src/test/style_test.rs
+++ b/mingling_picker/test/src/test/style_test.rs
@@ -1,7 +1,7 @@
use mingling_picker::PickerArgInfo;
use mingling_picker::parselib::{
- MaskedArg, Matcher, POWERSHELL_STYLE, ParserStyle, ParserStyleNamingCase, UNIX_STYLE,
- WINDOWS_STYLE, build_possible_flags,
+ FlagMatcher, MaskedArg, Matcher, POWERSHELL_STYLE, ParserStyle, ParserStyleNamingCase,
+ UNIX_STYLE, WINDOWS_STYLE, build_possible_flags,
};
// Style: formatting utilities
@@ -56,7 +56,7 @@ fn test_windows_style_match() {
info.set_long("verbose");
let args = vec![make_masked("/verbose", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &WINDOWS_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &WINDOWS_STYLE, &info);
assert_eq!(result, Some(0));
}
@@ -67,7 +67,7 @@ fn test_windows_style_match_case_insensitive() {
info.set_long("verbose");
let args = vec![make_masked("/VERBOSE", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &WINDOWS_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &WINDOWS_STYLE, &info);
assert_eq!(result, Some(0));
}
@@ -78,7 +78,7 @@ fn test_windows_style_no_match_on_unrelated_flag() {
info.set_long("verbose");
let args = vec![make_masked("/output", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &WINDOWS_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &WINDOWS_STYLE, &info);
assert_eq!(result, None);
}
@@ -89,7 +89,7 @@ fn test_powershell_style_match() {
info.set_long("Verbose");
let args = vec![make_masked("-Verbose", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &POWERSHELL_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info);
assert_eq!(result, Some(0));
}
@@ -99,7 +99,7 @@ fn test_powershell_style_match_case_insensitive() {
info.set_long("Verbose");
let args = vec![make_masked("-VERBOSE", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &POWERSHELL_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info);
assert_eq!(result, Some(0));
}
@@ -110,7 +110,7 @@ fn test_unix_style_case_sensitive_no_match() {
info.set_long("verbose");
let args = vec![make_masked("--VERBOSE", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &UNIX_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info);
assert_eq!(result, None);
}
@@ -126,7 +126,7 @@ fn test_windows_style_match_all() {
make_masked("/output", 1),
make_masked("/VERBOSE", 2),
];
- let result = <bool as Matcher>::on_match_all(&args, &WINDOWS_STYLE, &info);
+ let result = FlagMatcher::on_match_all(&args, &WINDOWS_STYLE, &info);
assert_eq!(result, vec![0, 2]);
}
@@ -142,7 +142,7 @@ fn test_windows_style_match_after_end_of_options() {
make_masked("--", 1),
make_masked("/verbose", 2),
];
- let result = <bool as Matcher>::on_match_all(&args, &WINDOWS_STYLE, &info);
+ let result = FlagMatcher::on_match_all(&args, &WINDOWS_STYLE, &info);
// end_of_options is always "--" regardless of style
assert_eq!(result, vec![0]);
}
@@ -162,7 +162,7 @@ fn test_kebab_case_naming_for_multiword_flag() {
info.set_long("flag_a");
let args = vec![make_masked("--flag-a", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &KEBAB_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &KEBAB_STYLE, &info);
assert_eq!(
result,
Some(0),
@@ -177,7 +177,7 @@ fn test_snake_case_should_not_match_as_long_flag() {
info.set_long("flag_a");
let args = vec![make_masked("--flag_a", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &KEBAB_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &KEBAB_STYLE, &info);
assert_eq!(
result, None,
"--flag_a should NOT match in kebab-style context"
@@ -185,17 +185,31 @@ fn test_snake_case_should_not_match_as_long_flag() {
}
#[test]
-fn test_snake_case_naming_for_unix_style() {
- // UNIX_STYLE uses snake case: `flag_a` stays `flag_a` → `--flag_a`
+fn test_kebab_case_naming_for_unix_style() {
+ // UNIX_STYLE now uses Kebab case: `flag_a` → `flag-a` → `--flag-a`
let mut info = PickerArgInfo::new();
info.set_long("flag_a");
- let args = vec![make_masked("--flag_a", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &UNIX_STYLE, &info);
+ let args = vec![make_masked("--flag-a", 0)];
+ let result = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info);
assert_eq!(
result,
Some(0),
- "--flag_a should match with snake-style UNIX_STYLE"
+ "--flag-a should match with kebab-style UNIX_STYLE"
+ );
+}
+
+#[test]
+fn test_snake_case_rejected_by_unix_style() {
+ // UNIX_STYLE uses Kebab: `--flag_a` (snake) should NOT match
+ let mut info = PickerArgInfo::new();
+ info.set_long("flag_a");
+
+ let args = vec![make_masked("--flag_a", 0)];
+ let result = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info);
+ assert_eq!(
+ result, None,
+ "--flag_a should NOT match under kebab-style UNIX_STYLE"
);
}
@@ -206,10 +220,83 @@ fn test_powershell_pascal_case_naming() {
info.set_long("verbose");
let args = vec![make_masked("-Verbose", 0)];
- let result = <bool as Matcher>::on_match_one(&args, &POWERSHELL_STYLE, &info);
+ let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info);
assert_eq!(
result,
Some(0),
"-Verbose should match verbose via Pascal case"
);
}
+
+#[test]
+fn test_flag_naming_kebab_matches_my_name() {
+ // UNIX_STYLE now uses Kebab: `my_name` → `my-name` → `--my-name`
+ let mut info = PickerArgInfo::new();
+ info.set_long("my_name");
+
+ let args = vec![make_masked("--my-name", 0)];
+ let result = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info);
+ assert_eq!(
+ result,
+ Some(0),
+ "--my-name should match via kebab conversion"
+ );
+}
+
+#[test]
+fn test_flag_naming_kebab_rejects_my_name_underscore() {
+ // Kebab style: `--my_name` (snake) should NOT match
+ let mut info = PickerArgInfo::new();
+ info.set_long("my_name");
+
+ let args = vec![make_masked("--my_name", 0)];
+ let result = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info);
+ assert_eq!(
+ result, None,
+ "--my_name should NOT match under kebab-style UNIX_STYLE"
+ );
+}
+
+#[test]
+fn test_flag_naming_pascal_matches_my_name() {
+ // `my_name` under Pascal → `MyName` → `-MyName`
+ let mut info = PickerArgInfo::new();
+ info.set_long("my_name");
+
+ let args = vec![make_masked("-MyName", 0)];
+ let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info);
+ assert_eq!(
+ result,
+ Some(0),
+ "-MyName should match via Pascal conversion"
+ );
+}
+
+#[test]
+fn test_flag_naming_pascal_matches_lowercase() {
+ // PowerShell is case-insensitive: `-myname` should also match
+ let mut info = PickerArgInfo::new();
+ info.set_long("my_name");
+
+ let args = vec![make_masked("-myname", 0)];
+ let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info);
+ assert_eq!(
+ result,
+ Some(0),
+ "-myname (lowercase) should match via case-insensitive Pascal"
+ );
+}
+
+#[test]
+fn test_flag_naming_pascal_rejects_my_name_underscore() {
+ // Pascal style: `-my_name` (underscore) should NOT match
+ let mut info = PickerArgInfo::new();
+ info.set_long("my_name");
+
+ let args = vec![make_masked("-my_name", 0)];
+ let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info);
+ assert_eq!(
+ result, None,
+ "-my_name should NOT match under Pascal-style naming"
+ );
+}
diff --git a/mingling_picker/test/src/test/value_flag_test.rs b/mingling_picker/test/src/test/value_flag_test.rs
new file mode 100644
index 0000000..d267a27
--- /dev/null
+++ b/mingling_picker/test/src/test/value_flag_test.rs
@@ -0,0 +1,174 @@
+use mingling_picker::value::Flag;
+use mingling_picker::{IntoPicker, macros::arg};
+
+// Basic Flag — present / absent
+
+#[test]
+fn test_flag_present() {
+ let flag: Flag = vec!["--verbose"]
+ .to_picker()
+ .pick(&arg![verbose: Flag])
+ .unwrap();
+ assert_eq!(flag, Flag::Active);
+}
+
+#[test]
+fn test_flag_absent_returns_inactive() {
+ // Unlike bool, Flag::pick returns Parsed(Inactive) when no match is found,
+ // so or_default() is NOT required — unwrap() works directly.
+ let flag: Flag = Vec::<&str>::new()
+ .to_picker()
+ .pick(&arg![verbose: Flag])
+ .unwrap();
+ assert_eq!(flag, Flag::Inactive);
+}
+
+// Short Flag
+
+#[test]
+fn test_flag_short_present() {
+ let flag: Flag = vec!["-v"]
+ .to_picker()
+ .pick(&arg![verbose: Flag, 'v'])
+ .unwrap();
+ assert_eq!(flag, Flag::Active);
+}
+
+// Multiple Flags
+
+#[test]
+fn test_two_flags_both_present() {
+ let (a, b): (Flag, Flag) = vec!["--flag-a", "--flag-b"]
+ .to_picker()
+ .pick(&arg![flag_a: Flag])
+ .pick(&arg![flag_b: Flag])
+ .unwrap();
+ assert_eq!(a, Flag::Active);
+ assert_eq!(b, Flag::Active);
+}
+
+#[test]
+fn test_two_flags_one_present() {
+ let (a, b): (Flag, Flag) = vec!["--flag-a"]
+ .to_picker()
+ .pick(&arg![flag_a: Flag])
+ .pick(&arg![flag_b: Flag])
+ .unwrap();
+ assert_eq!(a, Flag::Active);
+ assert_eq!(b, Flag::Inactive);
+}
+
+#[test]
+fn test_two_flags_neither_present() {
+ let (a, b): (Flag, Flag) = Vec::<&str>::new()
+ .to_picker()
+ .pick(&arg![flag_a: Flag])
+ .pick(&arg![flag_b: Flag])
+ .unwrap();
+ assert_eq!(a, Flag::Inactive);
+ assert_eq!(b, Flag::Inactive);
+}
+
+// After `--` (end-of-options)
+
+#[test]
+fn test_flag_after_end_of_options() {
+ let flag: Flag = vec!["--", "--verbose"]
+ .to_picker()
+ .pick(&arg![verbose: Flag])
+ .unwrap();
+ assert_eq!(flag, Flag::Inactive);
+}
+
+// Alias
+
+#[test]
+fn test_flag_with_alias() {
+ let flag: Flag = vec!["--cfg"]
+ .to_picker()
+ .pick(&arg![config: Flag, "cfg"])
+ .unwrap();
+ assert_eq!(flag, Flag::Active);
+}
+
+#[test]
+fn test_flag_primary_name() {
+ let flag: Flag = vec!["--config"]
+ .to_picker()
+ .pick(&arg![config: Flag, "cfg"])
+ .unwrap();
+ assert_eq!(flag, Flag::Active);
+}
+
+// Unrelated flag should not match
+
+#[test]
+fn test_unrelated_flag_does_not_match() {
+ let flag: Flag = vec!["--other"]
+ .to_picker()
+ .pick(&arg![verbose: Flag])
+ .unwrap();
+ assert_eq!(flag, Flag::Inactive);
+}
+
+// to_result / to_option
+
+#[test]
+fn test_flag_to_result() {
+ let result: Result<Flag, ()> = vec!["--verbose"]
+ .to_picker()
+ .pick(&arg![verbose: Flag])
+ .to_result();
+ assert_eq!(result, Ok(Flag::Active));
+}
+
+#[test]
+fn test_flag_to_option() {
+ let opt: Option<Flag> = vec!["--verbose"]
+ .to_picker()
+ .pick(&arg![verbose: Flag])
+ .to_option();
+ assert_eq!(opt, Some(Flag::Active));
+}
+
+// Bool conversions
+
+#[test]
+fn test_flag_converts_to_bool() {
+ let flag = Flag::Active;
+ assert!(bool::from(flag));
+
+ let flag = Flag::Inactive;
+ assert!(!bool::from(flag));
+}
+
+#[test]
+fn test_flag_from_bool() {
+ assert_eq!(Flag::from(true), Flag::Active);
+ assert_eq!(Flag::from(false), Flag::Inactive);
+}
+
+#[test]
+fn test_flag_deref_to_bool() {
+ let active = Flag::Active;
+ assert!(*active);
+
+ let inactive = Flag::Inactive;
+ assert!(!*inactive);
+}
+
+// Flag never triggers route (unlike bool)
+//
+// Flag::pick always returns Parsed, so the fallback chain
+// (default → route) is never entered.
+
+#[test]
+fn test_flag_absent_does_not_trigger_route() {
+ // Even without or_default / or_route, absent flag returns Inactive, not a route
+ let result: Result<Flag, &str> = Vec::<&str>::new()
+ .with_route::<&str>()
+ .pick(&arg![verbose: Flag])
+ .or_route(|| "should_not_fire")
+ .to_result();
+ assert_eq!(result, Ok(Flag::Inactive));
+}