use super::super::{ArchiveError, bundle};
use super::{AGENT, REFS, StubGit, tmp, write, ws_tmp};
use crate::workspace;
use std::fs;
#[test]
fn bundle_writes_bundle_and_matching_slices() {
let ws = ws_tmp();
write(&ws.path().join("steps/20260101-p1/001/meta.json"), "{}");
write(&ws.path().join("steps/20260101-other/001/meta.json"), "{}");
let out = tmp();
let git = StubGit::new(REFS);
bundle(ws.path(), AGENT, out.path(), &git).unwrap();
let runs = git.runs.borrow();
assert_eq!(runs[0][0], "bundle");
assert_eq!(runs[0][1], "create");
assert!(runs[0].contains(&"agents/20260101-p1".to_owned()));
assert!(runs[0].contains(&"agents/20260101-p1-20260102-c1".to_owned()));
assert!(runs[0].contains(&"refs/heads/config/default".to_owned()));
assert!(runs[0].contains(&"refs/heads/config/strict".to_owned()));
assert!(out.path().join("steps/20260101-p1/001/meta.json").exists());
assert!(!out.path().join("steps/20260101-other").exists());
assert!(!out.path().join("inbox").exists());
}
#[test]
fn bundle_rejects_unknown_agent() {
let ws = ws_tmp();
let out = tmp();
let git = StubGit::new(""); let err = bundle(ws.path(), AGENT, out.path(), &git).unwrap_err();
assert!(
matches!(err, ArchiveError::UnknownAgent(ref a) if a == AGENT),
"{err:?}"
);
}
#[test]
fn bundle_surfaces_branch_list_failure() {
let ws = ws_tmp();
let out = tmp();
let git = StubGit::new(REFS).fail_capture();
let err = bundle(ws.path(), AGENT, out.path(), &git).unwrap_err();
assert!(
matches!(
err,
ArchiveError::Git {
op: "branch --list",
..
}
),
"{err:?}"
);
}
#[test]
fn bundle_surfaces_bundle_create_failure() {
let ws = ws_tmp();
let out = tmp();
let git = StubGit::new(REFS).fail_run_at(0);
let err = bundle(ws.path(), AGENT, out.path(), &git).unwrap_err();
assert!(
matches!(
err,
ArchiveError::Git {
op: "bundle create",
..
}
),
"{err:?}"
);
}
#[test]
fn bundle_carries_only_config_lineages_that_reach_the_subtree() {
let ws = ws_tmp();
let out = tmp();
let git = StubGit::new(REFS).no_lineage();
bundle(ws.path(), AGENT, out.path(), &git).unwrap();
let runs = git.runs.borrow();
assert!(!runs[0].iter().any(|a| a.starts_with("refs/heads/config/")));
}
#[test]
fn bundle_surfaces_a_lineage_enumeration_failure() {
let ws = ws_tmp();
let out = tmp();
let git = StubGit::new(REFS).fail_lineage();
let err = bundle(ws.path(), AGENT, out.path(), &git).unwrap_err();
assert!(
matches!(
err,
ArchiveError::Git {
op: "config lineage",
..
}
),
"{err:?}"
);
}
#[test]
fn bundle_refuses_the_retired_layout_with_an_actionable_error() {
let ws = tmp();
fs::create_dir_all(ws.path().join("root/.git")).unwrap();
let out = tmp();
let git = StubGit::new(REFS);
let err = bundle(ws.path(), AGENT, out.path(), &git).unwrap_err();
let msg = err.to_string();
assert!(
matches!(
err,
ArchiveError::Layout(workspace::LayoutError::OldLayout(_))
),
"{err:?}"
);
assert!(msg.contains("retired per-conversation layout"), "{msg}");
assert!(msg.contains("lernie new"), "{msg}");
assert!(
git.runs.borrow().is_empty(),
"guard must precede any git op"
);
}
#[test]
fn bundle_refuses_a_non_workspace() {
let ws = tmp(); let out = tmp();
let git = StubGit::new(REFS);
let err = bundle(ws.path(), AGENT, out.path(), &git).unwrap_err();
assert!(
matches!(
err,
ArchiveError::Layout(workspace::LayoutError::NotAWorkspace(_))
),
"{err:?}"
);
assert!(err.to_string().contains("lernie new"), "{err}");
}