product-os-async-executor 0.0.20

Product OS : Async Executor provides a set of tools to handle async execution generically so that the desired async library (e.g. tokio, smol) to be used can be chosen at compile time.
Documentation
// API compatibility tests - ensures public API remains unchanged

use product_os_async_executor::BoxError;

#[cfg(feature = "moment")]
use product_os_async_executor::moment::Moment;

#[test]
fn test_box_error_type_exists() {
    use product_os_async_executor::read_write::IoError;
    let _error: BoxError = Box::new(IoError(String::from("test")));
}

#[test]
fn test_ioslice_type_exists() {
    use product_os_async_executor::IoSlice;
    fn _type_check(_: &IoSlice) {}
}

#[cfg(feature = "moment")]
#[test]
fn test_moment_default() {
    let moment = Moment::default();
    let now = moment.now();
    assert!(now.timestamp() > 0);
}

#[cfg(feature = "moment")]
#[test]
fn test_moment_new_with_function() {
    let custom_time = || chrono::Utc::now();
    let moment = Moment::new(Some(custom_time));
    let now = moment.now();
    assert!(now.timestamp() > 0);
}

#[cfg(feature = "moment")]
#[test]
fn test_moment_clone() {
    let moment = Moment::default();
    let cloned = moment.clone();
    let time1 = moment.now();
    let time2 = cloned.now();
    assert!(time1.timestamp() > 0);
    assert!(time2.timestamp() > 0);
}

#[cfg(feature = "moment")]
#[test]
fn test_moment_get_function() {
    let custom_time = || chrono::Utc::now();
    let moment = Moment::new(Some(custom_time));
    let func = moment.get_function();
    let time = func();
    assert!(time.timestamp() > 0);
}

#[cfg(feature = "moment")]
#[test]
fn test_moment_debug() {
    let moment = Moment::default();
    let debug_str = format!("{:?}", moment);
    assert!(debug_str.contains("Moment"));
}

// Test that chrono types are re-exported via specific re-exports
#[test]
fn test_chrono_reexports() {
    use product_os_async_executor::{DateTime, Utc};
    let _now: DateTime<Utc> = Utc::now();
}

#[test]
fn test_chrono_duration_reexport() {
    use product_os_async_executor::ChronoDuration;
    let _dur = ChronoDuration::seconds(5);
}

// Test read_write module exports
#[test]
fn test_async_read_trait_exists() {
    use product_os_async_executor::read_write::AsyncRead;
    use std::pin::Pin;
    use std::task::{Context, Poll};

    struct DummyReader;

    impl AsyncRead for DummyReader {
        fn poll_read(
            self: Pin<&mut Self>,
            _cx: &mut Context<'_>,
            buf: &mut [u8],
        ) -> Poll<Result<usize, product_os_async_executor::BoxError>> {
            buf[0] = b'x';
            Poll::Ready(Ok(1))
        }
    }

    let _reader = DummyReader;
}

#[test]
fn test_async_write_trait_exists() {
    use product_os_async_executor::read_write::AsyncWrite;
    use std::pin::Pin;
    use std::task::{Context, Poll};

    struct DummyWriter;

    impl AsyncWrite for DummyWriter {
        fn poll_write(
            self: Pin<&mut Self>,
            _cx: &mut Context<'_>,
            _buf: &[u8],
        ) -> Poll<Result<usize, product_os_async_executor::BoxError>> {
            Poll::Ready(Ok(1))
        }

        fn poll_flush(
            self: Pin<&mut Self>,
            _cx: &mut Context<'_>,
        ) -> Poll<Result<(), product_os_async_executor::BoxError>> {
            Poll::Ready(Ok(()))
        }

        fn poll_shutdown(
            self: Pin<&mut Self>,
            _cx: &mut Context<'_>,
        ) -> Poll<Result<(), product_os_async_executor::BoxError>> {
            Poll::Ready(Ok(()))
        }
    }

    let _writer = DummyWriter;
}

// Test ReadBuf correctness
#[test]
fn test_readbuf_new() {
    use product_os_async_executor::read_write::ReadBuf;

    let mut data = [1u8, 2, 3, 4, 5];
    let buf = ReadBuf::new(&mut data);
    // filled() should return empty slice (nothing filled yet)
    assert!(buf.filled().is_empty());
}

#[test]
fn test_readbuf_uninit() {
    use product_os_async_executor::read_write::ReadBuf;

    let data = vec![0u8; 10];
    let buf = ReadBuf::uninit(data);
    // Uninit buffer has nothing filled
    assert!(buf.filled().is_empty());
}

#[test]
fn test_readbuf_cursor_put_slice() {
    use product_os_async_executor::read_write::ReadBuf;

    let data = vec![0u8; 10];
    let mut buf = ReadBuf::uninit(data);
    let mut cursor = buf.unfilled();
    cursor.put_slice(&[1, 2, 3]);
    let filled = cursor.filled();
    assert_eq!(filled, &[1, 2, 3]);
}

#[test]
fn test_readbuf_debug() {
    use product_os_async_executor::read_write::ReadBuf;

    let data = vec![0u8; 5];
    let buf = ReadBuf::uninit(data);
    let debug_str = format!("{:?}", buf);
    assert!(debug_str.contains("ReadBuf"));
}

// Test that all executor types are available
#[cfg(feature = "exec_tokio")]
#[test]
fn test_tokio_executor_type_exists() {
    use product_os_async_executor::TokioExecutor;
    let _: Option<TokioExecutor> = None;
}

#[cfg(feature = "exec_smol")]
#[test]
fn test_smol_executor_type_exists() {
    use product_os_async_executor::SmolExecutor;
    let _: Option<SmolExecutor> = None;
}

#[cfg(feature = "exec_async_std")]
#[test]
#[allow(deprecated)]
fn test_async_std_executor_type_exists() {
    use product_os_async_executor::AsyncStdExecutor;
    let _: Option<AsyncStdExecutor> = None;
}

#[cfg(feature = "exec_embassy")]
#[test]
fn test_embassy_executor_type_exists() {
    use product_os_async_executor::EmbassyExecutor;
    let _: Option<EmbassyExecutor> = None;
}

// Test trait definitions remain unchanged
#[test]
fn test_executor_trait_exists() {
    use product_os_async_executor::Executor;

    fn _assert_executor_trait<X, T: Executor<X>>() {}
}

#[test]
fn test_executor_perform_trait_exists() {
    use product_os_async_executor::ExecutorPerform;

    fn _assert_executor_perform_trait<X, T: ExecutorPerform<X>>() {}
}

#[test]
fn test_timer_trait_exists() {
    use product_os_async_executor::Timer;

    fn _assert_timer_trait<T: Timer>() {}
}

#[test]
fn test_task_trait_exists() {
    use product_os_async_executor::Task;

    fn _assert_task_trait<Out: Send + 'static, T: Task<Out>>() {}
}

// Test IoError
#[test]
fn test_io_error_display() {
    use product_os_async_executor::read_write::IoError;
    let err = IoError("test error".to_string());
    assert_eq!(format!("{}", err), "test error");
}
#[test]
fn test_io_error_debug() {
    use product_os_async_executor::read_write::IoError;
    let err = IoError("test".to_string());
    let debug_str = format!("{:?}", err);
    assert!(debug_str.contains("IoError"));
}