From 8df3e4f2f82e1e993a32ebb5ce524bb6690fd8a0 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Sun, 24 Oct 2021 20:57:55 -0400 Subject: [PATCH 1/2] use TW's semantics for `start` --- docs/src/tasks.md | 2 +- taskchampion/src/task/task.rs | 125 +++++++--------------------------- 2 files changed, 27 insertions(+), 100 deletions(-) diff --git a/docs/src/tasks.md b/docs/src/tasks.md index ae354c62c..cfd6e1ef3 100644 --- a/docs/src/tasks.md +++ b/docs/src/tasks.md @@ -30,7 +30,7 @@ The following keys, and key formats, are defined: * `status` - one of `P` for a pending task (the default), `C` for completed or `D` for deleted * `description` - the one-line summary of the task * `modified` - the time of the last modification of this task -* `start.` - either an empty string (representing work on the task to the task that has not been stopped) or a timestamp (representing the time that work stopped) +* `start` - the most recent time at which this task was started (a task with no `start` key is not active) * `tag.` - indicates this task has tag `` (value is an empty string) * `wait` - indicates the time before which this task should be hidden, as it is not actionable diff --git a/taskchampion/src/task/task.rs b/taskchampion/src/task/task.rs index d96539e10..102d27aa8 100644 --- a/taskchampion/src/task/task.rs +++ b/taskchampion/src/task/task.rs @@ -100,9 +100,7 @@ impl Task { /// Determine whether this task is active -- that is, that it has been started /// and not stopped. pub fn is_active(&self) -> bool { - self.taskmap - .iter() - .any(|(k, v)| k.starts_with("start.") && v.is_empty()) + self.taskmap.contains_key("start") } /// Determine whether a given synthetic tag is present on this task. All other @@ -192,31 +190,18 @@ impl<'r> TaskMut<'r> { self.set_timestamp("modified", Some(modified)) } - /// Start the task by creating "start.", if the task is not already /// active. pub fn start(&mut self) -> anyhow::Result<()> { if self.is_active() { return Ok(()); } - let k = format!("start.{}", Utc::now().timestamp()); - self.set_string(k, Some(String::from(""))) + self.set_timestamp("start", Some(Utc::now())) } - /// Stop the task by adding the current timestamp to all un-resolved "start." keys. + /// Stop the task by removing the `start` key pub fn stop(&mut self) -> anyhow::Result<()> { - let keys = self - .taskmap - .iter() - .filter(|(k, v)| k.starts_with("start.") && v.is_empty()) - .map(|(k, _)| k) - .cloned() - .collect::>(); - let now = Utc::now(); - for key in keys { - println!("{}", key); - self.set_timestamp(&key, Some(now))?; - } - Ok(()) + self.set_timestamp("start", None) } /// Mark this task as complete @@ -340,10 +325,10 @@ mod test { } #[test] - fn test_is_active() { + fn test_is_active_active() { let task = Task::new( Uuid::new_v4(), - vec![(String::from("start.1234"), String::from(""))] + vec![(String::from("start"), String::from("1234"))] .drain(..) .collect(), ); @@ -352,14 +337,8 @@ mod test { } #[test] - fn test_is_active_stopped() { - let task = Task::new( - Uuid::new_v4(), - vec![(String::from("start.1234"), String::from("1235"))] - .drain(..) - .collect(), - ); - + fn test_is_active_inactive() { + let task = Task::new(Uuid::new_v4(), Default::default()); assert!(!task.is_active()); } @@ -405,7 +384,7 @@ mod test { Uuid::new_v4(), vec![ (String::from("tag.abc"), String::from("")), - (String::from("start.1234"), String::from("")), + (String::from("start"), String::from("1234")), ] .drain(..) .collect(), @@ -463,35 +442,21 @@ mod test { assert_eq!(tags, vec![utag("ok"), stag(SyntheticTag::Pending)]); } - fn count_taskmap(task: &TaskMut, f: fn(&(&String, &String)) -> bool) -> usize { - task.taskmap.iter().filter(f).count() - } - #[test] fn test_start() { with_mut_task(|mut task| { task.start().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 1 - ); + assert!(task.taskmap.contains_key("start")); + task.reload().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 1 - ); + assert!(task.taskmap.contains_key("start")); // second start doesn't change anything.. task.start().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 1 - ); + assert!(task.taskmap.contains_key("start")); + task.reload().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 1 - ); + assert!(task.taskmap.contains_key("start")); }); } @@ -500,23 +465,17 @@ mod test { with_mut_task(|mut task| { task.start().unwrap(); task.stop().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 0 - ); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && !v.is_empty()), - 1 - ); + assert!(!task.taskmap.contains_key("start")); + task.reload().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 0 - ); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && !v.is_empty()), - 1 - ); + assert!(!task.taskmap.contains_key("start")); + + // redundant call does nothing.. + task.stop().unwrap(); + assert!(!task.taskmap.contains_key("start")); + + task.reload().unwrap(); + assert!(!task.taskmap.contains_key("start")); }); } @@ -534,38 +493,6 @@ mod test { }); } - #[test] - fn test_stop_multiple() { - with_mut_task(|mut task| { - // simulate a task that has (through the synchronization process) been started twice - task.task - .taskmap - .insert(String::from("start.1234"), String::from("")); - task.task - .taskmap - .insert(String::from("start.5678"), String::from("")); - - task.stop().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 0 - ); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && !v.is_empty()), - 2 - ); - task.reload().unwrap(); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && v.is_empty()), - 0 - ); - assert_eq!( - count_taskmap(&task, |(k, v)| k.starts_with("start.") && !v.is_empty()), - 2 - ); - }); - } - #[test] fn test_add_tags() { with_mut_task(|mut task| { From 5648d20bde91726d69928cc2e63198463eb54328 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Mon, 25 Oct 2021 09:20:44 -0400 Subject: [PATCH 2/2] add changelog --- .changelogs/2021-10-25-issue23-integration.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .changelogs/2021-10-25-issue23-integration.md diff --git a/.changelogs/2021-10-25-issue23-integration.md b/.changelogs/2021-10-25-issue23-integration.md new file mode 100644 index 000000000..d10a4d0ec --- /dev/null +++ b/.changelogs/2021-10-25-issue23-integration.md @@ -0,0 +1 @@ +- The details of how task start/stop is represented have changed. Any existing tasks will all be treated as inactive (stopped).