diff --git a/pttodoer/src/main.rs b/pttodoer/src/main.rs index 37a0b07..29b15e5 100644 --- a/pttodoer/src/main.rs +++ b/pttodoer/src/main.rs @@ -243,6 +243,148 @@ impl DB { mod test_db { use super::*; + #[test] + fn edit_append_duplicate_keeps_both() { + use std::io::Seek; + + let db = new_test_db(1, 1); + let db_after = db._edit(|cwd| { + let files_in_dir = std::fs::read_dir(cwd).expect("failed to ls cwd").collect::>(); + assert_eq!(1, files_in_dir.len()); + let mut f = std::fs::OpenOptions::new() + .write(true) + .append(true) + .open(files_in_dir[0].as_ref().expect("failed to get file in dir").path()) + .expect("failed to open file for append"); + f.seek(std::io::SeekFrom::End(0)).expect("failed to seek to end"); + f.write_all(b"\n- f").expect("failed to append the file in cwd"); + f.write_all(b"\n- f").expect("failed to append the file in cwd"); + }).expect("failed to not edit"); + assert_ne!(db, db_after); + + assert_eq!(1, db_after.tasks_and_metadatas.len()); + assert_eq!(3, db_after.tasks_and_metadatas[0].tasks.len()); + assert_eq!(db.tasks_and_metadatas[0].tasks.0[0], db_after.tasks_and_metadatas[0].tasks.0[0]); + assert_eq!(Some("f".to_string()), db_after.tasks_and_metadatas[0].tasks.0[1].get("is".to_string())); + assert_eq!(Some("f".to_string()), db_after.tasks_and_metadatas[0].tasks.0[2].get("is".to_string())); + } + + #[test] + fn edit_schedule_future() { + let db = new_test_db(0, 0); + let db_after = db._edit(|cwd| { + let mut task = Task::new(); + task.set("k".to_string(), "v".to_string()); + task.set("schedule".to_string(), "2101-02-03".to_string()); + + let mut tasks = Tasks::new(); + tasks.0.push(task); + + let temp = TasksAndMetadata::new_with( + format!("{}/only", cwd), + TS::now(), + tasks, + ); + temp.save(false).expect("failed to save"); + }).expect("failed to not edit"); + assert_ne!(db, db_after); + + assert_eq!(1, db_after.tasks_and_metadatas.len()); + assert_eq!(1, db_after.tasks_and_metadatas[0].tasks.len()); + assert_eq!(0, db_after.tasks_and_metadatas[0].due().tasks.len()); + assert_eq!(1, db_after.tasks_and_metadatas[0].not_due().tasks.len()); + } + + #[test] + fn edit_schedule_past() { + let db = new_test_db(0, 0); + let db_after = db._edit(|cwd| { + let mut task = Task::new(); + task.set("k".to_string(), "v".to_string()); + task.set("schedule".to_string(), "2001-02-03".to_string()); + + let mut tasks = Tasks::new(); + tasks.0.push(task); + + let temp = TasksAndMetadata::new_with( + format!("{}/only", cwd), + TS::now(), + tasks, + ); + temp.save(false).expect("failed to save"); + }).expect("failed to not edit"); + assert_ne!(db, db_after); + + assert_eq!(1, db_after.tasks_and_metadatas.len()); + assert_eq!(1, db_after.tasks_and_metadatas[0].tasks.len()); + assert_eq!(1, db_after.tasks_and_metadatas[0].due().tasks.len()); + assert_eq!(0, db_after.tasks_and_metadatas[0].not_due().tasks.len()); + } + + + #[test] + fn edit_append_second_file() { + use std::io::Seek; + + let db = new_test_db(2, 1); + let db_after = db._edit(|cwd| { + let files_in_dir = std::fs::read_dir(cwd).expect("failed to ls cwd").collect::>(); + assert_eq!(2, files_in_dir.len()); + let mut f = std::fs::OpenOptions::new() + .write(true) + .append(true) + .open(files_in_dir[1].as_ref().expect("failed to get file in dir").path()) + .expect("failed to open file for append"); + f.seek(std::io::SeekFrom::End(0)).expect("failed to seek to end"); + f.write_all(b"\n- f").expect("failed to append the file in cwd"); + }).expect("failed to not edit"); + assert_ne!(db, db_after); + + assert_eq!(2, db_after.tasks_and_metadatas.len()); + assert_eq!(1, db_after.tasks_and_metadatas[0].tasks.len()); + assert_eq!(2, db_after.tasks_and_metadatas[1].tasks.len()); + assert_eq!(db.tasks_and_metadatas[1].tasks.0[0], db_after.tasks_and_metadatas[1].tasks.0[0]); + assert_eq!(Some("f".to_string()), db_after.tasks_and_metadatas[1].tasks.0[1].get("is".to_string())); + } + + #[test] + fn edit_append_current_file() { + use std::io::Seek; + + let db = new_test_db(1, 1); + let db_after = db._edit(|cwd| { + let files_in_dir = std::fs::read_dir(cwd).expect("failed to ls cwd").collect::>(); + assert_eq!(1, files_in_dir.len()); + let mut f = std::fs::OpenOptions::new() + .write(true) + .append(true) + .open(files_in_dir[0].as_ref().expect("failed to get file in dir").path()) + .expect("failed to open file for append"); + f.seek(std::io::SeekFrom::End(0)).expect("failed to seek to end"); + f.write_all(b"\n- f").expect("failed to append the file in cwd"); + }).expect("failed to not edit"); + assert_ne!(db, db_after); + + assert_eq!(1, db_after.tasks_and_metadatas.len()); + assert_eq!(2, db_after.tasks_and_metadatas[0].tasks.len()); + assert_eq!(db.tasks_and_metadatas[0].tasks.0[0], db_after.tasks_and_metadatas[0].tasks.0[0]); + assert_eq!(Some("f".to_string()), db_after.tasks_and_metadatas[0].tasks.0[1].get("is".to_string())); + } + + #[test] + fn edit_insert_new_second_file() { + let db = new_test_db(1, 1); + let db_after = db._edit(|cwd| { + let mut f = std::fs::File::create(format!("{}/new_second_file", cwd)).expect("failed to open a file in cwd"); + f.write_all(b"f").expect("failed to write a file in cwd"); + }).expect("failed to not edit"); + assert_ne!(db, db_after); + + assert_eq!(2, db_after.tasks_and_metadatas.len()); + assert_eq!(1, db_after.tasks_and_metadatas[1].tasks.len()); + assert_eq!(1, db_after.tasks_and_metadatas[0].tasks.len()); + } + #[test] fn edit_insert_empty() { let db = new_test_db(0, 0); @@ -354,7 +496,10 @@ impl TasksAndMetadata { } pub fn save(&self, dry_run: bool) -> Result<(), String> { - let version = file_version(self.file.clone())?; + let version = match file_version(self.file.clone()){ + Ok(v) => v, + Err(_) => self.version.clone(), + }; let mut file = self.file.clone(); if version != self.version { file = format!("{}.{}", &self.file, TS::now().to_string());