865 lines
20 KiB
Go
865 lines
20 KiB
Go
package recipes
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
// Test Recipe creation and basic operations
|
|
func TestNewRecipe(t *testing.T) {
|
|
recipe := NewRecipe()
|
|
if recipe == nil {
|
|
t.Error("NewRecipe should not return nil")
|
|
}
|
|
if recipe.Components == nil {
|
|
t.Error("Components map should be initialized")
|
|
}
|
|
if recipe.Products == nil {
|
|
t.Error("Products map should be initialized")
|
|
}
|
|
}
|
|
|
|
func TestNewRecipeFromRecipe(t *testing.T) {
|
|
// Test with nil source
|
|
recipe := NewRecipeFromRecipe(nil)
|
|
if recipe == nil {
|
|
t.Error("NewRecipeFromRecipe with nil should return valid recipe")
|
|
}
|
|
|
|
// Test with valid source
|
|
source := NewRecipe()
|
|
source.ID = 12345
|
|
source.Name = "Test Recipe"
|
|
source.Level = 50
|
|
source.Tier = 5
|
|
source.Icon = 100
|
|
source.Components[0] = []int32{1001, 1002}
|
|
source.Products[0] = &RecipeProducts{
|
|
ProductID: 2001,
|
|
ProductQty: 1,
|
|
}
|
|
|
|
copied := NewRecipeFromRecipe(source)
|
|
if copied == nil {
|
|
t.Error("NewRecipeFromRecipe should not return nil")
|
|
}
|
|
if copied.ID != source.ID {
|
|
t.Error("Copied recipe should have same ID")
|
|
}
|
|
if copied.Name != source.Name {
|
|
t.Error("Copied recipe should have same name")
|
|
}
|
|
if copied.Level != source.Level {
|
|
t.Error("Copied recipe should have same level")
|
|
}
|
|
if copied.Tier != source.Tier {
|
|
t.Error("Copied recipe should have same tier")
|
|
}
|
|
|
|
// Check component copying
|
|
if len(copied.Components[0]) != len(source.Components[0]) {
|
|
t.Error("Components should be copied")
|
|
}
|
|
|
|
// Check product copying
|
|
if copied.Products[0] == nil {
|
|
t.Error("Products should be copied")
|
|
}
|
|
if copied.Products[0].ProductID != source.Products[0].ProductID {
|
|
t.Error("Product data should be copied correctly")
|
|
}
|
|
}
|
|
|
|
func TestRecipeIsValid(t *testing.T) {
|
|
// Test invalid recipe (empty)
|
|
recipe := NewRecipe()
|
|
if recipe.IsValid() {
|
|
t.Error("Empty recipe should not be valid")
|
|
}
|
|
|
|
// Test valid recipe
|
|
recipe.ID = 12345
|
|
recipe.Name = "Valid Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5 // Need valid tier for validation
|
|
if !recipe.IsValid() {
|
|
t.Error("Recipe with valid data should be valid")
|
|
}
|
|
|
|
// Test invalid ID
|
|
recipe.ID = 0
|
|
if recipe.IsValid() {
|
|
t.Error("Recipe with ID 0 should not be valid")
|
|
}
|
|
|
|
// Test empty name
|
|
recipe.ID = 12345
|
|
recipe.Name = ""
|
|
if recipe.IsValid() {
|
|
t.Error("Recipe with empty name should not be valid")
|
|
}
|
|
|
|
// Test invalid level
|
|
recipe.Name = "Valid Recipe"
|
|
recipe.Tier = 5
|
|
recipe.Level = -1
|
|
if recipe.IsValid() {
|
|
t.Error("Recipe with negative level should not be valid")
|
|
}
|
|
|
|
recipe.Level = 101
|
|
if recipe.IsValid() {
|
|
t.Error("Recipe with level > 100 should not be valid")
|
|
}
|
|
|
|
// Test invalid tier
|
|
recipe.Level = 50
|
|
recipe.Tier = 0
|
|
if recipe.IsValid() {
|
|
t.Error("Recipe with tier 0 should not be valid")
|
|
}
|
|
|
|
recipe.Tier = 11
|
|
if recipe.IsValid() {
|
|
t.Error("Recipe with tier > 10 should not be valid")
|
|
}
|
|
}
|
|
|
|
func TestRecipeGetTotalBuildComponents(t *testing.T) {
|
|
recipe := NewRecipe()
|
|
|
|
// Test with no build components
|
|
if recipe.GetTotalBuildComponents() != 0 {
|
|
t.Error("Recipe with no build components should return 0")
|
|
}
|
|
|
|
// Add build components to different slots
|
|
recipe.Components[SlotBuild1] = []int32{1001}
|
|
recipe.Components[SlotBuild3] = []int32{1003, 1004}
|
|
|
|
count := recipe.GetTotalBuildComponents()
|
|
if count != 2 {
|
|
t.Errorf("Expected 2 build component slots, got %d", count)
|
|
}
|
|
}
|
|
|
|
func TestRecipeCanUseRecipeByClass(t *testing.T) {
|
|
recipe := NewRecipe()
|
|
|
|
// Test "any class" recipe
|
|
recipe.Classes = 2
|
|
if !recipe.CanUseRecipeByClass(1) {
|
|
t.Error("Any class recipe should be usable by any class")
|
|
}
|
|
|
|
// Test specific class requirement
|
|
recipe.Classes = 1 << 3 // Bit 3 set (class ID 3)
|
|
if !recipe.CanUseRecipeByClass(3) {
|
|
t.Error("Recipe should be usable by matching class")
|
|
}
|
|
if recipe.CanUseRecipeByClass(2) {
|
|
t.Error("Recipe should not be usable by non-matching class")
|
|
}
|
|
}
|
|
|
|
func TestRecipeComponentOperations(t *testing.T) {
|
|
recipe := NewRecipe()
|
|
|
|
// Test getting components by slot
|
|
recipe.Components[0] = []int32{1001, 1002, 1003}
|
|
components := recipe.GetComponentsBySlot(0)
|
|
if len(components) != 3 {
|
|
t.Error("Should return all components for slot")
|
|
}
|
|
|
|
// Test with empty slot
|
|
emptyComponents := recipe.GetComponentsBySlot(1)
|
|
if len(emptyComponents) != 0 {
|
|
t.Error("Empty slot should return empty slice")
|
|
}
|
|
}
|
|
|
|
func TestRecipeProductOperations(t *testing.T) {
|
|
recipe := NewRecipe()
|
|
|
|
// Test getting products for stage
|
|
recipe.Products[0] = &RecipeProducts{
|
|
ProductID: 2001,
|
|
ProductQty: 1,
|
|
ByproductID: 2002,
|
|
ByproductQty: 2,
|
|
}
|
|
|
|
products := recipe.GetProductsForStage(0)
|
|
if products == nil {
|
|
t.Error("Should return products for stage")
|
|
}
|
|
if products.ProductID != 2001 {
|
|
t.Error("Product ID should match")
|
|
}
|
|
if products.ByproductID != 2002 {
|
|
t.Error("Byproduct ID should match")
|
|
}
|
|
|
|
// Test with empty stage
|
|
emptyProducts := recipe.GetProductsForStage(1)
|
|
if emptyProducts != nil {
|
|
t.Error("Empty stage should return nil")
|
|
}
|
|
}
|
|
|
|
// Test MasterRecipeList operations
|
|
func TestNewMasterRecipeList(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
if list == nil {
|
|
t.Error("NewMasterRecipeList should not return nil")
|
|
}
|
|
if list.recipes == nil {
|
|
t.Error("Recipes map should be initialized")
|
|
}
|
|
if list.stats == nil {
|
|
t.Error("Statistics should be initialized")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListAddRecipe(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Test adding nil recipe
|
|
if list.AddRecipe(nil) {
|
|
t.Error("Adding nil recipe should fail")
|
|
}
|
|
|
|
// Test adding invalid recipe
|
|
invalidRecipe := NewRecipe()
|
|
if list.AddRecipe(invalidRecipe) {
|
|
t.Error("Adding invalid recipe should fail")
|
|
}
|
|
|
|
// Test adding valid recipe
|
|
validRecipe := NewRecipe()
|
|
validRecipe.ID = 12345
|
|
validRecipe.Name = "Test Recipe"
|
|
validRecipe.Level = 50
|
|
validRecipe.Tier = 5 // Need valid tier
|
|
if !list.AddRecipe(validRecipe) {
|
|
t.Error("Adding valid recipe should succeed")
|
|
}
|
|
|
|
// Test adding duplicate recipe
|
|
duplicate := NewRecipe()
|
|
duplicate.ID = 12345
|
|
duplicate.Name = "Duplicate"
|
|
duplicate.Level = 60
|
|
if list.AddRecipe(duplicate) {
|
|
t.Error("Adding duplicate recipe ID should fail")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListGetRecipe(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Test getting non-existent recipe
|
|
recipe := list.GetRecipe(99999)
|
|
if recipe != nil {
|
|
t.Error("Getting non-existent recipe should return nil")
|
|
}
|
|
|
|
// Add a recipe
|
|
testRecipe := NewRecipe()
|
|
testRecipe.ID = 12345
|
|
testRecipe.Name = "Test Recipe"
|
|
testRecipe.Level = 50
|
|
testRecipe.Tier = 5 // Need valid tier
|
|
list.AddRecipe(testRecipe)
|
|
|
|
// Test getting existing recipe
|
|
retrieved := list.GetRecipe(12345)
|
|
if retrieved == nil {
|
|
t.Error("Getting existing recipe should not return nil")
|
|
}
|
|
if retrieved.ID != 12345 {
|
|
t.Error("Retrieved recipe should have correct ID")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListSize(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Test empty list
|
|
if list.Size() != 0 {
|
|
t.Error("Empty list should have size 0")
|
|
}
|
|
|
|
// Add recipes
|
|
for i := 1; i <= 3; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Test Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
list.AddRecipe(recipe)
|
|
}
|
|
|
|
if list.Size() != 3 {
|
|
t.Error("List with 3 recipes should have size 3")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListClear(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Add some recipes
|
|
for i := 1; i <= 3; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Test Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
list.AddRecipe(recipe)
|
|
}
|
|
|
|
// Clear the list
|
|
list.ClearRecipes()
|
|
|
|
if list.Size() != 0 {
|
|
t.Error("Cleared list should have size 0")
|
|
}
|
|
if list.GetRecipe(1) != nil {
|
|
t.Error("Recipe should not exist after clear")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListGetRecipesByTier(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Add recipes with different tiers
|
|
for i := 1; i <= 5; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Test Recipe"
|
|
recipe.Level = int8(i * 10)
|
|
recipe.Tier = int8(i)
|
|
list.AddRecipe(recipe)
|
|
}
|
|
|
|
// Get recipes for tier 3
|
|
tier3Recipes := list.GetRecipesByTier(3)
|
|
if len(tier3Recipes) != 1 {
|
|
t.Errorf("Expected 1 recipe for tier 3, got %d", len(tier3Recipes))
|
|
}
|
|
if tier3Recipes[0].Tier != 3 {
|
|
t.Error("Recipe should have tier 3")
|
|
}
|
|
|
|
// Get recipes for non-existent tier
|
|
emptyTier := list.GetRecipesByTier(99)
|
|
if len(emptyTier) != 0 {
|
|
t.Error("Non-existent tier should return empty slice")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListGetRecipesBySkill(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Add recipes with different skills
|
|
skillRecipe1 := NewRecipe()
|
|
skillRecipe1.ID = 1
|
|
skillRecipe1.Name = "Skill Recipe 1"
|
|
skillRecipe1.Level = 50
|
|
skillRecipe1.Tier = 5
|
|
skillRecipe1.Skill = 100
|
|
list.AddRecipe(skillRecipe1)
|
|
|
|
skillRecipe2 := NewRecipe()
|
|
skillRecipe2.ID = 2
|
|
skillRecipe2.Name = "Skill Recipe 2"
|
|
skillRecipe2.Level = 60
|
|
skillRecipe2.Tier = 6
|
|
skillRecipe2.Skill = 100
|
|
list.AddRecipe(skillRecipe2)
|
|
|
|
differentSkillRecipe := NewRecipe()
|
|
differentSkillRecipe.ID = 3
|
|
differentSkillRecipe.Name = "Different Skill Recipe"
|
|
differentSkillRecipe.Level = 50
|
|
differentSkillRecipe.Tier = 5
|
|
differentSkillRecipe.Skill = 200
|
|
list.AddRecipe(differentSkillRecipe)
|
|
|
|
// Get recipes for skill 100
|
|
skill100Recipes := list.GetRecipesBySkill(100)
|
|
if len(skill100Recipes) != 2 {
|
|
t.Errorf("Expected 2 recipes for skill 100, got %d", len(skill100Recipes))
|
|
}
|
|
|
|
// Get recipes for skill 200
|
|
skill200Recipes := list.GetRecipesBySkill(200)
|
|
if len(skill200Recipes) != 1 {
|
|
t.Errorf("Expected 1 recipe for skill 200, got %d", len(skill200Recipes))
|
|
}
|
|
}
|
|
|
|
// Test PlayerRecipeList operations
|
|
func TestNewPlayerRecipeList(t *testing.T) {
|
|
playerList := NewPlayerRecipeList()
|
|
if playerList == nil {
|
|
t.Error("NewPlayerRecipeList should not return nil")
|
|
}
|
|
if playerList.recipes == nil {
|
|
t.Error("Recipes map should be initialized")
|
|
}
|
|
}
|
|
|
|
func TestPlayerRecipeListAddRecipe(t *testing.T) {
|
|
playerList := NewPlayerRecipeList()
|
|
|
|
// Test adding nil recipe
|
|
if playerList.AddRecipe(nil) {
|
|
t.Error("Adding nil recipe should fail")
|
|
}
|
|
|
|
// Test adding valid recipe
|
|
recipe := NewRecipe()
|
|
recipe.ID = 12345
|
|
recipe.Name = "Test Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
if !playerList.AddRecipe(recipe) {
|
|
t.Error("Adding valid recipe should succeed")
|
|
}
|
|
|
|
// Test adding duplicate recipe
|
|
duplicate := NewRecipe()
|
|
duplicate.ID = 12345
|
|
duplicate.Name = "Duplicate"
|
|
duplicate.Level = 60
|
|
if playerList.AddRecipe(duplicate) {
|
|
t.Error("Adding duplicate recipe should fail")
|
|
}
|
|
}
|
|
|
|
func TestPlayerRecipeListGetRecipe(t *testing.T) {
|
|
playerList := NewPlayerRecipeList()
|
|
|
|
// Test checking non-existent recipe
|
|
if playerList.GetRecipe(99999) != nil {
|
|
t.Error("Player should not have non-existent recipe")
|
|
}
|
|
|
|
// Add a recipe
|
|
recipe := NewRecipe()
|
|
recipe.ID = 12345
|
|
recipe.Name = "Test Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
playerList.AddRecipe(recipe)
|
|
|
|
// Test checking existing recipe
|
|
if playerList.GetRecipe(12345) == nil {
|
|
t.Error("Player should have added recipe")
|
|
}
|
|
}
|
|
|
|
func TestPlayerRecipeListSize(t *testing.T) {
|
|
playerList := NewPlayerRecipeList()
|
|
|
|
// Test empty list
|
|
if playerList.Size() != 0 {
|
|
t.Error("Empty player recipe list should have size 0")
|
|
}
|
|
|
|
// Add recipes
|
|
for i := 1; i <= 3; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Test Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
playerList.AddRecipe(recipe)
|
|
}
|
|
|
|
if playerList.Size() != 3 {
|
|
t.Error("Player recipe list with 3 recipes should have size 3")
|
|
}
|
|
}
|
|
|
|
// Test Recipe Book List operations
|
|
func TestNewMasterRecipeBookList(t *testing.T) {
|
|
bookList := NewMasterRecipeBookList()
|
|
if bookList == nil {
|
|
t.Error("NewMasterRecipeBookList should not return nil")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeBookListOperations(t *testing.T) {
|
|
bookList := NewMasterRecipeBookList()
|
|
|
|
// Test adding recipe book
|
|
recipeBook := NewRecipe()
|
|
recipeBook.ID = 5001
|
|
recipeBook.BookID = 5001 // Need BookID for recipe books
|
|
recipeBook.Name = "Test Recipe Book"
|
|
recipeBook.Level = 1
|
|
recipeBook.Tier = 1
|
|
|
|
if !bookList.AddRecipeBook(recipeBook) {
|
|
t.Error("Adding valid recipe book should succeed")
|
|
}
|
|
|
|
// Test getting recipe book
|
|
retrieved := bookList.GetRecipeBook(5001)
|
|
if retrieved == nil {
|
|
t.Error("Should retrieve added recipe book")
|
|
}
|
|
if retrieved.ID != 5001 {
|
|
t.Error("Retrieved recipe book should have correct ID")
|
|
}
|
|
|
|
// Test size
|
|
if bookList.Size() != 1 {
|
|
t.Error("Recipe book list should have size 1")
|
|
}
|
|
}
|
|
|
|
func TestNewPlayerRecipeBookList(t *testing.T) {
|
|
playerBookList := NewPlayerRecipeBookList()
|
|
if playerBookList == nil {
|
|
t.Error("NewPlayerRecipeBookList should not return nil")
|
|
}
|
|
}
|
|
|
|
// Test RecipeManager operations
|
|
func TestNewRecipeManager(t *testing.T) {
|
|
manager := NewRecipeManager()
|
|
if manager == nil {
|
|
t.Error("NewRecipeManager should not return nil")
|
|
}
|
|
if manager.masterRecipeList == nil {
|
|
t.Error("Master recipe list should be initialized")
|
|
}
|
|
if manager.masterRecipeBookList == nil {
|
|
t.Error("Master recipe book list should be initialized")
|
|
}
|
|
if manager.loadedRecipes == nil {
|
|
t.Error("Loaded recipes map should be initialized")
|
|
}
|
|
if manager.loadedRecipeBooks == nil {
|
|
t.Error("Loaded recipe books map should be initialized")
|
|
}
|
|
}
|
|
|
|
func TestRecipeManagerGetters(t *testing.T) {
|
|
manager := NewRecipeManager()
|
|
|
|
// Test getting master lists
|
|
masterList := manager.GetMasterRecipeList()
|
|
if masterList == nil {
|
|
t.Error("Should return master recipe list")
|
|
}
|
|
|
|
masterBookList := manager.GetMasterRecipeBookList()
|
|
if masterBookList == nil {
|
|
t.Error("Should return master recipe book list")
|
|
}
|
|
|
|
// Test getting non-existent recipe
|
|
recipe := manager.GetRecipe(99999)
|
|
if recipe != nil {
|
|
t.Error("Non-existent recipe should return nil")
|
|
}
|
|
|
|
// Test getting non-existent recipe book
|
|
book := manager.GetRecipeBook(99999)
|
|
if book != nil {
|
|
t.Error("Non-existent recipe book should return nil")
|
|
}
|
|
}
|
|
|
|
func TestRecipeManagerStatistics(t *testing.T) {
|
|
manager := NewRecipeManager()
|
|
|
|
// Test getting statistics when enabled
|
|
manager.GetStatistics() // Call method without assignment to avoid lock copy
|
|
|
|
// Test disabling statistics
|
|
manager.SetStatisticsEnabled(false)
|
|
manager.GetStatistics() // Call method without assignment to avoid lock copy
|
|
|
|
// Test enabling statistics
|
|
manager.SetStatisticsEnabled(true)
|
|
}
|
|
|
|
func TestRecipeManagerValidation(t *testing.T) {
|
|
manager := NewRecipeManager()
|
|
|
|
// Test validation of empty manager
|
|
issues := manager.Validate()
|
|
if len(issues) > 0 {
|
|
// Manager validation might find issues, that's fine
|
|
}
|
|
}
|
|
|
|
func TestRecipeManagerSize(t *testing.T) {
|
|
manager := NewRecipeManager()
|
|
|
|
// Test size of empty manager
|
|
recipes, books := manager.Size()
|
|
if recipes != 0 {
|
|
t.Error("Empty manager should have 0 recipes")
|
|
}
|
|
if books != 0 {
|
|
t.Error("Empty manager should have 0 recipe books")
|
|
}
|
|
}
|
|
|
|
// Test RecipeComponent operations
|
|
func TestRecipeComponent(t *testing.T) {
|
|
component := &RecipeComponent{
|
|
ItemID: 1001,
|
|
Slot: 0,
|
|
}
|
|
|
|
if component.ItemID != 1001 {
|
|
t.Error("Component item ID should be set correctly")
|
|
}
|
|
if component.Slot != 0 {
|
|
t.Error("Component slot should be set correctly")
|
|
}
|
|
}
|
|
|
|
// Test RecipeProducts operations
|
|
func TestRecipeProducts(t *testing.T) {
|
|
products := &RecipeProducts{
|
|
ProductID: 2001,
|
|
ProductQty: 1,
|
|
ByproductID: 2002,
|
|
ByproductQty: 2,
|
|
}
|
|
|
|
if products.ProductID != 2001 {
|
|
t.Error("Product ID should be set correctly")
|
|
}
|
|
if products.ProductQty != 1 {
|
|
t.Error("Product quantity should be set correctly")
|
|
}
|
|
if products.ByproductID != 2002 {
|
|
t.Error("Byproduct ID should be set correctly")
|
|
}
|
|
if products.ByproductQty != 2 {
|
|
t.Error("Byproduct quantity should be set correctly")
|
|
}
|
|
}
|
|
|
|
// Test Statistics operations
|
|
func TestNewStatistics(t *testing.T) {
|
|
stats := NewStatistics()
|
|
if stats == nil {
|
|
t.Error("NewStatistics should not return nil")
|
|
}
|
|
if stats.RecipesByTier == nil {
|
|
t.Error("RecipesByTier map should be initialized")
|
|
}
|
|
if stats.RecipesBySkill == nil {
|
|
t.Error("RecipesBySkill map should be initialized")
|
|
}
|
|
}
|
|
|
|
func TestStatisticsOperations(t *testing.T) {
|
|
stats := NewStatistics()
|
|
|
|
// Test incrementing lookups
|
|
initialLookups := stats.RecipeLookups
|
|
stats.IncrementRecipeLookups()
|
|
if stats.RecipeLookups != initialLookups+1 {
|
|
t.Error("Recipe lookups should be incremented")
|
|
}
|
|
|
|
// Test incrementing recipe book lookups
|
|
initialBookLookups := stats.RecipeBookLookups
|
|
stats.IncrementRecipeBookLookups()
|
|
if stats.RecipeBookLookups != initialBookLookups+1 {
|
|
t.Error("Recipe book lookups should be incremented")
|
|
}
|
|
|
|
// Test incrementing player recipe loads
|
|
initialLoads := stats.PlayerRecipeLoads
|
|
stats.IncrementPlayerRecipeLoads()
|
|
if stats.PlayerRecipeLoads != initialLoads+1 {
|
|
t.Error("Player recipe loads should be incremented")
|
|
}
|
|
|
|
// Test incrementing component queries
|
|
initialQueries := stats.ComponentQueries
|
|
stats.IncrementComponentQueries()
|
|
if stats.ComponentQueries != initialQueries+1 {
|
|
t.Error("Component queries should be incremented")
|
|
}
|
|
|
|
// Test getting snapshot
|
|
snapshot := stats.GetSnapshot()
|
|
if snapshot.RecipeLookups != stats.RecipeLookups {
|
|
t.Error("Snapshot should match current stats")
|
|
}
|
|
}
|
|
|
|
// Test error constants
|
|
func TestErrorConstants(t *testing.T) {
|
|
if ErrRecipeNotFound == nil {
|
|
t.Error("ErrRecipeNotFound should be defined")
|
|
}
|
|
if ErrRecipeBookNotFound == nil {
|
|
t.Error("ErrRecipeBookNotFound should be defined")
|
|
}
|
|
if ErrInvalidRecipeID == nil {
|
|
t.Error("ErrInvalidRecipeID should be defined")
|
|
}
|
|
if ErrDuplicateRecipe == nil {
|
|
t.Error("ErrDuplicateRecipe should be defined")
|
|
}
|
|
}
|
|
|
|
// Test constants
|
|
func TestConstants(t *testing.T) {
|
|
// Test slot constants
|
|
if SlotPrimary != 0 {
|
|
t.Error("SlotPrimary should be 0")
|
|
}
|
|
if SlotBuild1 != 1 {
|
|
t.Error("SlotBuild1 should be 1")
|
|
}
|
|
if SlotFuel != 5 {
|
|
t.Error("SlotFuel should be 5")
|
|
}
|
|
|
|
// Test stage constants
|
|
if Stage0 != 0 {
|
|
t.Error("Stage0 should be 0")
|
|
}
|
|
if Stage4 != 4 {
|
|
t.Error("Stage4 should be 4")
|
|
}
|
|
|
|
// Test validation constants
|
|
if MinRecipeID != 1 {
|
|
t.Error("MinRecipeID should be 1")
|
|
}
|
|
if MaxRecipeLevel != 100 {
|
|
t.Error("MaxRecipeLevel should be 100")
|
|
}
|
|
}
|
|
|
|
// Edge case tests
|
|
func TestRecipeEdgeCases(t *testing.T) {
|
|
recipe := NewRecipe()
|
|
|
|
// Test accessing non-existent component slots
|
|
components := recipe.GetComponentsBySlot(99)
|
|
if len(components) != 0 {
|
|
t.Error("Non-existent slot should return empty slice")
|
|
}
|
|
|
|
// Test accessing non-existent product stages
|
|
products := recipe.GetProductsForStage(99)
|
|
if products != nil {
|
|
t.Error("Non-existent stage should return nil")
|
|
}
|
|
|
|
// Test recipe with maximum values
|
|
recipe.ID = MaxRecipeID
|
|
recipe.Level = MaxRecipeLevel
|
|
recipe.Tier = MaxTier
|
|
recipe.Name = "Max Recipe"
|
|
if !recipe.IsValid() {
|
|
t.Error("Recipe with maximum valid values should be valid")
|
|
}
|
|
}
|
|
|
|
func TestMasterRecipeListEdgeCases(t *testing.T) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Test operations on empty list
|
|
emptyTier := list.GetRecipesByTier(1)
|
|
if len(emptyTier) != 0 {
|
|
t.Error("Empty list should return empty slice for tier query")
|
|
}
|
|
|
|
emptySkill := list.GetRecipesBySkill(100)
|
|
if len(emptySkill) != 0 {
|
|
t.Error("Empty list should return empty slice for skill query")
|
|
}
|
|
|
|
// Test clearing already empty list
|
|
list.ClearRecipes()
|
|
if list.Size() != 0 {
|
|
t.Error("Clearing empty list should keep size 0")
|
|
}
|
|
}
|
|
|
|
// Benchmark tests
|
|
func BenchmarkNewRecipe(b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
NewRecipe()
|
|
}
|
|
}
|
|
|
|
func BenchmarkRecipeCopy(b *testing.B) {
|
|
source := NewRecipe()
|
|
source.ID = 12345
|
|
source.Name = "Benchmark Recipe"
|
|
source.Level = 50
|
|
source.Tier = 5
|
|
source.Components[0] = []int32{1001, 1002, 1003}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
NewRecipeFromRecipe(source)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterRecipeListAdd(b *testing.B) {
|
|
list := NewMasterRecipeList()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Benchmark Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
list.AddRecipe(recipe)
|
|
}
|
|
}
|
|
|
|
func BenchmarkMasterRecipeListGet(b *testing.B) {
|
|
list := NewMasterRecipeList()
|
|
|
|
// Add test recipes
|
|
for i := 1; i <= 1000; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Benchmark Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
list.AddRecipe(recipe)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
list.GetRecipe(int32((i % 1000) + 1))
|
|
}
|
|
}
|
|
|
|
func BenchmarkPlayerRecipeListOperations(b *testing.B) {
|
|
playerList := NewPlayerRecipeList()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
recipe := NewRecipe()
|
|
recipe.ID = int32(i)
|
|
recipe.Name = "Benchmark Recipe"
|
|
recipe.Level = 50
|
|
recipe.Tier = 5
|
|
playerList.AddRecipe(recipe)
|
|
playerList.GetRecipe(int32(i))
|
|
}
|
|
} |