feat: resolve local review comments manually

This commit is contained in:
Valdemar Lorenzen
2026-10-16 15:42:33 +02:00
parent b558f82094
commit 6ae8bf06a8
6 changed files with 267 additions and 15 deletions
+126
View File
@@ -945,6 +945,20 @@ core_actions![
true,
true
),
(
"core.diff.review.resolve",
Action::ReviewResolve,
&[Mode::Normal],
true,
true
),
(
"core.diff.review.unresolve",
Action::ReviewUnresolve,
&[Mode::Normal],
true,
true
),
(
"core.diff.review.next",
Action::ReviewNext,
@@ -5254,6 +5268,8 @@ impl Editor {
| Action::DiffComment
| Action::ReviewEdit
| Action::ReviewDelete
| Action::ReviewResolve
| Action::ReviewUnresolve
| Action::ReviewNext
| Action::ReviewPrevious
| Action::ReviewOverview
@@ -8453,6 +8469,8 @@ impl Editor {
| Action::DiffComment
| Action::ReviewEdit
| Action::ReviewDelete
| Action::ReviewResolve
| Action::ReviewUnresolve
| Action::ReviewNext
| Action::ReviewPrevious
| Action::ReviewOverview
@@ -9367,6 +9385,8 @@ impl Editor {
Action::DiffComment
| Action::ReviewEdit
| Action::ReviewDelete
| Action::ReviewResolve
| Action::ReviewUnresolve
| Action::ReviewNext
| Action::ReviewPrevious
| Action::ReviewOverview
@@ -16090,6 +16110,112 @@ mod tests {
);
}
#[test]
fn review_resolution_persists_without_hiding_comments_or_changing_stale_anchors() {
use crate::review::{Review, Store};
let directory = Directory::new();
let root = directory.0.canonicalize().unwrap();
let storage = root.join("data");
let mut first = editor();
first.set_review_directory(storage.clone());
historical_diff(&mut first, &root, vec!["old".into()], vec!["new".into()]);
first.execute("diff.comment");
type_text(&mut first, "iFeedback");
first.handle(Input::Escape);
assert!(
first
.review_panel_title()
.unwrap()
.contains(" · unresolved · ")
);
first.execute("diff.review.resolve");
assert!(
first
.context()
.text
.contains("Comment #1 · resolved · current")
);
let store = Store::open(&storage).unwrap();
let document = &first.workspace_diff().unwrap().local_review.document;
let id = document.storage_id.unwrap();
let anchor = document.comments[0].anchor.clone();
assert!(store.load(&root, id).unwrap().comments[0].resolved);
first.execute("diff.review.next");
assert_eq!(first.context().text, "Feedback");
assert!(
first
.review_panel_title()
.unwrap()
.contains(" · resolved · ")
);
let export = root.join("resolved.json");
first.execute(&format!("diff.review.save {}", export.display()));
assert!(Review::load(&export, &root).unwrap().comments[0].resolved);
let mut stale = editor();
stale.set_review_directory(storage.clone());
historical_diff(
&mut stale,
&root,
vec!["changed".into()],
vec!["new".into()],
);
stale.execute("diff.review.overview");
assert!(
stale
.context()
.text
.contains("Comment #1 · resolved · stale")
);
first.execute("diff.review.unresolve 1");
assert!(!store.load(&root, id).unwrap().comments[0].resolved);
stale.execute("diff.review.unresolve 1");
assert!(stale.current_review_dirty());
assert!(
!stale
.workspace_diff()
.unwrap()
.local_review
.document
.comments[0]
.resolved
);
assert_eq!(
stale
.workspace_diff()
.unwrap()
.local_review
.document
.comments[0]
.anchor,
anchor
);
assert!(stale.message().contains("changed in another session"));
first.execute("diff.review.resolve");
assert!(
first
.context()
.text
.contains("Comment #1 · resolved · current")
);
first.execute("diff.review.unresolve");
assert!(
first
.context()
.text
.contains("Comment #1 · unresolved · current")
);
first.execute(&format!("diff.review.open {}", export.display()));
let imported = &first.workspace_diff().unwrap().local_review.document;
assert_ne!(imported.storage_id, Some(id));
assert!(
store
.load(&root, imported.storage_id.unwrap())
.unwrap()
.comments[0]
.resolved
);
}
#[test]
fn sqlite_review_conflicts_and_write_failures_keep_dirty_drafts() {
use crate::review::Store;