package appearances import ( "testing" "eq2emu/internal/database" ) func TestNew(t *testing.T) { db, err := database.NewSQLite("file::memory:?mode=memory&cache=shared") if err != nil { t.Fatalf("Failed to create test database: %v", err) } defer db.Close() // Test creating a new appearance appearance := New(db) if appearance == nil { t.Fatal("New returned nil") } if !appearance.IsNew() { t.Error("New appearance should be marked as new") } // Test setting values appearance.ID = 1001 appearance.Name = "Test Appearance" appearance.MinClient = 1096 if appearance.GetID() != 1001 { t.Errorf("Expected GetID() to return 1001, got %d", appearance.GetID()) } if appearance.GetName() != "Test Appearance" { t.Errorf("Expected GetName() to return 'Test Appearance', got %s", appearance.GetName()) } if appearance.GetMinClientVersion() != 1096 { t.Errorf("Expected GetMinClientVersion() to return 1096, got %d", appearance.GetMinClientVersion()) } } func TestNewWithData(t *testing.T) { db, err := database.NewSQLite("file::memory:?mode=memory&cache=shared") if err != nil { t.Fatalf("Failed to create test database: %v", err) } defer db.Close() appearance := NewWithData(100, "Human Male", 1096, db) if appearance == nil { t.Fatal("NewWithData returned nil") } if appearance.GetID() != 100 { t.Errorf("Expected ID 100, got %d", appearance.GetID()) } if appearance.GetName() != "Human Male" { t.Errorf("Expected name 'Human Male', got '%s'", appearance.GetName()) } if appearance.GetMinClientVersion() != 1096 { t.Errorf("Expected min client 1096, got %d", appearance.GetMinClientVersion()) } if !appearance.IsNew() { t.Error("NewWithData should create new appearance") } } func TestAppearanceGetters(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() app := NewWithData(123, "Test Appearance", 1096, db) if id := app.GetID(); id != 123 { t.Errorf("GetID() = %v, want 123", id) } if name := app.GetName(); name != "Test Appearance" { t.Errorf("GetName() = %v, want Test Appearance", name) } if nameStr := app.GetNameString(); nameStr != "Test Appearance" { t.Errorf("GetNameString() = %v, want Test Appearance", nameStr) } if minVer := app.GetMinClientVersion(); minVer != 1096 { t.Errorf("GetMinClientVersion() = %v, want 1096", minVer) } } func TestAppearanceSetters(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() app := NewWithData(100, "Original", 1000, db) app.SetName("Modified Name") if app.GetName() != "Modified Name" { t.Errorf("SetName failed: got %v, want Modified Name", app.GetName()) } app.SetMinClientVersion(2000) if app.GetMinClientVersion() != 2000 { t.Errorf("SetMinClientVersion failed: got %v, want 2000", app.GetMinClientVersion()) } } func TestIsCompatibleWithClient(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() app := NewWithData(100, "Test", 1096, db) tests := []struct { clientVersion int16 want bool }{ {1095, false}, // Below minimum {1096, true}, // Exact minimum {1097, true}, // Above minimum {2000, true}, // Well above minimum {0, false}, // Zero version } for _, tt := range tests { t.Run("", func(t *testing.T) { if got := app.IsCompatibleWithClient(tt.clientVersion); got != tt.want { t.Errorf("IsCompatibleWithClient(%v) = %v, want %v", tt.clientVersion, got, tt.want) } }) } } func TestAppearanceClone(t *testing.T) { db, _ := database.NewSQLite("file::memory:?mode=memory&cache=shared") defer db.Close() original := NewWithData(500, "Original Appearance", 1200, db) clone := original.Clone() if clone == nil { t.Fatal("Clone returned nil") } if clone == original { t.Error("Clone returned same pointer as original") } if clone.GetID() != original.GetID() { t.Errorf("Clone ID = %v, want %v", clone.GetID(), original.GetID()) } if clone.GetName() != original.GetName() { t.Errorf("Clone Name = %v, want %v", clone.GetName(), original.GetName()) } if clone.GetMinClientVersion() != original.GetMinClientVersion() { t.Errorf("Clone MinClientVersion = %v, want %v", clone.GetMinClientVersion(), original.GetMinClientVersion()) } if !clone.IsNew() { t.Error("Clone should always be marked as new") } // Verify modification independence clone.SetName("Modified Clone") if original.GetName() == "Modified Clone" { t.Error("Modifying clone affected original") } } // Test appearance type functions func TestGetAppearanceType(t *testing.T) { tests := []struct { typeName string expected int8 }{ {"hair_color1", AppearanceHairColor1}, {"soga_hair_color1", AppearanceSOGAHairColor1}, {"skin_color", AppearanceSkinColor}, {"eye_color", AppearanceEyeColor}, {"unknown_type", -1}, } for _, tt := range tests { t.Run(tt.typeName, func(t *testing.T) { result := GetAppearanceType(tt.typeName) if result != tt.expected { t.Errorf("GetAppearanceType(%q) = %d, want %d", tt.typeName, result, tt.expected) } }) } } func TestGetAppearanceTypeName(t *testing.T) { tests := []struct { typeConst int8 expected string }{ {AppearanceHairColor1, "hair_color1"}, {AppearanceSOGAHairColor1, "soga_hair_color1"}, {AppearanceSkinColor, "skin_color"}, {AppearanceEyeColor, "eye_color"}, {-1, "unknown"}, {100, "unknown"}, } for _, tt := range tests { t.Run("", func(t *testing.T) { result := GetAppearanceTypeName(tt.typeConst) if result != tt.expected { t.Errorf("GetAppearanceTypeName(%d) = %q, want %q", tt.typeConst, result, tt.expected) } }) } }