From 86033690f14007c0123d4bf1a7ff5478e258eba2 Mon Sep 17 00:00:00 2001 From: Tomasz Kurcz Date: Mon, 15 Apr 2024 14:24:33 +0200 Subject: [PATCH] refactor: reorganize tests --- .../tests/{tests.rs => smoke_test.rs} | 0 crates/mocks/src/backend.rs | 128 +++++++++- crates/mocks/src/encoding.rs | 15 ++ crates/storey/src/containers/column.rs | 32 +++ crates/storey/src/containers/item.rs | 24 ++ crates/storey/src/containers/map.rs | 64 +++++ crates/storey/src/containers/mod.rs | 1 - crates/storey/src/containers/test_mocks.rs | 1 - crates/storey/src/storage/branch.rs | 26 +- crates/storey/tests/backend.rs | 114 --------- crates/storey/tests/composition.rs | 37 +++ crates/storey/tests/containers.rs | 236 ------------------ crates/storey/tests/encoding.rs | 12 - crates/storey/tests/iteration.rs | 106 ++++++++ 14 files changed, 413 insertions(+), 383 deletions(-) rename crates/cw-storey/tests/{tests.rs => smoke_test.rs} (100%) delete mode 100644 crates/storey/src/containers/test_mocks.rs delete mode 100644 crates/storey/tests/backend.rs create mode 100644 crates/storey/tests/composition.rs delete mode 100644 crates/storey/tests/containers.rs delete mode 100644 crates/storey/tests/encoding.rs create mode 100644 crates/storey/tests/iteration.rs diff --git a/crates/cw-storey/tests/tests.rs b/crates/cw-storey/tests/smoke_test.rs similarity index 100% rename from crates/cw-storey/tests/tests.rs rename to crates/cw-storey/tests/smoke_test.rs diff --git a/crates/mocks/src/backend.rs b/crates/mocks/src/backend.rs index c34ccdd..413be91 100644 --- a/crates/mocks/src/backend.rs +++ b/crates/mocks/src/backend.rs @@ -1,6 +1,6 @@ use std::{cell::UnsafeCell, collections::BTreeMap}; -use storey_storage::IterableStorage as _; +use storey_storage::{IterableStorage, RevIterableStorage, StorageBackend, StorageBackendMut}; // `UnsafeCell` is needed here to implement interior mutability. // https://doc.rust-lang.org/book/ch15-05-interior-mutability.html @@ -31,14 +31,14 @@ impl Default for TestStorage { // Moreover, we can further guarantee that the dereference is valid because the data // is always initialized during construction. -impl storey_storage::StorageBackend for TestStorage { +impl StorageBackend for TestStorage { fn get(&self, key: &[u8]) -> Option> { // Safety: see above unsafe { (*self.0.get()).get(key).cloned() } } } -impl storey_storage::StorageBackendMut for TestStorage { +impl StorageBackendMut for TestStorage { fn set(&mut self, key: &[u8], value: &[u8]) { // Safety: see above unsafe { @@ -54,7 +54,7 @@ impl storey_storage::StorageBackendMut for TestStorage { } } -impl storey_storage::IterableStorage for TestStorage { +impl IterableStorage for TestStorage { type KeysIterator<'a> = Box> + 'a>; type ValuesIterator<'a> = Box> + 'a>; type PairsIterator<'a> = Box, Vec)> + 'a>; @@ -98,7 +98,7 @@ impl storey_storage::IterableStorage for TestStorage { } } -impl storey_storage::RevIterableStorage for TestStorage { +impl RevIterableStorage for TestStorage { type RevKeysIterator<'a> = Box> + 'a>; type RevValuesIterator<'a> = Box> + 'a>; type RevPairsIterator<'a> = Box, Vec)> + 'a>; @@ -141,3 +141,121 @@ fn check_bounds(v: &[u8], start: Option<&Vec>, end: Option<&Vec>) -> boo } true } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn storage_backend() { + // TODO: split this into smaller tests? + + let mut storage = TestStorage::new(); + + storage.set(&[0], b"bar"); + storage.set(&[1], b"baz"); + storage.set(&[1, 0], b"qux"); + storage.set(&[1, 1], b"quux"); + storage.set(&[2], b"qux"); + + let keys: Vec<_> = storage.keys(None, None).collect(); + assert_eq!( + keys, + vec![vec![0], vec![1], vec![1, 0], vec![1, 1], vec![2]] + ); + + let some_keys: Vec<_> = storage.keys(Some(&[1]), Some(&[2])).collect(); + assert_eq!(some_keys, vec![vec![1], vec![1, 0], vec![1, 1]]); + + let values: Vec<_> = storage.values(None, None).collect(); + assert_eq!( + values.iter().collect::>(), + vec![&b"bar"[..], b"baz", b"qux", b"quux", b"qux"] + ); + + let some_values: Vec<_> = storage.values(Some(&[1]), Some(&[2])).collect(); + assert_eq!( + some_values.iter().collect::>(), + vec![&b"baz"[..], b"qux", b"quux"] + ); + + let pairs: Vec<_> = storage.pairs(None, None).collect(); + assert_eq!( + pairs, + vec![ + (vec![0], b"bar".to_vec()), + (vec![1], b"baz".to_vec()), + (vec![1, 0], b"qux".to_vec()), + (vec![1, 1], b"quux".to_vec()), + (vec![2], b"qux".to_vec()), + ] + ); + + let some_pairs: Vec<_> = storage.pairs(Some(&[1]), Some(&[2])).collect(); + assert_eq!( + some_pairs, + vec![ + (vec![1], b"baz".to_vec()), + (vec![1, 0], b"qux".to_vec()), + (vec![1, 1], b"quux".to_vec()), + ] + ); + + let rev_keys: Vec<_> = storage.rev_keys(None, None).collect(); + assert_eq!( + rev_keys, + vec![vec![2], vec![1, 1], vec![1, 0], vec![1], vec![0]] + ); + + let some_rev_keys: Vec<_> = storage.rev_keys(Some(&[1]), Some(&[2])).collect(); + assert_eq!(some_rev_keys, vec![vec![1, 1], vec![1, 0], vec![1]]); + + let rev_values: Vec<_> = storage.rev_values(None, None).collect(); + assert_eq!( + rev_values.iter().collect::>(), + vec![&b"qux"[..], b"quux", b"qux", b"baz", b"bar"] + ); + + let some_rev_values: Vec<_> = storage.rev_values(Some(&[1]), Some(&[2])).collect(); + assert_eq!( + some_rev_values.iter().collect::>(), + vec![&b"quux"[..], b"qux", b"baz"] + ); + + let rev_pairs: Vec<_> = storage.rev_pairs(None, None).collect(); + assert_eq!( + rev_pairs, + vec![ + (vec![2], b"qux".to_vec()), + (vec![1, 1], b"quux".to_vec()), + (vec![1, 0], b"qux".to_vec()), + (vec![1], b"baz".to_vec()), + (vec![0], b"bar".to_vec()), + ] + ); + + let some_rev_pairs: Vec<_> = storage.rev_pairs(Some(&[1]), Some(&[2])).collect(); + assert_eq!( + some_rev_pairs, + vec![ + (vec![1, 1], b"quux".to_vec()), + (vec![1, 0], b"qux".to_vec()), + (vec![1], b"baz".to_vec()), + ] + ); + } + + #[test] + fn metadata() { + use storey_storage::StorageMut as _; + + let mut storage = TestStorage::new(); + storage.set_meta(&[0], b"meta"); + + assert_eq!(StorageBackend::get(&storage, &[0]), None); + assert_eq!( + StorageBackend::get(&storage, &[255, 0]), + Some(b"meta".to_vec()) + ); + } +} diff --git a/crates/mocks/src/encoding.rs b/crates/mocks/src/encoding.rs index 1d977aa..ffb2d03 100644 --- a/crates/mocks/src/encoding.rs +++ b/crates/mocks/src/encoding.rs @@ -54,3 +54,18 @@ impl MyTestEncoding for u64 { Ok(u64::from_le_bytes(bytes)) } } + +#[cfg(test)] +mod tests { + use storey_encoding::{DecodableWith as _, EncodableWith as _}; + + #[test] + fn encoding() { + assert_eq!(12u64.encode(), Ok(12u64.to_le_bytes().to_vec())); + } + + #[test] + fn decoding() { + assert_eq!(::decode(&12u64.to_le_bytes()), Ok(12)); + } +} diff --git a/crates/storey/src/containers/column.rs b/crates/storey/src/containers/column.rs index e99d95b..48b7b02 100644 --- a/crates/storey/src/containers/column.rs +++ b/crates/storey/src/containers/column.rs @@ -207,3 +207,35 @@ pub enum LenError { #[error("inconsistent state")] InconsistentState, } + +#[cfg(test)] +mod tests { + use super::*; + + use mocks::backend::TestStorage; + use mocks::encoding::TestEncoding; + + #[test] + fn column() { + let mut storage = TestStorage::new(); + + let column = Column::::new(&[0]); + let mut access = column.access(&mut storage); + + access.push(&1337).unwrap(); + access.push(&42).unwrap(); + + assert_eq!(access.get(0).unwrap(), Some(1337)); + assert_eq!(access.get(1).unwrap(), Some(42)); + assert_eq!(access.get(2).unwrap(), None); + assert_eq!(access.len().unwrap(), 2); + + access.remove(0).unwrap(); + assert_eq!(access.update(0, &9001), Err(UpdateError::NotFound)); + access.update(1, &9001).unwrap(); + + assert_eq!(access.get(0).unwrap(), None); + assert_eq!(access.get(1).unwrap(), Some(9001)); + assert_eq!(access.len().unwrap(), 1); + } +} diff --git a/crates/storey/src/containers/item.rs b/crates/storey/src/containers/item.rs index c88fd4a..cf4ff57 100644 --- a/crates/storey/src/containers/item.rs +++ b/crates/storey/src/containers/item.rs @@ -89,3 +89,27 @@ where Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + + use mocks::backend::TestStorage; + use mocks::encoding::TestEncoding; + + #[test] + fn item() { + let mut storage = TestStorage::new(); + + let item0 = Item::::new(&[0]); + item0.access(&mut storage).set(&42).unwrap(); + + let item1 = Item::::new(&[1]); + let access1 = item1.access(&storage); + + assert_eq!(item0.access(&storage).get().unwrap(), Some(42)); + assert_eq!(storage.get(&[0]), Some(42u64.to_le_bytes().to_vec())); + assert_eq!(access1.get().unwrap(), None); + assert_eq!(storage.get(&[1]), None); + } +} diff --git a/crates/storey/src/containers/map.rs b/crates/storey/src/containers/map.rs index 7a0e7d5..e71ffcf 100644 --- a/crates/storey/src/containers/map.rs +++ b/crates/storey/src/containers/map.rs @@ -148,3 +148,67 @@ impl Key for str { self.as_bytes() } } + +#[cfg(test)] +mod tests { + use super::*; + + use crate::containers::Item; + + use mocks::backend::TestStorage; + use mocks::encoding::TestEncoding; + use storey_storage::Storage as _; + + #[test] + fn map() { + let mut storage = TestStorage::new(); + + let map = Map::>::new(&[0]); + + map.access(&mut storage) + .entry_mut("foo") + .set(&1337) + .unwrap(); + + assert_eq!(map.access(&storage).entry("foo").get().unwrap(), Some(1337)); + assert_eq!( + storage.get(&[0, 3, 102, 111, 111]), + Some(1337u64.to_le_bytes().to_vec()) + ); + assert_eq!(map.access(&storage).entry("bar").get().unwrap(), None); + } + + #[test] + fn map_of_map() { + let mut storage = TestStorage::new(); + + let map = Map::>>::new(&[0]); + + map.access(&mut storage) + .entry_mut("foo") + .entry_mut("bar") + .set(&1337) + .unwrap(); + + assert_eq!( + map.access(&storage) + .entry("foo") + .entry("bar") + .get() + .unwrap(), + Some(1337) + ); + assert_eq!( + storage.get(&[0, 3, 102, 111, 111, 3, 98, 97, 114]), + Some(1337u64.to_le_bytes().to_vec()) + ); + assert_eq!( + map.access(&storage) + .entry("foo") + .entry("baz") + .get() + .unwrap(), + None + ); + } +} diff --git a/crates/storey/src/containers/mod.rs b/crates/storey/src/containers/mod.rs index 315eed2..0e0c6c1 100644 --- a/crates/storey/src/containers/mod.rs +++ b/crates/storey/src/containers/mod.rs @@ -1,7 +1,6 @@ pub mod column; mod item; mod map; -mod test_mocks; use std::marker::PhantomData; diff --git a/crates/storey/src/containers/test_mocks.rs b/crates/storey/src/containers/test_mocks.rs deleted file mode 100644 index 8b13789..0000000 --- a/crates/storey/src/containers/test_mocks.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/storey/src/storage/branch.rs b/crates/storey/src/storage/branch.rs index e33004c..4b8e49e 100644 --- a/crates/storey/src/storage/branch.rs +++ b/crates/storey/src/storage/branch.rs @@ -204,24 +204,22 @@ where mod tests { use super::*; - // TODO: move TestStorage and use it for these unit tests? + use mocks::backend::TestStorage; - // use crate::backend::TestStorage; - - // #[test] - // fn storage_branch() { - // let storage = TestStorage::new(); - // let branch = StorageBranch::new(&storage, b"foo".to_vec()); + #[test] + fn storage_branch() { + let mut storage = TestStorage::new(); + let mut branch = StorageBranch::new(&mut storage, b"foo".to_vec()); - // branch.set(b"bar", b"baz"); - // branch.set(b"qux", b"quux"); + branch.set(b"bar", b"baz"); + branch.set(b"qux", b"quux"); - // assert_eq!(storage.get(b"bar"), None); - // assert_eq!(storage.get(b"qux"), None); + assert_eq!(storage.get(b"bar"), None); + assert_eq!(storage.get(b"qux"), None); - // assert_eq!(storage.get(b"foobar"), Some(b"baz".to_vec())); - // assert_eq!(storage.get(b"fooqux"), Some(b"quux".to_vec())); - // } + assert_eq!(storage.get(b"foobar"), Some(b"baz".to_vec())); + assert_eq!(storage.get(b"fooqux"), Some(b"quux".to_vec())); + } #[test] fn sub_bounds_no_prefix() { diff --git a/crates/storey/tests/backend.rs b/crates/storey/tests/backend.rs deleted file mode 100644 index 4ef0214..0000000 --- a/crates/storey/tests/backend.rs +++ /dev/null @@ -1,114 +0,0 @@ -#[test] -fn storage_backend() { - // TODO: split this into multiple tests? - - use storey::storage::{IterableStorage as _, RevIterableStorage as _, StorageMut as _}; - - let mut storage = mocks::backend::TestStorage::new(); - - storage.set(&[0], b"bar"); - storage.set(&[1], b"baz"); - storage.set(&[1, 0], b"qux"); - storage.set(&[1, 1], b"quux"); - storage.set(&[2], b"qux"); - - let keys: Vec<_> = storage.keys(None, None).collect(); - assert_eq!( - keys, - vec![vec![0], vec![1], vec![1, 0], vec![1, 1], vec![2]] - ); - - let some_keys: Vec<_> = storage.keys(Some(&[1]), Some(&[2])).collect(); - assert_eq!(some_keys, vec![vec![1], vec![1, 0], vec![1, 1]]); - - let values: Vec<_> = storage.values(None, None).collect(); - assert_eq!( - values.iter().collect::>(), - vec![&b"bar"[..], b"baz", b"qux", b"quux", b"qux"] - ); - - let some_values: Vec<_> = storage.values(Some(&[1]), Some(&[2])).collect(); - assert_eq!( - some_values.iter().collect::>(), - vec![&b"baz"[..], b"qux", b"quux"] - ); - - let pairs: Vec<_> = storage.pairs(None, None).collect(); - assert_eq!( - pairs, - vec![ - (vec![0], b"bar".to_vec()), - (vec![1], b"baz".to_vec()), - (vec![1, 0], b"qux".to_vec()), - (vec![1, 1], b"quux".to_vec()), - (vec![2], b"qux".to_vec()), - ] - ); - - let some_pairs: Vec<_> = storage.pairs(Some(&[1]), Some(&[2])).collect(); - assert_eq!( - some_pairs, - vec![ - (vec![1], b"baz".to_vec()), - (vec![1, 0], b"qux".to_vec()), - (vec![1, 1], b"quux".to_vec()), - ] - ); - - let rev_keys: Vec<_> = storage.rev_keys(None, None).collect(); - assert_eq!( - rev_keys, - vec![vec![2], vec![1, 1], vec![1, 0], vec![1], vec![0]] - ); - - let some_rev_keys: Vec<_> = storage.rev_keys(Some(&[1]), Some(&[2])).collect(); - assert_eq!(some_rev_keys, vec![vec![1, 1], vec![1, 0], vec![1]]); - - let rev_values: Vec<_> = storage.rev_values(None, None).collect(); - assert_eq!( - rev_values.iter().collect::>(), - vec![&b"qux"[..], b"quux", b"qux", b"baz", b"bar"] - ); - - let some_rev_values: Vec<_> = storage.rev_values(Some(&[1]), Some(&[2])).collect(); - assert_eq!( - some_rev_values.iter().collect::>(), - vec![&b"quux"[..], b"qux", b"baz"] - ); - - let rev_pairs: Vec<_> = storage.rev_pairs(None, None).collect(); - assert_eq!( - rev_pairs, - vec![ - (vec![2], b"qux".to_vec()), - (vec![1, 1], b"quux".to_vec()), - (vec![1, 0], b"qux".to_vec()), - (vec![1], b"baz".to_vec()), - (vec![0], b"bar".to_vec()), - ] - ); - - let some_rev_pairs: Vec<_> = storage.rev_pairs(Some(&[1]), Some(&[2])).collect(); - assert_eq!( - some_rev_pairs, - vec![ - (vec![1, 1], b"quux".to_vec()), - (vec![1, 0], b"qux".to_vec()), - (vec![1], b"baz".to_vec()), - ] - ); -} - -#[test] -fn metadata() { - use storey::storage::StorageMut as _; - - let mut storage = mocks::backend::TestStorage::new(); - storage.set_meta(&[0], b"meta"); - - assert_eq!(storey::storage::StorageBackend::get(&storage, &[0]), None); - assert_eq!( - storey::storage::StorageBackend::get(&storage, &[255, 0]), - Some(b"meta".to_vec()) - ); -} diff --git a/crates/storey/tests/composition.rs b/crates/storey/tests/composition.rs new file mode 100644 index 0000000..25c4263 --- /dev/null +++ b/crates/storey/tests/composition.rs @@ -0,0 +1,37 @@ +use storey::containers::{Column, IterableAccessor as _, Map}; + +use mocks::backend::TestStorage; +use mocks::encoding::TestEncoding; + +#[test] +fn map_of_column() { + let mut storage = TestStorage::new(); + + let map = Map::>::new(&[0]); + let mut access = map.access(&mut storage); + + access.entry_mut("foo").push(&1337).unwrap(); + access.entry_mut("foo").push(&42).unwrap(); + access.entry_mut("bar").push(&9001).unwrap(); + + assert_eq!(access.entry("foo").get(0).unwrap(), Some(1337)); + assert_eq!(access.entry("foo").get(1).unwrap(), Some(42)); + assert_eq!(access.entry("foo").get(2).unwrap(), None); + assert_eq!(access.entry("foo").len().unwrap(), 2); + + assert_eq!(access.entry("bar").get(0).unwrap(), Some(9001)); + assert_eq!(access.entry("bar").len().unwrap(), 1); + + let all = access + .pairs(None, None) + .collect::, _>>() + .unwrap(); + assert_eq!( + all, + vec![ + (("bar".to_string(), 0), 9001), + (("foo".to_string(), 0), 1337), + (("foo".to_string(), 1), 42) + ] + ); +} diff --git a/crates/storey/tests/containers.rs b/crates/storey/tests/containers.rs deleted file mode 100644 index 0c14790..0000000 --- a/crates/storey/tests/containers.rs +++ /dev/null @@ -1,236 +0,0 @@ -use storey::containers::{Column, Item, IterableAccessor as _, Map}; -use storey::storage::Storage as _; - -use mocks::backend::TestStorage; -use mocks::encoding::TestEncoding; - -#[test] -fn item() { - let mut storage = TestStorage::new(); - - let item0 = Item::::new(&[0]); - item0.access(&mut storage).set(&42).unwrap(); - - let item1 = Item::::new(&[1]); - let access1 = item1.access(&storage); - - assert_eq!(item0.access(&storage).get().unwrap(), Some(42)); - assert_eq!(storage.get(&[0]), Some(42u64.to_le_bytes().to_vec())); - assert_eq!(access1.get().unwrap(), None); - assert_eq!(storage.get(&[1]), None); -} - -#[test] -fn map() { - let mut storage = TestStorage::new(); - - let map = Map::>::new(&[0]); - - map.access(&mut storage) - .entry_mut("foo") - .set(&1337) - .unwrap(); - - assert_eq!(map.access(&storage).entry("foo").get().unwrap(), Some(1337)); - assert_eq!( - storage.get(&[0, 3, 102, 111, 111]), - Some(1337u64.to_le_bytes().to_vec()) - ); - assert_eq!(map.access(&storage).entry("bar").get().unwrap(), None); -} - -#[test] -fn map_of_map() { - let mut storage = TestStorage::new(); - - let map = Map::>>::new(&[0]); - - map.access(&mut storage) - .entry_mut("foo") - .entry_mut("bar") - .set(&1337) - .unwrap(); - - assert_eq!( - map.access(&storage) - .entry("foo") - .entry("bar") - .get() - .unwrap(), - Some(1337) - ); - assert_eq!( - storage.get(&[0, 3, 102, 111, 111, 3, 98, 97, 114]), - Some(1337u64.to_le_bytes().to_vec()) - ); - assert_eq!( - map.access(&storage) - .entry("foo") - .entry("baz") - .get() - .unwrap(), - None - ); -} - -#[test] -fn simple_iteration() { - let mut storage = TestStorage::new(); - - let map = Map::>::new(&[0]); - let mut access = map.access(&mut storage); - - access.entry_mut("foo").set(&1337).unwrap(); - access.entry_mut("bar").set(&42).unwrap(); - - let items = access - .pairs(None, None) - .collect::, _>>() - .unwrap(); - assert_eq!( - items, - vec![ - (("bar".to_string(), ()), 42), - (("foo".to_string(), ()), 1337) - ] - ); -} - -#[test] -fn keys_iteration() { - let mut storage = TestStorage::new(); - - let map = Map::>::new(&[0]); - let mut access = map.access(&mut storage); - - access.entry_mut("foo").set(&1337).unwrap(); - access.entry_mut("bar").set(&42).unwrap(); - - let keys = access - .keys(None, None) - .collect::, _>>() - .unwrap(); - assert_eq!(keys, vec![("bar".to_string(), ()), ("foo".to_string(), ())]) -} - -#[test] -fn values_iteration() { - let mut storage = TestStorage::new(); - - let map = Map::>::new(&[0]); - let mut access = map.access(&mut storage); - - access.entry_mut("foo").set(&1337).unwrap(); - access.entry_mut("bar").set(&42).unwrap(); - - let values = access - .values(None, None) - .collect::, _>>() - .unwrap(); - assert_eq!(values, vec![42, 1337]) -} - -#[test] -fn composable_iteration() { - let mut storage = TestStorage::new(); - - let map = Map::>>::new(&[0]); - let mut access = map.access(&mut storage); - - // populate with data - access.entry_mut("foo").entry_mut("bar").set(&1337).unwrap(); - access.entry_mut("foo").entry_mut("baz").set(&42).unwrap(); - access - .entry_mut("qux") - .entry_mut("quux") - .set(&9001) - .unwrap(); - - // iterate over all items - let items = access - .pairs(None, None) - .collect::, _>>() - .unwrap(); - assert_eq!( - items, - vec![ - (("foo".to_string(), ("bar".to_string(), ())), 1337), - (("foo".to_string(), ("baz".to_string(), ())), 42), - (("qux".to_string(), ("quux".to_string(), ())), 9001) - ] - ); - - // iterate over items under "foo" - let items = access - .entry("foo") - .pairs(None, None) - .collect::, _>>() - .unwrap(); - assert_eq!( - items, - vec![ - (("bar".to_string(), ()), 1337), - (("baz".to_string(), ()), 42) - ] - ); -} - -#[test] -fn column() { - let mut storage = TestStorage::new(); - - let column = Column::::new(&[0]); - let mut access = column.access(&mut storage); - - access.push(&1337).unwrap(); - access.push(&42).unwrap(); - - assert_eq!(access.get(0).unwrap(), Some(1337)); - assert_eq!(access.get(1).unwrap(), Some(42)); - assert_eq!(access.get(2).unwrap(), None); - assert_eq!(access.len().unwrap(), 2); - - access.remove(0).unwrap(); - assert_eq!( - access.update(0, &9001), - Err(storey::containers::column::UpdateError::NotFound) - ); - access.update(1, &9001).unwrap(); - - assert_eq!(access.get(0).unwrap(), None); - assert_eq!(access.get(1).unwrap(), Some(9001)); - assert_eq!(access.len().unwrap(), 1); -} - -#[test] -fn map_of_column() { - let mut storage = TestStorage::new(); - - let map = Map::>::new(&[0]); - let mut access = map.access(&mut storage); - - access.entry_mut("foo").push(&1337).unwrap(); - access.entry_mut("foo").push(&42).unwrap(); - access.entry_mut("bar").push(&9001).unwrap(); - - assert_eq!(access.entry("foo").get(0).unwrap(), Some(1337)); - assert_eq!(access.entry("foo").get(1).unwrap(), Some(42)); - assert_eq!(access.entry("foo").get(2).unwrap(), None); - assert_eq!(access.entry("foo").len().unwrap(), 2); - - assert_eq!(access.entry("bar").get(0).unwrap(), Some(9001)); - assert_eq!(access.entry("bar").len().unwrap(), 1); - - let all = access - .pairs(None, None) - .collect::, _>>() - .unwrap(); - assert_eq!( - all, - vec![ - (("bar".to_string(), 0), 9001), - (("foo".to_string(), 0), 1337), - (("foo".to_string(), 1), 42) - ] - ); -} diff --git a/crates/storey/tests/encoding.rs b/crates/storey/tests/encoding.rs deleted file mode 100644 index c4c1584..0000000 --- a/crates/storey/tests/encoding.rs +++ /dev/null @@ -1,12 +0,0 @@ -use mocks as _; -use storey::encoding::{DecodableWith as _, EncodableWith as _}; - -#[test] -fn encoding() { - assert_eq!(12u64.encode(), Ok(12u64.to_le_bytes().to_vec())); -} - -#[test] -fn decoding() { - assert_eq!(::decode(&12u64.to_le_bytes()), Ok(12)); -} diff --git a/crates/storey/tests/iteration.rs b/crates/storey/tests/iteration.rs new file mode 100644 index 0000000..95e9274 --- /dev/null +++ b/crates/storey/tests/iteration.rs @@ -0,0 +1,106 @@ +use storey::containers::{Item, IterableAccessor as _, Map}; + +use mocks::backend::TestStorage; +use mocks::encoding::TestEncoding; + +#[test] +fn pairs_iteration() { + let mut storage = TestStorage::new(); + + let map = Map::>::new(&[0]); + let mut access = map.access(&mut storage); + + access.entry_mut("foo").set(&1337).unwrap(); + access.entry_mut("bar").set(&42).unwrap(); + + let items = access + .pairs(None, None) + .collect::, _>>() + .unwrap(); + assert_eq!( + items, + vec![ + (("bar".to_string(), ()), 42), + (("foo".to_string(), ()), 1337) + ] + ); +} + +#[test] +fn keys_iteration() { + let mut storage = TestStorage::new(); + + let map = Map::>::new(&[0]); + let mut access = map.access(&mut storage); + + access.entry_mut("foo").set(&1337).unwrap(); + access.entry_mut("bar").set(&42).unwrap(); + + let keys = access + .keys(None, None) + .collect::, _>>() + .unwrap(); + assert_eq!(keys, vec![("bar".to_string(), ()), ("foo".to_string(), ())]) +} + +#[test] +fn values_iteration() { + let mut storage = TestStorage::new(); + + let map = Map::>::new(&[0]); + let mut access = map.access(&mut storage); + + access.entry_mut("foo").set(&1337).unwrap(); + access.entry_mut("bar").set(&42).unwrap(); + + let values = access + .values(None, None) + .collect::, _>>() + .unwrap(); + assert_eq!(values, vec![42, 1337]) +} + +#[test] +fn complex_type_iteration() { + let mut storage = TestStorage::new(); + + let map = Map::>>::new(&[0]); + let mut access = map.access(&mut storage); + + // populate with data + access.entry_mut("foo").entry_mut("bar").set(&1337).unwrap(); + access.entry_mut("foo").entry_mut("baz").set(&42).unwrap(); + access + .entry_mut("qux") + .entry_mut("quux") + .set(&9001) + .unwrap(); + + // iterate over all items + let items = access + .pairs(None, None) + .collect::, _>>() + .unwrap(); + assert_eq!( + items, + vec![ + (("foo".to_string(), ("bar".to_string(), ())), 1337), + (("foo".to_string(), ("baz".to_string(), ())), 42), + (("qux".to_string(), ("quux".to_string(), ())), 9001) + ] + ); + + // iterate over items under "foo" + let items = access + .entry("foo") + .pairs(None, None) + .collect::, _>>() + .unwrap(); + assert_eq!( + items, + vec![ + (("bar".to_string(), ()), 1337), + (("baz".to_string(), ()), 42) + ] + ); +}