fix to-record, add more tests

tzemanovic
Jan 27, 2026, 2:55 PM
LJEWZVNPT7UXEL2J2WDGDAFBO5TYV5AQO6BMLC4KHLBMZZCSQASAC

Dependencies

  • [2] 6F7Q4ZLR avoid unused warns
  • [3] 7MJOO4E2 task wrappers tooling workaround
  • [4] LFEMJYYD start of to_record selection
  • [5] 5O4FWCFP add tests to_record selection and improve it
  • [6] 2SLTGWP6 add change files diffs to-record selection
  • [7] UPWS6J3B filter to-record changes from selection
  • [8] FU6P5QLG indicate when a file is a dir with appended '/'
  • [9] YGZ3VCW4 add push
  • [10] YBJRDOTC make all repo actions async
  • [11] JZXYSIYD channel selection!

Change contents

  • edit in libflorescence/src/to_record.rs at line 119
    [7.2904][7.2904:2925]()
    dbg!(&explicit);
  • edit in inflorescence_model/src/to_record.rs at line 58
    [6.6862][5.2500:2526](),[4.5208][5.2500:2526]()
    dbg!(&state);
  • replacement in inflorescence_model/src/to_record.rs at line 91
    [4.5547][4.5547:5701](),[4.5701][5.3822:4157](),[5.4157][4.5701:5801](),[4.5701][4.5701:5801]()
    let current = state
    .changes
    .get(&file)
    .and_then(|file| file.changes.get(&change).copied())
    .or_else(|| {
    state.files.get(&file).and_then(|pick| {
    if matches!(pick, PickSet::Partial) {
    Some(Pick::Include)
    } else {
    None
    }
    })
    })
    .unwrap_or_else(|| default_pick(state));
    let pick = next_pick(current);
    [4.5547]
    [4.5801]
    let pick = next_file_change_pick(&file, change, state);
  • edit in inflorescence_model/src/to_record.rs at line 111
    [4.6335][5.4546:4572]()
    dbg!(&state);
  • replacement in inflorescence_model/src/to_record.rs at line 130
    [8.8430][4.6811:6940](),[4.6811][4.6811:6940]()
    let current = state
    .files
    .get(file)
    .copied()
    .unwrap_or_else(|| default_pick_set(state));
    [8.8430]
    [4.6940]
    let current = (match state.overall {
    pick @ (PickSet::Include | PickSet::Exclude) => Some(pick),
    PickSet::Partial => None,
    })
    .or_else(|| state.files.get(file).copied())
    .unwrap_or_else(|| default_pick_set(state));
  • replacement in inflorescence_model/src/to_record.rs at line 151
    [5.4687][5.4687:4747](),[5.4747][6.7021:7088](),[6.7088][5.4810:4877](),[5.4810][5.4810:4877]()
    let current = state
    .changes
    .get(file)
    .and_then(|PartialFile { changes }| changes.get(&diff_id))
    .copied()
    .unwrap_or_else(|| default_pick(state));
    [5.4687]
    [5.4877]
    let current = (match state.overall {
    PickSet::Include => Some(Pick::Include),
    PickSet::Exclude => Some(Pick::Exclude),
    PickSet::Partial => None,
    })
    .or_else(|| {
    state.files.get(file).and_then(|pick| match pick {
    PickSet::Include => Some(Pick::Include),
    PickSet::Exclude => Some(Pick::Exclude),
    PickSet::Partial => None,
    })
    })
    .or_else(|| {
    state
    .changes
    .get(file)
    .and_then(|PartialFile { changes }| changes.get(&diff_id))
    .copied()
    })
    .unwrap_or_else(|| default_pick(state));
  • edit in inflorescence_model/src/to_record.rs at line 256
    [4.11810][5.4922:5021]()
    // dbg!(default_pick_set(state));
    // pick = Some(default_pick_set(state));
  • edit in inflorescence_model/src/to_record.rs at line 260
    [4.11965][5.5065:5109]()
    dbg!((*pick, change_pick));
  • edit in inflorescence_model/src/to_record.rs at line 279
    [4.12753][5.5166:5183]()
    dbg!(&pick);
  • edit in inflorescence_model/src/to_record/test.rs at line 66
    [5.6940]
    [5.6940]
    // Exclude A
    toggle_file(&mut state, file_a);
    assert_eq!(file(&state, file_a), PickSet::Exclude);
    assert_eq!(file(&state, file_b), PickSet::Include);
    assert_eq!(file(&state, file_c), PickSet::Include);
    assert_eq!(state.overall, PickSet::Partial);
  • replacement in inflorescence_model/src/to_record/test.rs at line 124
    [5.8831][5.8831:8848]()
    // Include C
    [5.8831]
    [5.8848]
    // Exclude C
  • replacement in inflorescence_model/src/to_record/test.rs at line 128
    [5.8997][5.8997:9102]()
    assert_eq!(file(&state, file_c), PickSet::Include);
    assert_eq!(state.overall, PickSet::Include);
    [5.8997]
    [5.9102]
    assert_eq!(file(&state, file_c), PickSet::Exclude);
    assert_eq!(state.overall, PickSet::Partial);
  • replacement in inflorescence_model/src/to_record/test.rs at line 135
    [5.9269][5.9269:9325]()
    assert_eq!(file(&state, file_c), PickSet::Include);
    [5.9269]
    [5.9325]
    assert_eq!(file(&state, file_c), PickSet::Exclude);
  • replacement in inflorescence_model/src/to_record/test.rs at line 142
    [5.9504][5.9504:9521]()
    // Exclude B
    [5.9504]
    [5.9521]
    // Include B
  • replacement in inflorescence_model/src/to_record/test.rs at line 145
    [5.9614][5.9614:9726]()
    assert_eq!(file(&state, file_b), PickSet::Exclude);
    assert_eq!(file(&state, file_c), PickSet::Include);
    [5.9614]
    [5.9726]
    assert_eq!(file(&state, file_b), PickSet::Include);
    assert_eq!(file(&state, file_c), PickSet::Exclude);
  • edit in inflorescence_model/src/to_record/test.rs at line 310
    [5.15182]
    #[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);
    }