eq2go/internal/titles/titles_test.go
2025-08-06 13:19:07 -05:00

862 lines
22 KiB
Go

package titles
import (
"fmt"
"path/filepath"
"sync"
"testing"
"time"
)
// Test Title struct creation and basic methods
func TestNewTitle(t *testing.T) {
title := NewTitle(1, "Test Title")
if title == nil {
t.Fatal("NewTitle returned nil")
}
if title.ID != 1 {
t.Errorf("Expected ID 1, got %d", title.ID)
}
if title.Name != "Test Title" {
t.Errorf("Expected name 'Test Title', got '%s'", title.Name)
}
if title.Position != TitlePositionSuffix {
t.Errorf("Expected default position %d, got %d", TitlePositionSuffix, title.Position)
}
}
func TestTitleFlags(t *testing.T) {
title := NewTitle(1, "Test Title")
// Test setting flags
title.SetFlag(FlagHidden)
if !title.HasFlag(FlagHidden) {
t.Error("Expected title to have FlagHidden after setting")
}
title.SetFlag(FlagTemporary)
if !title.HasFlag(FlagTemporary) {
t.Error("Expected title to have FlagTemporary after setting")
}
// Test clearing flags
title.ClearFlag(FlagHidden)
if title.HasFlag(FlagHidden) {
t.Error("Expected title not to have FlagHidden after clearing")
}
// Test toggle flags (manually implement toggle)
if title.HasFlag(FlagUnique) {
title.ClearFlag(FlagUnique)
} else {
title.SetFlag(FlagUnique)
}
if !title.HasFlag(FlagUnique) {
t.Error("Expected title to have FlagUnique after toggling")
}
// Toggle again
if title.HasFlag(FlagUnique) {
title.ClearFlag(FlagUnique)
} else {
title.SetFlag(FlagUnique)
}
if title.HasFlag(FlagUnique) {
t.Error("Expected title not to have FlagUnique after toggling again")
}
}
func TestTitleProperties(t *testing.T) {
title := NewTitle(1, "Test Title")
// Test description
title.SetDescription("A test description")
if title.Description != "A test description" {
t.Errorf("Expected description 'A test description', got '%s'", title.Description)
}
// Test category
title.SetCategory(CategoryAchievement)
if title.Category != CategoryAchievement {
t.Errorf("Expected category '%s', got '%s'", CategoryAchievement, title.Category)
}
// Test rarity
title.SetRarity(TitleRarityRare)
if title.Rarity != TitleRarityRare {
t.Errorf("Expected rarity %d, got %d", TitleRarityRare, title.Rarity)
}
// Test display name
title.Position = TitlePositionPrefix
displayName := title.GetDisplayName()
if displayName != "Test Title" {
t.Errorf("Expected display name 'Test Title', got '%s'", displayName)
}
}
func TestTitleTypeMethods(t *testing.T) {
title := NewTitle(1, "Test Title")
// Test hidden flag
title.SetFlag(FlagHidden)
if !title.IsHidden() {
t.Error("Expected title to be hidden")
}
// Test temporary flag
title.ClearFlag(FlagHidden)
title.SetFlag(FlagTemporary)
if !title.IsTemporary() {
t.Error("Expected title to be temporary")
}
// Test unique flag
title.ClearFlag(FlagTemporary)
title.SetFlag(FlagUnique)
if !title.IsUnique() {
t.Error("Expected title to be unique")
}
// Test account-wide flag
title.ClearFlag(FlagUnique)
title.SetFlag(FlagAccountWide)
if !title.IsAccountWide() {
t.Error("Expected title to be account-wide")
}
}
// Test MasterTitlesList
func TestMasterTitlesList(t *testing.T) {
mtl := NewMasterTitlesList()
if mtl == nil {
t.Fatal("NewMasterTitlesList returned nil")
}
// Test default titles are loaded
citizen, exists := mtl.GetTitle(TitleIDCitizen)
if !exists || citizen == nil {
t.Error("Expected Citizen title to be loaded by default")
} else if citizen.Name != "Citizen" {
t.Errorf("Expected Citizen title name, got '%s'", citizen.Name)
}
visitor, exists := mtl.GetTitle(TitleIDVisitor)
if !exists || visitor == nil {
t.Error("Expected Visitor title to be loaded by default")
}
newcomer, exists := mtl.GetTitle(TitleIDNewcomer)
if !exists || newcomer == nil {
t.Error("Expected Newcomer title to be loaded by default")
}
returning, exists := mtl.GetTitle(TitleIDReturning)
if !exists || returning == nil {
t.Error("Expected Returning title to be loaded by default")
}
// Test adding new title
testTitle := NewTitle(0, "Test Title") // ID will be assigned
testTitle.SetDescription("Test description")
testTitle.SetCategory(CategoryMiscellaneous)
err := mtl.AddTitle(testTitle)
if err != nil {
t.Fatalf("Failed to add title: %v", err)
}
// ID should have been assigned
if testTitle.ID == 0 {
t.Error("Title ID should have been assigned")
}
retrieved, exists := mtl.GetTitle(testTitle.ID)
if !exists || retrieved == nil {
t.Error("Failed to retrieve added title")
} else if retrieved.Name != "Test Title" {
t.Errorf("Expected retrieved title name 'Test Title', got '%s'", retrieved.Name)
}
// Test duplicate ID
duplicateTitle := NewTitle(testTitle.ID, "Duplicate")
err = mtl.AddTitle(duplicateTitle)
if err == nil {
t.Error("Should have failed to add title with duplicate ID")
}
}
func TestMasterTitlesListCategories(t *testing.T) {
mtl := NewMasterTitlesList()
// Add titles in different categories
for i := 0; i < 3; i++ {
title := NewTitle(0, fmt.Sprintf("Achievement Title %d", i))
title.SetCategory(CategoryAchievement)
mtl.AddTitle(title)
}
for i := 0; i < 2; i++ {
title := NewTitle(0, fmt.Sprintf("Quest Title %d", i))
title.SetCategory(CategoryQuest)
mtl.AddTitle(title)
}
// Test getting titles by category
achievementTitles := mtl.GetTitlesByCategory(CategoryAchievement)
if len(achievementTitles) < 3 {
t.Errorf("Expected at least 3 achievement titles, got %d", len(achievementTitles))
}
questTitles := mtl.GetTitlesByCategory(CategoryQuest)
if len(questTitles) < 2 {
t.Errorf("Expected at least 2 quest titles, got %d", len(questTitles))
}
// Test getting available categories
categories := mtl.GetAvailableCategories()
hasAchievement := false
hasQuest := false
for _, cat := range categories {
if cat == CategoryAchievement {
hasAchievement = true
}
if cat == CategoryQuest {
hasQuest = true
}
}
if !hasAchievement {
t.Error("Expected CategoryAchievement in available categories")
}
if !hasQuest {
t.Error("Expected CategoryQuest in available categories")
}
}
func TestMasterTitlesListSourceAndRarity(t *testing.T) {
mtl := NewMasterTitlesList()
// Add titles with different sources
title1 := NewTitle(0, "Achievement Source")
title1.Source = TitleSourceAchievement
title1.SetRarity(TitleRarityCommon)
mtl.AddTitle(title1)
title2 := NewTitle(0, "Quest Source")
title2.Source = TitleSourceQuest
title2.SetRarity(TitleRarityRare)
mtl.AddTitle(title2)
title3 := NewTitle(0, "PvP Source")
title3.Source = TitleSourcePvP
title3.SetRarity(TitleRarityEpic)
mtl.AddTitle(title3)
// Test getting titles by source
achievementSourceTitles := mtl.GetTitlesBySource(TitleSourceAchievement)
found := false
for _, t := range achievementSourceTitles {
if t.Name == "Achievement Source" {
found = true
break
}
}
if !found {
t.Error("Failed to find achievement source title")
}
// Test getting titles by rarity
rareTitles := mtl.GetTitlesByRarity(TitleRarityRare)
found = false
for _, t := range rareTitles {
if t.Name == "Quest Source" {
found = true
break
}
}
if !found {
t.Error("Failed to find rare title")
}
}
// Test PlayerTitlesList
func TestPlayerTitlesList(t *testing.T) {
mtl := NewMasterTitlesList()
// Add some titles to master list
title1 := NewTitle(100, "Title One")
title1.Position = TitlePositionPrefix
mtl.AddTitle(title1)
title2 := NewTitle(101, "Title Two")
title2.Position = TitlePositionSuffix
mtl.AddTitle(title2)
ptl := NewPlayerTitlesList(123, mtl)
if ptl == nil {
t.Fatal("NewPlayerTitlesList returned nil")
}
// Test adding title
err := ptl.AddTitle(100, 0, 0)
if err != nil {
t.Fatalf("Failed to add title to player: %v", err)
}
err = ptl.AddTitle(101, 0, 0)
if err != nil {
t.Fatalf("Failed to add second title to player: %v", err)
}
// Test getting titles (player starts with default Citizen title)
titles := ptl.GetAllTitles()
expectedTitleCount := 3 // Citizen + our 2 titles
if len(titles) != expectedTitleCount {
t.Errorf("Expected %d titles, got %d", expectedTitleCount, len(titles))
}
// Test has title
if !ptl.HasTitle(100) {
t.Error("Expected player to have title 100")
}
if !ptl.HasTitle(101) {
t.Error("Expected player to have title 101")
}
if ptl.HasTitle(999) {
t.Error("Expected player not to have title 999")
}
// Test setting active prefix
err = ptl.SetActivePrefix(100)
if err != nil {
t.Fatalf("Failed to set active prefix: %v", err)
}
activePrefixTitle, hasPrefix := ptl.GetActivePrefixTitle()
if !hasPrefix || activePrefixTitle.ID != 100 {
t.Errorf("Expected active prefix 100, got title ID: %v", activePrefixTitle)
}
// Test setting active suffix
err = ptl.SetActiveSuffix(101)
if err != nil {
t.Fatalf("Failed to set active suffix: %v", err)
}
activeSuffixTitle, hasSuffix := ptl.GetActiveSuffixTitle()
if !hasSuffix || activeSuffixTitle.ID != 101 {
t.Errorf("Expected active suffix 101, got title ID: %v", activeSuffixTitle)
}
// Test formatted name (the actual format may vary)
formattedName := ptl.GetFormattedName("PlayerName")
// Just check that it contains both titles and the player name
if !contains(formattedName, "Title One") {
t.Errorf("Formatted name should contain 'Title One', got '%s'", formattedName)
}
if !contains(formattedName, "Title Two") {
t.Errorf("Formatted name should contain 'Title Two', got '%s'", formattedName)
}
if !contains(formattedName, "PlayerName") {
t.Errorf("Formatted name should contain 'PlayerName', got '%s'", formattedName)
}
// Test removing title
err = ptl.RemoveTitle(100)
if err != nil {
t.Fatalf("Failed to remove title: %v", err)
}
if ptl.HasTitle(100) {
t.Error("Title 100 should have been removed")
}
// Active prefix should be cleared
_, hasPrefix = ptl.GetActivePrefixTitle()
if hasPrefix {
t.Error("Active prefix should be cleared after removing the title")
}
}
func TestPlayerTitlesExpiration(t *testing.T) {
mtl := NewMasterTitlesList()
// Add a temporary title to master list
tempTitle := NewTitle(200, "Temporary Title")
tempTitle.SetFlag(FlagTemporary)
tempTitle.ExpirationHours = 1 // Expires after 1 hour
mtl.AddTitle(tempTitle)
ptl := NewPlayerTitlesList(456, mtl)
// Add the temporary title
err := ptl.AddTitle(200, 0, 0)
if err != nil {
t.Fatalf("Failed to add temporary title: %v", err)
}
// Title should exist
if !ptl.HasTitle(200) {
t.Error("Expected player to have temporary title")
}
// Manually set expiration to past
if playerTitle, exists := ptl.titles[200]; exists {
playerTitle.ExpiresAt = time.Now().Add(-1 * time.Hour)
}
// Clean up expired titles
expired := ptl.CleanupExpiredTitles()
if expired != 1 {
t.Errorf("Expected 1 expired title, got %d", expired)
}
// Title should be removed
if ptl.HasTitle(200) {
t.Error("Expired title should have been removed")
}
}
// Test TitleManager
func TestTitleManager(t *testing.T) {
tm := NewTitleManager()
if tm == nil {
t.Fatal("NewTitleManager returned nil")
}
defer tm.Shutdown()
// Test getting player titles
playerTitles := tm.GetPlayerTitles(456)
if playerTitles == nil {
t.Error("GetPlayerTitles returned nil")
}
// Test granting title (use Visitor instead of Citizen to avoid conflicts)
err := tm.GrantTitle(456, TitleIDVisitor, 0, 0)
if err != nil {
t.Fatalf("Failed to grant title: %v", err)
}
// Verify title was granted (player starts with default Citizen title)
playerTitles = tm.GetPlayerTitles(456)
titles := playerTitles.GetAllTitles()
expectedCount := 2 // Citizen + Visitor
if len(titles) != expectedCount {
t.Errorf("Expected %d titles for player, got %d", expectedCount, len(titles))
}
// Verify the player has the visitor title
if !playerTitles.HasTitle(TitleIDVisitor) {
t.Error("Player should have Visitor title")
}
// Test revoking title
err = tm.RevokeTitle(456, TitleIDVisitor)
if err != nil {
t.Fatalf("Failed to revoke title: %v", err)
}
// Verify title was revoked (should still have Citizen)
playerTitles = tm.GetPlayerTitles(456)
titles = playerTitles.GetAllTitles()
if len(titles) != 1 {
t.Errorf("Expected 1 title after revoke, got %d", len(titles))
}
}
func TestTitleManagerCreateVariants(t *testing.T) {
tm := NewTitleManager()
defer tm.Shutdown()
// Test creating regular title
title, err := tm.CreateTitle("Regular Title", "A regular title", CategoryMiscellaneous, TitlePositionSuffix, TitleSourceQuest, TitleRarityCommon)
if err != nil {
t.Fatalf("Failed to create regular title: %v", err)
}
if title == nil {
t.Fatal("CreateTitle returned nil")
}
// Test creating achievement title
achievementTitle, err := tm.CreateAchievementTitle("Achievement Title", "An achievement title", 1000, TitlePositionPrefix, TitleRarityRare)
if err != nil {
t.Fatalf("Failed to create achievement title: %v", err)
}
if achievementTitle.AchievementID != 1000 {
t.Errorf("Expected achievement ID 1000, got %d", achievementTitle.AchievementID)
}
// Test creating temporary title
tempTitle, err := tm.CreateTemporaryTitle("Temp Title", "A temporary title", 24, TitlePositionSuffix, TitleSourceHoliday, TitleRarityCommon)
if err != nil {
t.Fatalf("Failed to create temporary title: %v", err)
}
if !tempTitle.HasFlag(FlagTemporary) {
t.Error("Temporary title should have FlagTemporary")
}
if tempTitle.ExpirationHours != 24 {
t.Errorf("Expected expiration hours 24, got %d", tempTitle.ExpirationHours)
}
// Test creating unique title
uniqueTitle, err := tm.CreateUniqueTitle("Unique Title", "A unique title", TitlePositionPrefix, TitleSourceMiscellaneous)
if err != nil {
t.Fatalf("Failed to create unique title: %v", err)
}
if !uniqueTitle.HasFlag(FlagUnique) {
t.Error("Unique title should have FlagUnique")
}
if uniqueTitle.Rarity != TitleRarityUnique {
t.Errorf("Expected rarity %d for unique title, got %d", TitleRarityUnique, uniqueTitle.Rarity)
}
}
func TestTitleManagerSearch(t *testing.T) {
tm := NewTitleManager()
defer tm.Shutdown()
// Create test titles
tm.CreateTitle("Dragon Slayer", "Defeated a dragon", CategoryCombat, TitlePositionSuffix, TitleSourceQuest, TitleRarityEpic)
tm.CreateTitle("Master Crafter", "Master of crafting", CategoryTradeskill, TitlePositionPrefix, TitleSourceTradeskill, TitleRarityRare)
tm.CreateTitle("Explorer", "Explored the world", CategoryExploration, TitlePositionSuffix, TitleSourceAchievement, TitleRarityCommon)
// Test search
results := tm.SearchTitles("dragon")
found := false
for _, title := range results {
if title.Name == "Dragon Slayer" {
found = true
break
}
}
if !found {
t.Error("Failed to find 'Dragon Slayer' in search results")
}
// Test search with description
results = tm.SearchTitles("crafting")
found = false
for _, title := range results {
if title.Name == "Master Crafter" {
found = true
break
}
}
if !found {
t.Error("Failed to find 'Master Crafter' when searching description")
}
}
func TestTitleManagerStatistics(t *testing.T) {
tm := NewTitleManager()
defer tm.Shutdown()
// Grant some titles (avoid Citizen which may be default)
tm.GrantTitle(1, TitleIDVisitor, 0, 0)
tm.GrantTitle(2, TitleIDNewcomer, 0, 0)
tm.GrantTitle(1, TitleIDReturning, 0, 0)
stats := tm.GetStatistics()
// Check statistics
if totalPlayers, ok := stats["total_players"].(int); ok {
if totalPlayers != 2 {
t.Errorf("Expected 2 total players, got %d", totalPlayers)
}
} else {
t.Error("Missing total_players in statistics")
}
if titlesGranted, ok := stats["titles_granted"].(int64); ok {
if titlesGranted != 3 {
t.Errorf("Expected 3 titles granted, got %d", titlesGranted)
}
} else {
t.Error("Missing titles_granted in statistics")
}
}
func TestTitleManagerConcurrency(t *testing.T) {
tm := NewTitleManager()
defer tm.Shutdown()
// Test concurrent access to player titles
var wg sync.WaitGroup
numPlayers := 10
numOperations := 100
for i := 0; i < numPlayers; i++ {
wg.Add(1)
go func(playerID int32) {
defer wg.Done()
for j := 0; j < numOperations; j++ {
// Grant title
tm.GrantTitle(playerID, TitleIDCitizen, 0, 0)
// Get player titles
ptl := tm.GetPlayerTitles(playerID)
_ = ptl.GetAllTitles()
// Set active title
tm.SetPlayerActivePrefix(playerID, TitleIDCitizen)
// Get formatted name
tm.GetPlayerFormattedName(playerID, fmt.Sprintf("Player%d", playerID))
// Revoke title
tm.RevokeTitle(playerID, TitleIDCitizen)
}
}(int32(i))
}
wg.Wait()
// Verify no crashes or data races
stats := tm.GetStatistics()
if stats == nil {
t.Error("Failed to get statistics after concurrent operations")
}
}
// Test Database Integration
func TestDatabaseIntegration(t *testing.T) {
// Create temporary database
tempDir := t.TempDir()
dbPath := filepath.Join(tempDir, "test_titles.db")
db, err := OpenDB(dbPath)
if err != nil {
t.Fatalf("Failed to open database: %v", err)
}
defer db.Close()
// Create tables
err = db.CreateTables()
if err != nil {
t.Fatalf("Failed to create tables: %v", err)
}
// Test master list database operations
mtl := NewMasterTitlesList()
// Add some test titles
title1 := NewTitle(500, "Database Test Title 1")
title1.SetDescription("Test description 1")
title1.SetCategory(CategoryMiscellaneous)
title1.Position = TitlePositionPrefix // Set as prefix title
mtl.AddTitle(title1)
title2 := NewTitle(501, "Database Test Title 2")
title2.SetDescription("Test description 2")
title2.SetCategory(CategoryAchievement)
title2.Position = TitlePositionSuffix // Set as suffix title
title2.AchievementID = 2000
mtl.AddTitle(title2)
// Save to database
err = mtl.SaveToDatabase(db)
if err != nil {
t.Fatalf("Failed to save master titles to database: %v", err)
}
// Create new master list and load from database
mtl2 := &MasterTitlesList{
titles: make(map[int32]*Title),
categorized: make(map[string][]*Title),
bySource: make(map[int32][]*Title),
byRarity: make(map[int32][]*Title),
byAchievement: make(map[uint32]*Title),
nextID: 1,
}
err = mtl2.LoadFromDatabase(db)
if err != nil {
t.Fatalf("Failed to load master titles from database: %v", err)
}
// Verify loaded titles
loadedTitle1, exists := mtl2.GetTitle(500)
if !exists || loadedTitle1 == nil {
t.Fatal("Failed to load title 500 from database")
}
if loadedTitle1.Name != "Database Test Title 1" {
t.Errorf("Expected title name 'Database Test Title 1', got '%s'", loadedTitle1.Name)
}
loadedTitle2, exists := mtl2.GetTitle(501)
if !exists || loadedTitle2 == nil {
t.Fatal("Failed to load title 501 from database")
}
if loadedTitle2.AchievementID != 2000 {
t.Errorf("Expected achievement ID 2000, got %d", loadedTitle2.AchievementID)
}
// Test player titles database operations
ptl := NewPlayerTitlesList(789, mtl2) // Use mtl2 which has titles loaded from database
ptl.AddTitle(500, 0, 0)
ptl.AddTitle(501, 2000, 0)
ptl.SetActivePrefix(500)
ptl.SetActiveSuffix(501)
// Save player titles
err = ptl.SaveToDatabase(db)
if err != nil {
t.Fatalf("Failed to save player titles to database: %v", err)
}
// Load player titles
ptl2 := NewPlayerTitlesList(789, mtl2)
err = ptl2.LoadFromDatabase(db)
if err != nil {
t.Fatalf("Failed to load player titles from database: %v", err)
}
// Verify loaded player titles
if !ptl2.HasTitle(500) {
t.Error("Expected player to have title 500")
}
if !ptl2.HasTitle(501) {
t.Error("Expected player to have title 501")
}
activePrefixTitle, hasPrefix := ptl2.GetActivePrefixTitle()
if !hasPrefix {
t.Error("Expected to have active prefix title")
} else if activePrefixTitle.ID != 500 {
t.Errorf("Expected active prefix 500, got %d", activePrefixTitle.ID)
}
activeSuffixTitle, hasSuffix := ptl2.GetActiveSuffixTitle()
if !hasSuffix {
t.Error("Expected to have active suffix title")
} else if activeSuffixTitle.ID != 501 {
t.Errorf("Expected active suffix 501, got %d", activeSuffixTitle.ID)
}
}
func TestDatabaseHelperFunctions(t *testing.T) {
// Test nullableUint32
if val := nullableUint32(0); val != nil {
t.Error("nullableUint32(0) should return nil")
}
if val := nullableUint32(123); val != uint32(123) {
t.Errorf("nullableUint32(123) should return 123, got %v", val)
}
// Test nullableTime
zeroTime := time.Time{}
if val := nullableTime(zeroTime); val != nil {
t.Error("nullableTime(zero) should return nil")
}
now := time.Now()
if val := nullableTime(now); val != now.Unix() {
t.Errorf("nullableTime(now) should return Unix timestamp, got %v", val)
}
}
// Benchmark tests
func BenchmarkTitleCreation(b *testing.B) {
for i := 0; i < b.N; i++ {
title := NewTitle(int32(i), fmt.Sprintf("Title %d", i))
title.SetDescription("Description")
title.SetCategory(CategoryMiscellaneous)
}
}
func BenchmarkMasterListAdd(b *testing.B) {
mtl := NewMasterTitlesList()
b.ResetTimer()
for i := 0; i < b.N; i++ {
title := NewTitle(int32(i+1000), fmt.Sprintf("Title %d", i))
mtl.AddTitle(title)
}
}
func BenchmarkPlayerListAdd(b *testing.B) {
mtl := NewMasterTitlesList()
// Pre-populate master list
for i := 0; i < 1000; i++ {
title := NewTitle(int32(i), fmt.Sprintf("Title %d", i))
mtl.AddTitle(title)
}
ptl := NewPlayerTitlesList(1, mtl)
b.ResetTimer()
for i := 0; i < b.N; i++ {
titleID := int32(i % 1000)
ptl.AddTitle(titleID, 0, 0)
ptl.RemoveTitle(titleID)
}
}
func BenchmarkTitleManagerGrant(b *testing.B) {
tm := NewTitleManager()
defer tm.Shutdown()
// Pre-create titles
for i := 0; i < 100; i++ {
tm.CreateTitle(fmt.Sprintf("Title %d", i), "Description", CategoryMiscellaneous, TitlePositionSuffix, TitleSourceQuest, TitleRarityCommon)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
playerID := int32(i % 100)
titleID := int32((i % 100) + 1)
tm.GrantTitle(playerID, titleID, 0, 0)
}
}
func BenchmarkTitleSearch(b *testing.B) {
tm := NewTitleManager()
defer tm.Shutdown()
// Create fewer titles for faster benchmark
for i := 0; i < 100; i++ {
name := fmt.Sprintf("Title %d", i)
if i%10 == 0 {
name = fmt.Sprintf("Dragon %d", i)
}
tm.CreateTitle(name, "Description", CategoryMiscellaneous, TitlePositionSuffix, TitleSourceQuest, TitleRarityCommon)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
tm.SearchTitles("dragon")
}
}
func BenchmarkConcurrentAccess(b *testing.B) {
tm := NewTitleManager()
defer tm.Shutdown()
// Pre-populate with titles
for i := 0; i < 10; i++ {
tm.CreateTitle(fmt.Sprintf("Title %d", i), "Description", CategoryMiscellaneous, TitlePositionSuffix, TitleSourceQuest, TitleRarityCommon)
}
b.ResetTimer()
// Use simpler sequential approach instead of RunParallel to avoid deadlocks
for i := 0; i < b.N; i++ {
playerID := int32(i % 10)
titleID := int32((i % 10) + 1)
tm.GrantTitle(playerID, titleID, 0, 0)
tm.GetPlayerFormattedName(playerID, "Player")
}
}