tiny-counter 0.1.0

Track event counts across time windows with fixed memory and fast queries
Documentation
//! Tests for .reserve() method and reservation patterns

use tiny_counter::{EventStore, TimeUnit};

#[test]
fn reservation_commit_records_event() {
    let store = EventStore::new();

    let reservation = store
        .limit()
        .at_most("api_call", 10, TimeUnit::Hours)
        .reserve("api_call")
        .unwrap();

    reservation.commit();

    assert_eq!(store.query("api_call").last_hours(1).sum(), Some(1));
}

#[test]
fn reservation_cancel_does_not_record() {
    let store = EventStore::new();

    let reservation = store
        .limit()
        .at_most("api_call", 10, TimeUnit::Hours)
        .reserve("api_call")
        .unwrap();

    reservation.cancel();

    // Cancel creates the event but with 0 count (due to pending tracking)
    assert_eq!(store.query("api_call").last_hours(1).sum(), Some(0));
}

#[test]
fn reservation_auto_cancels_on_drop() {
    let store = EventStore::new();

    {
        let _reservation = store
            .limit()
            .at_most("api_call", 10, TimeUnit::Hours)
            .reserve("api_call")
            .unwrap();

        // Reservation drops here without commit
    }

    // Auto-cancel creates the event but with 0 count (due to pending tracking)
    assert_eq!(store.query("api_call").last_hours(1).sum(), Some(0));
}

#[test]
fn reservation_prevents_over_limit() {
    let store = EventStore::new();

    // Fill to limit - 1
    for _ in 0..9 {
        store.record("limited");
    }

    // Reserve the last slot
    let reservation = store
        .limit()
        .at_most("limited", 10, TimeUnit::Hours)
        .reserve("limited")
        .unwrap();

    // Try to reserve another - should fail (pending counts)
    let result = store
        .limit()
        .at_most("limited", 10, TimeUnit::Hours)
        .reserve("limited");
    assert!(result.is_err());

    // Cancel first reservation
    reservation.cancel();

    // Now should be able to reserve again
    let result = store
        .limit()
        .at_most("limited", 10, TimeUnit::Hours)
        .reserve("limited");
    assert!(result.is_ok());
}