use std::io::{Read, Write}; use uuid::Uuid; use dodo::storage::{Directory, Result, Storage}; #[test] fn can_create_directory_storage() { let folder = fixture::create_folder(); let storage = Directory::new(&folder); assert!(storage.is_ok(), "storage should have been created"); } #[test] fn should_create_sub_folders() { let folder = fixture::create_folder().path().join("sub/folder"); let _storage = Directory::new(&folder).expect("could not create storage"); assert!(folder.exists(), "storage should have created folder and sub folders"); } #[test] fn cant_use_file_as_directory_storage() { let folder = fixture::create_folder(); let file = fixture::create_file_in(&folder, "file", "content"); let storage = Directory::new(&file); assert!(storage.expect_err("shouldn't be able to create storage in a file").is_other(), "shouldn't be able to create storage in a file"); } #[test] fn can_create_new_entry() { let folder = fixture::create_folder(); let mut storage = Directory::new(&folder).expect("could not create storage"); let id = { let (id, mut write) = storage.new().expect("could not create new entry"); write!(&mut write, "{}", "content").expect("could not write to new entry"); id }; fixture::assert_entry_equals(&folder, id, "content"); } #[test] fn can_read_existing_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); fixture::create_entry_in(&folder, id, "content"); let storage = Directory::new(&folder).expect("could not create storage"); let bytes = { let mut read = storage.read(id).expect("could not read storage"); let mut buffer = String::new(); read.read_to_string(&mut buffer).expect("could not read entry"); buffer }; assert_eq!(bytes, "content", "entry was read incorrectly"); } #[test] fn cant_read_absent_entry() { let folder = fixture::create_folder(); let storage = Directory::new(&folder).expect("could not create storage"); let entry = storage.read(Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap()); assert!(entry.expect_err("entry should not exist").is_not_found(), "could not read entry"); } #[test] fn can_write_to_absent_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let mut storage = Directory::new(&folder).expect("could not create storage"); { let mut write = storage.write(id).expect("could not write to storage"); write!(&mut write, "{}", "content").expect("could not write entry"); }; fixture::assert_entry_equals(&folder, id, "content"); } #[test] fn can_write_to_existing_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); fixture::create_entry_in(&folder, id, "content"); let mut storage = Directory::new(&folder).expect("could not create storage"); { let mut write = storage.write(id).expect("could not write to storage"); write!(&mut write, "{}", "new content").expect("could not write entry"); }; fixture::assert_entry_equals(&folder, id, "new content"); } #[test] fn can_overwrite_existing_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); fixture::create_entry_in(&folder, id, "content"); let mut storage = Directory::new(&folder).expect("could not create storage"); { let mut write = storage.overwrite(id).expect("could not write to storage"); write!(&mut write, "{}", "new content").expect("could not write entry"); }; fixture::assert_entry_equals(&folder, id, "new content"); } #[test] fn cant_overwrite_absent_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let mut storage = Directory::new(&folder).expect("could not create storage"); let entry = storage.overwrite(id); assert!(entry.expect_err("entry should not have existed").is_not_found(), "entry should not have been writen"); } #[test] fn can_delete_existing_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); fixture::create_entry_in(&folder, id, "content"); let mut storage = Directory::new(&folder).expect("could not create storage"); let deleted = storage.delete(id).expect("could not delete from storage"); assert!(deleted, "something should have been deleted"); fixture::assert_entry_not_exists(&folder, id); } #[test] fn can_delete_absent_entry() { let folder = fixture::create_folder(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let mut storage = Directory::new(&folder).expect("could not create storage"); let deleted = storage.delete(id).expect("could not delete from storage"); assert!(!deleted, "nothing should have been deleted"); fixture::assert_entry_not_exists(&folder, id); } #[test] fn can_clear_storage() { let folder = fixture::create_folder(); let id1 = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let id2 = Uuid::parse_str("e91b1660-30ee-4db2-bf3d-244a0386c10f").unwrap(); fixture::create_entry_in(&folder, id1, "content1"); fixture::create_entry_in(&folder, id2, "content2"); let mut storage = Directory::new(&folder).expect("could not create storage"); storage.clear().expect("could not clear storage"); fixture::assert_entry_not_exists(&folder, id1); fixture::assert_entry_not_exists(&folder, id2); } #[test] fn can_clear_empty_storage() { let folder = fixture::create_folder(); let mut storage = Directory::new(&folder).expect("could not create storage"); storage.clear().expect("could not clear storage"); } #[test] fn can_list_existing_entries() { let folder = fixture::create_folder(); let id1 = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let id2 = Uuid::parse_str("e91b1660-30ee-4db2-bf3d-244a0386c10f").unwrap(); fixture::create_entry_in(&folder, id1, "content1"); fixture::create_entry_in(&folder, id2, "content2"); let storage = Directory::new(&folder).expect("could not create storage"); let entries: Vec = storage .iter().expect("could not read storage") .collect::>>().expect("could not read storage"); assert!(entries.contains(&id1), "entry 1 should exist"); assert!(entries.contains(&id2), "entry 2 should exist."); } mod fixture { use std::{fs, path::{Path, PathBuf}}; use uuid::Uuid; pub fn create_folder() -> tempfile::TempDir { tempfile::tempdir().expect("could not create folder") } pub fn create_file_in>(folder: P, name: &str, content: &str) -> PathBuf { let path = folder.as_ref().join(name); fs::write(&path, content).expect("could not create file"); path } pub fn create_entry_in>(folder: P, id: Uuid, content: &str) { create_file_in(folder, &id.to_string(), content); } pub fn assert_entry_equals>(folder: P, id: Uuid, expected_content: &str) { let path = folder.as_ref().join(id.to_string()); assert!(path.exists(), "entry does not exist"); let actual_content = fs::read_to_string(&path).expect("entry does not exist"); assert_eq!(expected_content, actual_content, "entry has the wrong contents"); } pub fn assert_entry_not_exists>(folder: P, id: Uuid) { let path = folder.as_ref().join(id.to_string()); assert!(!path.exists(), "entry should have been deleted"); } }