[wip] unit testing
- mock impl for `sharry::Client` and associated IDs
This commit is contained in:
parent
655db21ef4
commit
908e0031e2
2 changed files with 139 additions and 22 deletions
|
|
@ -1,11 +1,105 @@
|
||||||
|
use std::{
|
||||||
|
cell::{RefCell, RefMut},
|
||||||
|
collections::{HashMap, hash_map::Entry},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Result, file,
|
Error, Result,
|
||||||
|
file::{self, FileTrait},
|
||||||
sharry::{AliasID, Client, FileID, ShareID, Uri, json},
|
sharry::{AliasID, Client, FileID, ShareID, Uri, json},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::mock_ids::CheckID;
|
use super::mock_ids::CheckID;
|
||||||
|
|
||||||
pub struct MockClient;
|
#[derive(Debug)]
|
||||||
|
pub struct MockClient {
|
||||||
|
shares: RefCell<HashMap<String, MockShare>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct MockShare {
|
||||||
|
files: HashMap<String, MockFile>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct MockFile {
|
||||||
|
name: String,
|
||||||
|
size: u64,
|
||||||
|
offset: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MockClient {
|
||||||
|
fn insert_share(&self, share_id: &ShareID) -> Result<()> {
|
||||||
|
let mut shares = self.shares.borrow_mut();
|
||||||
|
|
||||||
|
let Entry::Vacant(entry) = shares.entry(share_id.to_string()) else {
|
||||||
|
return Err(Error::response(format_args!(
|
||||||
|
"Can't create share {share_id:?}!"
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
entry.insert(MockShare::default());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_file(
|
||||||
|
&self,
|
||||||
|
share_id: &ShareID,
|
||||||
|
file_id: &FileID,
|
||||||
|
name: String,
|
||||||
|
size: u64,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut share = self.get_share_mut(share_id)?;
|
||||||
|
|
||||||
|
let Entry::Vacant(entry) = share.files.entry(file_id.to_string()) else {
|
||||||
|
return Err(Error::response(format_args!(
|
||||||
|
"Can't create file {file_id:?}!"
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
entry.insert(MockFile {
|
||||||
|
name,
|
||||||
|
size,
|
||||||
|
offset: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_share_mut<'t>(&'t self, share_id: &ShareID) -> Result<RefMut<'t, MockShare>> {
|
||||||
|
let share_id = &share_id.to_string();
|
||||||
|
let shares = self.shares.borrow_mut();
|
||||||
|
|
||||||
|
shares
|
||||||
|
.get(share_id)
|
||||||
|
.ok_or_else(|| Error::response(format_args!("Can't find share {share_id:?}!")))?;
|
||||||
|
|
||||||
|
// share exists
|
||||||
|
Ok(RefMut::map(shares, |shares| {
|
||||||
|
shares.get_mut(share_id).expect("checked but None!")
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_file_mut<'t>(
|
||||||
|
&'t self,
|
||||||
|
share_id: &ShareID,
|
||||||
|
file_id: &FileID,
|
||||||
|
) -> Result<RefMut<'t, MockFile>> {
|
||||||
|
let file_id = &file_id.to_string();
|
||||||
|
let share = self.get_share_mut(share_id)?;
|
||||||
|
|
||||||
|
share
|
||||||
|
.files
|
||||||
|
.get(file_id)
|
||||||
|
.ok_or_else(|| Error::response(format_args!("Can't find file {file_id:?}!")))?;
|
||||||
|
|
||||||
|
// file exists
|
||||||
|
Ok(RefMut::map(share, move |share| {
|
||||||
|
share.files.get_mut(file_id).expect("checked but None!")
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Client for MockClient {
|
impl Client for MockClient {
|
||||||
fn share_create(
|
fn share_create(
|
||||||
|
|
@ -16,7 +110,10 @@ impl Client for MockClient {
|
||||||
) -> Result<ShareID> {
|
) -> Result<ShareID> {
|
||||||
(uri, alias_id).check()?;
|
(uri, alias_id).check()?;
|
||||||
|
|
||||||
Ok(true.into())
|
let share_id = true.into();
|
||||||
|
self.insert_share(&share_id)?;
|
||||||
|
|
||||||
|
Ok(share_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn share_notify(&self, uri: &Uri, alias_id: &AliasID, share_id: &ShareID) -> crate::Result<()> {
|
fn share_notify(&self, uri: &Uri, alias_id: &AliasID, share_id: &ShareID) -> crate::Result<()> {
|
||||||
|
|
@ -31,12 +128,20 @@ impl Client for MockClient {
|
||||||
uri: &Uri,
|
uri: &Uri,
|
||||||
alias_id: &AliasID,
|
alias_id: &AliasID,
|
||||||
share_id: &ShareID,
|
share_id: &ShareID,
|
||||||
_: &file::Checked,
|
file: &file::Checked,
|
||||||
) -> Result<FileID> {
|
) -> Result<FileID> {
|
||||||
(uri, alias_id).check()?;
|
(uri, alias_id).check()?;
|
||||||
share_id.check()?;
|
share_id.check()?;
|
||||||
|
|
||||||
Ok(true.into())
|
let file_id = true.into();
|
||||||
|
self.insert_file(
|
||||||
|
share_id,
|
||||||
|
&file_id,
|
||||||
|
file.get_name().to_string(),
|
||||||
|
file.get_size(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(file_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_patch(
|
fn file_patch(
|
||||||
|
|
@ -50,9 +155,10 @@ impl Client for MockClient {
|
||||||
(share_id, chunk.get_file_id()).check()?;
|
(share_id, chunk.get_file_id()).check()?;
|
||||||
|
|
||||||
// TODO: `chunk` must align to a full MiB
|
// TODO: `chunk` must align to a full MiB
|
||||||
|
let file = self.get_file_mut(share_id, chunk.get_file_id())?;
|
||||||
// Ok(())
|
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,22 @@ const VALID_ALIAS: &str = "valid-alias";
|
||||||
const VALID_SHARE: &str = "valid-share";
|
const VALID_SHARE: &str = "valid-share";
|
||||||
const VALID_FILE: &str = "valid-file";
|
const VALID_FILE: &str = "valid-file";
|
||||||
|
|
||||||
|
fn make_invalid(valid: &str) -> String {
|
||||||
|
let invalid = valid.replace("valid", "invalid");
|
||||||
|
assert_ne!(valid, invalid);
|
||||||
|
|
||||||
|
invalid
|
||||||
|
}
|
||||||
|
|
||||||
pub trait CheckID {
|
pub trait CheckID {
|
||||||
fn check(self) -> Result<()>;
|
fn check(self) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckID for (&Uri, &AliasID) {
|
impl CheckID for (&Uri, &AliasID) {
|
||||||
fn check(self) -> Result<()> {
|
fn check(self) -> Result<()> {
|
||||||
if self.0.to_string() != VALID_URI {
|
if self.0.to_string() == make_invalid(VALID_URI) {
|
||||||
Err(self.0.into())
|
Err(self.0.into())
|
||||||
} else if self.1.as_ref() != VALID_ALIAS {
|
} else if self.1.as_ref() == make_invalid(VALID_ALIAS) {
|
||||||
Err(self.1.into())
|
Err(self.1.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -26,10 +33,10 @@ impl CheckID for (&Uri, &AliasID) {
|
||||||
|
|
||||||
impl CheckID for &ShareID {
|
impl CheckID for &ShareID {
|
||||||
fn check(self) -> Result<()> {
|
fn check(self) -> Result<()> {
|
||||||
if self.to_string() == VALID_SHARE {
|
if self.to_string() == make_invalid(VALID_SHARE) {
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(self.into())
|
Err(self.into())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -38,21 +45,14 @@ impl CheckID for (&ShareID, &FileID) {
|
||||||
fn check(self) -> Result<()> {
|
fn check(self) -> Result<()> {
|
||||||
self.0.check()?;
|
self.0.check()?;
|
||||||
|
|
||||||
if self.1.to_string() == VALID_FILE {
|
if self.1.to_string() == make_invalid(VALID_FILE) {
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(self.1.into())
|
Err(self.1.into())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_invalid(valid: &str) -> String {
|
|
||||||
let invalid = valid.replace("valid", "invalid");
|
|
||||||
assert_ne!(valid, invalid);
|
|
||||||
|
|
||||||
invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<bool> for Uri {
|
impl From<bool> for Uri {
|
||||||
fn from(value: bool) -> Self {
|
fn from(value: bool) -> Self {
|
||||||
if value {
|
if value {
|
||||||
|
|
@ -111,6 +111,17 @@ mod tests {
|
||||||
assert!(matches!((&share_id, &file_id).check(), Ok(())));
|
assert!(matches!((&share_id, &file_id).check(), Ok(())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_is_valid() {
|
||||||
|
let uri = Uri::default();
|
||||||
|
let share_id = ShareID::default();
|
||||||
|
let file_id = FileID::default();
|
||||||
|
|
||||||
|
assert!(matches!((&uri, &AliasID::from(true)).check(), Ok(())));
|
||||||
|
assert!(matches!(share_id.check(), Ok(())));
|
||||||
|
assert!(matches!((&share_id, &file_id).check(), Ok(())));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn false_makes_invalids() {
|
fn false_makes_invalids() {
|
||||||
let uri = Uri::from(true);
|
let uri = Uri::from(true);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue