test: boost coverage to 76% and optimize Store inspection

This commit is contained in:
Riz Ashraf committed 2026-09-18 09:49:19 +01:00
1 parent 81aac7245b
commit 26cf6cee80
3 files changed
+340 -1

No files matched your search

+330
View File
@@ -2690,4 +2690,334 @@ mod tests {
let tasks = handler.state.tasks.read();
assert_eq!(tasks[0].status, "in_progress");
}
#[tokio::test]
async fn test_handle_pin_file() {
let handler = setup_test_handler("pin_file");
let req = json!({
"jsonrpc": "2.0",
"id": 100,
"method": "tools/call",
"params": {
"name": "pin_file",
"arguments": {
"file_path": "/path/to/pinned.rs",
"namespace": "global"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let pinned = handler.state.pinned_files.read();
assert!(pinned.iter().any(|p| p.file_path == "/path/to/pinned.rs"));
}
#[tokio::test]
async fn test_handle_unpin_file() {
let handler = setup_test_handler("unpin_file");
handler.state.pinned_files.modify(|files| {
files.push(crate::models::PinnedFile {
namespace: "global".to_string(),
file_path: "/path/to/unpin.rs".to_string(),
timestamp: 0,
git_branch: None,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 101,
"method": "tools/call",
"params": {
"name": "unpin_file",
"arguments": {
"file_path": "/path/to/unpin.rs",
"namespace": "global"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let pinned = handler.state.pinned_files.read();
assert!(!pinned.iter().any(|p| p.file_path == "/path/to/unpin.rs"));
}
#[tokio::test]
async fn test_handle_learn_preference() {
let handler = setup_test_handler("learn_preference");
let req = json!({
"jsonrpc": "2.0",
"id": 102,
"method": "tools/call",
"params": {
"name": "learn_preference",
"arguments": {
"key": "formatting",
"value": "use spaces"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let prefs = handler.state.prefs.read();
assert!(prefs.values().any(|p| p.key == "formatting" && p.value == "use spaces"));
}
#[tokio::test]
async fn test_handle_read_preferences() {
let handler = setup_test_handler("read_preferences");
handler.state.prefs.modify(|prefs| {
prefs.insert("theme".to_string(), crate::models::Preference {
key: "theme".to_string(),
value: "dark".to_string(),
updated_at: 0,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 103,
"method": "tools/call",
"params": {
"name": "read_preferences",
"arguments": {}
}
});
let response = handler.handle_request(req).await.unwrap();
let content = response["result"]["content"][0]["text"].as_str().unwrap();
assert!(content.contains("theme"));
assert!(content.contains("dark"));
}
#[tokio::test]
async fn test_handle_delete_task() {
let handler = setup_test_handler("delete_task");
handler.state.tasks.modify(|tasks| {
tasks.push(crate::models::Task {
id: "task-to-delete".to_string(),
title: "".to_string(),
status: "".to_string(),
description: "".to_string(),
created_at: 0,
updated_at: 0,
git_branch: None,
acceptance_criteria: vec![],
dependencies: vec![],
parent_id: None,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 104,
"method": "tools/call",
"params": {
"name": "delete_task",
"arguments": {
"id": "task-to-delete"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let tasks = handler.state.tasks.read();
assert!(tasks.is_empty());
}
#[tokio::test]
async fn test_handle_add_milestone() {
let handler = setup_test_handler("add_milestone");
let req = json!({
"jsonrpc": "2.0",
"id": 105,
"method": "tools/call",
"params": {
"name": "add_milestone",
"arguments": {
"title": "v1.0",
"namespace": "global"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let milestones = handler.state.milestones.read();
assert_eq!(milestones.len(), 1);
assert_eq!(milestones[0].title, "v1.0");
}
#[tokio::test]
async fn test_handle_update_milestone() {
let handler = setup_test_handler("update_milestone");
handler.state.milestones.modify(|ms| {
ms.push(crate::models::Milestone {
id: "v1.0".to_string(),
title: "v1.0".to_string(),
status: "pending".to_string(),
namespace: "".to_string(),
target_date: None,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 106,
"method": "tools/call",
"params": {
"name": "update_milestone",
"arguments": {
"id": "v1.0",
"status": "completed"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let ms = handler.state.milestones.read();
assert_eq!(ms[0].status, "completed");
}
#[tokio::test]
async fn test_handle_list_milestones() {
let handler = setup_test_handler("list_milestones");
handler.state.milestones.modify(|ms| {
ms.push(crate::models::Milestone {
id: "v2.0".to_string(),
title: "v2.0".to_string(),
status: "pending".to_string(),
namespace: "".to_string(),
target_date: None,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 107,
"method": "tools/call",
"params": {
"name": "list_milestones",
"arguments": {}
}
});
let response = handler.handle_request(req).await.unwrap();
let content = response["result"]["content"][0]["text"].as_str().unwrap();
assert!(content.contains("v2.0"));
}
#[tokio::test]
async fn test_handle_add_pr_checklist_item() {
let handler = setup_test_handler("add_pr_checklist_item");
let req = json!({
"jsonrpc": "2.0",
"id": 108,
"method": "tools/call",
"params": {
"name": "add_pr_checklist_item",
"arguments": {
"description": "Check tests",
"namespace": "global"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let cl = handler.state.pr_checklists.read();
assert_eq!(cl.len(), 1);
assert_eq!(cl[0].description, "Check tests");
}
#[tokio::test]
async fn test_handle_clear_pr_checklist() {
let handler = setup_test_handler("clear_pr_checklist");
handler.state.pr_checklists.modify(|cl| {
cl.push(crate::models::PrChecklistItem {
namespace: "global".to_string(),
id: "item".to_string(),
description: "".to_string(),
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 109,
"method": "tools/call",
"params": {
"name": "clear_pr_checklist",
"arguments": {
"namespace": "global"
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let cl = handler.state.pr_checklists.read();
assert!(cl.is_empty());
}
#[tokio::test]
async fn test_handle_clear_handoff_memos() {
let handler = setup_test_handler("clear_handoff_memos");
handler.state.handoff_memos.modify(|ms| {
ms.push(crate::models::HandoffMemo {
id: "memo".to_string(),
namespace: "".to_string(),
content: "".to_string(),
author: "".to_string(),
timestamp: 0,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 110,
"method": "tools/call",
"params": {
"name": "clear_handoff_memos",
"arguments": {
"ids": ["memo"]
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let ms = handler.state.handoff_memos.read();
assert!(ms.is_empty());
}
#[tokio::test]
async fn test_handle_clear_sticky_notes() {
let handler = setup_test_handler("clear_sticky_notes");
handler.state.sticky.modify(|ns| {
ns.push(crate::models::StickyNote {
content: "".to_string(),
timestamp: 0,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 111,
"method": "tools/call",
"params": {
"name": "clear_sticky_notes",
"arguments": {}
}
});
let _ = handler.handle_request(req).await.unwrap();
let ns = handler.state.sticky.read();
assert!(ns.is_empty());
}
#[tokio::test]
async fn test_handle_delete_sticky_note() {
let handler = setup_test_handler("delete_sticky_note");
handler.state.sticky.modify(|ns| {
ns.push(crate::models::StickyNote {
content: "note1".to_string(),
timestamp: 0,
});
ns.push(crate::models::StickyNote {
content: "note2".to_string(),
timestamp: 0,
});
});
let req = json!({
"jsonrpc": "2.0",
"id": 112,
"method": "tools/call",
"params": {
"name": "delete_sticky_note",
"arguments": {
"index": 1
}
}
});
let _ = handler.handle_request(req).await.unwrap();
let ns = handler.state.sticky.read();
assert_eq!(ns.len(), 1);
assert_eq!(ns[0].content, "note2");
}
}
+8
View File
@@ -45,6 +45,14 @@ impl<T: DeserializeOwned + Default + Serialize + Clone + Send + 'static> Store<T
lock.clone()
}
pub fn inspect<F, R>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
let lock = self.cache.read().unwrap();
f(&lock)
}
pub fn modify<F: FnOnce(&mut T)>(&self, f: F) {
let mut lock = self.cache.write().unwrap();
f(&mut lock);