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<Uuid> = storage
.iter().expect("could not read storage")
.collect::<Result<Vec<Uuid>>>().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<P: AsRef<Path>>(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<P: AsRef<Path>>(folder: P, id: Uuid, content: &str) {
create_file_in(folder, &id.to_string(), content);
}
pub fn assert_entry_equals<P: AsRef<Path>>(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<P: AsRef<Path>>(folder: P, id: Uuid) {
let path = folder.as_ref().join(id.to_string());
assert!(!path.exists(), "entry should have been deleted");
}
}