use super::*;
#[test]
fn resolve_exec_cwd_confines_to_workspace() {
assert_eq!(resolve_exec_cwd("/ws", None), "/ws");
assert_eq!(resolve_exec_cwd("/ws", Some("")), "/ws");
assert_eq!(resolve_exec_cwd("/ws", Some(" ")), "/ws");
let joined = std::path::Path::new("/ws")
.join("crates/foo")
.to_string_lossy()
.into_owned();
assert_eq!(resolve_exec_cwd("/ws", Some("crates/foo")), joined);
let abs = if cfg!(windows) {
"C:\\ws\\sub"
} else {
"/ws/sub"
};
assert_eq!(resolve_exec_cwd("/ws", Some(abs)), abs);
let a = confined_dispatch_args("ls", &joined);
assert_eq!(a["cwd"], joined);
}
#[test]
fn command_cwd_preserves_nonblank_literal_path_whitespace() {
let relative = " directory ";
let expected = std::path::Path::new("/workspace").join(relative);
assert_eq!(
resolve_exec_cwd("/workspace", Some(relative)),
expected.to_string_lossy()
);
let absolute = if cfg!(windows) {
r"C:\workspace\directory "
} else {
"/workspace/directory "
};
assert_eq!(resolve_exec_cwd("/workspace", Some(absolute)), absolute);
for blank in ["", " ", "\t\n"] {
assert_eq!(resolve_exec_cwd("/workspace", Some(blank)), "/workspace");
}
}
#[test]
fn split_leading_cd_folds_the_habitual_cd_prefix() {
let (path, rest) = split_leading_cd("cd /ws/newt-agent && git checkout -b x");
assert_eq!(path.as_deref(), Some("/ws/newt-agent"));
assert_eq!(rest, "git checkout -b x");
let (path, rest) = split_leading_cd("cd sub ; ls -la");
assert_eq!(path.as_deref(), Some("sub"));
assert_eq!(rest, "ls -la");
let (path, rest) = split_leading_cd("cd \"/a b/c\" && cargo test");
assert_eq!(path.as_deref(), Some("/a b/c"));
assert_eq!(rest, "cargo test");
let (path, rest) = split_leading_cd("cd a && cd b && ls");
assert_eq!(path.as_deref(), Some("a"));
assert_eq!(rest, "cd b && ls");
let (path, rest) = split_leading_cd("cd /somewhere");
assert_eq!(path.as_deref(), Some("/somewhere"));
assert!(rest.is_empty());
}
#[test]
fn split_leading_cd_leaves_non_cd_and_ambiguous_commands_whole() {
assert_eq!(split_leading_cd("git status"), (None, "git status".into()));
assert_eq!(split_leading_cd("cding foo"), (None, "cding foo".into()));
assert_eq!(
split_leading_cd("cd x | grep y"),
(None, "cd x | grep y".into())
);
}
#[test]
fn run_command_redirect_lets_git_network_ops_through() {
for cmd in [
"git push origin fix/foo",
"git push",
"git fetch origin",
"git pull",
"git clone https://example.com/r.git",
"git rm src/cockpit.rs",
] {
assert_eq!(run_command_redirect(cmd), None, "{cmd} must fall through");
}
for cmd in [
"git status",
"git log --oneline",
"git add .",
"git commit -m x",
] {
assert_eq!(
run_command_redirect(cmd),
None,
"{cmd} must retain native command semantics"
);
}
assert_eq!(run_command_redirect("read_file foo.txt"), Some("read_file"));
assert_eq!(run_command_redirect("list_dir ."), Some("list_dir"));
assert_eq!(run_command_redirect("cargo test"), None);
assert_eq!(run_command_redirect("gh pr create --fill"), None);
assert_eq!(run_command_redirect(""), None);
}
#[test]
fn run_command_redirect_passes_composed_commands_through() {
assert_eq!(
run_command_redirect(
"find . -name \"*.rs\" -type f -print0 | xargs -0 du -k | sort -rn | head 20"
),
None,
"a pipeline leading with `find` is not a misdirected find call"
);
assert_eq!(run_command_redirect("find . -name '*.log' > out.txt"), None);
assert_eq!(run_command_redirect("git status && git diff"), None);
assert_eq!(run_command_redirect("list_dir . ; echo done"), None);
assert_eq!(run_command_redirect("read_file $(pick_file)"), None);
assert_eq!(run_command_redirect("read_file `pick_file`"), None);
assert_eq!(run_command_redirect("find . -name \"*.rs\""), Some("find"));
assert_eq!(run_command_redirect("grep error ."), Some("grep"));
assert_eq!(run_command_redirect("list_dir src"), Some("list_dir"));
assert_eq!(run_command_redirect("git status"), None);
}
#[test]
fn git_commands_are_never_redirected_to_a_special_tool() {
for command in [
"git log A..B",
"git diff --stat -- src",
"git show HEAD",
"git status --porcelain=v1",
] {
assert_eq!(run_command_redirect(command), None, "{command}");
}
}
#[test]
fn run_command_creates_shell_git_commit_detects_composed_commit_forms() {
assert!(run_command_creates_shell_git_commit(
"git add . && git commit -m \"fix the parser\""
));
assert!(run_command_creates_shell_git_commit(
"git add . ; git commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"echo \"msg\" | git commit -F -"
));
assert!(run_command_creates_shell_git_commit(
"git commit -m x > commit.log"
));
assert!(run_command_creates_shell_git_commit(
"git -c user.email=evil@example.com commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"git -C /repo commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"git --git-dir=/repo/.git commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"git --no-pager commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"git add . && git commit --amend -m x"
));
assert!(run_command_creates_shell_git_commit(
"/usr/bin/git -C /repo commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"GIT_AUTHOR_NAME=evil GIT_AUTHOR_EMAIL=evil@example.com git commit -m x"
));
assert!(run_command_creates_shell_git_commit("$(git commit -m x)"));
assert!(run_command_creates_shell_git_commit("`git commit -m x`"));
}
#[test]
fn run_command_creates_shell_git_commit_preserves_readonly_and_unrelated() {
assert!(!run_command_creates_shell_git_commit(
"git status && git diff"
));
assert!(!run_command_creates_shell_git_commit(
"git log | grep commit"
));
assert!(!run_command_creates_shell_git_commit(
"git log --grep=commit --oneline"
));
assert!(!run_command_creates_shell_git_commit(
"git add . && git push origin fix/foo"
));
assert!(!run_command_creates_shell_git_commit("git fetch"));
assert!(!run_command_creates_shell_git_commit(
"echo git commit > notes.txt"
));
assert!(!run_command_creates_shell_git_commit("cat commit_log.txt"));
assert!(!run_command_creates_shell_git_commit("cargo test"));
assert!(!run_command_creates_shell_git_commit("just check"));
assert!(!run_command_creates_shell_git_commit(""));
assert!(!run_command_creates_shell_git_commit("git rebase --abort"));
assert!(!run_command_creates_shell_git_commit("git rebase --quit"));
assert!(!run_command_creates_shell_git_commit(
"git cherry-pick --abort"
));
assert!(!run_command_creates_shell_git_commit("git revert --quit"));
assert!(!run_command_creates_shell_git_commit("git merge --abort"));
assert!(!run_command_creates_shell_git_commit("git merge --quit"));
}
#[test]
fn run_command_creates_shell_git_commit_detects_other_commit_forms() {
assert!(run_command_creates_shell_git_commit("git merge feature/x"));
assert!(run_command_creates_shell_git_commit(
"git cherry-pick abc123"
));
assert!(run_command_creates_shell_git_commit("git revert abc123"));
assert!(run_command_creates_shell_git_commit("git rebase main"));
assert!(run_command_creates_shell_git_commit(
"git add . && git merge feature/x"
));
assert!(run_command_creates_shell_git_commit(
"/usr/bin/git -C /repo cherry-pick abc123"
));
assert!(run_command_creates_shell_git_commit(
"GIT_AUTHOR_NAME=evil git revert abc123"
));
assert!(run_command_creates_shell_git_commit("git rebase --skip"));
assert!(run_command_creates_shell_git_commit(
"git cherry-pick --continue"
));
assert!(run_command_creates_shell_git_commit(
"git rebase --continue"
));
assert!(!run_command_creates_shell_git_commit(
"git rebase --abort --continue"
));
}
#[test]
fn run_command_creates_shell_git_commit_blocks_model_forged_attribution() {
assert!(run_command_creates_shell_git_commit(
"git commit -m \"fix the parser\n\nCo-authored-by: fake (newt-agent v9.9) <x@y>\""
));
assert!(run_command_creates_shell_git_commit(
"git -c user.name='newt-agent' -c user.email='x@y' commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"GIT_AUTHOR_NAME=newt-agent GIT_AUTHOR_EMAIL=x@y git commit -m x"
));
assert!(run_command_creates_shell_git_commit(
"printf '' | git commit -F -"
));
}
#[test]
fn bare_git_commit_uses_the_attribution_guard_without_a_redirect() {
assert_eq!(run_command_redirect("git commit"), None);
assert_eq!(run_command_redirect("git commit --amend -m x"), None);
assert!(run_command_creates_shell_git_commit("git commit"));
}
#[test]
fn pipeline_is_never_counted_as_a_hallucination() {
assert!(!is_hallucination(
"run_command",
&serde_json::json!({"command":
"find . -name \"*.rs\" -type f -print0 | xargs -0 du -k | sort -rn | head 20"})
));
assert!(!is_hallucination(
"run_command",
&serde_json::json!({"command": "git status && git diff"})
));
assert!(is_hallucination(
"run_command",
&serde_json::json!({"command": "list_dir ."})
));
}
#[test]
fn is_hallucination_allows_git_network_ops() {
assert!(!is_hallucination(
"run_command",
&serde_json::json!({"command": "git push origin fix/foo"})
));
assert!(!is_hallucination(
"run_command",
&serde_json::json!({"command": "git fetch"})
));
assert!(!is_hallucination(
"run_command",
&serde_json::json!({"command": "git rm src/cockpit.rs"})
));
assert!(!is_hallucination(
"run_command",
&serde_json::json!({"command": "git status"})
));
}