#![allow(clippy::unwrap_used, clippy::expect_used)]
use super::*;
use crate::error::Error;
use crate::types::{Capability, SequenceSet};
#[test]
fn two_command_pipeline_builds() {
let pipeline: Pipeline<'_, (Vec<Capability>, ((), ()))> =
DetachedPipeline::create().noop().capability();
assert_eq!(pipeline.commands.len(), 2);
assert_eq!(pipeline.pending.len(), 2);
}
#[test]
fn unfold_two_element_tuple_ok() {
let results: Vec<Result<Box<dyn std::any::Any + Send>, Error>> =
vec![Ok(Box::new(())), Ok(Box::new(vec![Capability::Imap4Rev1]))];
let (r0, r1) = <(Vec<Capability>, ((), ()))>::unfold(results).unwrap();
assert!(r0.is_ok());
assert_eq!(r0.unwrap(), ());
let caps = r1.unwrap();
assert_eq!(caps, vec![Capability::Imap4Rev1]);
}
#[test]
fn unfold_two_element_tuple_with_command_error() {
let results: Vec<Result<Box<dyn std::any::Any + Send>, Error>> = vec![
Err(Error::Protocol("test error".into())),
Ok(Box::new(vec![Capability::Imap4Rev1])),
];
let (r0, r1) = <(Vec<Capability>, ((), ()))>::unfold(results).unwrap();
assert!(r0.is_err());
assert!(r1.is_ok());
}
#[test]
fn unfold_type_mismatch() {
let results: Vec<Result<Box<dyn std::any::Any + Send>, Error>> = vec![
Ok(Box::new("wrong type".to_string())),
Ok(Box::new(vec![Capability::Imap4Rev1])),
];
let err = <(Vec<Capability>, ((), ()))>::unfold(results).unwrap_err();
assert!(matches!(err, PipelineError::TypeMismatch { index: 0 }));
}
#[test]
fn unfold_empty() {
let results: Vec<Result<Box<dyn std::any::Any + Send>, Error>> = vec![];
let () = <()>::unfold(results).unwrap();
}
#[test]
fn unfold_single() {
let results: Vec<Result<Box<dyn std::any::Any + Send>, Error>> = vec![Ok(Box::new(42u32))];
let (r0,) = <(u32, ())>::unfold(results).unwrap();
assert_eq!(r0.unwrap(), 42u32);
}
#[test]
fn three_command_pipeline_builds() {
let pipeline = DetachedPipeline::create().noop().capability().fetch(
SequenceSet::new("1:*").unwrap(),
"FLAGS".to_string(),
None,
);
assert_eq!(pipeline.commands.len(), 3);
assert_eq!(pipeline.pending.len(), 3);
}
struct DetachedPipeline;
impl DetachedPipeline {
fn create<'a>() -> Pipeline<'a, ()> {
let (cmd_tx, _cmd_rx) = tokio::sync::mpsc::channel(1);
let (_state_tx, state_rx) =
tokio::sync::watch::channel(super::super::driver::ConnectionStateSnapshot::default());
let (_events_tx, events_rx) = tokio::sync::mpsc::channel(1);
let conn = super::super::ImapConnection {
cmd_tx,
state_rx,
events_rx: tokio::sync::Mutex::new(events_rx),
driver_handle: tokio::sync::Mutex::new(None),
prebuilt_tag_counter: std::sync::atomic::AtomicU32::new(0),
host: String::new(),
};
let conn_ref: &'a super::super::ImapConnection = Box::leak(Box::new(conn));
Pipeline::new(conn_ref)
}
}