//! Regression tests for bash-compatible invocation shapes reaching the shipped
//! binary. bash keeps parsing short options after `-c` and takes the command
//! from the first operand, so `nash -c -l <cmd>` must run `<cmd>` rather than
//! reject the invocation for a missing `-c` value.

use std::process::{Command, Output};

fn run(args: &[&str]) -> Output {
    Command::new(env!("CARGO_BIN_EXE_nash"))
        .args(args)
        .output()
        .expect("spawn nash")
}

fn stdout_of(args: &[&str]) -> String {
    let output = run(args);
    assert!(
        output.status.success(),
        "nash {args:?} failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    String::from_utf8_lossy(&output.stdout).into_owned()
}

#[test]
fn command_follows_short_flags_after_dash_c() {
    assert_eq!(
        stdout_of(&["--noprofile", "--norc", "-c", "-l", "echo hi"]),
        "hi\n"
    );
}

#[test]
fn command_follows_several_short_flags_after_dash_c() {
    assert_eq!(
        stdout_of(&["--noprofile", "--norc", "-c", "-e", "-u", "echo hi"]),
        "hi\n"
    );
}

#[test]
fn short_flags_after_dash_c_still_take_effect() {
    // `-u` is hoisted ahead of `-c`, so the unset expansion must still fail.
    let output = run(&["--noprofile", "--norc", "-c", "-u", "echo ${undefined_var}"]);
    assert!(!output.status.success());
}

#[test]
fn positional_args_survive_short_flags_after_dash_c() {
    assert_eq!(
        stdout_of(&["--noprofile", "--norc", "-c", "-l", "echo $0", "myzero"]),
        "myzero\n"
    );
}

#[test]
fn combined_dash_lc_still_works() {
    assert_eq!(stdout_of(&["--noprofile", "--norc", "-lc", "echo hi"]), "hi\n");
}
