Repository: tokio-rs/tokio
File: tokio/tests/sync_mpsc.rs (Rust)

Code before:
    assert_ok!(tx.try_send("goodbye"));
    drop(tx);

    assert_eq!(rx.try_recv(), Ok("goodbye"));
    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
}

#[maybe_tokio_test]
async fn reserve_many_edge_cases() {
    // MAX_PERMITS as defined in `sync/batch_semaphore.rs`
    const MAX_PERMITS: usize = std::usize::MAX >> 3;

    let (tx, rx) = mpsc::channel::<()>(1);
    let mut permit = assert_ok!(tx.reserve_many(0).await);
    assert!(permit.next().is_none());

    assert_err!(tx.reserve_many(MAX_PERMITS + 1).await);
    assert_err!(tx.reserve_many(usize::MAX).await);

    // Dropping the receiver should close the channel
    drop(rx);
    match assert_err!(tx.try_reserve_many(0)) {
        TrySendError::Closed(()) => {}
        _ => panic!(),
    };
}

#[maybe_tokio_test]
async fn try_reserve_many_edge_cases() {
    // MAX_PERMITS as defined in `sync/batch_semaphore.rs`
    const MAX_PERMITS: usize = std::usize::MAX >> 3;

    let (tx, rx) = mpsc::channel::<()>(1);

    let mut permit = assert_ok!(tx.try_reserve_many(0));
    assert!(permit.next().is_none());

    let permit = tx.try_reserve_many(MAX_PERMITS + 1);
    match assert_err!(permit) {
        TrySendError::Full(..) => {}
        _ => panic!(),
    }

    let permit = tx.try_reserve_many(usize::MAX);
    match assert_err!(permit) {
        TrySendError::Full(..) => {}
        _ => panic!(),
    }

    // Dropping the receiver should close the channel
    drop(rx);

Review comment (suggestion):
This is missing some cases, such as `try_reserve_many(0)` when not closed, and `reserve_many(0)` when closed.
```suggestion
use tokio::sync::Semaphore::MAX_PERMITS;

#[maybe_tokio_test]
async fn reserve_many_above_cap() {
    let (tx, rx) = mpsc::channel::<()>(1);

    assert_err!(tx.reserve_many(2).await);
    assert_err!(tx.reserve_many(MAX_PERMITS + 1).await);
    assert_err!(tx.reserve_many(usize::MAX).await);
}

#[test]
fn try_reserve_many_zero() {
    let (tx, rx) = mpsc::channel::<()>(1);

    // Succeeds when not closed.
    assert!(assert_ok!(tx.try_reserve_many(0)).next().is_none());

    // Even when channel is full.
    tx.send(()).unwrap();
    assert!(assert_ok!(tx.try_reserve_many(0)).next().is_none());

    drop(rx);

    // Closed error when closed.
    assert!(tx.try_reserve_many(0) == TrySendError::Closed(()));
}

#[maybe_tokio_test]
async fn reserve_many_zero() {
    let (tx, rx) = mpsc::channel::<()>(1);

    // Succeeds when not closed.
    assert!(assert_ok!(tx.reserve_many(0).await).next().is_none());

    // Even when channel is full.
    tx.send(()).unwrap();
    assert!(assert_ok!(tx.reserve_many(0).await).next().is_none());

    drop(rx);

    // Closed error when closed.
    assert!(tx.reserve_many(0).await == TrySendError::Closed(()));
}
```

Code after:
    assert_ok!(tx.try_send("goodbye"));
    drop(tx);

    assert_eq!(rx.try_recv(), Ok("goodbye"));
    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
}

#[maybe_tokio_test]
async fn reserve_many_above_cap() {
    const MAX_PERMITS: usize = tokio::sync::Semaphore::MAX_PERMITS;
    let (tx, _rx) = mpsc::channel::<()>(1);

    assert_err!(tx.reserve_many(2).await);
    assert_err!(tx.reserve_many(MAX_PERMITS + 1).await);
    assert_err!(tx.reserve_many(usize::MAX).await);
}

#[test]
fn try_reserve_many_zero() {
    let (tx, rx) = mpsc::channel::<()>(1);

    // Succeeds when not closed.
    assert!(assert_ok!(tx.try_reserve_many(0)).next().is_none());

    // Even when channel is full.
    tx.try_send(()).unwrap();
    assert!(assert_ok!(tx.try_reserve_many(0)).next().is_none());

    drop(rx);

    // Closed error when closed.
    assert_eq!(
        assert_err!(tx.try_reserve_many(0)),
        TrySendError::Closed(())
    );
}

#[maybe_tokio_test]
async fn reserve_many_zero() {
    let (tx, rx) = mpsc::channel::<()>(1);

    // Succeeds when not closed.
    assert!(assert_ok!(tx.reserve_many(0).await).next().is_none());

    // Even when channel is full.
    tx.send(()).await.unwrap();
    assert!(assert_ok!(tx.reserve_many(0).await).next().is_none());

    drop(rx);

    // Closed error when closed.