244 lines · 9.1 KB · Rust
RawDownload
mod mark_path {    use git_tempfile::{AutoRemove, ContainingDirectory};     #[test]    fn it_persists_markers_along_with_newly_created_directories() -> crate::Result {        let dir = tempfile::tempdir()?;        let target = dir.path().join("a").join("b").join("file.tmp");        let new_filename = target.parent().unwrap().join("file.ext");        let handle = git_tempfile::mark_at(            &target,            ContainingDirectory::CreateAllRaceProof(Default::default()),            AutoRemove::TempfileAndEmptyParentDirectoriesUntil {                boundary_directory: dir.path().into(),            },        )?;         std::fs::create_dir(&new_filename)?;        let err = handle            .persist(&new_filename)            .expect_err("cannot persist onto directory");        let handle = err.handle;        std::fs::remove_dir(&new_filename)?;         handle.take().expect("still there").persist(&new_filename)?;        assert!(!target.exists(), "tempfile was renamed");        assert!(            new_filename.is_file(),            "new file was placed (and parent directories still exist)"        );        Ok(())    }     #[test]    fn it_can_create_the_containing_directory_and_remove_it_on_drop() -> crate::Result {        let dir = tempfile::tempdir()?;        let first_dir = "dir";        let filename = dir.path().join(first_dir).join("subdir").join("file.tmp");        let tempfile = git_tempfile::mark_at(            &filename,            ContainingDirectory::CreateAllRaceProof(Default::default()),            AutoRemove::TempfileAndEmptyParentDirectoriesUntil {                boundary_directory: dir.path().into(),            },        )?;        assert!(filename.is_file(), "specified file should exist precisely");        drop(tempfile);        assert!(            !filename.is_file(),            "after drop named files are deleted as well as extra directories"        );        assert!(            !dir.path().join(first_dir).is_dir(),            "previously created and now empty directories are deleted, too"        );        Ok(())    }}mod at_path {    use git_tempfile::{AutoRemove, ContainingDirectory};     #[test]    fn reduce_resource_usage_by_converting_files_to_markers_and_persist_them() -> crate::Result {        let dir = tempfile::tempdir()?;        let target = dir.path().join("a").join("file.tmp");        let new_filename = target.parent().unwrap().join("file.ext");        let mut file = git_tempfile::writable_at(            &target,            ContainingDirectory::CreateAllRaceProof(Default::default()),            AutoRemove::TempfileAndEmptyParentDirectoriesUntil {                boundary_directory: dir.path().into(),            },        )?;        file.with_mut(|f| f.as_file_mut().write_all(b"hello world"))??;        let mark = file.close()?;        mark.take().expect("still there").persist(&new_filename)?;        assert!(!target.exists(), "tempfile was renamed");        assert!(            new_filename.is_file(),            "new file was placed (and parent directories still exist)"        );        assert_eq!(            std::fs::read(new_filename)?,            &b"hello world"[..],            "written content is persisted, too"        );        Ok(())    }    use std::io::{ErrorKind, Write};     #[test]    fn it_persists_tempfiles_along_with_newly_created_directories() -> crate::Result {        let dir = tempfile::tempdir()?;        let target = dir.path().join("a").join("b").join("file.tmp");        let new_filename = target.parent().unwrap().join("file.ext");        assert!(            !new_filename.is_file(),            "the filename for persistence doesn't exist yet"        );        let handle = git_tempfile::writable_at(            &target,            ContainingDirectory::CreateAllRaceProof(Default::default()),            AutoRemove::TempfileAndEmptyParentDirectoriesUntil {                boundary_directory: dir.path().into(),            },        )?;        std::fs::create_dir(&new_filename)?;        let err = handle            .persist(&new_filename)            .expect_err("cannot persist onto directory");        let handle = err.handle;        std::fs::remove_dir(&new_filename)?;         let mut file = handle.take().expect("still there");        file.write_all(b"hello world")?;        drop(file.persist(&new_filename)?);        assert!(!target.exists(), "tempfile was renamed");        assert!(            new_filename.is_file(),            "new file was placed (and parent directories still exist)"        );        assert_eq!(            std::fs::read(new_filename)?,            &b"hello world"[..],            "written content is persisted, too"        );        Ok(())    }     #[test]    fn it_can_create_the_containing_directory_and_remove_it_on_drop() -> crate::Result {        let dir = tempfile::tempdir()?;        let first_dir = "dir";        let filename = dir.path().join(first_dir).join("subdir").join("file.tmp");        let tempfile = git_tempfile::writable_at(            &filename,            ContainingDirectory::CreateAllRaceProof(Default::default()),            AutoRemove::TempfileAndEmptyParentDirectoriesUntil {                boundary_directory: dir.path().into(),            },        )?;        assert!(filename.is_file(), "specified file should exist precisely");        drop(tempfile);        assert!(            !filename.is_file(),            "after drop named files are deleted as well as extra directories"        );        assert!(            !dir.path().join(first_dir).is_dir(),            "previously created and now empty directories are deleted, too"        );        assert!(dir.path().is_dir(), "it won't touch the containing directory");        Ok(())    }     #[test]    fn it_names_files_correctly_and_similarly_named_tempfiles_cannot_be_created() -> crate::Result {        let dir = tempfile::tempdir()?;        let filename = dir.path().join("something-specific.ext");        let tempfile = git_tempfile::writable_at(&filename, ContainingDirectory::Exists, AutoRemove::Tempfile)?;        let res = git_tempfile::writable_at(&filename, ContainingDirectory::Exists, AutoRemove::Tempfile);        assert!(            matches!(res, Err(err) if err.kind() == ErrorKind::AlreadyExists),            "only one tempfile can be created at a time, they are exclusive"        );        assert!(filename.is_file(), "specified file should exist precisely");        drop(tempfile);        assert!(!filename.is_file(), "after drop named files are deleted as well");        assert!(dir.path().is_dir(), "it won't touch the containing directory");        Ok(())    }} mod new {    use std::{        io::{ErrorKind, Write},        path::Path,    };     use git_tempfile::{AutoRemove, ContainingDirectory};     fn filecount_in(path: impl AsRef<Path>) -> usize {        std::fs::read_dir(path).expect("valid dir").count()    }     #[test]    fn it_can_be_kept() -> crate::Result {        let dir = tempfile::tempdir()?;        drop(            git_tempfile::new(dir.path(), ContainingDirectory::Exists, AutoRemove::Tempfile)?                .take()                .expect("not taken yet")                .keep()?,        );        assert_eq!(filecount_in(&dir), 1, "a temp file and persisted");        Ok(())    }     #[test]    fn it_is_removed_if_it_goes_out_of_scope() -> crate::Result {        let dir = tempfile::tempdir()?;        {            let _keep = git_tempfile::new(dir.path(), ContainingDirectory::Exists, AutoRemove::Tempfile)?;            assert_eq!(filecount_in(&dir), 1, "a temp file was created");        }        assert_eq!(filecount_in(&dir), 0, "lock was automatically removed");        Ok(())    }     #[test]    fn it_can_create_the_containing_directory_and_remove_it_when_dropped() -> crate::Result {        let dir = tempfile::tempdir()?;        let containing_dir = dir.path().join("dir");        assert!(!containing_dir.exists());        {            let mut writable = git_tempfile::new(                &containing_dir,                ContainingDirectory::CreateAllRaceProof(Default::default()),                AutoRemove::TempfileAndEmptyParentDirectoriesUntil {                    boundary_directory: dir.path().into(),                },            )?;            assert_eq!(                filecount_in(&dir),                1,                "a temp file was created, as well as the directory"            );            writable.with_mut(|tf| tf.write_all(b"hello world"))??;            assert_eq!(                writable                    .with_mut(|_tf| Err::<(), std::io::Error>(ErrorKind::Other.into()))?                    .unwrap_err()                    .kind(),                ErrorKind::Other,                "errors are propagated"            );            writable                .with_mut(|tf| assert!(tf.path().is_file()))                .expect("after seeing an error before the file still exists");        }        assert!(!containing_dir.is_dir(), "the now empty directory was deleted as well");        assert!(dir.path().is_dir(), "it won't touch the containing directory");        Ok(())    }}