use crate::support::{sandbox_with_plugin, stderr_of, stdout_of, Sandbox};
#[test]
fn with_no_plugins_it_exits_three_and_explains_itself() {
let sb = Sandbox::new();
sb.file("Cargo.toml");
let out = sb.run(&[]);
assert_eq!(
out.status.code(),
Some(3),
"no project type detected is exit code 3"
);
let err = stderr_of(&out);
assert!(err.contains("no project type detected"), "{err}");
assert!(
err.contains("look like"),
"it should state what it saw: {err}"
);
assert!(err.contains("rust"), "{err}");
assert!(
!err.contains("pmpx plugin add cargo"),
"it must not recommend a specific plugin: {err}"
);
assert!(err.contains(".pmpx.toml"), "{err}");
}
#[test]
fn exec_still_works_with_zero_plugins() {
let sb = Sandbox::new();
sb.file("Cargo.toml");
let out = sb.run(&["exec", "cargo", "--version"]);
assert!(
out.status.success(),
"it should succeed after degrading to passing through verbatim: {}",
stderr_of(&out)
);
assert!(stdout_of(&out).contains("cargo"), "{}", stdout_of(&out));
}
#[test]
fn detects_the_project_and_runs_the_backend_command() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
let out = sb.ok(&["build"]);
assert!(
out.contains("pmpx-probe"),
"the backend command should really run: {out}"
);
}
#[test]
fn the_plugin_receives_root_matched_verb_and_args_across_the_boundary() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
sb.file("fakepm.json");
let out = sb.ok(&["build"]);
let line = out
.lines()
.find(|l| l.contains("pmpx-probe"))
.unwrap_or_else(|| panic!("no echo came back: {out}"));
let got_root = line
.split_once("root=")
.and_then(|(_, rest)| rest.split_once(" matched="))
.map(|(root, _)| root)
.unwrap_or_else(|| panic!("the echo has no root=: {line}"));
let got = std::fs::canonicalize(got_root).unwrap_or_else(|e| {
panic!("the root the plugin received cannot be resolved ({got_root}): {e}")
});
let want = std::fs::canonicalize(&sb.project).expect("the sandbox directory should exist");
assert_eq!(got, want, "project_root was passed wrongly: {line}");
assert!(
line.contains("matched=fakepm.lock|fakepm.json"),
"matched is wrong (strong evidence should come first): {line}"
);
assert!(line.contains("verb=build"), "{line}");
assert!(line.contains("args="), "{line}");
}
#[test]
fn args_after_the_double_dash_reach_the_plugin() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
let out = sb.ok(&["test", "--", "--nocapture", "some-filter"]);
let line = out.lines().find(|l| l.contains("pmpx-probe")).unwrap();
assert!(line.contains("verb=test"), "{line}");
assert!(
line.contains("args=--nocapture,some-filter"),
"the arguments after `--` must go through verbatim: {line}"
);
}
#[test]
fn a_bare_pmpx_reports_the_selection() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
let out = sb.ok(&[]);
assert!(out.contains("Project root"), "{out}");
assert!(
out.contains("fakepm"),
"it should report the selected plugin: {out}"
);
}
#[test]
fn info_lists_every_candidate_and_score() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
let out = sb.ok(&["info"]);
assert!(out.contains("Candidates and scores"), "{out}");
assert!(out.contains("fakepm"), "{out}");
assert!(
out.contains("100"),
"strong evidence should be 100 points: {out}"
);
assert!(out.contains("compiled with"), "{out}");
assert!(out.contains("target"), "{out}");
}
#[test]
fn exec_falls_back_when_the_plugin_says_unsupported() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
let out = sb.run(&["exec", "cargo", "--version"]);
assert!(
out.status.success(),
"it should degrade to passing through verbatim when the plugin says unsupported: {}",
stderr_of(&out)
);
assert!(
stdout_of(&out).contains("cargo"),
"it should really have run cargo --version: {}",
stdout_of(&out)
);
}
#[test]
fn other_verbs_do_not_fall_back() {
let (_build, sb, _lib) = sandbox_with_plugin();
sb.file("fakepm.lock");
let out = sb.run(&["remove", "something"]);
assert_eq!(
out.status.code(),
Some(1),
"a plugin blowing up is exit code 1\nstderr: {}",
stderr_of(&out)
);
assert!(
stderr_of(&out).contains("fakepm"),
"it should say which plugin had the problem: {}",
stderr_of(&out)
);
}