test: add benchmarks for various components

Adds benchmarking tests to ensure the application remains low on resources.
Covers payload parsing, auth verification, IRC chat line formatting, and more.
This commit is contained in:
ruinivist
2026-05-31 23:13:18 +00:00
parent 0ae1b094c5
commit 7acb293dea
8 changed files with 144 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
package main
import "testing"
func BenchmarkMain(b *testing.B) {
// Not really useful for entire application start
}
+14
View File
@@ -323,3 +323,17 @@ func containsLine(lines []string, want string) bool {
}
return false
}
func BenchmarkHasScope(b *testing.B) {
scopes := []string{"chat:read", "chat:edit", "whispers:read", "user:read:email"}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = hasScope(scopes, "whispers:read")
}
}
func BenchmarkRandomAlphaNumeric(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = randomAlphaNumeric(32)
}
}
+16
View File
@@ -73,3 +73,19 @@ func writeConfig(t *testing.T, content string) string {
}
return path
}
func BenchmarkNormalizeStreamers(b *testing.B) {
streamers := []string{" StreamerOne ", "streamerTwo", "", "streamerOne", "https://twitch.tv/streamerThree"}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = normalizeStreamers(streamers)
}
}
func BenchmarkNormalizeStreamer(b *testing.B) {
streamer := " https://www.twitch.tv/StreamerName "
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = normalizeStreamer(streamer)
}
}
+12
View File
@@ -157,3 +157,15 @@ func TestPersistedOperationHashes(t *testing.T) {
t.Fatalf("stream info hash = %q", got)
}
}
func BenchmarkFormatErrors(b *testing.B) {
errs := []Error{
{Message: "first error"},
{Message: "second error"},
{Message: "third error"},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = formatErrors(errs)
}
}
+16
View File
@@ -221,3 +221,19 @@ func TestAuthFailureReturnsError(t *testing.T) {
t.Fatalf("err = %v", err)
}
}
func BenchmarkPingPayload(b *testing.B) {
line := "PING :tmi.twitch.tv"
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = pingPayload(line)
}
}
func BenchmarkIsJoinConfirmation(b *testing.B) {
line := ":jules!jules@jules.tmi.twitch.tv JOIN #parasocial"
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = isJoinConfirmation(line, "jules", "parasocial")
}
}
+16
View File
@@ -49,3 +49,19 @@ func TestParseFrameVideoPlaybackFallsBackToTopicSuffix(t *testing.T) {
t.Fatalf("event = %#v", frame.Event)
}
}
func BenchmarkParseFramePointsEarned(b *testing.B) {
msg := []byte(`{"type":"MESSAGE","data":{"topic":"community-points-user-v1.viewer","message":"{\"type\":\"points-earned\",\"data\":{\"timestamp\":\"2026-04-29T12:00:00Z\",\"balance\":{\"balance\":42,\"channel_id\":\"123\"}}}"}}`)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = parseFrame(msg)
}
}
func BenchmarkParseFrameClaimAvailable(b *testing.B) {
msg := []byte(`{"type":"MESSAGE","data":{"topic":"community-points-user-v1.viewer","message":"{\"type\":\"claim-available\",\"data\":{\"timestamp\":\"2026-04-29T12:00:00Z\",\"claim\":{\"id\":\"claim-1\",\"channel_id\":\"123\"}}}"}}`)
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = parseFrame(msg)
}
}
+28
View File
@@ -0,0 +1,28 @@
package tui
import "testing"
import "parasocial/internal/twitch"
func BenchmarkFormatIRCChatLine(b *testing.B) {
line := ":jules!jules@jules.tmi.twitch.tv PRIVMSG #parasocial :Hello world this is a test message"
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = formatIRCChatLine(line)
}
}
func BenchmarkNormalizeKey(b *testing.B) {
key := "SomeStreamerName"
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = normalizeKey(key)
}
}
func BenchmarkIsActive(b *testing.B) {
entry := twitch.StreamerEntry{Status: twitch.StreamerReady}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = isActive(entry)
}
}
+35
View File
@@ -0,0 +1,35 @@
package twitch
import "testing"
func BenchmarkBuildMinuteWatchedPayload(b *testing.B) {
userID := "user123"
channelID := "channel456"
login := "streamer"
metadata := &StreamMetadata{
BroadcastID: "bc123",
Game: &Game{Name: "Science", ID: "123"},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = BuildMinuteWatchedPayload(userID, channelID, login, metadata)
}
}
func BenchmarkEncodeMinuteWatchedPayload(b *testing.B) {
payload := MinuteWatchedPayload{
{
Event: "minute_watched",
Properties: minuteWatchedProperties{
ChannelID: "channel456",
BroadcastID: "bc123",
Player: "site",
UserID: "user123",
},
},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, _ = payload.Encode()
}
}