From b6482b4347402484a95dc527a534babf97c0bb60 Mon Sep 17 00:00:00 2001 From: Nikita Galaiko Date: Tue, 21 Feb 2023 14:32:52 +0100 Subject: [PATCH] make sure session exists when writing deltas --- src-tauri/src/deltas/deltas.rs | 11 +++- src-tauri/src/deltas/deltas_tests.rs | 72 +++++++++++++++++++++--- src-tauri/src/deltas/mod.rs | 1 + src-tauri/src/sessions/sessions_tests.rs | 2 +- src-tauri/src/watchers/delta.rs | 12 ++-- 5 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src-tauri/src/deltas/deltas.rs b/src-tauri/src/deltas/deltas.rs index e9273b0cc..01178e61b 100644 --- a/src-tauri/src/deltas/deltas.rs +++ b/src-tauri/src/deltas/deltas.rs @@ -27,7 +27,16 @@ pub fn read(project: &projects::Project, file_path: &Path) -> Result) -> Result<()> { +pub fn write( + repo: &git2::Repository, + project: &projects::Project, + file_path: &Path, + deltas: &Vec, +) -> Result<()> { + if sessions::Session::current(repo, project)?.is_none() { + sessions::Session::from_head(repo, project)?; + } + let delta_path = project.deltas_path().join(file_path); let delta_dir = delta_path.parent().unwrap(); std::fs::create_dir_all(&delta_dir)?; diff --git a/src-tauri/src/deltas/deltas_tests.rs b/src-tauri/src/deltas/deltas_tests.rs index 5ce3448c7..ca65acefa 100644 --- a/src-tauri/src/deltas/deltas_tests.rs +++ b/src-tauri/src/deltas/deltas_tests.rs @@ -1,19 +1,30 @@ -use crate::{deltas::operations::Operation, projects}; +use crate::{deltas::operations::Operation, projects, sessions}; use anyhow::Result; use std::path::Path; use tempfile::tempdir; -fn test_project() -> Result { +fn test_project() -> Result<(git2::Repository, projects::Project)> { let path = tempdir()?.path().to_str().unwrap().to_string(); std::fs::create_dir_all(&path)?; - git2::Repository::init(&path)?; + let repo = git2::Repository::init(&path)?; + let mut index = repo.index()?; + let oid = index.write_tree()?; + let sig = git2::Signature::now("test", "test@email.com").unwrap(); + let _commit = repo.commit( + Some("HEAD"), + &sig, + &sig, + "initial commit", + &repo.find_tree(oid)?, + &[], + )?; let project = projects::Project::from_path(path)?; - Ok(project) + Ok((repo, project)) } #[test] fn test_read_none() { - let project = test_project().unwrap(); + let (_repo, project) = test_project().unwrap(); let file_path = Path::new("test.txt"); let deltas = super::read(&project, file_path); assert!(deltas.is_ok()); @@ -22,7 +33,7 @@ fn test_read_none() { #[test] fn test_read_invalid() { - let project = test_project().unwrap(); + let (_repo, project) = test_project().unwrap(); let file_path = Path::new("test.txt"); let full_file_path = project.deltas_path().join(file_path); @@ -35,17 +46,62 @@ fn test_read_invalid() { #[test] fn test_write_read() { - let project = test_project().unwrap(); + let (repo, project) = test_project().unwrap(); let file_path = Path::new("test.txt"); let deltas = vec![super::Delta { operations: vec![Operation::Insert((0, "Hello, world!".to_string()))], timestamp_ms: 0, }]; - let write_result = super::write(&project, file_path, &deltas); + let write_result = super::write(&repo, &project, file_path, &deltas); assert!(write_result.is_ok()); let read_result = super::read(&project, file_path); assert!(read_result.is_ok()); assert_eq!(read_result.unwrap().unwrap(), deltas); } + +#[test] +fn test_write_must_create_session() { + let (repo, project) = test_project().unwrap(); + let file_path = Path::new("test.txt"); + + let deltas = vec![super::Delta { + operations: vec![Operation::Insert((0, "Hello, world!".to_string()))], + timestamp_ms: 0, + }]; + let write_result = super::write(&repo, &project, file_path, &deltas); + assert!(write_result.is_ok()); + + let current_session = sessions::Session::current(&repo, &project); + assert!(current_session.is_ok()); + let current_session = current_session.unwrap(); + + assert!(current_session.is_some()); +} + +#[test] +fn test_write_must_not_override_session() { + let (repo, project) = test_project().unwrap(); + let file_path = Path::new("test.txt"); + + let session_before_write = sessions::Session::from_head(&repo, &project); + assert!(session_before_write.is_ok()); + let session_before_write = session_before_write.unwrap(); + + let deltas = vec![super::Delta { + operations: vec![Operation::Insert((0, "Hello, world!".to_string()))], + timestamp_ms: 0, + }]; + let write_result = super::write(&repo, &project, file_path, &deltas); + assert!(write_result.is_ok()); + + let session_after_write = sessions::Session::current(&repo, &project); + assert!(session_after_write.is_ok()); + let session_after_write = session_after_write.unwrap(); + + assert!(session_after_write.is_some()); + let session_after_write = session_after_write.unwrap(); + + assert_eq!(session_before_write, session_after_write); +} diff --git a/src-tauri/src/deltas/mod.rs b/src-tauri/src/deltas/mod.rs index 2a6139ef2..5c8fa7d23 100644 --- a/src-tauri/src/deltas/mod.rs +++ b/src-tauri/src/deltas/mod.rs @@ -3,6 +3,7 @@ mod operations; mod text_document; pub use deltas::{list, read, write, Delta}; +pub use operations::Operation; pub use text_document::TextDocument; #[cfg(test)] diff --git a/src-tauri/src/sessions/sessions_tests.rs b/src-tauri/src/sessions/sessions_tests.rs index e1e216306..cbe87c919 100644 --- a/src-tauri/src/sessions/sessions_tests.rs +++ b/src-tauri/src/sessions/sessions_tests.rs @@ -46,7 +46,7 @@ fn test_current_none() { } #[test] -fn test_create_current() { +fn test_create_current_no_deltas() { let (repo, project) = test_project().unwrap(); let current_session = super::sessions::Session::from_head(&repo, &project); assert!(current_session.is_ok()); diff --git a/src-tauri/src/watchers/delta.rs b/src-tauri/src/watchers/delta.rs index 22777f59f..ce337a624 100644 --- a/src-tauri/src/watchers/delta.rs +++ b/src-tauri/src/watchers/delta.rs @@ -2,7 +2,7 @@ use crate::deltas::{read, write, Delta, TextDocument}; use crate::projects; use crate::{events, sessions}; use anyhow::{Context, Result}; -use git2::Repository; +use git2; use notify::{Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; use std::fs; use std::path::Path; @@ -37,7 +37,7 @@ impl<'a> DeltaWatchers<'a> { .unwrap() .insert(project.path.clone(), watcher); - let repo = Repository::open(project_path); + let repo = git2::Repository::open(project_path); thread::spawn(move || { if repo.is_err() { log::error!("failed to open git repo: {:?}", repo.err()); @@ -95,7 +95,7 @@ impl<'a> DeltaWatchers<'a> { fn register_file_change( window: &tauri::Window, project: &projects::Project, - repo: &Repository, + repo: &git2::Repository, kind: &EventKind, relative_file_path: &Path, ) -> Result)>, Box> { @@ -162,7 +162,7 @@ fn register_file_change( // if the file was modified, save the deltas let deltas = text_doc.get_deltas(); - write(project, relative_file_path, &deltas)?; + write(repo, project, relative_file_path, &deltas)?; return Ok(Some((session, deltas))); } @@ -172,7 +172,7 @@ fn register_file_change( // returns None if file is not UTF-8 // TODO: handle binary files fn get_latest_file_contents( - repo: &Repository, + repo: &git2::Repository, project: &projects::Project, relative_file_path: &Path, ) -> Result> { @@ -227,7 +227,7 @@ fn get_latest_file_contents( fn write_beginning_meta_files( window: &tauri::Window, project: &projects::Project, - repo: &Repository, + repo: &git2::Repository, ) -> Result> { match sessions::Session::current(repo, project) .map_err(|e| format!("Error while getting current session: {}", e.to_string()))?