feat(channels/qq_obv11): OneBot v11 渠道插件(正/反 WS 双模式 + CQ 媒体 + 限频,stdlib 自研 WS)

This commit is contained in:
Aska committed 2026-09-06 06:46:43 +08:00
1 parent f9f5a78a02
commit 7831b0ea1b
11 files changed
+2526

No files matched your search

@@ -0,0 +1,67 @@
package qq_obv11
import (
"errors"
"testing"
"time"
)
func TestRateLimiterAllowWithinWindow(t *testing.T) {
t.Parallel()
rl := newRateLimiter(3, 10*time.Second)
now := time.Now()
for i := 0; i < 3; i++ {
if !rl.allow(now) {
t.Fatalf("allow #%d denied, want allowed", i)
}
}
if rl.allow(now) {
t.Error("4th allow in window accepted, want denied")
}
}
func TestRateLimiterDeniedOverWindow(t *testing.T) {
t.Parallel()
rl := newRateLimiter(2, 10*time.Second)
base := time.Now()
if !rl.allow(base) || !rl.allow(base) {
t.Fatal("first two sends should be allowed")
}
if rl.allow(base) {
t.Error("third send within window allowed, want denied")
}
// After the window elapses, the budget frees up.
if !rl.allow(base.Add(11 * time.Second)) {
t.Error("send after window elapsed denied, want allowed")
}
}
func TestRateLimiterDisabledAllowsAll(t *testing.T) {
t.Parallel()
rl := newRateLimiter(0, 10*time.Second)
for i := 0; i < 100; i++ {
if !rl.allow(time.Now()) {
t.Fatalf("disabled limiter denied send #%d", i)
}
}
}
func TestRateLimiterNilAllows(t *testing.T) {
t.Parallel()
var rl *rateLimiter
if !rl.allow(time.Now()) {
t.Error("nil limiter denied send, want allowed")
}
}
func TestErrRateLimitedSentinel(t *testing.T) {
t.Parallel()
if !errors.Is(ErrRateLimited, ErrRateLimited) {
t.Error("ErrRateLimited should be its own sentinel")
}
}