use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
const BIN: &str = env!("CARGO_BIN_EXE_doctrine");
fn git(dir: &Path, args: &[&str]) {
let out = Command::new("git")
.arg("-C")
.arg(dir)
.args(args)
.output()
.expect("spawn git");
assert!(
out.status.success(),
"git {args:?} failed: {}",
String::from_utf8_lossy(&out.stderr)
);
}
fn init_source(dir: &Path) -> PathBuf {
fs::create_dir_all(dir.join(".doctrine")).unwrap();
git(dir, &["init", "-q", "-b", "main"]);
git(dir, &["config", "user.email", "t@example.com"]);
git(dir, &["config", "user.name", "Test"]);
fs::write(dir.join(".doctrine/.keep"), "").unwrap();
git(dir, &["add", "."]);
git(dir, &["commit", "-q", "-m", "base"]);
fs::canonicalize(dir).unwrap()
}
fn add_worktree(source: &Path, fork: &Path) {
git(
source,
&[
"worktree",
"add",
"-q",
"-b",
"feat",
fork.to_str().unwrap(),
],
);
}
fn record(root: &Path) -> Output {
Command::new(BIN)
.args(["memory", "record", "--type", "fact", "A fact", "-p"])
.arg(root)
.output()
.expect("spawn doctrine")
}
#[test]
fn record_on_a_linked_worktree_warns_but_succeeds() {
let tmp = tempfile::tempdir().unwrap();
let source = init_source(&tmp.path().join("src"));
let fork = tmp.path().join("fork");
add_worktree(&source, &fork);
let fork = fs::canonicalize(&fork).unwrap();
let out = record(&fork);
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(out.status.success(), "record must still succeed: {stderr}");
assert!(
stderr.contains("worktree"),
"expected a worktree warning on stderr, got: {stderr}"
);
assert!(
fork.join(".doctrine/memory/items").is_dir(),
"the item must have been written"
);
}
#[test]
fn record_on_the_primary_tree_is_silent() {
let tmp = tempfile::tempdir().unwrap();
let source = init_source(&tmp.path().join("src"));
let out = record(&source);
let stderr = String::from_utf8_lossy(&out.stderr);
assert!(out.status.success(), "record must succeed: {stderr}");
assert!(
!stderr.contains("worktree"),
"the primary tree must record silently, got: {stderr}"
);
}