use clap::Parser;
use crate::cli::{Cli, Command, RepairAction, ServicesAction};
use crate::commands::session::compose_session_instructions;
#[test]
fn cli_parses_attach() {
let cli = Cli::try_parse_from(["trusty-mpm", "attach", "frontend"]).unwrap();
match cli.command {
Command::Attach { target, json } => {
assert_eq!(target, "frontend");
assert!(!json);
}
other => panic!("expected Attach, got {other:?}"),
}
}
#[test]
fn cli_parses_attach_with_json() {
let cli = Cli::try_parse_from(["trusty-mpm", "attach", "abc-123", "--json"]).unwrap();
match cli.command {
Command::Attach { target, json } => {
assert_eq!(target, "abc-123");
assert!(json);
}
other => panic!("expected Attach, got {other:?}"),
}
}
#[test]
fn cli_attach_requires_target() {
assert!(Cli::try_parse_from(["trusty-mpm", "attach"]).is_err());
}
#[test]
fn cli_parses_connect() {
let cli = Cli::try_parse_from(["trusty-mpm", "connect"]).unwrap();
match cli.command {
Command::Connect { dir } => assert_eq!(dir, None),
other => panic!("expected Connect, got {other:?}"),
}
}
#[test]
fn cli_parses_connect_with_dir() {
let cli = Cli::try_parse_from(["trusty-mpm", "connect", "/work/p"]).unwrap();
match cli.command {
Command::Connect { dir } => assert_eq!(dir.as_deref(), Some("/work/p")),
other => panic!("expected Connect, got {other:?}"),
}
}
#[test]
fn cli_sm_aliases_reach_coordinator() {
for name in ["coordinator", "sm", "session-manager", "coord"] {
let cli = Cli::try_parse_from(["trusty-mpm", name, "hello there"])
.unwrap_or_else(|e| panic!("`tm {name}` must parse: {e}"));
match cli.command {
Command::Coordinator { message, action } => {
assert_eq!(
message.as_deref(),
Some("hello there"),
"`tm {name}` carries the message"
);
assert!(action.is_none(), "a plain message has no subcommand");
}
other => panic!("`tm {name}` must be Command::Coordinator, got {other:?}"),
}
}
}
#[test]
fn cli_parses_sm_serve_stdio() {
use crate::cli::CoordinatorAction;
for name in ["coordinator", "sm", "session-manager", "coord"] {
let cli = Cli::try_parse_from(["trusty-mpm", name, "serve", "--stdio"])
.unwrap_or_else(|e| panic!("`tm {name} serve --stdio` must parse: {e}"));
match cli.command {
Command::Coordinator { message, action } => {
assert!(message.is_none(), "the serve subcommand carries no message");
match action {
Some(CoordinatorAction::Serve { stdio }) => {
assert!(stdio, "--stdio sets the stdio flag");
}
other => panic!("`tm {name} serve` must be Serve, got {other:?}"),
}
}
other => panic!("`tm {name} serve` must be Command::Coordinator, got {other:?}"),
}
}
}
#[test]
fn cli_parses_daemon_custom_addr() {
let cli = Cli::try_parse_from(["trusty-mpm", "daemon", "--addr", "0.0.0.0:9000"]).unwrap();
match cli.command {
Command::Daemon { addr, .. } => assert_eq!(addr.to_string(), "0.0.0.0:9000"),
other => panic!("expected Daemon, got {other:?}"),
}
}
#[test]
fn cli_parses_services_list() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "list"]).unwrap();
assert!(matches!(
cli.command,
Command::Services {
action: ServicesAction::List { json: false }
}
));
}
#[test]
fn cli_parses_services_list_json() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "list", "--json"]).unwrap();
assert!(matches!(
cli.command,
Command::Services {
action: ServicesAction::List { json: true }
}
));
}
#[test]
fn cli_parses_services_status() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "status", "trusty-search"]).unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Status { name, json },
} => {
assert_eq!(name, "trusty-search");
assert!(!json);
}
other => panic!("expected services status, got {other:?}"),
}
}
#[test]
fn cli_parses_services_status_json() {
let cli = Cli::try_parse_from([
"trusty-mpm",
"services",
"status",
"trusty-search",
"--json",
])
.unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Status { name, json },
} => {
assert_eq!(name, "trusty-search");
assert!(json);
}
other => panic!("expected services status --json, got {other:?}"),
}
}
#[test]
fn cli_parses_services_port() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "port", "trusty-search"]).unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Port { name },
} => assert_eq!(name, "trusty-search"),
other => panic!("expected services port, got {other:?}"),
}
}
#[test]
fn cli_parses_services_url() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "url", "trusty-search"]).unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Url { name },
} => assert_eq!(name, "trusty-search"),
other => panic!("expected services url, got {other:?}"),
}
}
#[test]
fn cli_parses_services_health() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "health", "trusty-search"]).unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Health { name },
} => assert_eq!(name, "trusty-search"),
other => panic!("expected services health, got {other:?}"),
}
}
#[test]
fn cli_parses_services_log() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "log", "trusty-search"]).unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Log { name },
} => assert_eq!(name, "trusty-search"),
other => panic!("expected services log, got {other:?}"),
}
}
#[test]
fn cli_parses_services_init() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "init"]).unwrap();
assert!(matches!(
cli.command,
Command::Services {
action: ServicesAction::Init { force: false }
}
));
}
#[test]
fn cli_parses_services_init_force() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "init", "--force"]).unwrap();
assert!(matches!(
cli.command,
Command::Services {
action: ServicesAction::Init { force: true }
}
));
}
#[test]
fn cli_parses_services_restart() {
let cli = Cli::try_parse_from(["trusty-mpm", "services", "restart", "trusty-search"]).unwrap();
match cli.command {
Command::Services {
action: ServicesAction::Restart { name },
} => assert_eq!(name, "trusty-search"),
other => panic!("expected services restart, got {other:?}"),
}
}
#[test]
fn compose_session_instructions_display_matches_stash() {
let tmp = tempfile::tempdir().unwrap();
let project = tmp.path();
let fw = trusty_mpm::core::paths::FrameworkPaths::default();
let (display, _output, stash_path) =
compose_session_instructions(&fw, project).expect("compose succeeds");
let on_disk =
std::fs::read_to_string(&stash_path).expect("stash file must be readable after compose");
assert_eq!(
display, on_disk,
"tm session instructions display must equal the stash file (issue #382)"
);
}
#[test]
fn compose_session_instructions_display_matches_live_prompt() {
let tmp = tempfile::tempdir().unwrap();
let project = tmp.path();
let fw = trusty_mpm::core::paths::FrameworkPaths::default();
let (display, _output, _stash) =
compose_session_instructions(&fw, project).expect("compose succeeds");
let live_prompt = trusty_mpm::core::session_launch::build_system_prompt_for(project);
assert_eq!(
display, live_prompt,
"tm session instructions output must match the live launch prompt (issue #382)"
);
}
#[test]
fn compose_session_instructions_display_matches_live_prompt_with_override() {
let tmp = tempfile::tempdir().unwrap();
let project = tmp.path();
let fw = trusty_mpm::core::paths::FrameworkPaths::default();
let override_dir = project.join(".trusty-mpm");
std::fs::create_dir_all(&override_dir).unwrap();
std::fs::write(
override_dir.join("WORKFLOW.md"),
"# Custom Workflow\n\nCOMPOSE_OVERRIDE_MARKER\n",
)
.unwrap();
let (display, _output, _stash) =
compose_session_instructions(&fw, project).expect("compose succeeds");
let live_prompt = trusty_mpm::core::session_launch::build_system_prompt_for(project);
assert_eq!(
display, live_prompt,
"display and live prompt must match with overrides present (issue #382)"
);
assert!(
display.contains("COMPOSE_OVERRIDE_MARKER"),
"override must be reflected in display"
);
assert!(
!display.contains("# PM Workflow Configuration"),
"bundled workflow must be replaced in display"
);
}
#[test]
fn cli_parses_daemon_mcp() {
let cli = Cli::try_parse_from(["trusty-mpm", "daemon", "--mcp"]).unwrap();
match cli.command {
Command::Daemon { mcp, .. } => assert!(mcp),
other => panic!("expected Daemon, got {other:?}"),
}
}
#[test]
fn cli_parses_repair_deploy() {
let cli = Cli::try_parse_from(["trusty-mpm", "repair", "deploy"]).unwrap();
match cli.command {
Command::Repair {
action: RepairAction::Deploy { force },
} => {
assert!(!force, "force must default to false");
}
other => panic!("expected Repair {{ Deploy }}, got {other:?}"),
}
}
#[test]
fn cli_parses_repair_deploy_force() {
let cli = Cli::try_parse_from(["trusty-mpm", "repair", "deploy", "--force"]).unwrap();
match cli.command {
Command::Repair {
action: RepairAction::Deploy { force },
} => {
assert!(force, "force must be true with --force flag");
}
other => panic!("expected Repair {{ Deploy {{ force: true }} }}, got {other:?}"),
}
}