+
+ #[test]
+ fn toggle_file_and_change() {
+ let mut state = State::default();
+ assert_eq!(state.overall, PickSet::Include);
+
+ let file_a = "A";
+
+ let to_path = |raw: &str| file::Path {
+ raw: raw.to_string(),
+ is_dir: false,
+ };
+
+ let change_a_1 = repo::ChangedFileDiff::SolveNameConflict;
+
+ let changed_files = repo::ChangedFiles::from_iter([(
+ to_path(file_a),
+ repo::ChangedFile::from_iter([change_a_1.clone()]),
+ )]);
+
+ let toggle_file = |state: &mut State, file: &str| {
+ update(
+ state,
+ Msg::ToggleFile {
+ path: to_path(file),
+ },
+ &changed_files,
+ )
+ };
+ let toggle_change =
+ |state: &mut State, file: &str, change: &repo::ChangedFileDiff| {
+ update(
+ state,
+ Msg::ToggleChange {
+ path: to_path(file),
+ diff_id: diff::id_parts_hash(change),
+ },
+ &changed_files,
+ )
+ };
+
+ let file =
+ |state: &State, file: &str| *state.files.get(&to_path(file)).unwrap();
+ let change = |state: &State, file: &str, change: &repo::ChangedFileDiff| {
+ let diff_id = diff::id_parts_hash(change);
+ *state
+ .changes
+ .get(&to_path(file))
+ .unwrap()
+ .changes
+ .get(&diff_id)
+ .unwrap()
+ };
+
+ // Exclude A.1
+ toggle_change(&mut state, file_a, &change_a_1);
+ assert_eq!(change(&state, file_a, &change_a_1), Pick::Exclude);
+ assert_eq!(file(&state, file_a), PickSet::Exclude);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ // Include A
+ toggle_file(&mut state, file_a);
+ assert_eq!(file(&state, file_a), PickSet::Include);
+ assert_eq!(state.overall, PickSet::Include);
+
+ // Exclude A.1
+ toggle_change(&mut state, file_a, &change_a_1);
+ assert_eq!(change(&state, file_a, &change_a_1), Pick::Exclude);
+ assert_eq!(file(&state, file_a), PickSet::Exclude);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ // Include A
+ toggle_file(&mut state, file_a);
+ assert_eq!(file(&state, file_a), PickSet::Include);
+ assert_eq!(state.overall, PickSet::Include);
+
+ // Exclude A
+ toggle_file(&mut state, file_a);
+ assert_eq!(file(&state, file_a), PickSet::Exclude);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ // Include A.1
+ toggle_change(&mut state, file_a, &change_a_1);
+ assert_eq!(change(&state, file_a, &change_a_1), Pick::Include);
+ assert_eq!(file(&state, file_a), PickSet::Include);
+ assert_eq!(state.overall, PickSet::Include);
+ }
+
+ #[test]
+ fn toggle_overall_and_file() {
+ let mut state = State::default();
+ assert_eq!(state.overall, PickSet::Include);
+
+ let file_a = "A";
+ let file_b = "B";
+
+ let to_path = |raw: &str| file::Path {
+ raw: raw.to_string(),
+ is_dir: false,
+ };
+
+ let change_a_1 = repo::ChangedFileDiff::SolveNameConflict;
+ let change_b_1 = repo::ChangedFileDiff::SolveNameConflict;
+
+ let changed_files = repo::ChangedFiles::from_iter([
+ (
+ to_path(file_a),
+ repo::ChangedFile::from_iter([change_a_1.clone()]),
+ ),
+ (
+ to_path(file_b),
+ repo::ChangedFile::from_iter([change_b_1.clone()]),
+ ),
+ ]);
+
+ let toggle_file = |state: &mut State, file: &str| {
+ update(
+ state,
+ Msg::ToggleFile {
+ path: to_path(file),
+ },
+ &changed_files,
+ )
+ };
+
+ let file =
+ |state: &State, file: &str| *state.files.get(&to_path(file)).unwrap();
+
+ update(&mut state, Msg::ToggleOverall, &changed_files);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ // Include A
+ toggle_file(&mut state, file_a);
+ assert_eq!(file(&state, file_a), PickSet::Include);
+ assert_eq!(state.overall, PickSet::Partial);
+
+ update(&mut state, Msg::ToggleOverall, &changed_files);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ update(&mut state, Msg::ToggleOverall, &changed_files);
+ assert_eq!(state.overall, PickSet::Include);
+
+ // Exclude A
+ toggle_file(&mut state, file_a);
+ assert_eq!(file(&state, file_a), PickSet::Exclude);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ update(&mut state, Msg::ToggleOverall, &changed_files);
+ assert_eq!(state.overall, PickSet::Include);
+
+ // Exclude B
+ toggle_file(&mut state, file_b);
+ assert_eq!(file(&state, file_b), PickSet::Exclude);
+ assert_eq!(state.overall, PickSet::Exclude);
+
+ // Include B
+ toggle_file(&mut state, file_b);
+ assert_eq!(file(&state, file_b), PickSet::Include);
+ assert_eq!(state.overall, PickSet::Partial);
+ }