Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize tests #26

Merged
merged 1 commit into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
128 changes: 123 additions & 5 deletions crates/mocks/src/backend.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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<Vec<u8>> {
// 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 {
Expand All @@ -54,7 +54,7 @@ impl storey_storage::StorageBackendMut for TestStorage {
}
}

impl storey_storage::IterableStorage for TestStorage {
impl IterableStorage for TestStorage {
type KeysIterator<'a> = Box<dyn DoubleEndedIterator<Item = Vec<u8>> + 'a>;
type ValuesIterator<'a> = Box<dyn DoubleEndedIterator<Item = Vec<u8>> + 'a>;
type PairsIterator<'a> = Box<dyn DoubleEndedIterator<Item = (Vec<u8>, Vec<u8>)> + 'a>;
Expand Down Expand Up @@ -98,7 +98,7 @@ impl storey_storage::IterableStorage for TestStorage {
}
}

impl storey_storage::RevIterableStorage for TestStorage {
impl RevIterableStorage for TestStorage {
type RevKeysIterator<'a> = Box<dyn Iterator<Item = Vec<u8>> + 'a>;
type RevValuesIterator<'a> = Box<dyn Iterator<Item = Vec<u8>> + 'a>;
type RevPairsIterator<'a> = Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a>;
Expand Down Expand Up @@ -141,3 +141,121 @@ fn check_bounds(v: &[u8], start: Option<&Vec<u8>>, end: Option<&Vec<u8>>) -> 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<_>>(),
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<_>>(),
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<_>>(),
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<_>>(),
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())
);
}
}
15 changes: 15 additions & 0 deletions crates/mocks/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(<u64>::decode(&12u64.to_le_bytes()), Ok(12));
}
}
32 changes: 32 additions & 0 deletions crates/storey/src/containers/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<u64, TestEncoding>::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);
}
}
24 changes: 24 additions & 0 deletions crates/storey/src/containers/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<u64, TestEncoding>::new(&[0]);
item0.access(&mut storage).set(&42).unwrap();

let item1 = Item::<u64, TestEncoding>::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);
}
}
64 changes: 64 additions & 0 deletions crates/storey/src/containers/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<String, Item<u64, TestEncoding>>::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::<String, Map<String, Item<u64, TestEncoding>>>::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
);
}
}
1 change: 0 additions & 1 deletion crates/storey/src/containers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pub mod column;
mod item;
mod map;
mod test_mocks;

use std::marker::PhantomData;

Expand Down
1 change: 0 additions & 1 deletion crates/storey/src/containers/test_mocks.rs

This file was deleted.

26 changes: 12 additions & 14 deletions crates/storey/src/storage/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Loading
Loading