#![allow(clippy::vec_init_then_push)]
#![allow(unused)]
#[macro_export]
macro_rules! assert_enqueued {
(1 job, to: $backend:ident, $($tail:tt)*) => {
assert_enqueued!(@internal 1 to: $backend, $($tail)*);
};
($n:literal jobs, to: $backend:ident, $($tail:tt)*) => {
assert_enqueued!(@internal $n to: $backend, $($tail)*);
};
(1 job, $($tail:tt)*) => {
assert_enqueued!(@global 1 $($tail)*);
};
($n:literal jobs, $($tail:tt)*) => {
assert_enqueued!(@global $n $($tail)*);
};
(to: $backend:ident, $($tail:tt)*) => {
assert_enqueued!(@internal 1 to: $backend, $($tail)*);
};
(@global $n:literal $($tail:tt)*) => {{
let backend = $crate::global_backend::GlobalBackend::as_ref().expect("Global backend not set");
assert_enqueued!(@internal $n to: backend, $($tail)*);
}};
(@internal 1 to: $backend:ident, $($tail:tt)*) => {{
use $crate::backend::Query;
use $crate::backend::Backend;
let mut queries = Vec::new();
assert_enqueued!(@query queries; $($tail)*);
let jobs = $backend.query(Query::And(queries)).await.unwrap();
let all_jobs = $backend.query(Query::TagsAllOf(&[])).await.unwrap();
assert!(
!jobs.is_empty(),
"No jobs enqueue {}\n\nAll enqueued jobs:\n{all_jobs:#?}",
stringify!($($tail)*)
);
}};
(@internal $n:literal to: $backend:ident, $($tail:tt)*) => {{
use $crate::backend::Query;
use $crate::backend::Backend;
let mut queries = Vec::new();
assert_enqueued!(@query queries; $($tail)*);
let jobs = $backend.query(Query::And(queries)).await.unwrap();
let all_jobs = $backend.query(Query::TagsAllOf(&[])).await.unwrap();
assert!(
jobs.len() == $n,
"Unexpected number of jobs enqueued {},\n\n\
Expected {} jobs, found {} matching job enqueued:\n\n\
Matching jobs:\n\
{jobs:#?}\n\n\
All enqueued jobs:\n\
{all_jobs:#?}",
stringify!($($tail)*),
$n,
jobs.len(),
);
}};
(@query $vec:ident; with_data: $data:expr,) => {
$vec.push(Query::DataEquals(serde_json::to_value($data).unwrap()));
};
(@query $vec:ident; with_data: $data:expr $(, $($tail:tt)*)?) => {
$vec.push(Query::DataEquals(serde_json::to_value($data).unwrap()));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; with_metadata: $metadata:expr,) => {
$vec.push(Query::MetadataEquals(serde_json::to_value($metadata).unwrap()));
};
(@query $vec:ident; with_metadata: $metadata:expr $(, $($tail:tt)*)?) => {
$vec.push(Query::MetadataEquals(serde_json::to_value($metadata).unwrap()));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; tagged_with: $tags:expr,) => {
$vec.push(Query::TagsAllOf(&$tags));
};
(@query $vec:ident; tagged_with: $tags:expr $(, $($tail:tt)*)?) => {
$vec.push(Query::TagsAllOf(&$tags));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; scheduled_at: $scheduled_at:expr,) => {
$vec.push(Query::ScheduledAtEqual($scheduled_at));
};
(@query $vec:ident; scheduled_at: $scheduled_at:expr $(, $($tail:tt)*)?) => {
$vec.push(Query::ScheduledAtEqual($scheduled_at));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; scheduled_after: $scheduled_after:expr,) => {
$vec.push(Query::ScheduledAtAfter($scheduled_after));
};
(@query $vec:ident; scheduled_after: $scheduled_after:expr $(, $($tail:tt)*)?) => {
$vec.push(Query::ScheduledAtAfter($scheduled_after));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; scheduled_before: $scheduled_before:expr,) => {
$vec.push(Query::ScheduledAtBefore($scheduled_before));
};
(@query $vec:ident; scheduled_before: $scheduled_before:expr $(, $($tail:tt)*)?) => {
$vec.push(Query::ScheduledAtBefore($scheduled_before));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; for_executor: $executor:literal,) => {
$vec.push(Query::ExecutorEqual($executor));
};
(@query $vec:ident; for_executor: $executor:literal $(, $($tail:tt)*)?) => {
$vec.push(Query::ExecutorEqual($executor));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
(@query $vec:ident; for_executor: $executor:path,) => {{
use $executor as base;
$vec.push(Query::ExecutorEqual(base::NAME));
}};
(@query $vec:ident; for_executor: $executor:path $(, $($tail:tt)*)?) => {
use $executor as base;
$vec.push(Query::ExecutorEqual(base::NAME));
$(assert_enqueued!(@query $vec; $($tail)*))?
};
($($tail:tt)*) => {
assert_enqueued!(@global 1 $($tail)*);
};
}
pub use assert_enqueued;
#[cfg(test)]
mod test {
use chrono::{TimeDelta, Utc};
use crate::{
backend::memory::InMemoryBackend,
executor::{test::SimpleExecutor, Executor},
Rexecutor,
};
#[tokio::test]
async fn assert_enqueued() {
let backend = InMemoryBackend::new().paused();
let scheduled_at = Utc::now() + TimeDelta::minutes(5);
SimpleExecutor::builder()
.with_data("data".to_owned())
.with_metadata("metadata".to_owned())
.with_tags(vec!["tag1", "tag2", "tag3"])
.schedule_at(scheduled_at)
.enqueue_to_backend(&backend)
.await
.unwrap();
assert_enqueued!(
1 job,
to: backend,
with_data: "data".to_owned(),
for_executor: SimpleExecutor
);
assert_enqueued!(
to: backend,
with_data: "data".to_owned(),
for_executor: "simple_executor",
);
assert_enqueued!(
to: backend,
with_metadata: "metadata".to_owned(),
for_executor: SimpleExecutor
);
assert_enqueued!(
to: backend,
scheduled_at: scheduled_at,
for_executor: SimpleExecutor
);
assert_enqueued!(
to: backend,
scheduled_after: Utc::now(),
for_executor: SimpleExecutor
);
assert_enqueued!(
to: backend,
scheduled_before: Utc::now() + TimeDelta::hours(1),
for_executor: SimpleExecutor
);
assert_enqueued!(
to: backend,
with_data: "data".to_owned(),
for_executor: SimpleExecutor,
);
assert_enqueued!(
to: backend,
with_data: "data".to_owned(),
tagged_with: ["tag1", "tag2"],
for_executor: SimpleExecutor,
);
assert_enqueued!(
0 jobs,
to: backend,
with_data: "data2".to_owned(),
for_executor: SimpleExecutor
);
}
}