From 7e067fde8cbadc00b11bb9442fc59daf6d8d4073 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Sun, 22 Feb 2026 00:21:57 -0500 Subject: [PATCH] Moved client requests into lib testing. --- src/action/action_type.rs | 2 +- src/action/message.rs | 1 + src/action/user.rs | 10 +++- src/document/create.rs | 104 -------------------------------------- src/lib.rs | 37 +++++++++++--- tests/document_test.rs | 68 ++++++++++++++++++++----- 6 files changed, 95 insertions(+), 127 deletions(-) diff --git a/src/action/action_type.rs b/src/action/action_type.rs index 570c087..b66c080 100644 --- a/src/action/action_type.rs +++ b/src/action/action_type.rs @@ -5,7 +5,7 @@ pub enum Action { Addition, Create, Delete, - DocumentCreated, + DocumentCreated, Error, OnAddition, OnDelete, diff --git a/src/action/message.rs b/src/action/message.rs index a8e301d..8ba74a0 100644 --- a/src/action/message.rs +++ b/src/action/message.rs @@ -102,6 +102,7 @@ impl From for MsgAction { fn from(value: UserAction) -> Self { match value { UserAction::Addition(data) => Self::Addition(data), + UserAction::Delete(data) => Self::Delete(data), UserAction::Query(data) => Self::Query(data), UserAction::Update(data) => Self::Update(data), } diff --git a/src/action/user.rs b/src/action/user.rs index 8d7f17a..317ef02 100644 --- a/src/action/user.rs +++ b/src/action/user.rs @@ -1,9 +1,10 @@ -use super::{Addition, DocDef, FieldType, Query, Update}; +use super::{Addition, Delete, DocDef, FieldType, Query, Update}; use crate::{message::MessageAction, name::NameType}; #[derive(Clone, Debug)] pub enum UserAction { Addition(Addition), + Delete(Delete), Query(Query), Update(Update), } @@ -14,6 +15,12 @@ impl From for UserAction { } } +impl From for UserAction { + fn from(value: Delete) -> Self { + Self::Delete(value) + } +} + impl From for UserAction { fn from(value: Query) -> Self { Self::Query(value) @@ -30,6 +37,7 @@ impl MessageAction for UserAction { fn doc_name(&self) -> &NameType { match self { Self::Addition(data) => data.doc_name(), + Self::Delete(data) => data.doc_name(), Self::Query(data) => data.doc_name(), Self::Update(data) => data.doc_name(), } diff --git a/src/document/create.rs b/src/document/create.rs index ed19cf1..4ad546e 100644 --- a/src/document/create.rs +++ b/src/document/create.rs @@ -866,110 +866,6 @@ mod document_files { } } - #[test] - fn does_not_respond_to_create() { - let name = Name::english("quiet"); - let docdef = DocDef::new(name.clone()); - let mut test_doc: TestDocument = docdef.into(); - let alt = Name::english("alternate"); - test_doc.start(standard_paths()); - let docdef = DocDef::new(alt); - let msg = Message::new(docdef); - test_doc.get_queue().send(msg); - match test_doc.get_receiver().recv_timeout(TIMEOUT) { - Ok(msg) => unreachable!("should not receive: {:?}", msg), - Err(err) => match err { - RecvTimeoutError::Timeout => {} - _ => unreachable!("should have timed out"), - }, - } - } - - #[test] - fn does_document_respond_to_requests() { - let name = Name::english("listen"); - let docdef = DocDef::new(name.clone()); - let mut test_doc: TestDocument = docdef.into(); - test_doc.start(standard_paths()); - let queue = test_doc.get_queue(); - let msg_actions = [ - MsgAction::Addition(Addition::new(name.clone())), - MsgAction::Delete(Delete::new(name.clone())), - MsgAction::Query(Query::new(name.clone())), - MsgAction::Show(Show::new(name.clone())), - MsgAction::Update(Update::new(name.clone())), - ]; - for msg_action in msg_actions.iter() { - let msg = Message::new(msg_action.clone()); - queue.send(msg.clone()); - let result = match test_doc.get_receiver().recv_timeout(TIMEOUT) { - Ok(data) => data.clone(), - Err(err) => unreachable!("for {:?} got {:?}", msg_action, err), - }; - assert_eq!( - result.get_message_id(), - msg.get_message_id(), - "for {:?} response and reply ids should equal", - msg_action - ); - match result.get_action() { - MsgAction::Reply(data) => { - assert_eq!(data.len(), 0, "for {:?} got {:?}", msg_action, result) - } - MsgAction::Records(data) => { - assert_eq!(data.len(), 0, "for {:?} got {:?}", msg_action, result) - } - _ => unreachable!( - "for {:?} got {:?}: should have received a reply", - msg_action, - result.get_action() - ), - } - } - } - - #[test] - fn does_not_respond_to_other_document_requests() { - let name = Name::english("quiet"); - let alt = Name::english("alternate"); - let docdef = DocDef::new(name.clone()); - let mut test_doc: TestDocument = docdef.into(); - test_doc.start(standard_paths()); - let queue = test_doc.get_queue(); - let reg_msg = Register::new( - test_doc.get_sender_id(), - RegMsg::AddDocName([alt.clone()].to_vec()), - ); - let setup = Message::new(reg_msg.clone()); - queue.send(setup); - test_doc.get_receiver().recv_timeout(TIMEOUT).unwrap(); - let msg_actions = [ - MsgAction::Addition(Addition::new(alt.clone())), - MsgAction::Create(DocDef::new(alt.clone())), - MsgAction::Delete(Delete::new(alt.clone())), - MsgAction::Query(Query::new(alt.clone())), - MsgAction::Show(Show::new(alt.clone())), - MsgAction::Update(Update::new(alt.clone())), - ]; - let mut msgs: HashMap = HashMap::new(); - for msg_action in msg_actions.iter() { - let msg = Message::new(msg_action.clone()); - msgs.insert(msg.get_message_id().clone(), msg_action.clone()); - queue.send(msg); - } - match test_doc.get_receiver().recv_timeout(TIMEOUT) { - Ok(msg) => unreachable!( - "for {:?} should not receive: {:?}", - msgs.get(msg.get_message_id()).unwrap(), - msg - ), - Err(err) => match err { - RecvTimeoutError::Timeout => {} - _ => unreachable!("got {:?}, should have timed out", err), - }, - } - } - #[test] fn query_sends_on_query_message() { let count = 5; diff --git a/src/lib.rs b/src/lib.rs index e75e0c9..eb3cc74 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,17 +9,18 @@ pub use action::*; use document::{Clock, CreateDoc, Session}; use message::{wrapper::Message, MessageAction}; use queue::{ - data_director::{Include, Path, RegMsg, Register}, + data_director::{RegMsg, Register}, router::Queue, }; use std::{ - sync::mpsc::{channel, Receiver}, + sync::mpsc::{channel, Receiver, Sender}, time::Duration, }; use uuid::Uuid; pub use mtterror::{ErrorID, MTTError}; pub use name::{Name, NameType}; +pub use queue::data_director::{Include, Path}; #[cfg(test)] mod support_tests { @@ -38,10 +39,14 @@ pub struct MoreThanText { impl MoreThanText { pub fn new() -> Self { let queue = Queue::new(); - let mut output = Self { queue: queue.clone()}; + let mut output = Self { + queue: queue.clone(), + }; Clock::start(queue.clone()); CreateDoc::start(queue.clone()); - output.create_document(Session::document_definition()).unwrap(); + output + .create_document(Session::document_definition()) + .unwrap(); output } @@ -120,8 +125,8 @@ impl MoreThanText { Ok(data) => match data.get_action() { MsgAction::Records(data) => Ok(data.clone()), MsgAction::Error(err) => Err(err.clone()), - _ => unreachable!("should only receive records or errors") - } + _ => unreachable!("should only receive records or errors"), + }, Err(_) => Err(MTTError::new(NameType::None, ErrorID::TimeOut)), }; self.queue.remove_sender(&sender_id); @@ -155,8 +160,8 @@ impl MoreThanText { Ok(data) => match data.get_action() { MsgAction::DocumentCreated => Ok(()), MsgAction::Error(err) => Err(err.clone()), - _ => unreachable!("should only receive records or errors") - } + _ => unreachable!("should only receive records or errors"), + }, Err(_) => Err(MTTError::new(NameType::None, ErrorID::TimeOut)), }; self.queue.remove_sender(&sender_id); @@ -198,6 +203,10 @@ impl TestMoreThanText { self.mtt.records(request) } + pub fn create_document(&mut self, docdef: DocDef) -> Result<(), MTTError> { + self.mtt.create_document(docdef) + } + pub fn send_time_pulse(&self) { let msg = Clock::gen_message(); self.queue.send(msg); @@ -206,4 +215,16 @@ impl TestMoreThanText { pub fn random_name() -> Name { Name::english(Uuid::new_v4().to_string().as_str()) } + + pub fn register_channel(&self, paths: Vec) -> Receiver { + let mut queue = self.mtt.queue.clone(); + let (tx, rx) = channel(); + let sender_id = queue.add_sender(tx); + for path in paths.iter() { + let reg_msg = Register::new(sender_id.clone(), RegMsg::AddRoute(path.clone())); + queue.send(Message::new(reg_msg)); + rx.recv().unwrap(); // Wait for completion. + } + rx + } } diff --git a/tests/document_test.rs b/tests/document_test.rs index 481950d..a364a15 100644 --- a/tests/document_test.rs +++ b/tests/document_test.rs @@ -1,16 +1,11 @@ -use morethantext::{action::*, ErrorID, Name, MoreThanText, TestMoreThanText}; +use morethantext::{action::*, ErrorID, Include, MoreThanText, Name, Path, TestMoreThanText}; +use std::{ + sync::mpsc::{channel, RecvTimeoutError}, + time::Duration, +}; use uuid::Uuid; -#[test] -fn is_document_created() { - let mut mtt = MoreThanText::new(); - let doc_name = TestMoreThanText::random_name(); - let docdef = DocDef::new(doc_name.clone()); - mtt.create_document(docdef).unwrap(); - let qry = Query::new(doc_name); - let result = mtt.records(qry).unwrap(); - assert_eq!(result.len(), 0); -} +pub static TIMEOUT: Duration = Duration::from_millis(500); #[test] fn are_errors_produced_for_duplicate_names() { @@ -20,8 +15,55 @@ fn are_errors_produced_for_duplicate_names() { match mtt.create_document(docdef) { Ok(_) => assert!(false, "should have failed"), Err(err) => match err.error_id() { - ErrorID::NameAlreadyExists => {}, + ErrorID::NameAlreadyExists => {} _ => unreachable!("got {:?}, should be name already exists", err), - } + }, + } +} + +#[test] +fn does_document_respond_to() { + let mut mtt = MoreThanText::new(); + let doc_name = TestMoreThanText::random_name(); + let mut requests: Vec = Vec::new(); + requests.push(Addition::new(doc_name.clone()).into()); + requests.push(Delete::new(doc_name.clone()).into()); + requests.push(Query::new(doc_name.clone()).into()); + requests.push(Update::new(doc_name.clone()).into()); + let docdef = DocDef::new(doc_name.clone()); + mtt.create_document(docdef).unwrap(); + for req in requests.iter() { + let result = mtt.records(req.clone()).unwrap(); + assert_eq!(result.len(), 0, "from {:?}", req); + } +} + +#[test] +fn does_document_ignore_other_document_requests() { + let mut mtt = TestMoreThanText::new(); + let quiet = Name::english("quiet"); + let alt = Name::english("alt"); + mtt.create_document(DocDef::new(quiet.clone())).unwrap(); + mtt.create_document(DocDef::new(alt.clone())).unwrap(); + let paths = vec![Path::new( + Include::All, + Include::Just(quiet.clone().into()), + Include::All, + )]; + let rx = mtt.register_channel(paths); + let mut requests: Vec = Vec::new(); + requests.push(Addition::new(alt.clone()).into()); + requests.push(Delete::new(alt.clone()).into()); + requests.push(Query::new(alt.clone()).into()); + requests.push(Update::new(alt.clone()).into()); + for req in requests.iter() { + mtt.records(req.clone()).unwrap(); + } + match rx.recv_timeout(TIMEOUT) { + Ok(msg) => unreachable!("got {:?} should have timed out", msg), + Err(err) => match err { + RecvTimeoutError::Timeout => {} + _ => unreachable!("got {:?}, should have timed out", err), + }, } }