#![allow(clippy::unwrap_used, clippy::expect_used)]
mod helpers;
use std::collections::BTreeSet;
use git_meta_lib::*;
use helpers::*;
#[test]
fn get_nonexistent_key_returns_none() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::project();
let handle = session.target(&target);
let value = handle.get_value("does:not:exist").unwrap();
assert!(value.is_none());
}
#[test]
fn remove_nonexistent_key_returns_false() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::project();
let handle = session.target(&target);
let removed = handle.remove("nonexistent").unwrap();
assert!(!removed, "removing a nonexistent key should return false");
}
#[test]
fn set_remove_then_re_add() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::path("src/metrics");
let handle = session.target(&target);
handle.set_add("owners", "alice").unwrap();
handle.set_add("owners", "bob").unwrap();
handle.set_remove("owners", "alice").unwrap();
let value = handle.get_value("owners").unwrap().unwrap();
if let MetaValue::Set(members) = &value {
assert_eq!(members.len(), 1);
assert!(members.contains("bob"));
} else {
panic!("expected Set");
}
handle.set_add("owners", "alice").unwrap();
let value = handle.get_value("owners").unwrap().unwrap();
if let MetaValue::Set(members) = &value {
assert_eq!(members.len(), 2);
assert!(members.contains("alice"));
assert!(members.contains("bob"));
} else {
panic!("expected Set");
}
}
#[test]
fn authorship_tracks_writer() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::project();
let handle = session.target(&target);
handle.set("tracked:key", "some-value").unwrap();
let authorship = handle.get_authorship("tracked:key").unwrap();
assert!(authorship.is_some(), "authorship should exist after set");
let authorship = authorship.unwrap();
assert_eq!(authorship.email, "test@example.com");
}
#[test]
fn key_prefix_matching_returns_subkeys() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::project();
let handle = session.target(&target);
handle.set("agent:model", "claude").unwrap();
handle.set("agent:provider", "anthropic").unwrap();
handle.set("other:key", "unrelated").unwrap();
let agent_values = handle.get_all_values(Some("agent")).unwrap();
assert_eq!(
agent_values.len(),
2,
"should return only agent:* keys, got: {:?}",
agent_values
.iter()
.map(|(k, _)| k.as_str())
.collect::<Vec<_>>()
);
let keys: BTreeSet<String> = agent_values.iter().map(|(k, _)| k.clone()).collect();
assert!(keys.contains("agent:model"));
assert!(keys.contains("agent:provider"));
assert!(!keys.contains("other:key"));
let model_values = handle.get_all_values(Some("agent:model")).unwrap();
assert_eq!(model_values.len(), 1);
assert_eq!(model_values[0].0, "agent:model");
let all_values = handle.get_all_values(None).unwrap();
assert_eq!(all_values.len(), 3);
}
#[test]
fn namespaced_keys_work_correctly() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::project();
let handle = session.target(&target);
handle.set("agent:claude:session:id", "sess-123").unwrap();
handle.set("agent:claude:session:model", "opus").unwrap();
handle
.set("agent:claude:prompt", "make a sandwich")
.unwrap();
let session_values = handle.get_all_values(Some("agent:claude:session")).unwrap();
assert_eq!(session_values.len(), 2);
let keys: BTreeSet<String> = session_values.iter().map(|(k, _)| k.clone()).collect();
assert!(keys.contains("agent:claude:session:id"));
assert!(keys.contains("agent:claude:session:model"));
let agent_values = handle.get_all_values(Some("agent")).unwrap();
assert_eq!(agent_values.len(), 3);
}
#[test]
fn multiple_targets_are_independent() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target_a = Target::branch("branch-a");
let target_b = Target::branch("branch-b");
session.target(&target_a).set("status", "draft").unwrap();
session.target(&target_b).set("status", "ready").unwrap();
assert_eq!(
session.target(&target_a).get_value("status").unwrap(),
Some(MetaValue::String("draft".to_string()))
);
assert_eq!(
session.target(&target_b).get_value("status").unwrap(),
Some(MetaValue::String("ready".to_string()))
);
}
#[test]
fn list_remove_by_index() {
let (_dir, repo) = setup_repo();
let session = open_session(repo);
let target = Target::project();
let handle = session.target(&target);
handle.list_push("items", "a").unwrap();
handle.list_push("items", "b").unwrap();
handle.list_push("items", "c").unwrap();
handle.list_remove("items", 1).unwrap();
let entries = handle.list_entries("items").unwrap();
assert_eq!(entries.len(), 2);
assert_eq!(entries[0].value, "a");
assert_eq!(entries[1].value, "c");
}