tiny-counter 0.1.0

Track event counts across time windows with fixed memory and fast queries
Documentation
//! Tests for .at_most() rate limiting constraint

use chrono::Duration;
use tiny_counter::{EventStore, TimeUnit};

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

    for _ in 0..5 {
        let result = store
            .limit()
            .at_most("api_call", 10, TimeUnit::Hours)
            .check_and_record("api_call");
        assert!(result.is_ok());
    }

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

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

    // Fill to limit
    for _ in 0..10 {
        store.record("api_call");
    }

    // Next call should be rejected
    let result = store
        .limit()
        .at_most("api_call", 10, TimeUnit::Hours)
        .check_and_record("api_call");

    assert!(result.is_err());

    // Count should remain at limit
    assert_eq!(store.query("api_call").last_hours(1).sum(), Some(10));
}

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

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

    // Next call should succeed (we're at 9, limit is 10)
    let result = store
        .limit()
        .at_most("limited", 10, TimeUnit::Hours)
        .check_and_record("limited");
    assert!(result.is_ok());

    // Now at limit, next should fail
    let result = store
        .limit()
        .at_most("limited", 10, TimeUnit::Hours)
        .check_and_record("limited");
    assert!(result.is_err());
}

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

    // Use tuple syntax for multiple units
    let result = store
        .limit()
        .at_most("event", 10, (1, TimeUnit::Minutes))
        .at_most("event", 100, (1, TimeUnit::Hours))
        .check_and_record("event");

    assert!(result.is_ok());
}

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

    let result = store
        .limit()
        .at_most("event", 100, Duration::days(7))
        .check_and_record("event");

    assert!(result.is_ok());
}