From 55d5b1354ed9d8c0f29fab498ac3466b724519e3 Mon Sep 17 00:00:00 2001 From: K0ntr4 Date: Mon, 8 Apr 2024 17:34:58 +0200 Subject: [PATCH] added tablewriter to improve printing, made main and screenshot functions more reusable, updated readme and improved tests --- README.md | 31 ++--------- go.mod | 2 + go.sum | 4 ++ main.go | 90 ++++-------------------------- src/screenshot.go | 46 +++++++++++++++ src/takeScreenshot.go | 57 ------------------- src/utils.go | 85 +++++++++++++++++++--------- tests/random_test.go | 12 ++-- tests/utils_test.go | 127 +++++++++++++++++++++++++++++++++++++++--- 9 files changed, 251 insertions(+), 203 deletions(-) create mode 100644 src/screenshot.go delete mode 100644 src/takeScreenshot.go diff --git a/README.md b/README.md index 65f6de8..77804ea 100644 --- a/README.md +++ b/README.md @@ -41,34 +41,10 @@ The Pokemon Battle Advisor provides a convenient way to strategize and optimize 1. **Define Your Party:** ```go - func getMoveIgnoreError(name string) pokemonbattleadvisor.Move { - move, err := pokemonbattleadvisor.GetHelperStructsMove(name) - if err != nil { - return pokemonbattleadvisor.Move{} - } - return move - } - - func getTypesIgnoreError(pokemonName string) []string { - types, err := pokemonbattleadvisor.GetHelperStructsTypes(pokemonName) - if err != nil { - return []string{} - } - return types - } - func main() { var party = []pokemonbattleadvisor.Pokemon{ - { - Name: "weavile", Types: getTypesIgnoreError("weavile"), - Abilities: []string{"pressure"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("poison-jab"), - getMoveIgnoreError("false-swipe"), - getMoveIgnoreError("hail"), - getMoveIgnoreError("blizzard"), - }, - }, + pokemonbattleadvisor.GetPartyPokemon("weavile", []string{"pressure"}, []string{"poison-jab", "false-swipe", "hail", "blizzard"}), + } // Add more party members as needed } ``` @@ -80,7 +56,7 @@ The Pokemon Battle Advisor provides a convenient way to strategize and optimize ```go func getEnemyPokemon() (enemy pokemonbattleadvisor.Pokemon) { // Capture a screenshot of the battle - screenshot, err := pokemonbattleadvisor.TakeScreenshot() + screenshot, err = pokemonbattleadvisor.TakeScreenshot(0, 1250, 450, 1600, 800) // Adjust display and coordinates as needed if err != nil { return } @@ -140,5 +116,6 @@ The Pokemon Battle Advisor project utilizes several external libraries and resou - [imjeffhi/pokemon_classifier](https://huggingface.co/imjeffhi/pokemon_classifier): Utilizes a Hugging Face model for Pokemon classification. - [sajari/fuzzy](https://pkg.go.dev/github.com/sajari/fuzzy@v1.0.0): Implements fuzzy search functionality for improved user experience. - [kbinani/screenshot](https://pkg.go.dev/github.com/kbinani/screenshot@v0.0.0-20230812210009-b87d31814237): Enables capturing screenshots for automatic enemy detection. +- [olekukonko/typewriter](https://pkg.go.dev/github.com/olekukonko/tablewriter@v0.0.5): Provides table formatting functionality for improved output presentation. Special thanks to the developers and maintainers of these libraries for their contributions to the Pokemon Battle Advisor project. Their work greatly enhances the functionality and usability of the tool. \ No newline at end of file diff --git a/go.mod b/go.mod index cc55904..499d0b4 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/Kardbord/hfapigo/v2 v2.1.0 github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237 github.com/mtslzr/pokeapi-go v1.4.0 + github.com/olekukonko/tablewriter v0.0.5 github.com/sajari/fuzzy v1.0.0 ) @@ -13,6 +14,7 @@ require ( github.com/gen2brain/shm v0.0.0-20230802011745-f2460f5984f7 // indirect github.com/jezek/xgb v1.1.0 // indirect github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect golang.org/x/sys v0.11.0 // indirect ) diff --git a/go.sum b/go.sum index 15b37a5..09a1a38 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,12 @@ github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237 h1:YOp8St+CM/AQ github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237/go.mod h1:e7qQlOY68wOz4b82D7n+DdaptZAi+SHW0+yKiWZzEYE= github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mtslzr/pokeapi-go v1.4.0 h1:fp8+9OOxY168Nk4Tk27wCNG9f8MV+MVWO1fIlKjWW/M= github.com/mtslzr/pokeapi-go v1.4.0/go.mod h1:QYc519LxPVY3T2fm8ufHfvGSu4xUG+erNLHA5luiqq0= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/main.go b/main.go index 002f3d3..584e2b1 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,7 @@ func getEnemyPokemon() (enemy pokemonbattleadvisor.Pokemon) { var screenshot string var classifierResult string - screenshot, err = pokemonbattleadvisor.TakeScreenshot() + screenshot, err = pokemonbattleadvisor.TakeScreenshot(0, 1250, 450, 1600, 800) if err != nil { return } @@ -40,85 +40,15 @@ func getEnemyPokemon() (enemy pokemonbattleadvisor.Pokemon) { return enemy } -func getMoveIgnoreError(name string) pokemonbattleadvisor.Move { - move, err := pokemonbattleadvisor.GetHelperStructsMove(name) - if err != nil { - return pokemonbattleadvisor.Move{} - } - return move -} - -func getTypesIgnoreError(pokemonName string) []string { - types, err := pokemonbattleadvisor.GetHelperStructsTypes(pokemonName) - if err != nil { - return []string{} - } - return types -} - func main() { var enemy = getEnemyPokemon() var party = []pokemonbattleadvisor.Pokemon{ - { - Name: "weavile", Types: getTypesIgnoreError("weavile"), - Abilities: []string{"pressure"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("poison-jab"), - getMoveIgnoreError("false-swipe"), - getMoveIgnoreError("hail"), - getMoveIgnoreError("blizzard"), - }, - }, - { - Name: "clefable", Types: getTypesIgnoreError("clefable"), - Abilities: []string{"unaware"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("moonblast"), - getMoveIgnoreError("flash"), - getMoveIgnoreError("flamethrower"), - getMoveIgnoreError("double-slap"), - }, - }, - { - Name: "azumarill", Types: getTypesIgnoreError("azumarill"), - Abilities: []string{"huge-power"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("ice-beam"), - getMoveIgnoreError("play-rough"), - getMoveIgnoreError("surf"), - getMoveIgnoreError("hydro-pump"), - }, - }, - { - Name: "luxray", Types: getTypesIgnoreError("luxray"), - Abilities: []string{"rivalry"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("thunderbolt"), - getMoveIgnoreError("crunch"), - getMoveIgnoreError("flash"), - getMoveIgnoreError("discharge"), - }, - }, - { - Name: "ludicolo", Types: getTypesIgnoreError("ludicolo"), - Abilities: []string{"swift-swim"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("dive"), - getMoveIgnoreError("surf"), - getMoveIgnoreError("giga-drain"), - getMoveIgnoreError("energy-ball"), - }, - }, - { - Name: "sceptile", Types: getTypesIgnoreError("sceptile"), - Abilities: []string{"overgrow"}, - Moves: []pokemonbattleadvisor.Move{ - getMoveIgnoreError("cut"), - getMoveIgnoreError("dig"), - getMoveIgnoreError("energy-ball"), - getMoveIgnoreError("giga-drain"), - }, - }, + pokemonbattleadvisor.GetPartyPokemon("weavile", []string{"pressure"}, []string{"poison-jab", "false-swipe", "hail", "blizzard"}), + pokemonbattleadvisor.GetPartyPokemon("clefable", []string{"unaware"}, []string{"moonblast", "flash", "flamethrower", "double-slap"}), + pokemonbattleadvisor.GetPartyPokemon("azumarill", []string{"huge-power"}, []string{"ice-beam", "play-rough", "surf", "hydro-pump"}), + pokemonbattleadvisor.GetPartyPokemon("luxray", []string{"rivalry"}, []string{"thunderbolt", "crunch", "flash", "discharge"}), + pokemonbattleadvisor.GetPartyPokemon("ludicolo", []string{"swift-swim"}, []string{"dive", "surf", "giga-drain", "energy-ball"}), + pokemonbattleadvisor.GetPartyPokemon("sceptile", []string{"overgrow"}, []string{"cut", "dig", "energy-ball", "giga-drain"}), } pokemonbattleadvisor.PrintParty(&party) @@ -126,9 +56,11 @@ func main() { if shouldSwitch { fmt.Println("Should switch") fmt.Printf("Best party member: %s\n", party[partyMember].Name) - fmt.Printf("Best move: %s\n", party[partyMember].Moves[move].Name) + fmt.Println("Best move:") + pokemonbattleadvisor.PrintHelperStructsMove(&party[partyMember].Moves[move]) } else { fmt.Println("Should not switch") - fmt.Printf("Best move: %s\n", party[0].Moves[move].Name) + fmt.Println("Best move:") + pokemonbattleadvisor.PrintHelperStructsMove(&party[partyMember].Moves[move]) } } diff --git a/src/screenshot.go b/src/screenshot.go new file mode 100644 index 0000000..7976166 --- /dev/null +++ b/src/screenshot.go @@ -0,0 +1,46 @@ +package pokemonbattleadvisor + +import ( + "fmt" + "github.com/kbinani/screenshot" + "image" + "image/png" + "os" +) + +const defaultScreenshotPath = "screenshot.png" + +func save(img *image.RGBA, filePath string) (err error) { + var file *os.File + file, err = os.Create(filePath) + if err != nil { + return err + } + defer file.Close() + err = png.Encode(file, img) + if err != nil { + return err + } + return nil +} + +func TakeScreenshot(monitorIndex int, boundaries ...int) (string, error) { + var img *image.RGBA + var err error + + if !(len(boundaries) == 4) { + fmt.Printf("No correct boundaries provided, taking full screenshot\n") + img, err = screenshot.CaptureDisplay(monitorIndex) + } else { + img, err = screenshot.CaptureRect(image.Rect(boundaries[0], boundaries[1], boundaries[2], boundaries[3])) + } + if err != nil { + return "", err + } + + err = save(img, defaultScreenshotPath) + if err != nil { + return "", err + } + return defaultScreenshotPath, nil +} diff --git a/src/takeScreenshot.go b/src/takeScreenshot.go deleted file mode 100644 index bd4759e..0000000 --- a/src/takeScreenshot.go +++ /dev/null @@ -1,57 +0,0 @@ -package pokemonbattleadvisor - -import ( - "fmt" - "github.com/kbinani/screenshot" - "image" - "image/png" - "os" -) - -const defaultScreenshotPath = "screenshot.png" - -var cropBoarderByResolutions = map[[2]int]image.Rectangle{ // Crop boarder for different resolutions for pokemon revolution - {3840, 2160}: image.Rect(1900, 700, 2400, 1000), - {2560, 1440}: image.Rect(1250, 450, 1600, 800), - {1920, 1080}: image.Rect(950, 350, 1200, 500), - {1600, 900}: image.Rect(800, 300, 1000, 400), -} - -func save(img *image.RGBA, filePath string) (err error) { - var file *os.File - file, err = os.Create(filePath) - if err != nil { - return err - } - defer file.Close() - err = png.Encode(file, img) - if err != nil { - return err - } - return nil -} - -func getBounds(rectangle image.Rectangle) image.Rectangle { - if cropBoarderByResolutions[[2]int{rectangle.Dx(), rectangle.Dy()}] == (image.Rectangle{}) { - fmt.Printf("Resolution %dx%d is not supported please get enemy pokemon by name directly for improved accuracy\n", rectangle.Dx(), rectangle.Dy()) - return image.Rect(0, 0, rectangle.Dx(), rectangle.Dy()) - } - return cropBoarderByResolutions[[2]int{rectangle.Dx(), rectangle.Dy()}] -} - -func TakeScreenshot() (filename string, err error) { - var img *image.RGBA - - bounds := getBounds(screenshot.GetDisplayBounds(0)) - - img, err = screenshot.CaptureRect(bounds) - if err != nil { - return "", err - } - - err = save(img, defaultScreenshotPath) - if err != nil { - return "", err - } - return defaultScreenshotPath, nil -} diff --git a/src/utils.go b/src/utils.go index 65bb362..c44d45c 100644 --- a/src/utils.go +++ b/src/utils.go @@ -5,9 +5,40 @@ import ( "fmt" "github.com/mtslzr/pokeapi-go" "github.com/mtslzr/pokeapi-go/structs" + "github.com/olekukonko/tablewriter" "math/big" + "os" + "strings" ) +func getMoveIgnoreError(name string) Move { + move, err := GetHelperStructsMove(name) + if err != nil { + return Move{} + } + return move +} + +func getTypesIgnoreError(pokemonName string) []string { + types, err := GetHelperStructsTypes(pokemonName) + if err != nil { + return []string{} + } + return types +} + +func GetPartyPokemon(name string, abilities, moves []string) (pokemon Pokemon) { + pokemon = Pokemon{ + Name: name, + Types: getTypesIgnoreError(name), + Abilities: abilities, + } + for _, move := range moves { + pokemon.Moves = append(pokemon.Moves, getMoveIgnoreError(move)) + } + return pokemon +} + func GetHelperStructsTypes(pokemonName string) (types []string, err error) { var p structs.Pokemon p, err = pokeapi.Pokemon(pokemonName) @@ -99,39 +130,43 @@ func PokemonByName(name string) (pokemon Pokemon, err error) { } func PrintHelperStructsMove(move *Move) { - println(move.Name) - for range move.Name { - print("-") - } - println() - println("Type: ", move.Type) - fmt.Printf("Damage: %.1f\n", move.Damage) - fmt.Printf("Accuracy: %.1f\n", move.Accuracy) + data := [][]string{ + {"Name", move.Name}, + {"Type", move.Type}, + {"Damage", fmt.Sprintf("%.1f", move.Damage)}, + {"Accuracy", fmt.Sprintf("%.1f", move.Accuracy)}, + } + + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"Attribute", "Value"}) + + for _, v := range data { + table.Append(v) + } + table.Render() } func PrintHelperStructsPokemon(pokemon *Pokemon) { - println(pokemon.Name) - for range pokemon.Name { - print("-") - } - println() - println("Types: ") - for _, t := range pokemon.Types { - println(t) - } - println("Abilities: ") - for _, ability := range pokemon.Abilities { - println(ability) - } - println("Moves:") - for i := 0; i < len(pokemon.Moves); i++ { - PrintHelperStructsMove(&pokemon.Moves[i]) + pokemonTable := tablewriter.NewWriter(os.Stdout) + pokemonTable.SetHeader([]string{"Attribute", "Value"}) + pokemonTable.Append([]string{"Name", pokemon.Name}) + pokemonTable.Append([]string{"Types", strings.Join(pokemon.Types, ", ")}) + pokemonTable.Append([]string{"Abilities", strings.Join(pokemon.Abilities, ", ")}) + for i, move := range pokemon.Moves { + moveData := []string{ + fmt.Sprintf("Move #%d", i+1), + fmt.Sprintf("Name: %s\nType: %s\nDamage: %.1f\nAccuracy: %.1f", move.Name, move.Type, move.Damage, move.Accuracy), + } + pokemonTable.Append(moveData) } - println() + pokemonTable.Render() } func PrintParty(party *[]Pokemon) { for i := 0; i < len(*party); i++ { PrintHelperStructsPokemon(&(*party)[i]) + if i < len(*party)-1 { + fmt.Println() + } } } diff --git a/tests/random_test.go b/tests/random_test.go index 3185110..2ebfd28 100644 --- a/tests/random_test.go +++ b/tests/random_test.go @@ -46,9 +46,9 @@ func TestGetEnemyPokemonByName(t *testing.T) { t.Errorf("Expected abilities length: %d, got: %d", len(testCase.expectedAbilities), len(enemy.Abilities)) } - for _, ability := range enemy.Abilities { - if !slices.Contains(testCase.expectedAbilities, ability) { - t.Errorf("Expected ability: %s, got: %s", testCase.expectedAbilities, ability) + for _, ability := range testCase.expectedAbilities { + if !slices.Contains(enemy.Abilities, ability) { + t.Errorf("Expected ability: %s, got: %s", ability, enemy.Abilities) } } @@ -56,9 +56,9 @@ func TestGetEnemyPokemonByName(t *testing.T) { t.Errorf("Expected types length: %d, got: %d", len(testCase.expectedTypes), len(enemy.Types)) } - for _, typ := range enemy.Types { - if !slices.Contains(testCase.expectedTypes, typ) { - t.Errorf("Expected type: %s, got: %s", testCase.expectedTypes, typ) + for _, typ := range testCase.expectedTypes { + if !slices.Contains(enemy.Types, typ) { + t.Errorf("Expected type: %s, got: %s", typ, enemy.Types) } } }) diff --git a/tests/utils_test.go b/tests/utils_test.go index d64481d..f859c95 100644 --- a/tests/utils_test.go +++ b/tests/utils_test.go @@ -7,6 +7,115 @@ import ( "testing" ) +func TestGetPartyPokemon(t *testing.T) { + testCases := []struct { + name string + pokemonName string + abilities []string + moves []string + expectedName string + expectedAbilities []string + expectedTypes []string + expectedMoves []pokemonbattleadvisor.Move + }{ + { + name: "Test get party pokemon weavile", + pokemonName: "weavile", + abilities: []string{"pressure"}, + moves: []string{"poison-jab", "false-swipe", "hail", "blizzard"}, + expectedName: "weavile", + expectedAbilities: []string{"pressure"}, + expectedTypes: []string{"dark", "ice"}, + expectedMoves: []pokemonbattleadvisor.Move{ + {Name: "poison-jab", Type: "poison", Damage: 80.0, Accuracy: 1.0}, + {Name: "false-swipe", Type: "normal", Damage: 40.0, Accuracy: 1.0}, + {Name: "hail", Type: "ice", Damage: 0.0, Accuracy: 0.0}, + {Name: "blizzard", Type: "ice", Damage: 110.0, Accuracy: 0.7}, + }, + }, + { + name: "Test get party pokemon clefable", + pokemonName: "clefable", + abilities: []string{"unaware"}, + moves: []string{"moonblast", "flash", "flamethrower", "double-slap"}, + expectedName: "clefable", + expectedAbilities: []string{"unaware"}, + expectedTypes: []string{"fairy"}, + expectedMoves: []pokemonbattleadvisor.Move{ + {Name: "moonblast", Type: "fairy", Damage: 95.0, Accuracy: 1.0}, + {Name: "flash", Type: "normal", Damage: 0.0, Accuracy: 1.0}, + {Name: "flamethrower", Type: "fire", Damage: 90.0, Accuracy: 1.0}, + {Name: "double-slap", Type: "normal", Damage: 45.0, Accuracy: 0.85}, + }, + }, + { + name: "Test get party pokemon azumarill", + pokemonName: "azumarill", + abilities: []string{"huge-power"}, + moves: []string{"ice-beam", "play-rough", "surf", "hydro-pump"}, + expectedName: "azumarill", + expectedAbilities: []string{"huge-power"}, + expectedTypes: []string{"water", "fairy"}, + expectedMoves: []pokemonbattleadvisor.Move{ + {Name: "ice-beam", Type: "ice", Damage: 90.0, Accuracy: 1.0}, + {Name: "play-rough", Type: "fairy", Damage: 90.0, Accuracy: 0.9}, + {Name: "surf", Type: "water", Damage: 90.0, Accuracy: 1.0}, + {Name: "hydro-pump", Type: "water", Damage: 110.0, Accuracy: 0.8}, + }, + }, + { + name: "Test get party pokemon charmander", + pokemonName: "charmander", + abilities: []string{"blaze"}, + moves: []string{"ember", "flamethrower", "fire-blast", "fire-spin"}, + expectedName: "charmander", + expectedAbilities: []string{"blaze"}, + expectedTypes: []string{"fire"}, + expectedMoves: []pokemonbattleadvisor.Move{ + {Name: "ember", Type: "fire", Damage: 40.0, Accuracy: 1.0}, + {Name: "flamethrower", Type: "fire", Damage: 90.0, Accuracy: 1.0}, + {Name: "fire-blast", Type: "fire", Damage: 110.0, Accuracy: 0.85}, + {Name: "fire-spin", Type: "fire", Damage: 35.0, Accuracy: 0.85}, + }, + }, + } + + for _, tc := range testCases { + testCase := tc + t.Run(testCase.name, func(t *testing.T) { + actual := pokemonbattleadvisor.GetPartyPokemon(testCase.pokemonName, testCase.abilities, testCase.moves) + + if actual.Name != testCase.expectedName { + t.Errorf("Expected name: %s, got: %s", testCase.expectedName, actual.Name) + } + + if len(actual.Abilities) != len(testCase.expectedAbilities) { + t.Errorf("Expected abilities length: %d, got: %d", len(testCase.expectedAbilities), len(actual.Abilities)) + } + + for i, ability := range actual.Abilities { + if ability != testCase.expectedAbilities[i] { + t.Errorf("Expected ability at index %d: %s, got: %s", i, testCase.expectedAbilities[i], ability) + } + } + + if len(actual.Types) != len(testCase.expectedTypes) { + t.Errorf("Expected types length: %d, got: %d", len(testCase.expectedTypes), len(actual.Types)) + } + + if len(actual.Moves) != len(testCase.expectedMoves) { + t.Errorf("Expected moves length: %d, got: %d", len(testCase.expectedMoves), len(actual.Moves)) + } + + for _, move := range testCase.expectedMoves { + if !slices.Contains(actual.Moves, move) { + t.Errorf("Expected move: %v, got: %v", move, actual.Moves) + } + } + }) + } +} + func TestGetHelperStructsMove(t *testing.T) { testCases := []struct { name string @@ -175,9 +284,9 @@ func TestPokemonByName(t *testing.T) { t.Errorf("Expected abilities length: %d, got: %d", len(tc.expectedAbilities), len(actual.Abilities)) } - for i, ability := range actual.Abilities { - if !slices.Contains(tc.expectedAbilities, ability) { - t.Errorf("Expected ability at index %d: %s, got: %s", i, tc.expectedAbilities[i], ability) + for i, ability := range tc.expectedAbilities { + if !slices.Contains(actual.Abilities, ability) { + t.Errorf("Expected ability at index %d: %s, got: %s", i, ability, actual.Abilities[i]) } } @@ -185,9 +294,9 @@ func TestPokemonByName(t *testing.T) { t.Errorf("Expected types length: %d, got: %d", len(tc.expectedTypes), len(actual.Types)) } - for i, typ := range actual.Types { - if !slices.Contains(tc.expectedTypes, typ) { - t.Errorf("Expected type at index %d: %s, got: %s", i, tc.expectedTypes[i], typ) + for i, typ := range tc.expectedTypes { + if !slices.Contains(actual.Types, typ) { + t.Errorf("Expected type at index %d: %s, got: %s", i, typ, actual.Types[i]) } } }) @@ -406,9 +515,9 @@ func TestCastToHelperStructsPokemon(t *testing.T) { t.Errorf("Expected moves length: %d, got: %d", len(expected.Moves), len(actual.Moves)) } - for _, move := range actual.Moves { - if !slices.Contains(expected.Moves, move) { - t.Errorf("Expected move: %v, got: %v", move, expected.Moves) + for _, move := range expected.Moves { + if !slices.Contains(actual.Moves, move) { + t.Errorf("Expected move: %v, got: %v", move, actual.Moves) } }