diff options
Diffstat (limited to 'mingling_picker/test')
| -rw-r--r-- | mingling_picker/test/Cargo.lock | 68 | ||||
| -rw-r--r-- | mingling_picker/test/Cargo.toml | 9 | ||||
| -rw-r--r-- | mingling_picker/test/src/lib.rs | 23 | ||||
| -rw-r--r-- | mingling_picker/test/src/test.rs | 10 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/arg_matcher_test.rs | 289 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/basic_test.rs | 223 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/multi_arg_test.rs | 181 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/multi_value_test.rs | 66 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/pos_matcher_test.rs | 141 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/priority_test.rs | 85 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/route_test.rs | 200 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/style_test.rs | 300 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/value_flag_test.rs | 174 | ||||
| -rw-r--r-- | mingling_picker/test/src/test/value_string_test.rs | 171 |
14 files changed, 0 insertions, 1940 deletions
diff --git a/mingling_picker/test/Cargo.lock b/mingling_picker/test/Cargo.lock deleted file mode 100644 index 0fef84b..0000000 --- a/mingling_picker/test/Cargo.lock +++ /dev/null @@ -1,68 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "just_fmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6170dccbc3ea15dfb7f2da964097f814aba1dd8f746d4ffc56f33245c38e6d96" - -[[package]] -name = "mingling_picker" -version = "0.3.0" -dependencies = [ - "just_fmt", - "mingling_picker_macros", -] - -[[package]] -name = "mingling_picker_macros" -version = "0.3.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "syn" -version = "2.0.119" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "test-mingling-picker" -version = "0.1.0" -dependencies = [ - "mingling_picker", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/mingling_picker/test/Cargo.toml b/mingling_picker/test/Cargo.toml deleted file mode 100644 index 127546c..0000000 --- a/mingling_picker/test/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "test-mingling-picker" -version = "0.1.0" -edition = "2024" - -[workspace] - -[dependencies] -mingling_picker = { path = "../" } diff --git a/mingling_picker/test/src/lib.rs b/mingling_picker/test/src/lib.rs deleted file mode 100644 index eac6cad..0000000 --- a/mingling_picker/test/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Using `assert_eq!(x, true)` is clearer than `assert!(x)` for expressing expected values -// -// BECAUSE `assert!` only checks if the boolean value is true, -// while `assert_eq!` explicitly shows the expected value -#![allow(clippy::bool_assert_comparison)] - -#[cfg(test)] -mod test; - -use mingling_picker::parselib::MaskedArg; - -/// Create a single `MaskedArg` from a raw string and its original index. -pub fn make_masked(raw: &str, idx: usize) -> MaskedArg<'_> { - MaskedArg { raw, raw_idx: idx } -} - -/// Create a `Vec<MaskedArg>` from an array of `(raw, raw_idx)` pairs. -pub fn make_args<'a>(pairs: &'a [(&'a str, usize)]) -> Vec<MaskedArg<'a>> { - pairs - .iter() - .map(|&(raw, idx)| MaskedArg { raw, raw_idx: idx }) - .collect() -} diff --git a/mingling_picker/test/src/test.rs b/mingling_picker/test/src/test.rs deleted file mode 100644 index 9c53514..0000000 --- a/mingling_picker/test/src/test.rs +++ /dev/null @@ -1,10 +0,0 @@ -mod arg_matcher_test; -mod basic_test; -mod multi_arg_test; -mod multi_value_test; -mod pos_matcher_test; -mod priority_test; -mod route_test; -mod style_test; -mod value_flag_test; -mod value_string_test; diff --git a/mingling_picker/test/src/test/arg_matcher_test.rs b/mingling_picker/test/src/test/arg_matcher_test.rs deleted file mode 100644 index 7b37bc8..0000000 --- a/mingling_picker/test/src/test/arg_matcher_test.rs +++ /dev/null @@ -1,289 +0,0 @@ -use mingling_picker::PickerArgInfo; -use mingling_picker::parselib::{ArgMatcher, Matcher, POWERSHELL_STYLE, UNIX_STYLE}; - -use crate::make_args; - -// on_match_one — Named - -#[test] -fn test_match_one_named_basic() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name", 0), ("Alice", 1)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_match_one_named_eq_mode() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name=Alice", 0)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_match_one_named_no_match() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--other", 0), ("Alice", 1)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -#[test] -fn test_match_one_named_short_flag() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - info.set_short('n'); - let args = make_args(&[("-n", 0), ("Alice", 1)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_match_one_named_after_end_of_options() { - // Flags after `--` should not be matched. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--", 0), ("--name", 1), ("Alice", 2)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -// on_match_one — Positional - -#[test] -fn test_match_one_positional_basic() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("file.txt", 0)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_match_one_positional_takes_first() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("a.txt", 0), ("b.txt", 1)]); - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(0)); -} - -// on_match_all — Named, single occurrence - -#[test] -fn test_match_all_named_flag_plus_value() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name", 0), ("Alice", 1)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -#[test] -fn test_match_all_named_eq_mode() { - // --name=Alice: value is inline, only tag the flag position. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name=Alice", 0)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} - -#[test] -fn test_match_all_named_no_value() { - // Flag at end with no following arg: only tag the flag. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name", 0)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} - -#[test] -fn test_match_all_named_value_looks_like_flag() { - // The next arg looks like a flag — still tag it. - // Validation is the Pickable's responsibility. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name", 0), ("--other", 1)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -// on_match_all — Named, multiple occurrences (Single per flag) - -#[test] -fn test_match_all_named_two_occurrences() { - // --name Alice --name Bob → each occurrence gets one value. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name", 0), ("Alice", 1), ("--name", 2), ("Bob", 3)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2, 3]); -} - -#[test] -fn test_match_all_named_skips_non_matching_args() { - // --val a b --val d → only pairs (0,1) and (3,4); idx 2 ("b") left free. - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val", 0), ("a", 1), ("b", 2), ("--val", 3), ("d", 4)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 3, 4]); -} - -// on_match_all — Named, short flag - -#[test] -fn test_match_all_named_short_flag() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - info.set_short('n'); - let args = make_args(&[("-n", 0), ("Alice", 1)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -// on_match_all — Named, eq + non-eq mixed - -#[test] -fn test_match_all_named_mixed_eq_and_regular() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--name=Alice", 0), ("--name", 1), ("Bob", 2)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2]); -} - -// on_match_all — Named, case insensitive (PowerShell) - -#[test] -fn test_match_all_named_powershell_case_insensitive() { - let mut info = PickerArgInfo::new(); - info.set_long("Name"); - let args = make_args(&[("-name", 0), ("Alice", 1)]); - let result = ArgMatcher::on_match_all(&args, &POWERSHELL_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -// on_match_all — Positional - -#[test] -fn test_match_all_positional_single() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("file.txt", 0)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} - -#[test] -fn test_match_all_positional_multiple() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("a.txt", 0), ("b.txt", 1)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -// End-of-options marker (`--`) - -#[test] -fn test_match_all_named_stops_at_end_of_options() { - // --name before `--` should match, --name after should not. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[ - ("--name", 0), - ("Alice", 1), - ("--", 2), - ("--name", 3), - ("Bob", 4), - ]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -#[test] -fn test_match_all_positional_stops_at_end_of_options() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("before", 0), ("--", 1), ("after", 2)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} - -// Empty args - -#[test] -fn test_match_one_empty() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = vec![]; - let result = ArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -#[test] -fn test_match_all_empty() { - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = vec![]; - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} - -// Verify that -- itself is never matched as a flag - -#[test] -fn test_match_all_end_of_options_not_matched() { - // `--` should neither match as a flag nor take a value. - let mut info = PickerArgInfo::new(); - info.set_long("name"); - let args = make_args(&[("--", 0)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} - -// `--` should never be consumed as a value by a named flag. - -#[test] -fn test_match_all_named_does_not_consume_end_marker() { - // `--flag` before `--`, but the next position IS `--`. - // Only tag the flag, don't consume the end-of-options marker. - let mut info = PickerArgInfo::new(); - info.set_long("flag"); - let args = make_args(&[("--flag", 0), ("--", 1), ("value", 2)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0], "should NOT consume -- as a value"); -} - -#[test] -fn test_match_all_named_does_not_consume_end_marker_flag_before_end() { - // Simulates: --flag -- you where -- is end-of-options. - // The flag should be tagged but -- should NOT be consumed as its value. - let mut info = PickerArgInfo::new(); - info.set_long("flag"); - - let args = make_args(&[("--flag", 0), ("--", 1), ("you", 2)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!( - result, - vec![0], - "flag before --: only tag flag, leave -- for positional" - ); -} - -#[test] -fn test_match_all_flag_after_end_has_value() { - // Flag after `--` should not match at all. - let mut info = PickerArgInfo::new(); - info.set_long("flag"); - let args = make_args(&[("--", 0), ("--flag", 1), ("value", 2)]); - let result = ArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} diff --git a/mingling_picker/test/src/test/basic_test.rs b/mingling_picker/test/src/test/basic_test.rs deleted file mode 100644 index 78b154e..0000000 --- a/mingling_picker/test/src/test/basic_test.rs +++ /dev/null @@ -1,223 +0,0 @@ -use mingling_picker::{IntoPicker, macros::arg}; - -// Basic bool flag — present / absent - -#[test] -fn test_bool_flag_present() { - let args = vec!["--verbose"]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .unwrap(); - assert_eq!(parsed, true); -} - -#[test] -fn test_bool_flag_absent() { - let args: Vec<&str> = vec![]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .unwrap(); - assert_eq!(parsed, false); -} - -// Short flag — '-v' - -#[test] -fn test_bool_short_flag_present() { - let args = vec!["-v"]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool, 'v']) - .or_default() - .unwrap(); - assert_eq!(parsed, true); -} - -// Multiple bool flags at once - -#[test] -fn test_two_bool_flags_both_present() { - // 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(&arg![flag_a: bool]) - .or_default() - .pick(&arg![flag_b: bool]) - .or_default() - .unwrap(); - assert_eq!(a, true); - assert_eq!(b, true); -} - -#[test] -fn test_two_bool_flags_one_present() { - let args = vec!["--flag-a"]; - let (a, b) = args - .to_picker() - .pick(&arg![flag_a: bool]) - .or_default() - .pick(&arg![flag_b: bool]) - .or_default() - .unwrap(); - assert_eq!(a, true); - assert_eq!(b, false); -} - -#[test] -fn test_two_bool_flags_neither_present() { - let args: Vec<&str> = vec![]; - let (a, b) = args - .to_picker() - .pick(&arg![flag_a: bool]) - .or_default() - .pick(&arg![flag_b: bool]) - .or_default() - .unwrap(); - assert_eq!(a, false); - assert_eq!(b, false); -} - -// Mixed short and long flags - -#[test] -fn test_short_and_long_flags() { - let args = vec!["-a", "--long-b"]; - let (a, b) = args - .to_picker() - .pick(&arg![flag_a: bool, 'a']) - .or_default() - .pick(&arg![long_b: bool]) - .or_default() - .unwrap(); - assert_eq!(a, true); - assert_eq!(b, true); -} - -// Flags after `--` (end-of-options marker) should not be parsed. - -#[test] -fn test_flag_after_end_of_options() { - let args = vec!["--", "--verbose"]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .unwrap(); - assert_eq!(parsed, false); -} - -// Alias matching for bool flags - -#[test] -fn test_bool_flag_with_alias() { - let args = vec!["--cfg"]; - let parsed = args - .to_picker() - .pick(&arg![config: bool, "cfg"]) - .or_default() - .unwrap(); - assert_eq!(parsed, true); -} - -#[test] -fn test_bool_flag_primary_name() { - let args = vec!["--config"]; - let parsed = args - .to_picker() - .pick(&arg![config: bool, "cfg"]) - .or_default() - .unwrap(); - assert_eq!(parsed, true); -} - -// Short flag + alias for bool flag - -#[test] -fn test_bool_flag_short_and_alias() { - let args = vec!["-v"]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool, 'v', "cfg"]) - .or_default() - .unwrap(); - assert_eq!(parsed, true); -} - -// Default values: .or() / .or_default() - -#[test] -fn test_or_default_without_args() { - let args: Vec<&str> = vec![]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .unwrap(); - assert_eq!(parsed, false); -} - -#[test] -fn test_or_custom_default() { - let args: Vec<&str> = vec![]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool]) - .or(|| true) - .unwrap(); - assert_eq!(parsed, true); -} - -// to_result / to_option interface - -#[test] -fn test_to_result_ok() { - let args = vec!["--verbose"]; - let result = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .to_result(); - assert_eq!(result, Ok(true)); -} - -#[test] -fn test_to_option_some() { - let args = vec!["--verbose"]; - let opt = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .to_option(); - assert_eq!(opt, Some(true)); -} - -// Chain with_route passthrough - -#[test] -fn test_with_route_chain() { - let args = vec!["--flag"]; - let parsed = args - .with_route::<String>() - .pick(&arg![flag: bool]) - .or_default() - .unwrap(); - assert_eq!(parsed, true); -} - -// Unrelated flag should not match - -#[test] -fn test_unrelated_flag_does_not_match() { - let args = vec!["--other"]; - let parsed = args - .to_picker() - .pick(&arg![verbose: bool]) - .or_default() - .unwrap(); - assert_eq!(parsed, false); -} diff --git a/mingling_picker/test/src/test/multi_arg_test.rs b/mingling_picker/test/src/test/multi_arg_test.rs deleted file mode 100644 index 377357e..0000000 --- a/mingling_picker/test/src/test/multi_arg_test.rs +++ /dev/null @@ -1,181 +0,0 @@ -use mingling_picker::parselib::{Matcher, MultiArgMatcher, UNIX_STYLE}; -use mingling_picker::PickerArgInfo; - -use crate::make_args; - -// on_match_one — basic - -#[test] -fn test_multi_one_finds_first_flag() { - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--other", 0), ("--val", 1), ("a", 2), ("b", 3)]); - let result = MultiArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(1)); -} - -#[test] -fn test_multi_one_no_match() { - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--other", 0)]); - let result = MultiArgMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -// on_match_all — named, basic multi-value - -#[test] -fn test_multi_all_flag_takes_all_values_until_next_flag() { - // --val a b c → all three values belong to --val - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val", 0), ("a", 1), ("b", 2), ("c", 3)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2, 3]); -} - -#[test] -fn test_multi_all_stops_at_next_flag() { - // --val a b --other c d → only a,b belong to --val - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val", 0), ("a", 1), ("b", 2), ("--other", 3), ("c", 4)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2]); -} - -#[test] -fn test_multi_all_flag_no_values() { - // --val at end with no values → just the flag - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val", 0)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} - -#[test] -fn test_multi_all_empty() { - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = vec![]; - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} - -// on_match_all — named, multiple occurrences of same flag - -#[test] -fn test_multi_all_two_occurrences() { - // --val a b --val c d → two groups - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[ - ("--val", 0), ("a", 1), ("b", 2), - ("--val", 3), ("c", 4), ("d", 5), - ]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2, 3, 4, 5]); -} - -#[test] -fn test_multi_all_skips_non_matching_args() { - // --val a --other b --val c → only --val groups - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[ - ("--val", 0), ("a", 1), - ("--other", 2), ("b", 3), - ("--val", 4), ("c", 5), - ]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 4, 5]); -} - -// on_match_all — named, eq mode - -#[test] -fn test_multi_all_eq_mode() { - // --val=a b → eq mode + one extra value - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val=a", 0), ("b", 1)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -#[test] -fn test_multi_all_eq_mode_no_extra() { - // --val=a alone → just the eq flag - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val=a", 0)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} - -#[test] -fn test_multi_all_mixed_eq_and_regular() { - // --val=a b --val c d - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[ - ("--val=a", 0), ("b", 1), ("--val", 2), ("c", 3), ("d", 4), - ]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2, 3, 4]); -} - -// on_match_all — short flag - -#[test] -fn test_multi_all_short_flag() { - let mut info = PickerArgInfo::new(); - info.set_short('v'); - info.set_long("val"); - let args = make_args(&[("-v", 0), ("a", 1), ("b", 2)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1, 2]); -} - -// on_match_all — end-of-options marker - -#[test] -fn test_multi_all_stops_at_end_of_options() { - // --val a -- b → stops before `--` - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--val", 0), ("a", 1), ("--", 2), ("b", 3)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -#[test] -fn test_multi_all_flag_after_end_ignored() { - let mut info = PickerArgInfo::new(); - info.set_long("val"); - let args = make_args(&[("--", 0), ("--val", 1), ("a", 2)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} - -// on_match_all — positional - -#[test] -fn test_multi_all_positional() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("a.txt", 0), ("b.txt", 1)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0, 1]); -} - -#[test] -fn test_multi_all_positional_stops_at_end_of_options() { - let mut info = PickerArgInfo::new(); - info.set_positional(true); - let args = make_args(&[("a.txt", 0), ("--", 1), ("b.txt", 2)]); - let result = MultiArgMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![0]); -} diff --git a/mingling_picker/test/src/test/multi_value_test.rs b/mingling_picker/test/src/test/multi_value_test.rs deleted file mode 100644 index 0f56517..0000000 --- a/mingling_picker/test/src/test/multi_value_test.rs +++ /dev/null @@ -1,66 +0,0 @@ -use mingling_picker::value::{Flag, VecUntil}; -use mingling_picker::{IntoPicker, macros::arg}; - -#[test] -fn test_vec_until_i16_named() { - let (nums, rest): (VecUntil<i16>, Flag) = vec!["--nums", "1", "2", "3", "abc"] - .to_picker() - .pick(&arg![nums: VecUntil<i16>]) - .pick(&arg![rest: Flag]) - .unwrap(); - assert_eq!(*nums, vec![1i16, 2, 3]); - assert_eq!(rest, Flag::Inactive); -} - -#[test] -fn test_vec_until_i16_stops_at_non_number() { - let nums: VecUntil<i16> = vec!["--nums", "42", "abc", "100"] - .to_picker() - .pick(&arg![nums: VecUntil<i16>]) - .unwrap(); - assert_eq!(*nums, vec![42i16]); -} - -#[test] -fn test_vec_until_i16_empty() { - let nums: VecUntil<i16> = vec!["--nums"] - .to_picker() - .pick(&arg![nums: VecUntil<i16>]) - .unwrap(); - assert!(nums.is_empty()); -} - -#[test] -fn test_vec_until_i16_stops_at_next_flag() { - let nums: VecUntil<i16> = vec!["--nums", "1", "2", "--other", "3"] - .to_picker() - .pick(&arg![nums: VecUntil<i16>]) - .unwrap(); - assert_eq!(*nums, vec![1i16, 2]); -} - -#[test] -fn test_vec_until_i16_stops_at_end_of_options() { - let nums: VecUntil<i16> = vec!["--nums", "1", "2", "--", "3"] - .to_picker() - .pick(&arg![nums: VecUntil<i16>]) - .unwrap(); - assert_eq!(*nums, vec![1i16, 2]); -} - -// Two VecUntil<T> with different boundary behaviours - -#[test] -fn test_vec_until_f64_and_i16_positional() { - // Both are positional VecUntil. f64 takes all valid floats, - // i16 takes what's left. But note: "1", "2", "3" are also valid - // f64 values, so f64's check_boundary never fires — it consumes - // everything, and i16 gets nothing. - let (floats, ints): (VecUntil<f64>, VecUntil<i16>) = vec!["1.5", "2.5", "3.5", "1", "2", "3"] - .to_picker() - .pick(&arg![VecUntil<f64>]) - .pick(&arg![VecUntil<i16>]) - .unwrap(); - assert_eq!(*floats, vec![1.5, 2.5, 3.5]); - assert_eq!(*ints, vec![1i16, 2, 3]); -} diff --git a/mingling_picker/test/src/test/pos_matcher_test.rs b/mingling_picker/test/src/test/pos_matcher_test.rs deleted file mode 100644 index b5319f5..0000000 --- a/mingling_picker/test/src/test/pos_matcher_test.rs +++ /dev/null @@ -1,141 +0,0 @@ -use mingling_picker::PickerArgInfo; -use mingling_picker::parselib::{MaskedArg, Matcher, PositionalMatcher, UNIX_STYLE, WINDOWS_STYLE}; - -fn make_args<'a>(pairs: &'a [(&'a str, usize)]) -> Vec<MaskedArg<'a>> { - pairs - .iter() - .map(|&(raw, idx)| MaskedArg { raw, raw_idx: idx }) - .collect() -} - -// on_match_one — basic - -#[test] -fn test_pos_one_takes_first_non_flag() { - let info = PickerArgInfo::new(); - let args = make_args(&[("--verbose", 0), ("file.txt", 1)]); - let result = PositionalMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(1)); -} - -#[test] -fn test_pos_one_takes_first_if_no_flag() { - let info = PickerArgInfo::new(); - let args = make_args(&[("file.txt", 0)]); - let result = PositionalMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_pos_one_all_flags_returns_none() { - let info = PickerArgInfo::new(); - let args = make_args(&[("--verbose", 0), ("--name", 1)]); - let result = PositionalMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -#[test] -fn test_pos_one_empty_returns_none() { - let info = PickerArgInfo::new(); - let args = vec![]; - let result = PositionalMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -// on_match_one — after `--` - -#[test] -fn test_pos_one_after_end_takes_even_flag_like() { - // After `--`, accept everything including `--verbose`. - let info = PickerArgInfo::new(); - let args = make_args(&[("--", 0), ("--verbose", 1), ("file.txt", 2)]); - let result = PositionalMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, Some(1)); -} - -#[test] -fn test_pos_one_only_end_returns_none() { - let info = PickerArgInfo::new(); - let args = make_args(&[("--", 0)]); - let result = PositionalMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -// on_match_one — Windows style prefix - -#[test] -fn test_pos_one_windows_skips_slash_prefix() { - let info = PickerArgInfo::new(); - let args = make_args(&[("/Verbose", 0), ("file.txt", 1)]); - let result = PositionalMatcher::on_match_one(&args, &WINDOWS_STYLE, &info); - assert_eq!(result, Some(1)); -} - -// on_match_all — basic - -#[test] -fn test_pos_all_collects_non_flags() { - let info = PickerArgInfo::new(); - let args = make_args(&[("--verbose", 0), ("a.txt", 1), ("--name", 2), ("b.txt", 3)]); - let result = PositionalMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![1, 3]); -} - -#[test] -fn test_pos_all_only_flags_returns_empty() { - let info = PickerArgInfo::new(); - let args = make_args(&[("--a", 0), ("--b", 1)]); - let result = PositionalMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} - -#[test] -fn test_pos_all_empty() { - let info = PickerArgInfo::new(); - let args = vec![]; - let result = PositionalMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert!(result.is_empty()); -} - -// on_match_all — after `--` - -#[test] -fn test_pos_all_after_end_accepts_everything() { - // After `--`, even `--verbose` is accepted as positional. - let info = PickerArgInfo::new(); - let args = make_args(&[ - ("--verbose", 0), - ("a.txt", 1), - ("--", 2), - ("--flag", 3), - ("b.txt", 4), - ]); - let result = PositionalMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![1, 3, 4]); -} - -#[test] -fn test_pos_all_only_after_end() { - let info = PickerArgInfo::new(); - let args = make_args(&[("--", 0), ("arg1", 1), ("--arg2", 2)]); - let result = PositionalMatcher::on_match_all(&args, &UNIX_STYLE, &info); - assert_eq!(result, vec![1, 2]); -} - -// on_match_all — mixed before/after `--` - -#[test] -fn test_pos_all_mixed() { - let info = PickerArgInfo::new(); - let args = make_args(&[ - ("infile", 0), - ("--verbose", 1), - ("--", 2), - ("outfile", 3), - ("--extra", 4), - ]); - let result = PositionalMatcher::on_match_all(&args, &UNIX_STYLE, &info); - // Before `--`: "infile" (skip --verbose). - // After `--`: everything — "outfile", "--extra". - assert_eq!(result, vec![0, 3, 4]); -} diff --git a/mingling_picker/test/src/test/priority_test.rs b/mingling_picker/test/src/test/priority_test.rs deleted file mode 100644 index 8179389..0000000 --- a/mingling_picker/test/src/test/priority_test.rs +++ /dev/null @@ -1,85 +0,0 @@ -use mingling_picker::value::Flag; -use mingling_picker::{IntoPicker, macros::arg}; - -// Same flag name, different Pickable types -// -// PickerArgAttr priority: Flag < Single -// So Single and Multi should parse BEFORE Flag when sharing -// the same flag name. - -#[test] -fn test_single_takes_flag_when_sharing_name() { - // --name Alice: String consumes it, Flag sees nothing. - let (name, verbose): (String, Flag) = vec!["--name", "Alice"] - .to_picker() - .pick(&arg![name: String]) // Single, parsed first - .pick(&arg![name: Flag]) // Flag, parsed second, nothing left - .unwrap(); - assert_eq!(name, "Alice"); - assert_eq!(verbose, Flag::Inactive); -} - -#[test] -fn test_flag_only_triggers_when_single_missing() { - // --verbose: only Flag matches, String gets default. - let (name, verbose): (String, Flag) = vec!["--verbose"] - .to_picker() - .pick(&arg![name: String]) // Single, no match → default "" - .or_default() - .pick(&arg![name: Flag]) // Flag, no --name in args → Inactive - .unwrap(); - assert_eq!(name, ""); - assert_eq!(verbose, Flag::Inactive); -} - -#[test] -fn test_flag_gets_leftovers_after_single_consumes_value() { - // --name Alice --name: String takes "--name Alice", Flag takes "--name". - let (name, verbose): (String, Flag) = vec!["--name", "Alice", "--name"] - .to_picker() - .pick(&arg![name: String]) // Single: tag [0, 1], consumes --name Alice - .pick(&arg![name: Flag]) // Flag: tags position 2 (--name) - .unwrap(); - assert_eq!(name, "Alice"); - assert_eq!( - verbose, - Flag::Active, - "Flag should see --name at position 2 after String consumed positions 0-1" - ); -} - -#[test] -fn test_short_flag_sharing_same_letter() { - // -n Alice: String takes it, Flag misses. - let (name, verbose): (String, Flag) = vec!["-n", "Alice"] - .to_picker() - .pick(&arg![name: String, 'n']) // Single, parsed first - .pick(&arg![name: Flag, 'n']) // Flag, parsed second - .unwrap(); - assert_eq!(name, "Alice"); - assert_eq!(verbose, Flag::Inactive); -} - -#[test] -fn test_flag_captures_remaining_after_single_partial_consume() { - // --name Alice --verbose: String takes --name Alice, Flag takes --verbose. - let (name, verbose): (String, Flag) = vec!["--name", "Alice", "--verbose"] - .to_picker() - .pick(&arg![name: String]) // Single: tag [0, 1] - .pick(&arg![verbose: Flag]) // Flag: tag [2] - .unwrap(); - assert_eq!(name, "Alice"); - assert_eq!(verbose, Flag::Active); -} - -#[test] -fn test_single_skips_already_claimed_positions() { - // --verbose --name Alice: Flag takes --verbose, String takes --name Alice. - let (verbose, name): (Flag, String) = vec!["--verbose", "--name", "Alice"] - .to_picker() - .pick(&arg![verbose: Flag]) // Flag: tag [0] - .pick(&arg![name: String]) // Single: tag [1, 2] - .unwrap(); - assert_eq!(verbose, Flag::Active); - assert_eq!(name, "Alice"); -} diff --git a/mingling_picker/test/src/test/route_test.rs b/mingling_picker/test/src/test/route_test.rs deleted file mode 100644 index 9261db1..0000000 --- a/mingling_picker/test/src/test/route_test.rs +++ /dev/null @@ -1,200 +0,0 @@ -use mingling_picker::{IntoPicker, macros::arg}; - -// Route mechanism — or_route - -#[test] -fn test_or_route_triggered_to_result() { - // flag not present and no default value → route triggered → Err - let args: Vec<&str> = vec![]; - let result: Result<bool, &'static str> = args - .with_route::<&'static str>() - .pick(&arg![verbose: bool]) - .or_route(|| "missing_verbose") - .to_result(); - assert_eq!(result, Err("missing_verbose")); -} - -#[test] -fn test_or_route_not_triggered_when_flag_present() { - // flag present → route not triggered → Ok - let args = vec!["--verbose"]; - let result: Result<bool, &'static str> = args - .with_route::<&'static str>() - .pick(&arg![verbose: bool]) - .or_route(|| "missing_verbose") - .to_result(); - assert_eq!(result, Ok(true)); -} - -#[test] -fn test_or_default_priority_over_or_route() { - // or_default takes priority over or_route: even if the flag is absent, - // having a default prevents the route from being triggered - let args: Vec<&str> = vec![]; - let result: Result<bool, &'static str> = args - .with_route::<&'static str>() - .pick(&arg![verbose: bool]) - .or_default() - .or_route(|| "should_not_reach") - .to_result(); - assert_eq!(result, Ok(false)); -} - -#[test] -fn test_or_route_to_option_returns_none() { - // When route is triggered, to_option returns None - let args: Vec<&str> = vec![]; - let opt: Option<bool> = args - .with_route::<&'static str>() - .pick(&arg![verbose: bool]) - .or_route(|| "missing") - .to_option(); - assert_eq!(opt, None); -} - -#[test] -#[should_panic(expected = "called `Option::unwrap()` on a `None` value")] -fn test_or_route_unwrap_panics() { - let args: Vec<&str> = vec![]; - args.with_route::<&'static str>() - .pick(&arg![verbose: bool]) - .or_route(|| "missing") - .unwrap(); -} - -#[test] -fn test_or_route_with_string_route() { - // Route type is String - let args: Vec<&str> = vec![]; - let result: Result<bool, String> = args - .with_route::<String>() - .pick(&arg![verbose: bool]) - .or_route(|| "route_hit".to_string()) - .to_result(); - assert_eq!(result, Err("route_hit".to_string())); -} - -#[test] -fn test_or_route_with_custom_enum() { - // Route type is a custom enum - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[allow(dead_code)] - enum Redirect { - Help, - Version, - } - - let args: Vec<&str> = vec![]; - let result: Result<bool, Redirect> = args - .with_route::<Redirect>() - .pick(&arg![verbose: bool]) - .or_route(|| Redirect::Help) - .to_result(); - assert_eq!(result, Err(Redirect::Help)); -} - -// Route mechanism — multiple flags - -#[test] -fn test_two_flags_first_missing_triggers_route() { - // Both flags missing; first has or_route → Err("first"); - // first route wins (first-checked, first-triggered) - let args: Vec<&str> = vec![]; - let result: Result<(bool, bool), &'static str> = args - .with_route::<&'static str>() - .pick(&arg![flag_a: bool]) - .or_route(|| "first_missing") - .pick(&arg![flag_b: bool]) - .or_route(|| "second_missing") - .to_result(); - assert_eq!(result, Err("first_missing")); -} - -#[test] -fn test_two_flags_second_missing_triggers_route() { - // First has or_default (no route triggered), second missing with or_route → Err("second") - let args: Vec<&str> = vec![]; - let result: Result<(bool, bool), &'static str> = args - .with_route::<&'static str>() - .pick(&arg![flag_a: bool]) - .or_default() - .pick(&arg![flag_b: bool]) - .or_route(|| "second_missing") - .to_result(); - assert_eq!(result, Err("second_missing")); -} - -#[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 result: Result<(bool, bool), &'static str> = args - .with_route::<&'static str>() - .pick(&arg![flag_a: bool]) - .or_route(|| "first_missing") - .pick(&arg![flag_b: bool]) - .or_route(|| "second_missing") - .to_result(); - assert_eq!(result, Ok((true, true))); -} - -#[test] -fn test_two_flags_first_missing_no_route_second_has_route() { - // First missing but has no or_route, second missing with or_route → Err("second") - // Note: the first has neither route nor default, so pick failure does not modify error_route - let args: Vec<&str> = vec![]; - let result: Result<(bool, bool), &'static str> = args - .with_route::<&'static str>() - .pick(&arg![flag_a: bool]) - // No or_default, no or_route either - .pick(&arg![flag_b: bool]) - .or_route(|| "second_missing") - .to_result(); - assert_eq!(result, Err("second_missing")); -} - -#[test] -fn test_two_flags_only_second_has_default() { - // First is missing with no default/route (v1=NotFound), second is missing but has or_default - // Use unpack to check both results - let args: Vec<&str> = vec![]; - let (a, b) = args - .to_picker() - .pick(&arg![flag_a: bool]) - .pick(&arg![flag_b: bool]) - .or_default() - .unpack(); - assert_eq!(a, None); - assert_eq!(b, Some(false)); -} - -// Route with with_route - -#[test] -fn test_with_route_and_or_route() { - // with_route::<String>() sets the Route type + or_route triggers - let args: Vec<&str> = vec![]; - let result: Result<bool, String> = args - .with_route::<String>() - .pick(&arg![verbose: bool]) - .or_route(|| "redirected".to_string()) - .to_result(); - assert_eq!(result, Err("redirected".to_string())); -} - -#[test] -fn test_with_route_type_switch() { - // with_route switching Route type clears old route_$ and error_route - let args: Vec<&str> = vec![]; - let result: Result<(bool, bool), i32> = args - .with_route::<String>() - .pick(&arg![verbose: bool]) - .or_route(|| "string_route".to_string()) - .with_route::<i32>() - .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) - // The second flag is missing and has or_route → Err(-1) - assert_eq!(result, Err(-1)); -} diff --git a/mingling_picker/test/src/test/style_test.rs b/mingling_picker/test/src/test/style_test.rs deleted file mode 100644 index 3c337b9..0000000 --- a/mingling_picker/test/src/test/style_test.rs +++ /dev/null @@ -1,300 +0,0 @@ -use mingling_picker::PickerArgInfo; -use mingling_picker::parselib::{ - FlagMatcher, Matcher, POWERSHELL_STYLE, ParserStyle, ParserStyleNamingCase, UNIX_STYLE, - WINDOWS_STYLE, build_possible_flags, -}; - -use crate::make_masked; - -// Style: formatting utilities - -#[test] -fn test_unix_style_flag_string() { - assert_eq!(UNIX_STYLE.flag_string('v'), "-v"); - assert_eq!(UNIX_STYLE.flag_string("verbose"), "--verbose"); -} - -#[test] -fn test_windows_style_flag_string() { - assert_eq!(WINDOWS_STYLE.flag_string('v'), "/v"); - assert_eq!(WINDOWS_STYLE.flag_string("verbose"), "/verbose"); -} - -#[test] -fn test_powershell_style_flag_string() { - assert_eq!(POWERSHELL_STYLE.flag_string('v'), "-v"); - assert_eq!(POWERSHELL_STYLE.flag_string("Verbose"), "-Verbose"); -} - -#[test] -fn test_build_possible_flags_windows() { - // Build PickerArgInfo from a flag definition: `verbose: bool` - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - let flags = build_possible_flags(&WINDOWS_STYLE, &info); - assert_eq!(flags, vec!["/Verbose"]); -} - -#[test] -fn test_build_possible_flags_with_short_and_alias() { - let mut info = PickerArgInfo::new(); - info.set_short('n'); - info.set_long("name"); - info.set_alias(vec!["nickname"]); - let flags = build_possible_flags(&UNIX_STYLE, &info); - assert_eq!(flags, vec!["-n", "--name", "--nickname"]); -} - -// Style: matching with different styles via Matcher trait - -#[test] -fn test_windows_style_match() { - // Windows style: /verbose (case insensitive) - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - - let args = vec![make_masked("/verbose", 0)]; - let result = FlagMatcher::on_match_one(&args, &WINDOWS_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_windows_style_match_case_insensitive() { - // Windows style is case-insensitive: /VERBOSE should match "verbose" - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - - let args = vec![make_masked("/VERBOSE", 0)]; - let result = FlagMatcher::on_match_one(&args, &WINDOWS_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_windows_style_no_match_on_unrelated_flag() { - // Different flag should not match - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - - let args = vec![make_masked("/output", 0)]; - let result = FlagMatcher::on_match_one(&args, &WINDOWS_STYLE, &info); - assert_eq!(result, None); -} - -#[test] -fn test_powershell_style_match() { - // PowerShell style: -Verbose (case insensitive) - let mut info = PickerArgInfo::new(); - info.set_long("Verbose"); - - let args = vec![make_masked("-Verbose", 0)]; - let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_powershell_style_match_case_insensitive() { - let mut info = PickerArgInfo::new(); - info.set_long("Verbose"); - - let args = vec![make_masked("-VERBOSE", 0)]; - let result = FlagMatcher::on_match_one(&args, &POWERSHELL_STYLE, &info); - assert_eq!(result, Some(0)); -} - -#[test] -fn test_unix_style_case_sensitive_no_match() { - // UNIX style is case-sensitive: --VERBOSE should NOT match --verbose - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - - let args = vec![make_masked("--VERBOSE", 0)]; - let result = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!(result, None); -} - -#[test] -fn test_windows_style_match_all() { - // on_match_all should find all matching flags - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - info.set_short('v'); - - let args = vec![ - make_masked("/v", 0), - make_masked("/output", 1), - make_masked("/VERBOSE", 2), - ]; - let result = FlagMatcher::on_match_all(&args, &WINDOWS_STYLE, &info); - assert_eq!(result, vec![0, 2]); -} - -#[test] -fn test_windows_style_match_after_end_of_options() { - // end_of_options is always "--" regardless of style - // Flags after -- should not match - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - - let args = vec![ - make_masked("/verbose", 0), - make_masked("--", 1), - make_masked("/verbose", 2), - ]; - let result = FlagMatcher::on_match_all(&args, &WINDOWS_STYLE, &info); - // end_of_options is always "--" regardless of style - assert_eq!(result, vec![0]); -} - -// Naming case conversion - -/// A Unix-like style with kebab-case naming. -const KEBAB_STYLE: ParserStyle<'static> = ParserStyle { - naming_case: ParserStyleNamingCase::Kebab, - ..UNIX_STYLE -}; - -#[test] -fn test_kebab_case_naming_for_multiword_flag() { - // flag name `flag_a` → Kebab → `flag-a` → `--flag-a` - 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, &KEBAB_STYLE, &info); - assert_eq!( - result, - Some(0), - "--flag-a should match flag_a via kebab-case conversion" - ); -} - -#[test] -fn test_snake_case_should_not_match_as_long_flag() { - // With kebab naming, `--flag_a` (snake) should NOT match `flag_a` - 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, &KEBAB_STYLE, &info); - assert_eq!( - result, None, - "--flag_a should NOT match in kebab-style context" - ); -} - -#[test] -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 = FlagMatcher::on_match_one(&args, &UNIX_STYLE, &info); - assert_eq!( - result, - Some(0), - "--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" - ); -} - -#[test] -fn test_powershell_pascal_case_naming() { - // POWERSHELL_STYLE uses Pascal case: `verbose` → `Verbose` → `-Verbose` - let mut info = PickerArgInfo::new(); - info.set_long("verbose"); - - let args = vec![make_masked("-Verbose", 0)]; - 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 deleted file mode 100644 index d267a27..0000000 --- a/mingling_picker/test/src/test/value_flag_test.rs +++ /dev/null @@ -1,174 +0,0 @@ -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)); -} diff --git a/mingling_picker/test/src/test/value_string_test.rs b/mingling_picker/test/src/test/value_string_test.rs deleted file mode 100644 index b1e5c0b..0000000 --- a/mingling_picker/test/src/test/value_string_test.rs +++ /dev/null @@ -1,171 +0,0 @@ -use mingling_picker::{IntoPicker, macros::arg}; - -// Basic named String — present / absent - -#[test] -fn test_string_named_present() { - let val: String = vec!["--name", "Alice"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .unwrap(); - assert_eq!(val, "Alice"); -} - -#[test] -fn test_string_named_absent_uses_default() { - let val: String = Vec::<&str>::new() - .to_picker() - .pick(&arg![name: String]) - .or_default() - .unwrap(); - assert_eq!(val, ""); -} - -// Named String — eq mode - -#[test] -fn test_string_named_eq_mode() { - let val: String = vec!["--name=Alice"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .unwrap(); - assert_eq!(val, "Alice"); -} - -// Named String — short flag - -#[test] -fn test_string_named_short_flag() { - let val: String = vec!["-n", "Alice"] - .to_picker() - .pick(&arg![name: String, 'n']) - .or_default() - .unwrap(); - assert_eq!(val, "Alice"); -} - -// Named String — no value after flag - -#[test] -fn test_string_named_missing_value_triggers_default() { - // --name at end with no following arg → pick returns NotFound → or_default gives "" - let val: String = vec!["--name"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .unwrap(); - assert_eq!(val, ""); -} - -// Positional String - -#[test] -fn test_string_positional() { - let val: String = vec!["file.txt"] - .to_picker() - .pick(&arg![String]) - .or_default() - .unwrap(); - assert_eq!(val, "file.txt"); -} - -#[test] -fn test_string_positional_takes_first() { - let val: String = vec!["first", "second"] - .to_picker() - .pick(&arg![String]) - .or_default() - .unwrap(); - assert_eq!(val, "first"); -} - -// Multiple occurrences (Single only tags one occurrence per Parseable) - -#[test] -fn test_string_two_named_flags() { - let (a, b): (String, String) = vec!["--name", "Alice", "--greeting", "Hello"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .pick(&arg![greeting: String]) - .or_default() - .unwrap(); - assert_eq!(a, "Alice"); - assert_eq!(b, "Hello"); -} - -// Mixed named + positional - -#[test] -fn test_string_named_and_positional() { - let (name, file): (String, String) = vec!["--name", "Alice", "file.txt"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .pick(&arg![String]) - .or_default() - .unwrap(); - assert_eq!(name, "Alice"); - assert_eq!(file, "file.txt"); -} - -// After `--` (end-of-options) - -#[test] -fn test_string_named_after_end_of_options() { - // Named arg after `--` should not be matched → default - let val: String = vec!["--", "--name", "Alice"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .unwrap(); - assert_eq!(val, ""); -} - -// Unrelated flag should not match → default - -#[test] -fn test_string_unrelated_flag() { - let val: String = vec!["--other", "value"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .unwrap(); - assert_eq!(val, ""); -} - -// to_result / to_option - -#[test] -fn test_string_to_result() { - let result: Result<String, ()> = vec!["--name", "Alice"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .to_result(); - assert_eq!(result, Ok("Alice".to_string())); -} - -#[test] -fn test_string_to_option() { - let opt: Option<String> = vec!["--name", "Alice"] - .to_picker() - .pick(&arg![name: String]) - .or_default() - .to_option(); - assert_eq!(opt, Some("Alice".to_string())); -} - -// Custom default via .or() - -#[test] -fn test_string_custom_default() { - let val: String = Vec::<&str>::new() - .to_picker() - .pick(&arg![name: String]) - .or(|| "default_name".to_string()) - .unwrap(); - assert_eq!(val, "default_name"); -} |
