diff options
Diffstat (limited to 'mingling_picker/test')
| -rw-r--r-- | mingling_picker/test/src/test.rs | 1 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/basic_test.rs | 52 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/route_test.rs | 44 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/style_test.rs | 123 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/value_flag_test.rs | 174 |
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)); +} |
