use std::io::{Read, Write}; use uuid::Uuid; use dodo::storage::{Memory, Result, Storage}; #[test] fn can_create_memory_storage() { Memory::new(); } #[test] fn can_create_new_entry() { let mut storage = Memory::new(); 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(&storage, id, "content"); } #[test] fn new_entry_created_when_writer_is_dropped() { let mut storage = Memory::new(); 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"); fixture::assert_entry_not_exists(&storage, id); id }; fixture::assert_entry_equals(&storage, id, "content"); } #[test] fn can_read_existing_entry() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); 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 storage = Memory::new(); let entry = storage.read(Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap()); assert!(entry.expect_err("entry should not exist").is_not_found(), "entry should not have been readable"); } #[test] fn can_write_to_absent_entry() { let mut storage = Memory::new(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); { 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(&storage, id, "content"); } #[test] fn can_write_to_existing_entry() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); { 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(&storage, id, "new content"); } #[test] fn writen_entry_created_when_writer_is_dropped() { let mut storage = Memory::new(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); { let mut write = storage.write(id).expect("could not write to storage"); write!(&mut write, "{}", "content").expect("could not write entry"); fixture::assert_entry_not_exists(&storage, id); }; fixture::assert_entry_equals(&storage, id, "content"); } #[test] fn should_not_modify_entry_while_writing() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); let mut read = storage.read(id).expect("entry should have been readable"); { let mut write = storage.write(id).expect("could not write to storage"); write!(&mut write, "{}", "new content").expect("could not write entry"); } let mut bytes = String::new(); read.read_to_string(&mut bytes).expect("could not read entry"); assert_eq!(bytes, "content", "entry was read incorrectly"); } #[test] fn can_overwrite_existing_entry() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); { 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(&storage, id, "new content"); } #[test] fn cant_overwrite_absent_entry() { let mut storage = Memory::new(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let entry = storage.overwrite(id); assert!(entry.is_err(), "entry should not have been writen"); } #[test] fn should_not_modify_entry_while_overwriting() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); let mut read = storage.read(id).expect("could not read storage"); { let mut write = storage.overwrite(id).expect("could not write to storage"); write!(&mut write, "{}", "new content").expect("could not write entry"); } let mut bytes = String::new(); read.read_to_string(&mut bytes).expect("could not read entry"); assert_eq!(bytes, "content", "entry was read incorrectly"); } #[test] fn can_delete_existing_entry() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); let deleted = storage.delete(id).expect("could not delete from storage"); assert!(deleted, "something should have been deleted"); fixture::assert_entry_not_exists(&storage, id); } #[test] fn should_not_modify_entry_while_deleting() { let mut storage = Memory::new(); let id = fixture::create_entry(&mut storage, "content"); let mut read = storage.read(id).expect("could not read storage"); storage.delete(id).expect("could not delete from storage"); let mut bytes = String::new(); read.read_to_string(&mut bytes).expect("could not read entry"); assert_eq!(bytes, "content", "entry was read incorrectly"); } #[test] fn can_delete_absent_entry() { let mut storage = Memory::new(); let id = Uuid::parse_str("78190929-3d84-4735-9e40-80e3cd5530e9").unwrap(); let deleted = storage.delete(id).expect("could not delete from storage"); assert!(!deleted, "nothing should have been deleted"); fixture::assert_entry_not_exists(&storage, id); } #[test] fn can_clear_storage() { let mut storage = Memory::new(); let id1 = fixture::create_entry(&mut storage, "content"); let id2 = fixture::create_entry(&mut storage, "content"); storage.clear().expect("could not clear storage"); fixture::assert_entry_not_exists(&storage, id1); fixture::assert_entry_not_exists(&storage, id2); } #[test] fn can_clear_empty_storage() { let mut storage = Memory::new(); storage.clear().expect("could not clear storage"); } #[test] fn can_list_existing_entries() { let mut storage = Memory::new(); let id1 = fixture::create_entry(&mut storage, "content"); let id2 = fixture::create_entry(&mut storage, "content"); 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::io::{Read, Write}; use uuid::Uuid; use dodo::{Memory, Storage}; pub fn create_entry(storage: &mut Memory, content: &str) -> Uuid { let (id, mut write) = storage.new().expect("could not write to storage"); write!(&mut write, "{}", content).expect("could not write entry"); id } pub fn assert_entry_equals(storage: &Memory, id: Uuid, expected_content: &str) { let mut reader = storage.read(id).expect("entry does not exist"); let mut actual_content = String::new(); reader.read_to_string(&mut actual_content).expect("entry could not be read"); assert_eq!(expected_content, actual_content, "entry has the wrong contents"); } pub fn assert_entry_not_exists(storage: &Memory, id: Uuid) { assert!(storage.read(id).expect_err("entry should not exist").is_not_found(), "entry should not exist"); } }