351 lines
9.3 KiB
Go
351 lines
9.3 KiB
Go
package factions
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestNewFaction(t *testing.T) {
|
|
faction := NewFaction(1, "Test Faction", "TestType", "A test faction")
|
|
if faction == nil {
|
|
t.Fatal("NewFaction returned nil")
|
|
}
|
|
|
|
if faction.ID != 1 {
|
|
t.Errorf("Expected ID 1, got %d", faction.ID)
|
|
}
|
|
|
|
if faction.Name != "Test Faction" {
|
|
t.Errorf("Expected name 'Test Faction', got '%s'", faction.Name)
|
|
}
|
|
|
|
if faction.Type != "TestType" {
|
|
t.Errorf("Expected type 'TestType', got '%s'", faction.Type)
|
|
}
|
|
|
|
if faction.Description != "A test faction" {
|
|
t.Errorf("Expected description 'A test faction', got '%s'", faction.Description)
|
|
}
|
|
}
|
|
|
|
func TestMasterFactionList(t *testing.T) {
|
|
mfl := NewMasterList()
|
|
if mfl == nil {
|
|
t.Fatal("NewMasterFactionList returned nil")
|
|
}
|
|
|
|
// Test adding faction
|
|
faction := NewFaction(100, "Test Faction", "Test", "Test faction")
|
|
err := mfl.AddFaction(faction)
|
|
if err != nil {
|
|
t.Fatalf("Failed to add faction: %v", err)
|
|
}
|
|
|
|
// Test getting faction
|
|
retrieved := mfl.GetFaction(100)
|
|
if retrieved == nil {
|
|
t.Error("Failed to retrieve added faction")
|
|
} else if retrieved.Name != "Test Faction" {
|
|
t.Errorf("Expected name 'Test Faction', got '%s'", retrieved.Name)
|
|
}
|
|
|
|
// Test getting all factions
|
|
factions := mfl.GetAllFactions()
|
|
if len(factions) == 0 {
|
|
t.Error("Expected at least one faction")
|
|
}
|
|
}
|
|
|
|
func TestPlayerFaction(t *testing.T) {
|
|
mfl := NewMasterList()
|
|
pf := NewPlayerFaction(mfl)
|
|
if pf == nil {
|
|
t.Fatal("NewPlayerFaction returned nil")
|
|
}
|
|
|
|
// Use faction ID > 10 since IDs <= 10 are special factions that always return 0
|
|
testFactionID := int32(100)
|
|
|
|
// Test setting faction value
|
|
pf.SetFactionValue(testFactionID, 1000)
|
|
value := pf.GetFactionValue(testFactionID)
|
|
if value != 1000 {
|
|
t.Errorf("Expected faction value 1000, got %d", value)
|
|
}
|
|
|
|
// Test faction modification
|
|
pf.IncreaseFaction(testFactionID, 500)
|
|
value = pf.GetFactionValue(testFactionID)
|
|
if value != 1500 {
|
|
t.Errorf("Expected faction value 1500 after increase, got %d", value)
|
|
}
|
|
|
|
pf.DecreaseFaction(testFactionID, 200)
|
|
value = pf.GetFactionValue(testFactionID)
|
|
if value != 1300 {
|
|
t.Errorf("Expected faction value 1300 after decrease, got %d", value)
|
|
}
|
|
|
|
// Test consideration calculation
|
|
consideration := pf.GetCon(testFactionID)
|
|
if consideration < -4 || consideration > 4 {
|
|
t.Errorf("Consideration %d is out of valid range [-4, 4]", consideration)
|
|
}
|
|
}
|
|
|
|
func TestFactionRelations(t *testing.T) {
|
|
mfl := NewMasterList()
|
|
|
|
// Add test factions
|
|
faction1 := NewFaction(1, "Faction 1", "Test", "Test faction 1")
|
|
faction2 := NewFaction(2, "Faction 2", "Test", "Test faction 2")
|
|
faction3 := NewFaction(3, "Faction 3", "Test", "Test faction 3")
|
|
|
|
mfl.AddFaction(faction1)
|
|
mfl.AddFaction(faction2)
|
|
mfl.AddFaction(faction3)
|
|
|
|
// Test hostile relations
|
|
mfl.AddHostileFaction(1, 2)
|
|
|
|
// Check if faction 2 is in the hostile list for faction 1
|
|
hostiles := mfl.GetHostileFactions(1)
|
|
isHostile := false
|
|
for _, hostileID := range hostiles {
|
|
if hostileID == 2 {
|
|
isHostile = true
|
|
break
|
|
}
|
|
}
|
|
if !isHostile {
|
|
t.Error("Expected faction 2 to be hostile to faction 1")
|
|
}
|
|
|
|
// Test friendly relations
|
|
mfl.AddFriendlyFaction(1, 3)
|
|
|
|
// Check if faction 3 is in the friendly list for faction 1
|
|
friendlies := mfl.GetFriendlyFactions(1)
|
|
isFriendly := false
|
|
for _, friendlyID := range friendlies {
|
|
if friendlyID == 3 {
|
|
isFriendly = true
|
|
break
|
|
}
|
|
}
|
|
if !isFriendly {
|
|
t.Error("Expected faction 3 to be friendly to faction 1")
|
|
}
|
|
|
|
// Test removing relations - need to implement RemoveHostileFaction first
|
|
// For now, just verify current state
|
|
hostiles = mfl.GetHostileFactions(1)
|
|
isHostile = false
|
|
for _, hostileID := range hostiles {
|
|
if hostileID == 2 {
|
|
isHostile = true
|
|
break
|
|
}
|
|
}
|
|
if !isHostile {
|
|
t.Error("Expected faction 2 to still be hostile to faction 1 (removal not implemented)")
|
|
}
|
|
}
|
|
|
|
func TestFactionValidation(t *testing.T) {
|
|
mfl := NewMasterList()
|
|
|
|
// Test nil faction
|
|
err := mfl.AddFaction(nil)
|
|
if err == nil {
|
|
t.Error("Expected error when adding nil faction")
|
|
}
|
|
|
|
// Test invalid faction ID
|
|
faction := NewFaction(0, "Invalid", "Test", "Invalid faction")
|
|
err = mfl.AddFaction(faction)
|
|
if err == nil {
|
|
t.Error("Expected error when adding faction with ID 0")
|
|
}
|
|
|
|
// Test empty name
|
|
faction = NewFaction(1, "", "Test", "Empty name faction")
|
|
err = mfl.AddFaction(faction)
|
|
if err == nil {
|
|
t.Error("Expected error when adding faction with empty name")
|
|
}
|
|
}
|
|
|
|
func TestMasterListBespokeFeatures(t *testing.T) {
|
|
mfl := NewMasterList()
|
|
|
|
// Create test factions with different properties
|
|
faction1 := NewFaction(1, "Special Faction", "Special", "A special faction")
|
|
faction2 := NewFaction(20, "City Faction", "City", "A city faction")
|
|
faction3 := NewFaction(21, "Guild Faction", "Guild", "A guild faction")
|
|
faction4 := NewFaction(30, "Another City", "City", "Another city faction")
|
|
|
|
// Add factions
|
|
mfl.AddFaction(faction1)
|
|
mfl.AddFaction(faction2)
|
|
mfl.AddFaction(faction3)
|
|
mfl.AddFaction(faction4)
|
|
|
|
// Test GetFactionSafe
|
|
retrieved, exists := mfl.GetFactionSafe(20)
|
|
if !exists || retrieved == nil {
|
|
t.Error("GetFactionSafe should return existing faction and true")
|
|
}
|
|
|
|
_, exists = mfl.GetFactionSafe(9999)
|
|
if exists {
|
|
t.Error("GetFactionSafe should return false for non-existent ID")
|
|
}
|
|
|
|
// Test GetFactionByName (case-insensitive)
|
|
found := mfl.GetFactionByName("city faction")
|
|
if found == nil || found.ID != 20 {
|
|
t.Error("GetFactionByName should find 'City Faction' (case insensitive)")
|
|
}
|
|
|
|
found = mfl.GetFactionByName("GUILD FACTION")
|
|
if found == nil || found.ID != 21 {
|
|
t.Error("GetFactionByName should find 'Guild Faction' (uppercase)")
|
|
}
|
|
|
|
found = mfl.GetFactionByName("NonExistent")
|
|
if found != nil {
|
|
t.Error("GetFactionByName should return nil for non-existent faction")
|
|
}
|
|
|
|
// Test GetFactionsByType
|
|
cityFactions := mfl.GetFactionsByType("City")
|
|
if len(cityFactions) != 2 {
|
|
t.Errorf("GetFactionsByType('City') returned %v results, want 2", len(cityFactions))
|
|
}
|
|
|
|
guildFactions := mfl.GetFactionsByType("Guild")
|
|
if len(guildFactions) != 1 {
|
|
t.Errorf("GetFactionsByType('Guild') returned %v results, want 1", len(guildFactions))
|
|
}
|
|
|
|
// Test GetSpecialFactions and GetRegularFactions
|
|
specialFactions := mfl.GetSpecialFactions()
|
|
if len(specialFactions) != 1 {
|
|
t.Errorf("GetSpecialFactions() returned %v results, want 1", len(specialFactions))
|
|
}
|
|
|
|
regularFactions := mfl.GetRegularFactions()
|
|
if len(regularFactions) != 3 {
|
|
t.Errorf("GetRegularFactions() returned %v results, want 3", len(regularFactions))
|
|
}
|
|
|
|
// Test GetTypes
|
|
types := mfl.GetTypes()
|
|
if len(types) < 3 {
|
|
t.Errorf("GetTypes() returned %v types, want at least 3", len(types))
|
|
}
|
|
|
|
// Verify types contains expected values
|
|
typeMap := make(map[string]bool)
|
|
for _, factionType := range types {
|
|
typeMap[factionType] = true
|
|
}
|
|
if !typeMap["Special"] || !typeMap["City"] || !typeMap["Guild"] {
|
|
t.Error("GetTypes() should contain 'Special', 'City', and 'Guild'")
|
|
}
|
|
|
|
// Test UpdateFaction
|
|
updatedFaction := &Faction{
|
|
ID: 20,
|
|
Name: "Updated City Faction",
|
|
Type: "UpdatedCity",
|
|
Description: "An updated city faction",
|
|
}
|
|
|
|
err := mfl.UpdateFaction(updatedFaction)
|
|
if err != nil {
|
|
t.Errorf("UpdateFaction failed: %v", err)
|
|
}
|
|
|
|
// Verify the update worked
|
|
retrieved = mfl.GetFaction(20)
|
|
if retrieved.Name != "Updated City Faction" {
|
|
t.Errorf("Expected updated name 'Updated City Faction', got '%s'", retrieved.Name)
|
|
}
|
|
|
|
if retrieved.Type != "UpdatedCity" {
|
|
t.Errorf("Expected updated type 'UpdatedCity', got '%s'", retrieved.Type)
|
|
}
|
|
|
|
// Test updating non-existent faction
|
|
nonExistentFaction := &Faction{ID: 9999, Name: "Non-existent"}
|
|
err = mfl.UpdateFaction(nonExistentFaction)
|
|
if err == nil {
|
|
t.Error("UpdateFaction should fail for non-existent faction")
|
|
}
|
|
|
|
// Test GetAllFactionsList
|
|
allList := mfl.GetAllFactionsList()
|
|
if len(allList) != 4 {
|
|
t.Errorf("GetAllFactionsList() returned %v factions, want 4", len(allList))
|
|
}
|
|
|
|
// Test GetFactionIDs
|
|
ids := mfl.GetFactionIDs()
|
|
if len(ids) != 4 {
|
|
t.Errorf("GetFactionIDs() returned %v IDs, want 4", len(ids))
|
|
}
|
|
}
|
|
|
|
func TestMasterListConcurrency(t *testing.T) {
|
|
mfl := NewMasterList()
|
|
|
|
// Add initial factions
|
|
for i := 1; i <= 50; i++ {
|
|
faction := NewFaction(int32(i+100), "Faction", "Test", "Test faction")
|
|
mfl.AddFaction(faction)
|
|
}
|
|
|
|
// Test concurrent access
|
|
done := make(chan bool, 10)
|
|
|
|
// Concurrent readers
|
|
for i := 0; i < 5; i++ {
|
|
go func() {
|
|
defer func() { done <- true }()
|
|
for j := 0; j < 100; j++ {
|
|
mfl.GetFaction(int32(j%50 + 101))
|
|
mfl.GetFactionsByType("Test")
|
|
mfl.GetFactionByName("faction")
|
|
mfl.HasFaction(int32(j%50 + 101))
|
|
}
|
|
}()
|
|
}
|
|
|
|
// Concurrent writers
|
|
for i := 0; i < 5; i++ {
|
|
go func(workerID int) {
|
|
defer func() { done <- true }()
|
|
for j := 0; j < 10; j++ {
|
|
factionID := int32(workerID*1000 + j + 1000)
|
|
faction := NewFaction(factionID, "Worker Faction", "Worker", "Worker test faction")
|
|
mfl.AddFaction(faction) // Some may fail due to concurrent additions
|
|
}
|
|
}(i)
|
|
}
|
|
|
|
// Wait for all goroutines
|
|
for i := 0; i < 10; i++ {
|
|
<-done
|
|
}
|
|
|
|
// Verify final state - should have at least 50 initial factions
|
|
finalCount := mfl.GetFactionCount()
|
|
if finalCount < 50 {
|
|
t.Errorf("Expected at least 50 factions after concurrent operations, got %d", finalCount)
|
|
}
|
|
if finalCount > 100 {
|
|
t.Errorf("Expected at most 100 factions after concurrent operations, got %d", finalCount)
|
|
}
|
|
}
|