include recurring tasks in working-set, but not +PENDING

This commit is contained in:
Dustin J. Mitchell 2022-12-15 02:52:39 +00:00 committed by Tomas Babej
parent 9add31104b
commit e6f28bb7e6
2 changed files with 69 additions and 8 deletions

View file

@ -211,12 +211,21 @@ impl Replica {
/// Rebuild this replica's working set, based on whether tasks are pending or not. If
/// `renumber` is true, then existing tasks may be moved to new working-set indices; in any
/// case, on completion all pending tasks are in the working set and all non- pending tasks are
/// not.
/// case, on completion all pending and recurring tasks are in the working set and all tasks
/// with other statuses are not.
pub fn rebuild_working_set(&mut self, renumber: bool) -> anyhow::Result<()> {
let pending = String::from(Status::Pending.to_taskmap());
self.taskdb
.rebuild_working_set(|t| t.get("status") == Some(&pending), renumber)?;
let recurring = String::from(Status::Recurring.to_taskmap());
self.taskdb.rebuild_working_set(
|t| {
if let Some(st) = t.get("status") {
st == &pending || st == &recurring
} else {
false
}
},
renumber,
)?;
Ok(())
}
@ -454,6 +463,27 @@ mod tests {
assert!(ws.by_uuid(t.get_uuid()).is_none());
}
#[test]
fn rebuild_working_set_includes_recurring() {
let mut rep = Replica::new_inmemory();
let t = rep
.new_task(Status::Completed, "another task".into())
.unwrap();
let uuid = t.get_uuid();
let t = rep.get_task(uuid).unwrap().unwrap();
{
let mut t = t.into_mut(&mut rep);
t.set_status(Status::Recurring).unwrap();
}
rep.rebuild_working_set(true).unwrap();
let ws = rep.working_set().unwrap();
assert!(ws.by_uuid(uuid).is_some());
}
#[test]
fn new_pending_adds_to_working_set() {
let mut rep = Replica::new_inmemory();
@ -472,6 +502,24 @@ mod tests {
assert_eq!(ws.by_uuid(t.get_uuid()), Some(1));
}
#[test]
fn new_recurring_adds_to_working_set() {
let mut rep = Replica::new_inmemory();
let t = rep
.new_task(Status::Recurring, "to-be-recurring".into())
.unwrap();
let uuid = t.get_uuid();
let ws = rep.working_set().unwrap();
assert_eq!(ws.len(), 1); // only one non-none value
assert!(ws.by_index(0).is_none());
assert_eq!(ws.by_index(1), Some(uuid));
let ws = rep.working_set().unwrap();
assert_eq!(ws.by_uuid(t.get_uuid()), Some(1));
}
#[test]
fn get_does_not_exist() {
let mut rep = Replica::new_inmemory();

View file

@ -328,13 +328,13 @@ impl<'r> TaskMut<'r> {
/// new status puts it in that set.
pub fn set_status(&mut self, status: Status) -> anyhow::Result<()> {
match status {
Status::Pending => {
// clear "end" when a task becomes "pending"
Status::Pending | Status::Recurring => {
// clear "end" when a task becomes "pending" or "recurring"
if self.taskmap.contains_key(Prop::End.as_ref()) {
self.set_timestamp(Prop::End.as_ref(), None)?;
}
let uuid = self.uuid;
self.replica.add_to_working_set(uuid)?;
// ..and add to working set
self.replica.add_to_working_set(self.uuid)?;
}
Status::Completed | Status::Deleted => {
// set "end" when a task is deleted or completed
@ -860,6 +860,19 @@ mod test {
});
}
#[test]
fn test_set_status_recurring() {
with_mut_task(|mut task| {
task.done().unwrap();
task.set_status(Status::Recurring).unwrap();
assert_eq!(task.get_status(), Status::Recurring);
assert!(!task.taskmap.contains_key("end"));
assert!(!task.has_tag(&stag(SyntheticTag::Pending))); // recurring is not +PENDING
assert!(!task.has_tag(&stag(SyntheticTag::Completed)));
});
}
#[test]
fn test_set_status_completed() {
with_mut_task(|mut task| {