from __future__ import annotations import asyncio import pytest from yuxi.channels.adapters.wechat.rate_limiter import TokenBucketRateLimiter class TestTokenBucketRateLimiter: def test_initial_tokens_available(self): limiter = TokenBucketRateLimiter(rate=10, per=60.0) assert limiter.available_tokens == 10.0 def test_acquire_sync_depletes(self): limiter = TokenBucketRateLimiter(rate=5, per=60.0) results = [limiter.acquire_sync() for _ in range(5)] assert all(results) assert limiter.acquire_sync() is False def test_acquire_sync_beyond_limit(self): limiter = TokenBucketRateLimiter(rate=1, per=60.0) assert limiter.acquire_sync() is True assert limiter.acquire_sync() is False @pytest.mark.asyncio async def test_acquire_async_depletes(self): limiter = TokenBucketRateLimiter(rate=3, per=60.0) results = [await limiter.acquire() for _ in range(3)] assert all(results) assert await limiter.acquire() is False def test_rate_property(self): limiter = TokenBucketRateLimiter(rate=20, per=30.0) assert limiter.rate == 20 def test_period_property(self): limiter = TokenBucketRateLimiter(rate=10, per=45.0) assert limiter.period == 45.0 def test_zero_rate(self): limiter = TokenBucketRateLimiter(rate=0, per=60.0) assert limiter.acquire_sync() is False def test_tokens_refill_after_time(self): import time limiter = TokenBucketRateLimiter(rate=10, per=60.0) for _ in range(10): limiter.acquire_sync() assert limiter.acquire_sync() is False limiter._last_refill = time.monotonic() - 60.0 assert limiter.acquire_sync() is True def test_tokens_never_exceed_rate(self): import time limiter = TokenBucketRateLimiter(rate=5, per=60.0) limiter._last_refill = time.monotonic() - 600.0 limiter.acquire_sync() assert limiter.available_tokens <= limiter.rate