xenith-core 0.1.0

Transport-agnostic traits, types, and errors for xenith cross-chain state sync
Documentation
/// Generates the standard transport compliance test suite for any
/// [`crate::MessagingTransport`] implementation.
///
/// Invoke this macro inside a `#[cfg(test)] mod tests { ... }` block,
/// passing an expression that constructs the transport under test.
/// The constructed transport **must** include [`crate::ChainId`]`(1)` in its
/// set of supported chains; all compliance tests use chain 1 as the canonical
/// supported destination.
///
/// # Example
///
/// ```rust,ignore
/// #[cfg(test)]
/// mod tests {
///     use super::*;
///     use xenith_core::transport_compliance_tests;
///
///     transport_compliance_tests!(MyTransport::new(
///         [0u8; 20],
///         vec![(xenith_core::ChainId(1), 101u32)],
///     ));
/// }
/// ```
///
/// # Generated tests
///
/// | Test name | What it checks |
/// |---|---|
/// | `compliance_send_to_supported_chain` | `send_message` to ChainId(1) returns `Ok` |
/// | `compliance_send_to_unsupported_chain` | `send_message` to ChainId(999_999) returns `UnsupportedChain` |
/// | `compliance_estimate_fee_returns_u128` | `estimate_fee` returns `Ok(fee)` with `fee > 0` |
/// | `compliance_message_status_is_valid_variant` | `message_status` returns a recognised variant |
/// | `compliance_transport_is_send_sync` | The transport type satisfies `Send + Sync` |
#[macro_export]
macro_rules! transport_compliance_tests {
    ($constructor:expr) => {
        #[tokio::test]
        async fn compliance_send_to_supported_chain() {
            let t = $constructor;
            let result = t
                .send_message(
                    $crate::ChainId(1),
                    ::bytes::Bytes::new(),
                    $crate::SendOptions::default(),
                )
                .await;
            assert!(
                result.is_ok(),
                "send_message to a supported chain must return Ok(MessageId), got {result:?}"
            );
        }

        #[tokio::test]
        async fn compliance_send_to_unsupported_chain() {
            let t = $constructor;
            let result = t
                .send_message(
                    $crate::ChainId(999_999),
                    ::bytes::Bytes::new(),
                    $crate::SendOptions::default(),
                )
                .await;
            assert!(
                matches!(result, Err($crate::XenithError::UnsupportedChain(_))),
                "send_message to ChainId(999_999) must return Err(UnsupportedChain), got {result:?}"
            );
        }

        #[tokio::test]
        async fn compliance_estimate_fee_returns_u128() {
            let t = $constructor;
            let fee = t
                .estimate_fee($crate::ChainId(1), ::bytes::Bytes::new())
                .await
                .expect("estimate_fee must succeed for a supported chain");
            assert!(fee > 0, "estimate_fee must return a non-zero value, got {fee}");
        }

        #[tokio::test]
        async fn compliance_message_status_is_valid_variant() {
            let t = $constructor;
            let id = t
                .send_message(
                    $crate::ChainId(1),
                    ::bytes::Bytes::new(),
                    $crate::SendOptions::default(),
                )
                .await
                .expect("send_message must succeed before checking message_status");
            let status = t
                .message_status(id)
                .await
                .expect("message_status must return Ok");
            assert!(
                matches!(
                    status,
                    $crate::MessageStatus::Pending
                        | $crate::MessageStatus::InFlight
                        | $crate::MessageStatus::Delivered
                        | $crate::MessageStatus::Failed { .. }
                ),
                "message_status returned an unexpected variant: {status:?}"
            );
        }

        #[test]
        fn compliance_transport_is_send_sync() {
            fn assert_send_sync<T: Send + Sync>(_: &T) {}
            let t = $constructor;
            assert_send_sync(&t);
        }

        #[test]
        fn compliance_sender_address_is_option() {
            let t = $constructor;
            // sender_address() must compile and return Some or None — both are valid.
            let _addr: Option<[u8; 20]> = t.sender_address();
        }

        #[tokio::test]
        async fn compliance_poll_incoming_returns_vec() {
            let t = $constructor;
            let result = t.poll_incoming().await;
            assert!(
                result.is_ok(),
                "poll_incoming must return Ok(vec), got {result:?}"
            );
        }
    };
}