use super::*;
fn args(items: &[&str]) -> Vec<String> {
items.iter().map(|s| s.to_string()).collect()
}
#[test]
fn exact_short_no_value() {
let mut idx = 0;
let argv = args(&["neomacs", "-nw"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::Bare,
);
assert_eq!(idx, 1);
}
#[test]
fn exact_long_no_value() {
let mut idx = 0;
let argv = args(&["neomacs", "--no-window-system"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::Bare,
);
assert_eq!(idx, 1);
}
#[test]
fn long_prefix_meets_minlen() {
let mut idx = 0;
let argv = args(&["neomacs", "--no-w"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::Bare,
);
assert_eq!(idx, 1);
}
#[test]
fn long_form_distinct_aliases_need_separate_calls() {
let mut idx = 0;
let argv = args(&["neomacs", "--no-windows"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::NoMatch,
);
assert_eq!(idx, 0);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-windows"), 6, false),
ArgMatch::Bare,
);
assert_eq!(idx, 1);
}
#[test]
fn long_prefix_below_minlen_does_not_match() {
let mut idx = 0;
let argv = args(&["neomacs", "--no"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::NoMatch,
);
assert_eq!(idx, 0);
}
#[test]
fn long_with_value_inline_eq() {
let mut idx = 0;
let argv = args(&["neomacs", "--temacs=pdump"]);
assert_eq!(
argmatch(&argv, &mut idx, "-temacs", Some("--temacs"), 8, true),
ArgMatch::Value("pdump".to_string()),
);
assert_eq!(idx, 1);
}
#[test]
fn long_with_value_separate_token() {
let mut idx = 0;
let argv = args(&["neomacs", "--chdir", "/tmp"]);
assert_eq!(
argmatch(&argv, &mut idx, "-chdir", Some("--chdir"), 4, true),
ArgMatch::Value("/tmp".to_string()),
);
assert_eq!(idx, 2);
}
#[test]
fn short_with_value_separate_token() {
let mut idx = 0;
let argv = args(&["neomacs", "-t", "/dev/pts/3"]);
assert_eq!(
argmatch(&argv, &mut idx, "-t", Some("--terminal"), 4, true),
ArgMatch::Value("/dev/pts/3".to_string()),
);
assert_eq!(idx, 2);
}
#[test]
fn missing_value_at_eof_signals_explicitly() {
let mut idx = 0;
let argv = args(&["neomacs", "--chdir"]);
assert_eq!(
argmatch(&argv, &mut idx, "-chdir", Some("--chdir"), 4, true),
ArgMatch::MissingValue,
);
assert_eq!(idx, 0);
}
#[test]
fn no_match_leaves_idx_untouched() {
let mut idx = 0;
let argv = args(&["neomacs", "--unrelated"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::NoMatch,
);
assert_eq!(idx, 0);
}
#[test]
fn empty_argv_returns_no_match() {
let mut idx = 0;
let argv = args(&["neomacs"]);
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::NoMatch,
);
assert_eq!(idx, 0);
}
#[test]
fn long_form_only_short_unset() {
let mut idx = 0;
let argv = args(&["neomacs", "-display"]);
assert_eq!(
argmatch(&argv, &mut idx, "-display", None, 0, false),
ArgMatch::Bare,
);
assert_eq!(idx, 1);
}
#[test]
fn idx_threading_walks_argv_one_match_at_a_time() {
let argv = args(&["neomacs", "-nw", "--batch"]);
let mut idx = 0;
assert_eq!(
argmatch(&argv, &mut idx, "-nw", Some("--no-window-system"), 6, false),
ArgMatch::Bare,
);
assert_eq!(idx, 1);
assert_eq!(
argmatch(&argv, &mut idx, "-batch", Some("--batch"), 5, false),
ArgMatch::Bare,
);
assert_eq!(idx, 2);
}
#[test]
fn sort_args_keeps_program_name_at_index_zero() {
let mut argv = args(&["neomacs"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs"]);
}
#[test]
fn sort_args_brings_high_priority_options_before_files() {
let mut argv = args(&["neomacs", "file.txt", "--no-splash"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "--no-splash", "file.txt"]);
}
#[test]
fn sort_args_respects_priority_ordering_among_options() {
let mut argv = args(&["neomacs", "-L", "/lib", "--no-splash", "-nw"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "-nw", "--no-splash", "-L", "/lib"]);
}
#[test]
fn sort_args_keeps_option_value_pairs_glued() {
let mut argv = args(&["neomacs", "-L", "/usr/lib", "-nw"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "-nw", "-L", "/usr/lib"]);
}
#[test]
fn sort_args_dedupes_zero_arg_duplicate_options() {
let mut argv = args(&["neomacs", "-nw", "-nw"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "-nw"]);
}
#[test]
fn sort_args_does_not_dedupe_value_taking_options() {
let mut argv = args(&["neomacs", "-L", "/a", "-L", "/b"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "-L", "/a", "-L", "/b"]);
}
#[test]
fn sort_args_stable_within_equal_priority() {
let mut argv = args(&["neomacs", "-bd", "blue", "-fg", "white", "-bg", "black"]);
sort_args(&mut argv).unwrap();
assert_eq!(
argv,
vec!["neomacs", "-bd", "blue", "-fg", "white", "-bg", "black",]
);
}
#[test]
fn sort_args_long_form_inline_value_collapses_nargs() {
let mut argv = args(&["neomacs", "file.el", "--temacs=pdump"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "--temacs=pdump", "file.el"]);
}
#[test]
fn sort_args_double_dash_terminator_pins_remaining_args_to_end() {
let mut argv = args(&["neomacs", "--", "literal-arg", "-nw"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "--", "literal-arg", "-nw"]);
}
#[test]
fn sort_args_kill_sinks_to_the_end() {
let mut argv = args(&["neomacs", "-kill", "file.txt"]);
sort_args(&mut argv).unwrap();
assert_eq!(argv, vec!["neomacs", "file.txt", "-kill"]);
}
#[test]
fn sort_args_missing_value_returns_error() {
let mut argv = args(&["neomacs", "-L"]);
let err = sort_args(&mut argv).unwrap_err();
assert!(err.contains("'-L'"), "error message: {err}");
assert!(err.contains("requires an argument"));
}
#[test]
fn sort_args_unknown_flag_treated_as_plain_arg() {
let mut argv = args(&["neomacs", "--no-splash", "--unknown", "file.txt"]);
sort_args(&mut argv).unwrap();
assert_eq!(
argv,
vec!["neomacs", "--no-splash", "--unknown", "file.txt"]
);
}