use assert_cmd::Command;
use predicates::prelude::*;
#[test]
fn help_lists_legacy_and_scriptable_interfaces() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("--continue"))
.stdout(predicate::str::contains("--allow-adult"))
.stdout(predicate::str::contains("--update"))
.stdout(predicate::str::contains("anikoto2"));
}
#[test]
fn invalid_mode_fails_before_network_for_episodes() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["episodes", "show", "--mode", "invalid"])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid input"));
}
#[test]
fn download_help_distinguishes_show_ids_from_titles() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["download", "--help"])
.assert()
.success()
.stdout(predicate::str::contains("not an anime title"));
}
#[test]
fn help_documents_provider_selection() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("--provider"))
.stdout(predicate::str::contains("ANI_CLI_RS_PROVIDER"));
}
#[test]
fn removed_allanime_provider_is_rejected() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["--provider", "allanime", "search", "example"])
.assert()
.failure()
.stderr(predicate::str::contains(
"invalid value 'allanime' for '--provider <PROVIDER>'",
));
}
#[test]
fn invalid_default_anikoto_ids_fail_before_network() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["--provider", "anikoto", "episodes", "not-a-valid-id"])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid input"));
}
#[test]
fn environment_can_select_anikoto() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.env("ANI_CLI_PROVIDER", "anikoto2")
.args(["episodes", "not a slug"])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid input"));
}
#[test]
fn prefixed_ids_auto_route_to_anikoto() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["episodes", "anikoto:not-base64"])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid input"));
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["episodes", "anikoto2:not-base64"])
.assert()
.failure()
.stderr(predicate::str::contains("Invalid input"));
}
#[test]
fn showcase_search_is_fixture_backed_and_hidden_from_help() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["--demo-mode", "--provider", "anikoto", "search", "starfall"])
.assert()
.success()
.stdout(predicate::str::contains(
"anikoto:showcase-starfall-atelier\tStarfall Atelier (12 episodes)",
));
Command::cargo_bin("ani-cli-rs")
.unwrap()
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains("--demo-mode").not());
}
#[test]
fn showcase_exposes_deterministic_episodes_and_quality_metadata() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args([
"--demo-mode",
"episodes",
"showcase:starfall-atelier",
"--json",
])
.assert()
.success()
.stdout(predicate::str::contains("\"1\""))
.stdout(predicate::str::contains("\"12\""));
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args([
"--demo-mode",
"--provider",
"anikoto",
"links",
"anikoto:showcase-starfall-atelier",
"1",
"--quality",
"720p",
"--json",
])
.assert()
.success()
.stdout(predicate::str::contains("\"resolution\": \"720p\""))
.stdout(predicate::str::contains("\"label\": \"English\""))
.stdout(predicate::str::contains("showcase.invalid"));
}
#[test]
fn showcase_adult_filter_is_explicit() {
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["--demo-mode", "search", "velvet"])
.assert()
.success()
.stdout(predicate::str::is_empty());
Command::cargo_bin("ani-cli-rs")
.unwrap()
.args(["--demo-mode", "search", "velvet", "--allow-adult"])
.assert()
.success()
.stdout(predicate::str::contains("Velvet Nebula"));
}