feat: scope local reviews to comparisons

This commit is contained in:
2026-10-25 01:00:58 +02:00
parent 815fcccbe8
commit 448c3bf477
15 changed files with 760 additions and 72 deletions
+39 -5
View File
@@ -2370,6 +2370,7 @@ fn live_state(before: Vec<String>, after: Vec<String>, eof: bool) -> DiffState {
loaded: true,
}],
});
state.review_comparison = Some(["base".into(), "working:snapshot".into()]);
state.files = Some(FilePicker::from_paths(
PathBuf::new(),
[(0, PathBuf::from("file"))],
@@ -2764,7 +2765,33 @@ fn restored_review_marks_use_file_identities_and_rename_paths_not_catalog_order(
}
#[test]
fn unchanged_file_review_survives_other_files_changing() {
fn review_marks_cannot_cross_comparison_scopes_even_with_matching_file_identities() {
let mut review = crate::review::ReviewState::default();
let mut state = DiffState::new();
let mut first = comparison();
first.files[0].review_revisions = Some(["file-before".into(), "file-after".into()]);
state.request_kind = Some(RequestKind::Comparison);
state.apply_result(1, Ok(Outcome::Comparison(first)));
state.toggle_reviewed(&mut review).unwrap();
let initial_scope = review.document.comparison.clone();
let mut second = comparison();
second.files[0].review_revisions = Some(["file-before".into(), "file-after".into()]);
second.revisions[1] = "another-head".into();
state.request_kind = Some(RequestKind::Comparison);
state.apply_result(2, Ok(Outcome::Comparison(second)));
state.restore_reviewed_files(&review);
assert!(state.reviewed_files.is_empty());
assert_eq!(
state.toggle_reviewed(&mut review),
Err("Select the review for this comparison first")
);
assert!(state.reviewed_files.is_empty());
assert_eq!(review.document.comparison, initial_scope);
assert_eq!(review.document.reviewed_files.len(), 1);
}
#[test]
fn working_refresh_retains_scope_and_unchanged_file_progress() {
let mut review = crate::review::ReviewState::default();
use crate::repository::Repository;
use std::sync::{Arc, atomic::AtomicBool};
@@ -2825,20 +2852,27 @@ fn unchanged_file_review_survives_other_files_changing() {
.compare(2, &before, &after, ComparisonMode::Snapshots, &[])
.unwrap();
assert_ne!(changes.revisions, original_revisions);
state.request_kind = Some(RequestKind::Comparison);
state.apply_result(2, Ok(Outcome::Comparison(changes)));
state.after = Some(after);
state.request_kind = None;
state.pending = None;
state.loading = false;
state.queue_checkout_refresh(true);
state.take_request();
assert!(state.apply_result(2, Ok(Outcome::CheckoutRefresh(Some(changes)))));
assert_eq!(state.review_comparison, Some(original_revisions));
review.document = store.load(&root, id).unwrap();
state.restore_reviewed_files(&review);
assert_eq!(state.reviewed_files, BTreeSet::from([0]));
state.load_file(0);
let detail = repository.load_file(2, 0).unwrap();
state.apply_result(
assert!(state.apply_result(
3,
Ok(Outcome::File {
comparison_id: 2,
file_index: 0,
file: detail,
}),
);
));
state.restore_reviewed_files(&review);
assert_eq!(state.reviewed_files, BTreeSet::from([0]));
std::fs::remove_dir_all(root).unwrap();