package classes import ( "testing" ) func TestGetClassID(t *testing.T) { tests := []struct { name string input string expected int8 }{ {"Uppercase", "WARRIOR", ClassWarrior}, {"Lowercase", "warrior", ClassWarrior}, {"Mixed case", "WaRrIoR", ClassWarrior}, {"With spaces", " WARRIOR ", ClassWarrior}, {"Invalid", "INVALID_CLASS", -1}, {"Empty", "", -1}, {"Tradeskill", "CARPENTER", ClassCarpenter}, {"Special", "CHANNELER", ClassChanneler}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := GetClassID(tt.input) if result != tt.expected { t.Errorf("GetClassID(%q) = %d, want %d", tt.input, result, tt.expected) } }) } } func TestGetClassName(t *testing.T) { tests := []struct { classID int8 expected string }{ {ClassWarrior, "WARRIOR"}, {ClassPriest, "PRIEST"}, {ClassCarpenter, "CARPENTER"}, {ClassChanneler, "CHANNELER"}, {-1, ""}, {100, ""}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetClassName(tt.classID) if result != tt.expected { t.Errorf("GetClassName(%d) = %q, want %q", tt.classID, result, tt.expected) } }) } } func TestGetClassNameCase(t *testing.T) { tests := []struct { classID int8 expected string }{ {ClassWarrior, "Warrior"}, {ClassShadowknight, "Shadowknight"}, {ClassTroubador, "Troubador"}, {ClassCarpenter, "Carpenter"}, {-1, ""}, {100, ""}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetClassNameCase(tt.classID) if result != tt.expected { t.Errorf("GetClassNameCase(%d) = %q, want %q", tt.classID, result, tt.expected) } }) } } func TestGetBaseClass(t *testing.T) { tests := []struct { classID int8 expected int8 }{ {ClassGuardian, ClassFighter}, {ClassBerserker, ClassFighter}, {ClassTemplar, ClassPriest}, {ClassWizard, ClassMage}, {ClassRanger, ClassScout}, {ClassChanneler, ClassPriest}, {ClassCommoner, ClassCommoner}, {ClassFighter, ClassCommoner}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetBaseClass(tt.classID) if result != tt.expected { t.Errorf("GetBaseClass(%d) = %d, want %d", tt.classID, result, tt.expected) } }) } } func TestGetSecondaryBaseClass(t *testing.T) { tests := []struct { classID int8 expected int8 }{ {ClassGuardian, ClassWarrior}, {ClassBerserker, ClassWarrior}, {ClassMonk, ClassBrawler}, {ClassTemplar, ClassCleric}, {ClassWizard, ClassSorcerer}, {ClassRanger, ClassPredator}, {ClassBeastlord, ClassAnimalist}, {ClassChanneler, ClassShaper}, {ClassWarrior, ClassCommoner}, // No secondary {ClassFighter, ClassCommoner}, // No secondary } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetSecondaryBaseClass(tt.classID) if result != tt.expected { t.Errorf("GetSecondaryBaseClass(%d) = %d, want %d", tt.classID, result, tt.expected) } }) } } func TestGetTSBaseClass(t *testing.T) { tests := []struct { classID int8 expected int8 }{ {3, 1}, // Guardian (3+42=45 >= ClassArtisan) returns ClassArtisan-44 = 1 {10, 1}, // Paladin (10+42=52 >= ClassArtisan) returns ClassArtisan-44 = 1 {0, 0}, // Commoner (0+42=42 < ClassArtisan) returns 0 {1, 1}, // Fighter (1+42=43 < ClassArtisan) returns 1 {2, 2}, // Warrior (2+42=44 < ClassArtisan) returns 2 } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetTSBaseClass(tt.classID) if result != tt.expected { t.Errorf("GetTSBaseClass(%d) = %d, want %d", tt.classID, result, tt.expected) } }) } } func TestIsValidClassID(t *testing.T) { tests := []struct { classID int8 expected bool }{ {ClassCommoner, true}, {ClassWarrior, true}, {ClassAlchemist, true}, {-1, false}, {100, false}, {58, false}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := IsValidClassID(tt.classID) if result != tt.expected { t.Errorf("IsValidClassID(%d) = %v, want %v", tt.classID, result, tt.expected) } }) } } func TestIsAdventureClass(t *testing.T) { tests := []struct { classID int8 expected bool }{ {ClassCommoner, true}, {ClassWarrior, true}, {ClassChanneler, true}, {ClassArtisan, false}, {ClassCarpenter, false}, {-1, false}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := IsAdventureClass(tt.classID) if result != tt.expected { t.Errorf("IsAdventureClass(%d) = %v, want %v", tt.classID, result, tt.expected) } }) } } func TestIsTradeskillClass(t *testing.T) { tests := []struct { classID int8 expected bool }{ {ClassArtisan, true}, {ClassCarpenter, true}, {ClassAlchemist, true}, {ClassWarrior, false}, {ClassCommoner, false}, {-1, false}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := IsTradeskillClass(tt.classID) if result != tt.expected { t.Errorf("IsTradeskillClass(%d) = %v, want %v", tt.classID, result, tt.expected) } }) } } func TestGetClassType(t *testing.T) { tests := []struct { classID int8 expected string }{ {ClassWarrior, ClassTypeAdventure}, {ClassChanneler, ClassTypeAdventure}, {ClassArtisan, ClassTypeTradeskill}, {ClassCarpenter, ClassTypeTradeskill}, {-1, ClassTypeSpecial}, {100, ClassTypeSpecial}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetClassType(tt.classID) if result != tt.expected { t.Errorf("GetClassType(%d) = %q, want %q", tt.classID, result, tt.expected) } }) } } func TestGetAllClasses(t *testing.T) { classes := GetAllClasses() // Check we have the right number of classes if len(classes) != 58 { t.Errorf("GetAllClasses() returned %d classes, want 58", len(classes)) } // Check a few specific classes if name, ok := classes[ClassWarrior]; !ok || name != "Warrior" { t.Errorf("GetAllClasses()[ClassWarrior] = %q, %v; want 'Warrior', true", name, ok) } if name, ok := classes[ClassCarpenter]; !ok || name != "Carpenter" { t.Errorf("GetAllClasses()[ClassCarpenter] = %q, %v; want 'Carpenter', true", name, ok) } } func TestGetClassInfo(t *testing.T) { // Test valid class info := GetClassInfo(ClassGuardian) if !info["valid"].(bool) { t.Error("GetClassInfo(ClassGuardian) should be valid") } if info["class_id"].(int8) != ClassGuardian { t.Errorf("GetClassInfo(ClassGuardian).class_id = %v, want %d", info["class_id"], ClassGuardian) } if info["name"].(string) != "GUARDIAN" { t.Errorf("GetClassInfo(ClassGuardian).name = %v, want 'GUARDIAN'", info["name"]) } if info["display_name"].(string) != "Guardian" { t.Errorf("GetClassInfo(ClassGuardian).display_name = %v, want 'Guardian'", info["display_name"]) } if info["base_class"].(int8) != ClassFighter { t.Errorf("GetClassInfo(ClassGuardian).base_class = %v, want %d", info["base_class"], ClassFighter) } if info["secondary_base_class"].(int8) != ClassWarrior { t.Errorf("GetClassInfo(ClassGuardian).secondary_base_class = %v, want %d", info["secondary_base_class"], ClassWarrior) } if !info["is_adventure"].(bool) { t.Error("GetClassInfo(ClassGuardian).is_adventure should be true") } if info["is_tradeskill"].(bool) { t.Error("GetClassInfo(ClassGuardian).is_tradeskill should be false") } // Test invalid class info = GetClassInfo(-1) if info["valid"].(bool) { t.Error("GetClassInfo(-1) should be invalid") } } func TestGetClassHierarchy(t *testing.T) { tests := []struct { classID int8 expected []int8 }{ {ClassGuardian, []int8{ClassGuardian, ClassWarrior, ClassFighter, ClassCommoner}}, {ClassWizard, []int8{ClassWizard, ClassSorcerer, ClassMage, ClassCommoner}}, {ClassFighter, []int8{ClassFighter, ClassCommoner}}, {ClassCommoner, []int8{ClassCommoner}}, {-1, nil}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetClassHierarchy(tt.classID) if len(result) != len(tt.expected) { t.Errorf("GetClassHierarchy(%d) = %v, want %v", tt.classID, result, tt.expected) return } for i, id := range result { if id != tt.expected[i] { t.Errorf("GetClassHierarchy(%d)[%d] = %d, want %d", tt.classID, i, id, tt.expected[i]) } } }) } } func TestIsSameArchetype(t *testing.T) { tests := []struct { classID1 int8 classID2 int8 expected bool }{ {ClassGuardian, ClassBerserker, true}, // Both Fighter archetype {ClassGuardian, ClassMonk, true}, // Both Fighter archetype {ClassWizard, ClassWarlock, true}, // Both Mage archetype {ClassGuardian, ClassWizard, false}, // Different archetypes {ClassCommoner, ClassCommoner, true}, // Same class {-1, ClassGuardian, false}, // Invalid class {ClassGuardian, -1, false}, // Invalid class } for _, tt := range tests { t.Run("", func(t *testing.T) { result := IsSameArchetype(tt.classID1, tt.classID2) if result != tt.expected { t.Errorf("IsSameArchetype(%d, %d) = %v, want %v", tt.classID1, tt.classID2, result, tt.expected) } }) } } func TestGetArchetypeClasses(t *testing.T) { // Test Fighter archetype fighterClasses := GetArchetypeClasses(ClassFighter) expectedFighterCount := 9 // Warrior through Paladin (2-10) if len(fighterClasses) != expectedFighterCount { t.Errorf("GetArchetypeClasses(ClassFighter) returned %d classes, want %d", len(fighterClasses), expectedFighterCount) } // Verify all returned classes are fighters for _, classID := range fighterClasses { if GetBaseClass(classID) != ClassFighter { t.Errorf("GetArchetypeClasses(ClassFighter) returned non-fighter class %d", classID) } } // Test Mage archetype mageClasses := GetArchetypeClasses(ClassMage) expectedMageCount := 9 // Sorcerer through Necromancer (22-30) if len(mageClasses) != expectedMageCount { t.Errorf("GetArchetypeClasses(ClassMage) returned %d classes, want %d", len(mageClasses), expectedMageCount) } }